windows-nt/Source/XPSP1/NT/multimedia/opengl/scrsave/common/ssa8.c
2020-09-26 16:20:57 +08:00

250 lines
5.4 KiB
C

/******************************Module*Header*******************************\
* Module Name: ssa8.c
*
* Operations on .a8 files
*
* Copyright (c) 1995 Microsoft Corporation
*
\**************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "tk.h"
#include "sscommon.h"
#define ESCAPE 0
#define ESC_ENDLINE 0
#define ESC_ENDBITMAP 1
#define ESC_DELTA 2
#define ESC_RANDOM 3
#define RANDOM_COUNT(c) ((c)-(ESC_RANDOM-1))
#define COUNT_SIZE 256
#define MAXRUN (COUNT_SIZE-1)
#define MAXRND (RANDOM_COUNT(COUNT_SIZE)-1)
typedef unsigned char *HwMem;
typedef unsigned long HwMemSize;
#define HW_UNALIGNED UNALIGNED
static HwMemSize HwuRld(HwMem src, HwMem dest, HwMemSize stride)
{
unsigned short code;
unsigned char run, esc;
size_t len;
HwMem s;
HwMem f;
s = src;
f = dest;
for (;;)
{
code = *((unsigned short HW_UNALIGNED *)s)++;
run = code & 0xff;
esc = code >> 8;
if (run == ESCAPE)
{
if (esc == ESC_ENDBITMAP)
{
break;
}
else if (esc == ESC_DELTA)
{
len = *((unsigned short HW_UNALIGNED *)s)++;
while (len-- > 0)
{
*f = 0;
f += stride;
}
}
else if (esc >= ESC_RANDOM)
{
len = RANDOM_COUNT(esc);
while (len-- > 0)
{
*f = *s++;
f += stride;
}
}
}
else
{
while (run-- > 0)
{
*f = esc;
f += stride;
}
}
}
return (HwMemSize)((ULONG_PTR)(s-src));
}
static HwMemSize HwuRldTo32(HwMem src, HwMem dest, HwMemSize stride,
DWORD *translate)
{
unsigned short code;
unsigned char run, esc;
size_t len;
HwMem s;
DWORD *f, tran;
s = src;
f = (DWORD *)dest;
for (;;)
{
code = *((unsigned short HW_UNALIGNED *)s)++;
run = code & 0xff;
esc = code >> 8;
if (run == ESCAPE)
{
if (esc == ESC_ENDBITMAP)
{
break;
}
else if (esc == ESC_DELTA)
{
len = *((unsigned short HW_UNALIGNED *)s)++;
while (len-- > 0)
{
*f = translate[0];
f += stride;
}
}
else if (esc >= ESC_RANDOM)
{
len = RANDOM_COUNT(esc);
while (len-- > 0)
{
*f = translate[*s++];
f += stride;
}
}
}
else
{
tran = translate[esc];
while (run-- > 0)
{
*f = tran;
f += stride;
}
}
}
return (HwMemSize)((ULONG_PTR)(s-src));
}
#define ALPHA_SIGNATURE 0xa0a1a2a3
#define COMPRESS_NONE 0
#define COMPRESS_RLE 1
BOOL ss_A8ImageLoad(void *pvResource, TEXTURE *ptex)
{
DWORD compress;
DWORD size;
DWORD *pal;
BYTE *buf;
DWORD *pdwA8;
pdwA8 = (DWORD *)pvResource;
// Check data signature for alpha texture format
if (*pdwA8 != ALPHA_SIGNATURE)
{
return FALSE;
}
pdwA8++;
ptex->width = *pdwA8++;
ptex->height = *pdwA8++;
// Make sure depth is 8bpp
if (*pdwA8 != 8)
{
return FALSE;
}
pdwA8++;
size = ptex->width*ptex->height;
// Compression type
compress = *pdwA8++;
// Compressed data size only if compressed, not used
pdwA8++;
// Remember pointer to palette data
pal = pdwA8;
pdwA8 += 256;
if (ss_PalettedTextureEnabled())
{
// Allocate data for final image
ptex->data = malloc(size);
if (ptex->data == NULL)
{
return FALSE;
}
ptex->pal_size = 256;
ptex->pal = malloc(ptex->pal_size*sizeof(RGBQUAD));
if (ptex->pal == NULL)
{
free(ptex->data);
return FALSE;
}
memcpy(ptex->pal, pal, ptex->pal_size*sizeof(RGBQUAD));
// Unpack 8bpp data into final image
if (compress == COMPRESS_NONE)
{
memcpy(ptex->data, pdwA8, size);
}
else
{
HwuRld((HwMem)pdwA8, ptex->data, 1);
}
ptex->format = GL_COLOR_INDEX;
ptex->components = GL_COLOR_INDEX8_EXT;
}
else
{
// Allocate data for final image
ptex->data = malloc(size*sizeof(DWORD));
if (ptex->data == NULL)
{
return FALSE;
}
ptex->pal_size = 0;
ptex->pal = NULL;
// Unpack 8bpp data into final image
if (compress == COMPRESS_NONE)
{
DWORD i;
BYTE *src;
DWORD *dst;
src = (BYTE *)pdwA8;
dst = (DWORD *)ptex->data;
for (i = 0; i < size; i++)
{
*dst++ = pal[*src++];
}
}
else
{
HwuRldTo32((HwMem)pdwA8, ptex->data, 1, pal);
}
ptex->format = GL_BGRA_EXT;
ptex->components = 4;
}
return TRUE;
}