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

📄 gd_gif_in.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
字号:
#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#include "gd.h"#include "php.h"/* Used only when debugging GIF compression code *//* #define DEBUGGING_ENVARS */#ifdef DEBUGGING_ENVARSstatic int verbose_set = 0;static int verbose;#define VERBOSE (verbose_set?verbose:set_verbose())static int set_verbose(void){	verbose = !!getenv("GIF_VERBOSE");	verbose_set = 1;	return(verbose);}#else#define VERBOSE 0#endif#define        MAXCOLORMAPSIZE         256#define        TRUE    1#define        FALSE   0#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        ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0)#define LM_to_uint(a,b)                        (((b)<<8)|(a))/* We may eventually want to use this information, but def it out for now */#if 0static struct {	unsigned int    Width;	unsigned int    Height;	unsigned char   ColorMap[3][MAXCOLORMAPSIZE];	unsigned int    BitPixel;	unsigned int    ColorResolution;	unsigned int    Background;	unsigned int    AspectRatio;} GifScreen;#endifstatic struct {	int     transparent;	int     delayTime;	int     inputFlag;	int     disposal;} Gif89 = { -1, -1, -1, 0 };static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);static int DoExtension (gdIOCtx *fd, int label, int *Transparent);static int GetDataBlock (gdIOCtx *fd, unsigned char *buf);static int GetCode (gdIOCtx *fd, int code_size, int flag);static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size);static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */int ZeroDataBlock;gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource){	gdIOCtx         *in = gdNewSSCtx(inSource, NULL);	gdImagePtr      im;	im = gdImageCreateFromGifCtx(in);	in->gd_free(in);	return im;}	gdImagePtrgdImageCreateFromGif(FILE *fdFile){	gdIOCtx		*fd = gdNewFileCtx(fdFile);	gdImagePtr    	im = 0;	im = gdImageCreateFromGifCtx(fd);	fd->gd_free(fd);	return im;}gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd){	/* 1.4       int imageNumber; */	int BitPixel;	int ColorResolution;	int Background;	int AspectRatio;	int Transparent = (-1);	unsigned char   buf[16];	unsigned char   c;	unsigned char   ColorMap[3][MAXCOLORMAPSIZE];	unsigned char   localColorMap[3][MAXCOLORMAPSIZE];	int             imw, imh;	int             useGlobalColormap;	int             bitPixel;	int	       i;	/*1.4//int             imageCount = 0; */	char            version[4];	gdImagePtr im = 0;	ZeroDataBlock = FALSE;	/*1.4//imageNumber = 1; */	if (! ReadOK(fd,buf,6)) {		return 0;	}	if (strncmp((char *)buf,"GIF",3) != 0) {		return 0;	}	strncpy(version, (char *)buf + 3, 3);	version[3] = '\0';	if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {		return 0;	}	if (! ReadOK(fd,buf,7)) {		return 0;	}	BitPixel        = 2<<(buf[4]&0x07);	ColorResolution = (int) (((buf[4]&0x70)>>3)+1);	Background      = buf[5];	AspectRatio     = buf[6];	imw = LM_to_uint(buf[0],buf[1]);	imh = LM_to_uint(buf[2],buf[3]);	if (BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */		if (ReadColorMap(fd, BitPixel, ColorMap)) {			return 0;		}	}	for (;;) {		if (! ReadOK(fd,&c,1)) {			return 0;		}		if (c == ';') {         /* GIF terminator */			goto terminated;		}		if (c == '!') {         /* Extension */			if (! ReadOK(fd,&c,1)) {				return 0;			}			DoExtension(fd, c, &Transparent);			continue;		}		if (c != ',') {         /* Not a valid start character */			continue;		}		/*1.4//++imageCount; */		if (! ReadOK(fd,buf,9)) {			return 0;		}		useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);		bitPixel = 1<<((buf[8]&0x07)+1);		if (!useGlobalColormap) {			if (ReadColorMap(fd, bitPixel, localColorMap)) {				return 0;			}		}		if (!(im = gdImageCreate(imw, imh))) {			return 0;		}		im->interlace = BitSet(buf[8], INTERLACE);		if (! useGlobalColormap) {			ReadImage(im, fd, imw, imh, localColorMap,					BitSet(buf[8], INTERLACE));			/*1.4//imageCount != imageNumber); */		} else {			ReadImage(im, fd, imw, imh,					ColorMap,					BitSet(buf[8], INTERLACE));			/*1.4//imageCount != imageNumber); */		}		if (Transparent != (-1)) {			gdImageColorTransparent(im, Transparent);		}		goto terminated;	}terminated:	/* Terminator before any image was declared! */	if (!im) {		return 0;	}	if (!im->colorsTotal) {		gdImageDestroy(im);		return 0;	}	/* Check for open colors at the end, so	   we can reduce colorsTotal and ultimately	   BitsPerPixel */	for (i=((im->colorsTotal-1)); (i>=0); i--) {		if (im->open[i]) {			im->colorsTotal--;		} else {			break;		}	}	return im;}static int ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256]){	int             i;	unsigned char   rgb[3];	for (i = 0; i < number; ++i) {		if (! ReadOK(fd, rgb, sizeof(rgb))) {			return TRUE;		}		buffer[CM_RED][i] = rgb[0] ;		buffer[CM_GREEN][i] = rgb[1] ;		buffer[CM_BLUE][i] = rgb[2] ;	}	return FALSE;}static int DoExtension(gdIOCtx *fd, int label, int *Transparent){	static unsigned char     buf[256];	switch (label) {		case 0xf9:              /* Graphic Control Extension */			(void) GetDataBlock(fd, (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)				*Transparent = buf[3];			while (GetDataBlock(fd, (unsigned char*) buf) > 0)				;			return FALSE;		default:			break;	}	while (GetDataBlock(fd, (unsigned char*) buf) > 0)		;	return FALSE;}	static intGetDataBlock_(gdIOCtx *fd, unsigned char *buf){	unsigned char   count;	if (! ReadOK(fd,&count,1)) {		return -1;	}	ZeroDataBlock = count == 0;	if ((count != 0) && (! ReadOK(fd, buf, count))) {		return -1;	}	return count;}static int GetDataBlock(gdIOCtx *fd, unsigned char *buf){	int rv;	int i;	char *tmp = NULL;	rv = GetDataBlock_(fd,buf);	if (VERBOSE) {		if (rv > 0) {			tmp = safe_emalloc(3 * rv, sizeof(char), 1);			for (i=0;i<rv;i++) {				sprintf(&tmp[3*sizeof(char)*i], " %02x", buf[i]);			}		} else {			tmp = estrdup("");		}		php_gd_error_ex(E_NOTICE, "[GetDataBlock returning %d: %s]", rv, tmp);		efree(tmp);	}	return(rv);}static int GetCode_(gdIOCtx *fd, int code_size, int flag){	static unsigned char    buf[280];	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) {			if (curbit >= lastbit) {				/* Oh well */			}			return -1;		}		buf[0] = buf[last_byte-2];		buf[1] = buf[last_byte-1];		if ((count = GetDataBlock(fd, &buf[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 |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;	curbit += code_size;	return ret;}	static intGetCode(gdIOCtx *fd, int code_size, int flag){	int rv;	rv = GetCode_(fd,code_size,flag);	if (VERBOSE) php_gd_error_ex(E_NOTICE, "[GetCode(,%d,%d) returning %d]",code_size,flag,rv);	return(rv);}#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)static int LWZReadByte_(gdIOCtx *fd, 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      table[2][(1<< MAX_LWZ_BITS)];	static int      stack[STACK_SIZE], *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(fd, 0, TRUE);		fresh = TRUE;		for (i = 0; i < clear_code; ++i) {			table[0][i] = 0;			table[1][i] = i;		}		for (; i < (1<<MAX_LWZ_BITS); ++i)			table[0][i] = table[1][0] = 0;		sp = stack;		return 0;	} else if (fresh) {		fresh = FALSE;		do {			firstcode = oldcode =				GetCode(fd, code_size, FALSE);		} while (firstcode == clear_code);		return firstcode;	}	if (sp > stack)		return *--sp;	while ((code = GetCode(fd, code_size, FALSE)) >= 0) {		if (code == clear_code) {			for (i = 0; i < clear_code; ++i) {				table[0][i] = 0;				table[1][i] = i;			}			for (; i < (1<<MAX_LWZ_BITS); ++i)				table[0][i] = table[1][i] = 0;			code_size = set_code_size+1;			max_code_size = 2*clear_code;			max_code = clear_code+2;			sp = stack;			firstcode = oldcode =				GetCode(fd, code_size, FALSE);			return firstcode;		} else if (code == end_code) {			int             count;			unsigned char   buf[260];			if (ZeroDataBlock)				return -2;			while ((count = GetDataBlock(fd, buf)) > 0)				;			if (count != 0)				return -2;		}		incode = code;		if (sp == (stack + STACK_SIZE)) {			/* Bad compressed data stream */			return -1;		}		if (code >= max_code) {			*sp++ = firstcode;			code = oldcode;		}		while (code >= clear_code) {			if (sp == (stack + STACK_SIZE)) {				/* Bad compressed data stream */				return -1;			}			*sp++ = table[1][code];			if (code == table[0][code]) {				/* Oh well */			}			code = table[0][code];		}		*sp++ = firstcode = table[1][code];		if ((code = max_code) <(1<<MAX_LWZ_BITS)) {			table[0][code] = oldcode;			table[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;		if (sp > stack)			return *--sp;	}	return code;}static int LWZReadByte(gdIOCtx *fd, int flag, int input_code_size){	int rv;	rv = LWZReadByte_(fd,flag,input_code_size);	if (VERBOSE) php_gd_error_ex(E_NOTICE, "[LWZReadByte(,%d,%d) returning %d]",flag,input_code_size,rv);	return(rv);}static void ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /*1.4//, int ignore) */{	unsigned char   c;	int             v;	int             xpos = 0, ypos = 0, pass = 0;	int i;	/*	 **  Initialize the Compression routines	 */	if (! ReadOK(fd,&c,1)) {		return;	}	if (c > MAX_LWZ_BITS) {		return;		}	/* Stash the color map into the image */	for (i=0; (i<gdMaxColors); i++) {		im->red[i] = cmap[CM_RED][i];		im->green[i] = cmap[CM_GREEN][i];		im->blue[i] = cmap[CM_BLUE][i];		im->open[i] = 1;	}	/* Many (perhaps most) of these colors will remain marked open. */	im->colorsTotal = gdMaxColors;	if (LWZReadByte(fd, TRUE, c) < 0) {		return;	}	/*	 **  If this is an "uninteresting picture" ignore it.	 **  REMOVED For 1.4	 */	/*if (ignore) { */	/*        while (LWZReadByte(fd, FALSE, c) >= 0) */	/*                ; */	/*        return; */	/*} */	while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {		/* This how we recognize which colors are actually used. */		if (im->open[v]) {			im->open[v] = 0;		}		gdImageSetPixel(im, xpos, ypos, 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:	if (LWZReadByte(fd,FALSE,c)>=0) {		/* Ignore extra */	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -