gd_gif_out.c

来自「Linux/Unix下的绘图函数库(Graphic Drawing Librar」· C语言 代码 · 共 1,194 行 · 第 1/3 页

C
1,194
字号
				     max_x-min_x+1, max_y-min_y+1);			if (pim)				gdImageDestroy (pim);			tim = pim = pim2;		}		/* now let's compare pixels for transparent		   optimization.  But only if transparent is set. */		if (transparent >= 0) {			for (y = 0; y < tim->sy; ++y)				for (x = 0; x < tim->sx; ++x)					if (comparewithmap					    (prev_tim, tim,					     prev_tim->pixels[min_y+y][min_x+x],					     tim->pixels[y][x], 0)) {						gdImageSetPixel (tim, x, y,								 transparent);						break;					}		}		if (prev_pim)			gdImageDestroy (prev_pim);	}	BitsPerPixel = colorstobpp(tim->colorsTotal);	/* All set, let's do it. */	GIFAnimEncode(		out, tim->sx, tim->sy, LeftOfs, TopOfs, interlace, transparent,		Delay, Disposal, BitsPerPixel,		LocalCM ? tim->red : 0, tim->green, tim->blue, tim); fail_end:	if (pim) {		/* Destroy palette based temporary image. */		gdImageDestroy(	pim);	}}BGD_DECLARE(void) gdImageGifAnimEnd(FILE *outFile){#if 1  putc (';', outFile);#else  gdIOCtx *out = gdNewFileCtx (outFile);  gdImageGifAnimEndCtx (out);  out->gd_free (out);#endif}BGD_DECLARE(void *) gdImageGifAnimEndPtr (int *size){  char *rv = (char *) gdMalloc (1);  *rv = ';';  *size = 1;  return (void *)rv;}BGD_DECLARE(void) gdImageGifAnimEndCtx(gdIOCtx *out){	/*	 * Write the GIF file terminator	 */	gdPutC( ';', out );}static intcolorstobpp(int colors){    int bpp = 0;    if ( colors <= 2 )        bpp = 1;    else if ( colors <= 4 )        bpp = 2;    else if ( colors <= 8 )        bpp = 3;    else if ( colors <= 16 )        bpp = 4;    else if ( colors <= 32 )        bpp = 5;    else if ( colors <= 64 )        bpp = 6;    else if ( colors <= 128 )        bpp = 7;    else if ( colors <= 256 )        bpp = 8;    return bpp;    }/***************************************************************************** * * GIFENCODE.C    - GIF Image compression interface * * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent, *            BitsPerPixel, Red, Green, Blue, gdImagePtr ) * *****************************************************************************/#define TRUE 1#define FALSE 0/* * Bump the 'curx' and 'cury' to point to the next pixel */static voidBumpPixel(GifCtx *ctx){        /*         * Bump the current X position         */        ++(ctx->curx);        /*         * If we are at the end of a scan line, set curx back to the beginning         * If we are interlaced, bump the cury to the appropriate spot,         * otherwise, just increment it.         */        if( ctx->curx == ctx->Width ) {                ctx->curx = 0;                if( !ctx->Interlace )                        ++(ctx->cury);                else {                     switch( ctx->Pass ) {                       case 0:                          ctx->cury += 8;                          if( ctx->cury >= ctx->Height ) {                                ++(ctx->Pass);                                ctx->cury = 4;                          }                          break;                       case 1:                          ctx->cury += 8;                          if( ctx->cury >= ctx->Height ) {                                ++(ctx->Pass);                                ctx->cury = 2;                          }                          break;                       case 2:                          ctx->cury += 4;                          if( ctx->cury >= ctx->Height ) {                             ++(ctx->Pass);                             ctx->cury = 1;                          }                          break;                       case 3:                          ctx->cury += 2;                          break;                        }                }        }}/* * Return the next pixel from the image */static intGIFNextPixel(gdImagePtr im, GifCtx *ctx){        int r;        if( ctx->CountDown == 0 )                return EOF;        --(ctx->CountDown);        r = gdImageGetPixel(im, ctx->curx, ctx->cury);        BumpPixel(ctx);        return r;}/* public */static voidGIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im){        int B;        int RWidth, RHeight;        int LeftOfs, TopOfs;        int Resolution;        int ColorMapSize;        int InitCodeSize;        int i;	GifCtx ctx;        ctx.Interlace = GInterlace;	ctx.in_count = 1;	memset(&ctx, 0, sizeof(ctx));        ColorMapSize = 1 << BitsPerPixel;        RWidth = ctx.Width = GWidth;        RHeight = ctx.Height = GHeight;        LeftOfs = TopOfs = 0;        Resolution = BitsPerPixel;        /*         * Calculate number of bits we are expecting         */        ctx.CountDown = (long)ctx.Width * (long)ctx.Height;        /*         * Indicate which pass we are on (if interlace)         */        ctx.Pass = 0;        /*         * The initial code size         */        if( BitsPerPixel <= 1 )                InitCodeSize = 2;        else                InitCodeSize = BitsPerPixel;        /*         * Set up the current x and y position         */        ctx.curx = ctx.cury = 0;        /*         * Write the Magic header         */        gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );        /*         * Write out the screen width and height         */        gifPutWord( RWidth, fp );        gifPutWord( RHeight, fp );        /*         * Indicate that there is a global colour map         */        B = 0x80;       /* Yes, there is a color map */        /*         * OR in the resolution         */        B |= (Resolution - 1) << 5;        /*         * OR in the Bits per Pixel         */        B |= (BitsPerPixel - 1);        /*         * Write it out         */        gdPutC( B, fp );        /*         * Write out the Background colour         */        gdPutC( Background, fp );        /*         * Byte of 0's (future expansion)         */        gdPutC( 0, fp );        /*         * Write out the Global Colour Map         */        for( i=0; i<ColorMapSize; ++i ) {                gdPutC( Red[i], fp );                gdPutC( Green[i], fp );                gdPutC( Blue[i], fp );        }	/*	 * Write out extension for transparent colour index, if necessary.	 */	if ( Transparent >= 0 ) {	    gdPutC( '!', fp );	    gdPutC( 0xf9, fp );	    gdPutC( 4, fp );	    gdPutC( 1, fp );	    gdPutC( 0, fp );	    gdPutC( 0, fp );	    gdPutC( (unsigned char) Transparent, fp );	    gdPutC( 0, fp );	}        /*         * Write an Image separator         */        gdPutC( ',', fp );        /*         * Write the Image header         */        gifPutWord( LeftOfs, fp );        gifPutWord( TopOfs, fp );        gifPutWord( ctx.Width, fp );        gifPutWord( ctx.Height, fp );        /*         * Write out whether or not the image is interlaced         */        if( ctx.Interlace )                gdPutC( 0x40, fp );        else                gdPutC( 0x00, fp );        /*         * Write out the initial code size         */        gdPutC( InitCodeSize, fp );        /*         * Go and actually compress the data         */        compress( InitCodeSize+1, fp, im, &ctx );        /*         * Write out a Zero-length packet (to end the series)         */        gdPutC( 0, fp );        /*         * Write the GIF file terminator         */        gdPutC( ';', fp );}static voidGIFAnimEncode(gdIOCtxPtr fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, int GInterlace, int Transparent, int Delay, int Disposal, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im){	int B;        int ColorMapSize;        int InitCodeSize;        int i;	GifCtx ctx;        ctx.Interlace = GInterlace;	ctx.in_count = 1;	memset(&ctx, 0, sizeof(ctx));        ColorMapSize = 1 << BitsPerPixel;	if (LeftOfs < 0) LeftOfs = 0;	if (TopOfs < 0) TopOfs = 0;	if (Delay < 0) Delay = 100;	if (Disposal < 0) Disposal = 1;	ctx.Width = IWidth;        ctx.Height = IHeight;        /*         * Calculate number of bits we are expecting         */        ctx.CountDown = (long)ctx.Width * (long)ctx.Height;        /*         * Indicate which pass we are on (if interlace)         */        ctx.Pass = 0;        /*         * The initial code size         */        if( BitsPerPixel <= 1 )                InitCodeSize = 2;        else                InitCodeSize = BitsPerPixel;        /*         * Set up the current x and y position         */        ctx.curx = ctx.cury = 0;	/*	 * Write out extension for image animation and looping	 */	gdPutC( '!', fp );	gdPutC( 0xf9, fp );	gdPutC( 4, fp );	gdPutC( (Transparent >= 0 ? 1 : 0)		| (Disposal << 2), fp );	gdPutC( (unsigned char)(Delay & 255), fp );	gdPutC( (unsigned char)((Delay >> 8) & 255), fp );	gdPutC( (unsigned char) Transparent, fp );	gdPutC( 0, fp );	/*	 * Write an Image separator	 */	gdPutC( ',', fp );        /*         * Write out the Image header         */        gifPutWord( LeftOfs, fp );        gifPutWord( TopOfs, fp );        gifPutWord( ctx.Width, fp );        gifPutWord( ctx.Height, fp );

⌨️ 快捷键说明

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