⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 giftobmp.c

📁 IP网络语音通讯软件源代码. 不可多得的语音源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
	
		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 + -