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 + -
显示快捷键?