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

📄 gd_gif_out.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 2 页
字号:
        /*         * 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 );}/*************************************************************************** * *  GIFCOMPR.C       - GIF Image compression routines * *  Lempel-Ziv compression based on 'compress'.  GIF modifications by *  David Rowley (mgardi@watdcsu.waterloo.edu) * ***************************************************************************//* * General DEFINEs */#define GIFBITS    12#ifdef NO_UCHAR typedef char   char_type;#else /*NO_UCHAR*/ typedef        unsigned char   char_type;#endif /*NO_UCHAR*//* * * GIF Image compression - modified 'compress' * * Based on: compress.c - File compression ala IEEE Computer, June 1984. * * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas) *              Jim McKie               (decvax!mcvax!jim) *              Steve Davies            (decvax!vax135!petsd!peora!srd) *              Ken Turkowski           (decvax!decwrl!turtlevax!ken) *              James A. Woods          (decvax!ihnp4!ames!jaw) *              Joe Orost               (decvax!vax135!petsd!joe) * */#include <ctype.h>#define ARGVAL() (*++(*argv) || (--argc && *++argv))#ifdef COMPATIBLE               /* But wrong! */# define MAXCODE(n_bits)        ((code_int) 1 << (n_bits) - 1)#else /*COMPATIBLE*/# define MAXCODE(n_bits)        (((code_int) 1 << (n_bits)) - 1)#endif /*COMPATIBLE*/#define HashTabOf(i)       ctx->htab[i]#define CodeTabOf(i)    ctx->codetab[i]/* * To save much memory, we overlay the table used by compress() with those * used by decompress().  The tab_prefix table is the same size and type * as the codetab.  The tab_suffix table needs 2**GIFBITS characters.  We * get this from the beginning of htab.  The output stack uses the rest * of htab, and contains characters.  There is plenty of room for any * possible stack (stack used to be 8000 characters). */#define tab_prefixof(i) CodeTabOf(i)#define tab_suffixof(i)        ((char_type*)(htab))[i]#define de_stack               ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))/* * compress stdin to stdout * * Algorithm:  use open addressing double hashing (no chaining) on the * prefix code / next character combination.  We do a variant of Knuth's * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime * secondary probe.  Here, the modular division first probe is gives way * to a faster exclusive-or manipulation.  Also do block compression with * an adaptive reset, whereby the code table is cleared when the compression * ratio decreases, but after the table fills.  The variable-length output * codes are re-sized at this point, and a special CLEAR code is generated * for the decompressor.  Late addition:  construct the table according to * file size for noticeable speed improvement on small files.  Please direct * questions about this implementation to ames!jaw. */static voidoutput(code_int code, GifCtx *ctx);static voidcompress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *ctx){    register long fcode;    register code_int i /* = 0 */;    register int c;    register code_int ent;    register code_int disp;    register code_int hsize_reg;    register int hshift;    /*     * Set up the globals:  g_init_bits - initial number of bits     *                      g_outfile   - pointer to output file     */    ctx->g_init_bits = init_bits;    ctx->g_outfile = outfile;    /*     * Set up the necessary values     */    ctx->offset = 0;    ctx->out_count = 0;    ctx->clear_flg = 0;    ctx->in_count = 1;    ctx->maxcode = MAXCODE(ctx->n_bits = ctx->g_init_bits);    ctx->ClearCode = (1 << (init_bits - 1));    ctx->EOFCode = ctx->ClearCode + 1;    ctx->free_ent = ctx->ClearCode + 2;    char_init(ctx);    ent = GIFNextPixel( im, ctx );    hshift = 0;    for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )        ++hshift;    hshift = 8 - hshift;                /* set hash code range bound */    hsize_reg = hsize;    cl_hash( (count_int) hsize_reg, ctx );            /* clear hash table */    output( (code_int)ctx->ClearCode, ctx );#ifdef SIGNED_COMPARE_SLOW    while ( (c = GIFNextPixel( im )) != (unsigned) EOF ) {#else /*SIGNED_COMPARE_SLOW*/    while ( (c = GIFNextPixel( im, ctx )) != EOF ) {  /* } */#endif /*SIGNED_COMPARE_SLOW*/        ++(ctx->in_count);        fcode = (long) (((long) c << maxbits) + ent);        i = (((code_int)c << hshift) ^ ent);    /* xor hashing */        if ( HashTabOf (i) == fcode ) {            ent = CodeTabOf (i);            continue;        } else if ( (long)HashTabOf (i) < 0 )      /* empty slot */            goto nomatch;        disp = hsize_reg - i;           /* secondary hash (after G. Knott) */        if ( i == 0 )            disp = 1;probe:        if ( (i -= disp) < 0 )            i += hsize_reg;        if ( HashTabOf (i) == fcode ) {            ent = CodeTabOf (i);            continue;        }        if ( (long)HashTabOf (i) > 0 )            goto probe;nomatch:        output ( (code_int) ent, ctx );        ++(ctx->out_count);        ent = c;#ifdef SIGNED_COMPARE_SLOW        if ( (unsigned) ctx->free_ent < (unsigned) maxmaxcode) {#else /*SIGNED_COMPARE_SLOW*/        if ( ctx->free_ent < maxmaxcode ) {  /* } */#endif /*SIGNED_COMPARE_SLOW*/            CodeTabOf (i) = ctx->free_ent++; /* code -> hashtable */            HashTabOf (i) = fcode;        } else                cl_block(ctx);    }    /*     * Put out the final code.     */    output( (code_int)ent, ctx );    ++(ctx->out_count);    output( (code_int) ctx->EOFCode, ctx );}/***************************************************************** * TAG( output ) * * Output the given code. * Inputs: *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes *              that n_bits =< (long)wordsize - 1. * Outputs: *      Outputs code to the file. * Assumptions: *      Chars are 8 bits long. * Algorithm: *      Maintain a GIFBITS character long buffer (so that 8 codes will * fit in it exactly).  Use the VAX insv instruction to insert each * code in turn.  When the buffer fills up empty it and start over. */static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,                                  0x001F, 0x003F, 0x007F, 0x00FF,                                  0x01FF, 0x03FF, 0x07FF, 0x0FFF,                                  0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };static voidoutput(code_int code, GifCtx *ctx){    ctx->cur_accum &= masks[ ctx->cur_bits ];    if( ctx->cur_bits > 0 )        ctx->cur_accum |= ((long)code << ctx->cur_bits);    else        ctx->cur_accum = code;    ctx->cur_bits += ctx->n_bits;    while( ctx->cur_bits >= 8 ) {        char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx );        ctx->cur_accum >>= 8;        ctx->cur_bits -= 8;    }    /*     * If the next entry is going to be too big for the code size,     * then increase it, if possible.     */   if ( ctx->free_ent > ctx->maxcode || ctx->clear_flg ) {            if( ctx->clear_flg ) {                ctx->maxcode = MAXCODE (ctx->n_bits = ctx->g_init_bits);                ctx->clear_flg = 0;            } else {                ++(ctx->n_bits);                if ( ctx->n_bits == maxbits )                    ctx->maxcode = maxmaxcode;                else                    ctx->maxcode = MAXCODE(ctx->n_bits);            }        }    if( code == ctx->EOFCode ) {        /*         * At EOF, write the rest of the buffer.         */        while( ctx->cur_bits > 0 ) {                char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx);                ctx->cur_accum >>= 8;                ctx->cur_bits -= 8;        }        flush_char(ctx);    }}/* * Clear out the hash table */static voidcl_block (GifCtx *ctx)             /* table clear for block compress */{        cl_hash ( (count_int) hsize, ctx );        ctx->free_ent = ctx->ClearCode + 2;        ctx->clear_flg = 1;        output( (code_int)ctx->ClearCode, ctx);}static voidcl_hash(register count_int chsize, GifCtx *ctx)          /* reset code table */                         {        register count_int *htab_p = ctx->htab+chsize;        register long i;        register long m1 = -1;        i = chsize - 16;        do {                            /* might use Sys V memset(3) here */                *(htab_p-16) = m1;                *(htab_p-15) = m1;                *(htab_p-14) = m1;                *(htab_p-13) = m1;                *(htab_p-12) = m1;                *(htab_p-11) = m1;                *(htab_p-10) = m1;                *(htab_p-9) = m1;                *(htab_p-8) = m1;                *(htab_p-7) = m1;                *(htab_p-6) = m1;                *(htab_p-5) = m1;                *(htab_p-4) = m1;                *(htab_p-3) = m1;                *(htab_p-2) = m1;                *(htab_p-1) = m1;                htab_p -= 16;        } while ((i -= 16) >= 0);        for ( i += 16; i > 0; --i )                *--htab_p = m1;}/****************************************************************************** * * GIF Specific routines * ******************************************************************************//* * Set up the 'byte output' routine */static voidchar_init(GifCtx *ctx){        ctx->a_count = 0;}/* * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */static voidchar_out(int c, GifCtx *ctx){        ctx->accum[ ctx->a_count++ ] = c;        if( ctx->a_count >= 254 )                flush_char(ctx);}/* * Flush the packet to disk, and reset the accumulator */static voidflush_char(GifCtx *ctx){        if( ctx->a_count > 0 ) {                gdPutC( ctx->a_count, ctx->g_outfile );                gdPutBuf( ctx->accum, ctx->a_count, ctx->g_outfile );                ctx->a_count = 0;        }}static int gifPutWord(int w, gdIOCtx *out){	/* Byte order is little-endian */	gdPutC(w & 0xFF, out);	gdPutC((w >> 8) & 0xFF, out);	return 0;}

⌨️ 快捷键说明

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