/* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static int LZWPostEncode(TIFF* tif) { register LZWCodecState *sp = EncoderState(tif); uint8* op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; long nextdata = sp->lzw_nextdata; long outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); TIFFFlushData1(tif); op = tif->tif_rawdata; } if (sp->enc_oldcode != (hcode_t) -1) { PutNextCode(op, sp->enc_oldcode); sp->enc_oldcode = (hcode_t) -1; } PutNextCode(op, CODE_EOI); if (nextbits > 0) *op++ = (unsigned char)(nextdata << (8-nextbits)); tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); return (1); }
/* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static int LZWPostEncode(TIFF* tif) { register LZWCodecState *sp = EncoderState(tif); uint8* op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; unsigned long nextdata = sp->lzw_nextdata; long outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); if( !TIFFFlushData1(tif) ) return 0; op = tif->tif_rawdata; } if (sp->enc_oldcode != (hcode_t) -1) { PutNextCode(op, sp->enc_oldcode); sp->enc_oldcode = (hcode_t) -1; } PutNextCode(op, CODE_EOI); /* Explicit 0xff masking to make icc -check=conversions happy */ if (nextbits > 0) *op++ = (unsigned char)((nextdata << (8-nextbits))&0xff); tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); return (1); }
/* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static int LZWPostEncode(TIFF* tif) { register LZWCodecState *sp = EncoderState(tif); uint8* op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; unsigned long nextdata = sp->lzw_nextdata; long outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); if( !TIFFFlushData1(tif) ) return 0; op = tif->tif_rawdata; } if (sp->enc_oldcode != (hcode_t) -1) { int free_ent = sp->lzw_free_ent; PutNextCode(op, sp->enc_oldcode); sp->enc_oldcode = (hcode_t) -1; free_ent ++; if (free_ent == CODE_MAX-1) { /* table is full, emit clear code and reset */ outcount = 0; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; } else { /* * If the next entry is going to be too big for * the code size, then increase it, if possible. */ if (free_ent > sp->lzw_maxcode) { nbits++; assert(nbits <= BITS_MAX); } } } PutNextCode(op, CODE_EOI); /* Explicit 0xff masking to make icc -check=conversions happy */ if (nextbits > 0) *op++ = (unsigned char)((nextdata << (8-nextbits))&0xff); tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); return (1); }
/* * Encode a chunk of pixels. * * Uses an 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 CODE_CLEAR is generated * for the decoder. */ static int LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { register LZWCodecState *sp = EncoderState(tif); register long fcode; register hash_t *hp; register int h, c; hcode_t ent; long disp; long incount, outcount, checkpoint; unsigned long nextdata; long nextbits; int free_ent, maxcode, nbits; uint8* op; uint8* limit; (void) s; if (sp == NULL) return (0); assert(sp->enc_hashtab != NULL); /* * Load local state. */ incount = sp->enc_incount; outcount = sp->enc_outcount; checkpoint = sp->enc_checkpoint; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; free_ent = sp->lzw_free_ent; maxcode = sp->lzw_maxcode; nbits = sp->lzw_nbits; op = tif->tif_rawcp; limit = sp->enc_rawlimit; ent = (hcode_t)sp->enc_oldcode; if (ent == (hcode_t) -1 && cc > 0) { /* * NB: This is safe because it can only happen * at the start of a strip where we know there * is space in the data buffer. */ PutNextCode(op, CODE_CLEAR); ent = *bp++; cc--; incount++; } while (cc > 0) { c = *bp++; cc--; incount++; fcode = ((long)c << BITS_MAX) + ent; h = (c << HSHIFT) ^ ent; /* xor hashing */ #ifdef _WINDOWS /* * Check hash index for an overflow. */ if (h >= HSIZE) h -= HSIZE; #endif hp = &sp->enc_hashtab[h]; if (hp->hash == fcode) { ent = hp->code; continue; } if (hp->hash >= 0) { /* * Primary hash failed, check secondary hash. */ disp = HSIZE - h; if (h == 0) disp = 1; do { /* * Avoid pointer arithmetic because of * wraparound problems with segments. */ if ((h -= disp) < 0) h += HSIZE; hp = &sp->enc_hashtab[h]; if (hp->hash == fcode) { ent = hp->code; goto hit; } } while (hp->hash >= 0); } /* * New entry, emit code and add to table. */ /* * Verify there is space in the buffer for the code * and any potential Clear code that might be emitted * below. The value of limit is setup so that there * are at least 4 bytes free--room for 2 codes. */ if (op > limit) { tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); if( !TIFFFlushData1(tif) ) return 0; op = tif->tif_rawdata; } PutNextCode(op, ent); ent = (hcode_t)c; hp->code = (hcode_t)(free_ent++); hp->hash = fcode; if (free_ent == CODE_MAX-1) { /* table is full, emit clear code and reset */ cl_hash(sp); sp->enc_ratio = 0; incount = 0; outcount = 0; free_ent = CODE_FIRST; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else { /* * If the next entry is going to be too big for * the code size, then increase it, if possible. */ if (free_ent > maxcode) { nbits++; assert(nbits <= BITS_MAX); maxcode = (int) MAXCODE(nbits); } else if (incount >= checkpoint) { long rat; /* * Check compression ratio and, if things seem * to be slipping, clear the hash table and * reset state. The compression ratio is a * 24+8-bit fractional number. */ checkpoint = incount+CHECK_GAP; CALCRATIO(sp, rat); if (rat <= sp->enc_ratio) { cl_hash(sp); sp->enc_ratio = 0; incount = 0; outcount = 0; free_ent = CODE_FIRST; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else sp->enc_ratio = rat; } } hit: ; } /* * Restore global state. */ sp->enc_incount = incount; sp->enc_outcount = outcount; sp->enc_checkpoint = checkpoint; sp->enc_oldcode = ent; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->lzw_free_ent = (unsigned short)free_ent; sp->lzw_maxcode = (unsigned short)maxcode; sp->lzw_nbits = (unsigned short)nbits; tif->tif_rawcp = op; return (1); }