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

📄 gd_gif_out.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#include "gd.h"/* Code drawn from ppmtogif.c, from the pbmplus package**** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A** Lempel-Zim compression based on "compress".**** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>**** Copyright (C) 1989 by Jef Poskanzer.**** 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.**** The Graphics Interchange Format(c) is the Copyright property of** CompuServe Incorporated.  GIF(sm) is a Service Mark property of** CompuServe Incorporated.*//* * a code_int must be able to hold 2**GIFBITS values of type int, and also -1 */typedef int             code_int;#ifdef SIGNED_COMPARE_SLOWtypedef unsigned long int count_int;typedef unsigned short int count_short;#else /*SIGNED_COMPARE_SLOW*/typedef long int          count_int;#endif /*SIGNED_COMPARE_SLOW*//* 2.0.28: threadsafe */#define maxbits GIFBITS/* should NEVER generate this code */#define maxmaxcode ((code_int)1 << GIFBITS)#define HSIZE  5003            /* 80% occupancy */#define hsize HSIZE            /* Apparently invariant, left over from 					compress */typedef struct {	int Width, Height;	int curx, cury;	long CountDown;	int Pass;	int Interlace;        int n_bits;                        /* number of bits/code */        code_int maxcode;                  /* maximum code, given n_bits */        count_int htab [HSIZE];        unsigned short codetab [HSIZE];	code_int free_ent;                  /* first unused entry */	/*	 * block compression parameters -- after all codes are used up,	 * and compression rate changes, start over.	 */	int clear_flg;	int offset;	long int in_count;            /* length of input */	long int out_count;           /* # of codes output (for debugging) */	int g_init_bits;	gdIOCtx * g_outfile;	int ClearCode;	int EOFCode;	unsigned long cur_accum;	int cur_bits;        /*         * Number of characters so far in this 'packet'         */        int a_count;        /*         * Define the storage for the packet accumulator         */        char accum[ 256 ];} GifCtx;static int gifPutWord(int w, gdIOCtx *out);static int colorstobpp(int colors);static void BumpPixel (GifCtx *ctx);static int GIFNextPixel (gdImagePtr im, GifCtx *ctx);static void GIFEncode (gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im, GifCtx *ctx);static void output (code_int code, GifCtx *ctx);static void cl_block (GifCtx *ctx);static void cl_hash (register count_int chsize, GifCtx *ctx);static void char_init (GifCtx *ctx);static void char_out (int c, GifCtx *ctx);static void flush_char (GifCtx *ctx);void * gdImageGifPtr (gdImagePtr im, int *size){  void *rv;  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);  gdImageGifCtx (im, out);  rv = gdDPExtractData (out, size);  out->gd_free (out);  return rv;}void gdImageGif (gdImagePtr im, FILE * outFile){  gdIOCtx *out = gdNewFileCtx (outFile);  gdImageGifCtx (im, out);  out->gd_free (out);}void gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out){	gdImagePtr pim = 0, tim = im;	int interlace, transparent, BitsPerPixel;	interlace = im->interlace;	transparent = im->transparent;	if (im->trueColor) {		/* Expensive, but the only way that produces an			acceptable result: mix down to a palette			based temporary image. */		pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);		if (!pim) {			return;		}		tim = pim; 	}	BitsPerPixel = colorstobpp(tim->colorsTotal);	/* All set, let's do it. */	GIFEncode(		out, tim->sx, tim->sy, tim->interlace, 0, tim->transparent, BitsPerPixel,		tim->red, tim->green, tim->blue, tim);	if (pim) {		/* Destroy palette based temporary image. */		gdImageDestroy(	pim);	}}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;		memset(&ctx, 0, sizeof(ctx));        ctx.Interlace = GInterlace;		ctx.in_count = 1;        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 );

⌨️ 快捷键说明

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