windows-nt/Source/XPSP1/NT/multimedia/opengl/toolkits/libmtk/texa8.cxx
2020-09-26 16:20:57 +08:00

272 lines
5.6 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 "mtk.h"
#include "texture.hxx"
#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 (;;)
{
#if 0
// orig
code = *((unsigned short HW_UNALIGNED *)s)++;
#else
// code = *( ((unsigned short *)s)++ );
//mf: will this incremement OK ?
code = *( ((unsigned short HW_UNALIGNED *)s ++) );
#endif
run = code & 0xff;
esc = code >> 8;
if (run == ESCAPE)
{
if (esc == ESC_ENDBITMAP)
{
break;
}
else if (esc == ESC_DELTA)
{
#if 0
len = *((unsigned short HW_UNALIGNED *)s)++;
#else
len = *((unsigned short HW_UNALIGNED *)s++);
#endif
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 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 (;;)
{
#if 0
code = *((unsigned short HW_UNALIGNED *)s)++;
#else
code = *((unsigned short HW_UNALIGNED *)s++);
#endif
run = code & 0xff;
esc = code >> 8;
if (run == ESCAPE)
{
if (esc == ESC_ENDBITMAP)
{
break;
}
else if (esc == ESC_DELTA)
{
#if 0
len = *((unsigned short HW_UNALIGNED *)s)++;
#else
len = *((unsigned short HW_UNALIGNED *)s++);
#endif
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 s-src;
}
#define ALPHA_SIGNATURE 0xa0a1a2a3
#define COMPRESS_NONE 0
#define COMPRESS_RLE 1
BOOL
TEXTURE::A8ImageLoad(void *pvResource )
{
DWORD compress;
DWORD size;
DWORD *pal;
BYTE *buf;
DWORD *pdwA8;
PUCHAR data;
pdwA8 = (DWORD *)pvResource;
// Check data signature for alpha texture format
if (*pdwA8 != ALPHA_SIGNATURE)
{
return FALSE;
}
pdwA8++;
width = *pdwA8++;
height = *pdwA8++;
// Make sure depth is 8bpp
if (*pdwA8 != 8)
{
return FALSE;
}
pdwA8++;
size = width*height;
// Compression type
compress = *pdwA8++;
// Compressed data size only if compressed, not used
pdwA8++;
// Remember pointer to palette data
pal = pdwA8;
pdwA8 += 256;
if (mtk_PalettedTextureEnabled())
{
// Allocate data for final image
data = (PUCHAR) malloc(size);
if (data == NULL)
{
return FALSE;
}
pal_size = 256;
pal = (DWORD *) malloc(pal_size*sizeof(RGBQUAD));
if (pal == NULL)
{
free(data);
return FALSE;
}
memcpy(pal, pal, pal_size*sizeof(RGBQUAD));
// Unpack 8bpp data into final image
if (compress == COMPRESS_NONE)
{
memcpy(data, pdwA8, size);
}
else
{
HwuRld((HwMem)pdwA8, data, 1);
}
format = GL_COLOR_INDEX;
components = GL_COLOR_INDEX8_EXT;
}
else
{
// Allocate data for final image
data = (PUCHAR) malloc(size*sizeof(DWORD));
if (data == NULL)
{
return FALSE;
}
pal_size = 0;
pal = NULL;
// Unpack 8bpp data into final image
if (compress == COMPRESS_NONE)
{
DWORD i;
BYTE *src;
DWORD *dst;
src = (BYTE *)pdwA8;
dst = (DWORD *)data;
for (i = 0; i < size; i++)
{
*dst++ = pal[*src++];
}
}
else
{
HwuRldTo32((HwMem)pdwA8, data, 1, pal);
}
format = GL_BGRA_EXT;
components = 4;
}
return TRUE;
}