📄 giftobmp.c
字号:
if (sp > LZWstack)
return *--sp;
}
return code;
}
// DOEXTENSION -- Process extension items
static int DoExtension(int label)
{
char buf[256];
#ifdef GIF_DEBUG
char *str;
#endif
switch (label) {
case 0x01: /* Plain Text Extension */
#ifdef GIF_DEBUG
str = "Plain Text Extension";
#endif
break;
case 0xff: /* Application Extension */
#ifdef GIF_DEBUG
str = "Application Extension";
#endif
break;
case 0xfe: /* Comment Extension */
#ifdef GIF_DEBUG
str = "Comment Extension";
#endif
// This line should fix many crashes because John Walker was
// originally checking for a zero return, which would never
// occur because if the block is zero length, GetDataBlock()
// returns -1, never 0.
while (GetDataBlock((unsigned char *) buf) != -1) {
}
return FALSE;
case 0xf9: /* Graphic Control Extension */
#ifdef GIF_DEBUG
str = "Graphic Control Extension";
#endif
(void) GetDataBlock((unsigned char *) buf);
Gif89.disposal = (buf[0] >> 2) & 0x7;
Gif89.inputFlag = (buf[0] >> 1) & 0x1;
Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
if ((buf[0] & 0x1) != 0)
Gif89.transparent = buf[3];
// This line should fix many crashes because John Walker was
// originally checking for a zero return, which would never
// occur because if the block is zero length, GetDataBlock()
// returns -1, never 0.
while (GetDataBlock((unsigned char *) buf) != -1) ;
return FALSE;
default:
break;
}
// This line should fix many crashes because John Walker was
// originally checking for a zero return, which would never
// occur because if the block is zero length, GetDataBlock()
// returns -1, never 0.
while (GetDataBlock((unsigned char *) buf) != -1) ;
return FALSE;
}
/* READIMAGE -- Read all components of image and, if successful,
create the in-memory .BMP file. */
static int ReadImage(int len, int height,
int ncolours, unsigned char FAR cmap[3][MAXCOLORMAPSIZE],
int interlace, int ignore)
{
unsigned char c;
int v, linelen;
int xpos = 0, ypos = 0, pass = 0;
DWORD bfsize;
BYTE _huge *pixels;
LPBITMAPFILEHEADER bfh;
LPBITMAPINFO bi;
LPBITMAPINFOHEADER bh;
// Initialize the Compression routines
ReadOK(fd, &c, 1);
if (LWZReadByte(TRUE, c) < 0)
return FALSE;
// If this is an "uninteresting picture" ignore it.
if (ignore) {
while (LWZReadByte(FALSE, c) >= 0) ;
return FALSE;
}
// Allocate the in-memory bitmap file.
linelen = (len + 3) & (~3);
bmpFile = (LPBYTE) GlobalAllocPtr(GPTR, bfsize =
sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD) + (linelen * ((DWORD) height)));
bfh = (LPBITMAPFILEHEADER) bmpFile;
bi = (LPBITMAPINFO) (bmpFile + sizeof(BITMAPFILEHEADER));
bh = &(bi->bmiHeader);
pixels = bmpFile + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD);
// Build file header
_fmemcpy(&bfh->bfType, "BM", 2);
bfh->bfSize = bfsize;
bfh->bfOffBits = ((LPBYTE) pixels) - bmpFile;
// Build BITMAPINFOHEADER
bh->biSize = sizeof(BITMAPINFOHEADER);
bh->biWidth = len;
bh->biHeight = height;
bh->biPlanes = 1;
bh->biBitCount = 8;
bh->biCompression = BI_RGB;
bh->biSizeImage = 0;
bh->biClrUsed = bh->biClrImportant = ncolours;
// Transcribe colour table to the bmiColors list
for (v = 0; v < ncolours; v++) {
bi->bmiColors[v].rgbRed = cmap[CM_RED][v];
bi->bmiColors[v].rgbGreen = cmap[CM_GREEN][v];
bi->bmiColors[v].rgbBlue = cmap[CM_BLUE][v];
}
while ((v = LWZReadByte(FALSE, c)) >= 0 ) {
if (ypos > 0 && ypos < height) {
pixels[(linelen * ((DWORD) ((height - 1) - ypos))) + xpos] = v;
}
++xpos;
if (xpos == len) {
xpos = 0;
if (interlace) {
switch (pass) {
case 0:
case 1:
ypos += 8; break;
case 2:
ypos += 4; break;
case 3:
ypos += 2; break;
}
if (ypos >= height) {
++pass;
switch (pass) {
case 1:
ypos = 4; break;
case 2:
ypos = 2; break;
case 3:
ypos = 1; break;
default:
goto fini;
}
}
} else {
++ypos;
}
}
if (ypos >= height)
break;
}
fini:
return TRUE;
}
/* GIFTOBMP -- Convert an in-memory GIF file to an in-memory
.BMP file. Returns NULL if anything went wrong
in the conversion process. */
LPBYTE GIFtoBMP(LPBYTE gif, int imageNumber)
{
unsigned char buf[16];
unsigned char c;
int useGlobalColormap;
int bitPixel;
int imageCount = 0;
char version[4];
gifFile = gif;
gifAddr = 0;
fatal = FALSE;
ReadOK(fd, buf, 6);
if (strncmp((char *) buf,"GIF",3) != 0)
pm_error("not a GIF file");
strncpy(version, (char *) buf + 3, 3);
version[3] = '\0';
if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0))
pm_error("bad version number, not '87a' or '89a'");
GIFcontext = (struct context FAR *) GlobalAllocPtr(GPTR, sizeof(struct context));
if (GIFcontext == NULL) {
return NULL;
}
ReadOK(fd,buf,7);
GifScreen.Width = LM_to_uint(buf[0], buf[1]);
GifScreen.Height = LM_to_uint(buf[2], buf[3]);
GifScreen.BitPixel = 2 << (buf[4] & 0x07);
GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
GifScreen.Background = buf[5];
GifScreen.AspectRatio = buf[6];
if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
if (!ReadColorMap(GifScreen.BitPixel, GifScreen.ColorMap))
pm_error("error reading global colormap");
}
for (;;) {
ReadOK(fd, &c, 1);
if (c == ';') { /* GIF terminator */
if (imageCount < imageNumber)
pm_error("Too few images found in file");
if (GIFcontext != NULL) {
GlobalFreePtr(GIFcontext);
GIFcontext = NULL;
}
return bmpFile;
}
if (c == '!') { /* Extension */
ReadOK(fd, &c, 1);
DoExtension(c);
continue;
}
if (c != ',') { /* Not a valid start character */
continue;
}
++imageCount;
ReadOK(fd, buf, 9);
useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
bitPixel = 1 << ((buf[8] & 0x07) + 1);
if (!useGlobalColormap) {
if (!ReadColorMap(bitPixel, localColorMap))
pm_error("error reading local colormap");
ReadImage(LM_to_uint(buf[4], buf[5]),
LM_to_uint(buf[6], buf[7]),
bitPixel, localColorMap,
BitSet(buf[8], INTERLACE), imageCount != imageNumber);
} else {
ReadImage(LM_to_uint(buf[4], buf[5]),
LM_to_uint(buf[6], buf[7]),
GifScreen.BitPixel, GifScreen.ColorMap,
BitSet(buf[8], INTERLACE), imageCount != imageNumber);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -