📄 giftobmp.c
字号:
/*
Convert in-memory face GIF file to BMP format.
based on the NETPBM utility GIFTOPNM:
*/
/* +-------------------------------------------------------------------+ */
/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */
/* | Permission to use, copy, modify, and distribute this software | */
/* | and its documentation for any purpose and without fee is hereby | */
/* | granted, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. This software is | */
/* | provided "as is" without express or implied warranty. | */
/* +-------------------------------------------------------------------+ */
#include "netfone.h"
#define MAXCOLORMAPSIZE 256
#define CM_RED 0
#define CM_GREEN 1
#define CM_BLUE 2
#define MAX_LWZ_BITS 12
#define INTERLACE 0x40
#define LOCALCOLORMAP 0x80
#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
#define PBM_TYPE 1
#define PGM_TYPE 2
#define PPM_TYPE 3
static LPBYTE gifFile; // In-memory GIF file pointer
static long gifAddr; // "Seek address" in GIF file
static LPBYTE bmpFile = NULL; // In-memory BMP file being constructed
#define ReadOK(file, buffer, len) ((_fmemcpy(buffer, gifFile + gifAddr, len), gifAddr += len), TRUE)
#define LM_to_uint(a, b) (((b) << 8) | (a))
struct GifScreenStruct {
unsigned int Width;
unsigned int Height;
unsigned char ColorMap[3][MAXCOLORMAPSIZE];
unsigned int BitPixel;
unsigned int ColorResolution;
unsigned int Background;
unsigned int AspectRatio;
int GrayScale;
};
static struct {
int transparent;
int delayTime;
int inputFlag;
int disposal;
} Gif89 = { -1, -1, -1, 0 };
/* GIFtoBMP uses a lot of storage for LZW decoding, colour map
tables etc. To avoid busting DGROUP in 16 bit medium memory
model or going to large model (which would block multiple
instances running at once), we define these buffers as members
of a "context" structure which is allocated from the global heap
for the duration of our processing. */
static struct context {
struct GifScreenStruct c_GifScreen;
unsigned char c_GetCodebuf[280];
int c_LZWtable[2][(1 << MAX_LWZ_BITS)];
int c_LZWstack[(1 << (MAX_LWZ_BITS)) * 2];
unsigned char c_localColorMap[3][MAXCOLORMAPSIZE];
} FAR *GIFcontext = NULL;
// Now define shortcuts to access items in the context
#define GifScreen GIFcontext->c_GifScreen
#define GetCodebuf GIFcontext->c_GetCodebuf
#define LZWtable GIFcontext->c_LZWtable
#define LZWstack GIFcontext->c_LZWstack
#define localColorMap GIFcontext->c_localColorMap
#define pm_error(x) { fatal = TRUE; \
if (GIFcontext != NULL) { GlobalFreePtr(GIFcontext); GIFcontext = NULL; } \
if (bmpFile != NULL) { GlobalFreePtr(bmpFile); bmpFile = NULL; } \
return FALSE; }
static int fatal;
static int ZeroDataBlock = FALSE;
// READCOLORMAP -- Read colour palette table
static int ReadColorMap(int number, unsigned char FAR buffer[3][MAXCOLORMAPSIZE])
{
int i;
unsigned char rgb[3];
int flag;
flag = FALSE;
for (i = 0; i < number; ++i) {
ReadOK(fd, rgb, sizeof(rgb));
buffer[CM_RED][i] = rgb[0];
buffer[CM_GREEN][i] = rgb[1];
buffer[CM_BLUE][i] = rgb[2];
flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]);
}
return TRUE;
}
// GETDATABLOCK -- Read a variable-sized data block
static int GetDataBlock(LPBYTE buf)
{
unsigned char count;
ReadOK(fd, &count, 1);
ZeroDataBlock = count == 0;
if (count == 0) {
return -1;
}
ReadOK(fd, buf, count);
return count;
}
// GETCODE -- Read LZW code
static int GetCode(int code_size, int flag)
{
static int curbit, lastbit, done, last_byte;
int i, j, ret;
unsigned char count;
if (flag) {
curbit = 0;
lastbit = 0;
done = FALSE;
return 0;
}
if ((curbit + code_size) >= lastbit) {
if (done) {
return -1;
}
GetCodebuf[0] = GetCodebuf[last_byte - 2];
GetCodebuf[1] = GetCodebuf[last_byte - 1];
if ((count = GetDataBlock(&GetCodebuf[2])) == 0)
done = TRUE;
last_byte = 2 + count;
curbit = (curbit - lastbit) + 16;
lastbit = (2 + count) * 8 ;
}
ret = 0;
for (i = curbit, j = 0; j < code_size; ++i, ++j)
ret |= ((GetCodebuf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
curbit += code_size;
return ret;
}
// LWZREADBYTE -- Read next uncompressed byte from the compressed stream
static int LWZReadByte(int flag, int input_code_size)
{
static int fresh = FALSE;
int code, incode;
static int code_size, set_code_size;
static int max_code, max_code_size;
static int firstcode, oldcode;
static int clear_code, end_code;
static int FAR *sp;
register int i;
if (flag) {
set_code_size = input_code_size;
code_size = set_code_size + 1;
clear_code = 1 << set_code_size ;
end_code = clear_code + 1;
max_code_size = 2 * clear_code;
max_code = clear_code+2;
GetCode(0, TRUE);
fresh = TRUE;
for (i = 0; i < clear_code; ++i) {
LZWtable[0][i] = 0;
LZWtable[1][i] = i;
}
for (; i < (1 << MAX_LWZ_BITS); ++i)
LZWtable[0][i] = LZWtable[1][0] = 0;
sp = LZWstack;
return 0;
} else if (fresh) {
fresh = FALSE;
do {
firstcode = oldcode =
GetCode(code_size, FALSE);
} while (firstcode == clear_code);
return firstcode;
}
if (sp > LZWstack)
return *--sp;
while ((code = GetCode(code_size, FALSE)) >= 0) {
if (code == clear_code) {
for (i = 0; i < clear_code; ++i) {
LZWtable[0][i] = 0;
LZWtable[1][i] = i;
}
for (; i < (1 << MAX_LWZ_BITS); ++i)
LZWtable[0][i] = LZWtable[1][i] = 0;
code_size = set_code_size + 1;
max_code_size = 2 * clear_code;
max_code = clear_code + 2;
sp = LZWstack;
firstcode = oldcode =
GetCode(code_size, FALSE);
return firstcode;
} else if (code == end_code) {
int count;
unsigned char buf[260];
if (ZeroDataBlock)
return -2;
while ((count = GetDataBlock(buf)) > 0) ;
return -2;
}
incode = code;
if (code >= max_code) {
*sp++ = firstcode;
code = oldcode;
}
while (code >= clear_code) {
*sp++ = LZWtable[1][code];
if (code == LZWtable[0][code]) {
fatal = TRUE;
return -1;
}
code = LZWtable[0][code];
}
*sp++ = firstcode = LZWtable[1][code];
if ((code = max_code) <(1 << MAX_LWZ_BITS)) {
LZWtable[0][code] = oldcode;
LZWtable[1][code] = firstcode;
++max_code;
if ((max_code >= max_code_size) &&
(max_code_size < (1 << MAX_LWZ_BITS))) {
max_code_size *= 2;
++code_size;
}
}
oldcode = incode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -