static void compress(int init_bits, FILE *outfile, byte *data, int len) { register long fcode; register int i = 0; register int c; register int ent; register int disp; register int hsize_reg; register int hshift; /* * Set up the globals: g_init_bits - initial number of bits g_outfile - * pointer to output file */ g_init_bits = init_bits; g_outfile = outfile; /* initialize 'compress' globals */ maxbits = XV_BITS; maxmaxcode = 1<<XV_BITS; memset(htab, 0, sizeof(htab)); memset(codetab, 0, sizeof(codetab)); hsize = HSIZE; free_ent = 0; clear_flg = 0; in_count = 1; out_count = 0; cur_accum = 0; cur_bits = 0; /* Set up the necessary values */ out_count = 0; clear_flg = 0; in_count = 1; maxcode = MAXCODE(n_bits = g_init_bits); ClearCode = (1 << (init_bits - 1)); EOFCode = ClearCode + 1; free_ent = ClearCode + 2; char_init(); ent = pc2nc[*data++]; len--; 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); /* clear hash table */ output(ClearCode); while (len) { c = pc2nc[*data++]; len--; in_count++; fcode = (long)(((long) c << maxbits) + ent); i = (((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(ent); out_count++; ent = c; if (free_ent < maxmaxcode) { CodeTabOf (i) = free_ent++; /* code -> hashtable */ HashTabOf (i) = fcode; } else { cl_block(); } } /* Put out the final code */ output(ent); out_count++; output(EOFCode); }
static void compress( int init_bits, FILE *outfile, ifun_t* ReadValue ) { 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 */ g_init_bits = init_bits; g_outfile = outfile; /* * Set up the necessary values */ offset = 0; out_count = 0; clear_flg = 0; in_count = 1; maxcode = MAXCODE(n_bits = g_init_bits); ClearCode = (1 << (init_bits - 1)); EOFCode = ClearCode + 1; free_ent = ClearCode + 2; char_init(); ent = GIFNextPixel( ReadValue ); 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); /* clear hash table */ output( (code_int)ClearCode ); while ( (c = GIFNextPixel( ReadValue )) != EOF ) { in_count++; fcode = (long) (((long) c << maxbits) + ent); /* i = (((code_int)c << hshift) ~ ent); */ /* xor hashing */ 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 ); out_count++; ent = c; if ( free_ent < maxmaxcode ) { CodeTabOf (i) = free_ent++; /* code -> hashtable */ HashTabOf (i) = fcode; } else cl_block(); } /* * Put out the final code. */ output( (code_int)ent ); out_count++; output( (code_int) EOFCode ); return; }
static void compress(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 const unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; /* Arbitrary value to mark output is done. When we see EOFCode, then we don't * expect to see any more data. If we do (e.g. corrupt image inputs), cur_bits * might be negative, so flag it to return early. */ #define CUR_BITS_FINISHED -1000 static void output(code_int code, GifCtx *ctx) { if (ctx->cur_bits == CUR_BITS_FINISHED) { return; } 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; } /* Flag that it's done to prevent re-entry. */ ctx->cur_bits = CUR_BITS_FINISHED; flush_char(ctx); } } /* * Clear out the hash table */ static void cl_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 void cl_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 void char_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 void char_out(int c, GifCtx *ctx) { ctx->accum[ ctx->a_count++ ] = c; if( ctx->a_count >= 254 ) flush_char(ctx); }