/* * Reset encoding state at the start of a strip. */ static int LZMAPreEncode(TIFF* tif, uint16 s) { static const char module[] = "LZMAPreEncode"; LZMAState *sp = EncoderState(tif); (void) s; assert(sp != NULL); if( sp->state != LSTATE_INIT_ENCODE ) tif->tif_setupencode(tif); sp->stream.next_out = tif->tif_rawdata; sp->stream.avail_out = (size_t)tif->tif_rawdatasize; if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { TIFFErrorExt(tif->tif_clientdata, module, "Liblzma cannot deal with buffers this size"); return 0; } return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK); }
static int ZIPSetupEncode(TIFF* tif) { static const char module[] = "ZIPSetupEncode"; ZIPState* sp = EncoderState(tif); assert(sp != NULL); if (sp->state & ZSTATE_INIT_DECODE) { inflateEnd(&sp->stream); sp->state = 0; } if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); return (0); } else { sp->state |= ZSTATE_INIT_ENCODE; return (1); } }
int TIFFInitLZW(TIFF* tif, int scheme) { assert(scheme == COMPRESSION_LZW); /* * Allocate state block so tag methods have storage to record values. */ tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LZWCodecState)); if (tif->tif_data == NULL) goto bad; DecoderState(tif)->dec_codetab = NULL; DecoderState(tif)->dec_decode = NULL; EncoderState(tif)->enc_hashtab = NULL; LZWState(tif)->rw_mode = tif->tif_mode; /* * Install codec methods. */ tif->tif_setupdecode = LZWSetupDecode; tif->tif_predecode = LZWPreDecode; tif->tif_decoderow = LZWDecode; tif->tif_decodestrip = LZWDecode; tif->tif_decodetile = LZWDecode; tif->tif_setupencode = LZWSetupEncode; tif->tif_preencode = LZWPreEncode; tif->tif_postencode = LZWPostEncode; tif->tif_encoderow = LZWEncode; tif->tif_encodestrip = LZWEncode; tif->tif_encodetile = LZWEncode; tif->tif_cleanup = LZWCleanup; /* * Setup predictor setup. */ (void) TIFFPredictorInit(tif); return (1); bad: TIFFErrorExt(tif->tif_clientdata, "TIFFInitLZW", "No space for LZW state block"); return (0); }
static int ZIPSetupEncode(TIFF* tif) { ZIPState* sp = EncoderState(tif); static char module[] = "ZIPSetupEncode"; assert(sp != NULL); /* * We use the undocumented feature of a negiatve window * bits to suppress writing the header in the output * stream. This is necessary when the resulting image * is made up of multiple strips or tiles as otherwise * libgz will not write a header for each strip/tile and * the decoder will fail. */ if (deflateInit2(&sp->stream, Z_DEFAULT_COMPRESSION, DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0) != Z_OK) { TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); return (0); } else return (1); }
/* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static int ZIPPostEncode(TIFF* tif) { static const char module[] = "ZIPPostEncode"; ZIPState *sp = EncoderState(tif); int state; sp->stream.avail_in = 0; #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ do { state = deflate(&sp->stream, Z_FINISH); switch (state) { case Z_STREAM_END: case Z_OK: if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; TIFFFlushData1(tif); sp->stream.next_out = tif->tif_rawdata; sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ } break; default: TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", sp->stream.msg); return (0); } } while (state != Z_STREAM_END); return (1); }
/* * Encode a chunk of pixels. */ static int ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) { ZIPState* sp = EncoderState(tif); static const char module[] = "ZIPEncode"; (void) s; sp->stream.next_in = bp; sp->stream.avail_in = cc; do { if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { TIFFError(module, "%s: Encoder error: %s", tif->tif_name, sp->stream.msg); return (0); } if (sp->stream.avail_out == 0) { tif->tif_rawcc = tif->tif_rawdatasize; TIFFFlushData1(tif); sp->stream.next_out = tif->tif_rawdata; sp->stream.avail_out = tif->tif_rawdatasize; } } while (sp->stream.avail_in > 0); return (1); }
/* * Encode a chunk of pixels. */ static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { static const char module[] = "ZIPEncode"; ZIPState *sp = EncoderState(tif); assert(sp != NULL); assert(sp->state == ZSTATE_INIT_ENCODE); (void) s; sp->stream.next_in = bp; assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, we need to simplify this code to reflect a ZLib that is likely updated to deal with 8byte memory sizes, though this code will respond appropriately even before we simplify it */ sp->stream.avail_in = (uInt) cc; if ((tmsize_t)sp->stream.avail_in != cc) { TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); return (0); } do { if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s", SAFE_MSG(sp)); return (0); } if (sp->stream.avail_out == 0) { tif->tif_rawcc = tif->tif_rawdatasize; TIFFFlushData1(tif); sp->stream.next_out = tif->tif_rawdata; sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ } } while (sp->stream.avail_in > 0); return (1); }
/* * Encode a chunk of pixels. */ static int LERCEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { static const char module[] = "LERCEncode"; LERCState *sp = EncoderState(tif); (void)s; assert(sp != NULL); assert(sp->state == LSTATE_INIT_ENCODE); if( (uint64)sp->uncompressed_offset + (uint64)cc > sp->uncompressed_size ) { TIFFErrorExt(tif->tif_clientdata, module, "Too many bytes written"); return 0; } memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc); sp->uncompressed_offset += (unsigned)cc; return 1; }
/* * Reset encoding state at the start of a strip. */ static int ZIPPreEncode(TIFF* tif, uint16 s) { static const char module[] = "ZIPPreEncode"; ZIPState *sp = EncoderState(tif); (void) s; assert(sp != NULL); if( sp->state != ZSTATE_INIT_ENCODE ) tif->tif_setupencode( tif ); sp->stream.next_out = tif->tif_rawdata; assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, we need to simplify this code to reflect a ZLib that is likely updated to deal with 8byte memory sizes, though this code will respond appropriately even before we simplify it */ sp->stream.avail_out = (uInt)tif->tif_rawdatasize; if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); return (0); } return (deflateReset(&sp->stream) == Z_OK); }
/* * Finish off an encoded strip by flushing it. */ static int TWebPPostEncode(TIFF* tif) { static const char module[] = "WebPPostEncode"; int64_t stride; WebPState *sp = EncoderState(tif); assert(sp != NULL); assert(sp->state == LSTATE_INIT_ENCODE); stride = (int64_t)sp->sPicture.width * sp->nSamples; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 if (sp->nSamples == 4) { if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) { TIFFErrorExt(tif->tif_clientdata, module, "WebPPictureImportRGBA() failed" ); return 0; } } else #endif if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) { TIFFErrorExt(tif->tif_clientdata, module, "WebPPictureImportRGB() failed"); return 0; } if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) { #if WEBP_ENCODER_ABI_VERSION >= 0x0100 const char* pszErrorMsg = NULL; switch(sp->sPicture.error_code) { case VP8_ENC_ERROR_OUT_OF_MEMORY: pszErrorMsg = "Out of memory"; break; case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: pszErrorMsg = "Out of memory while flushing bits"; break; case VP8_ENC_ERROR_NULL_PARAMETER: pszErrorMsg = "A pointer parameter is NULL"; break; case VP8_ENC_ERROR_INVALID_CONFIGURATION: pszErrorMsg = "Configuration is invalid"; break; case VP8_ENC_ERROR_BAD_DIMENSION: pszErrorMsg = "Picture has invalid width/height"; break; case VP8_ENC_ERROR_PARTITION0_OVERFLOW: pszErrorMsg = "Partition is bigger than 512k. Try using less " "SEGMENTS, or increase PARTITION_LIMIT value"; break; case VP8_ENC_ERROR_PARTITION_OVERFLOW: pszErrorMsg = "Partition is bigger than 16M"; break; case VP8_ENC_ERROR_BAD_WRITE: pszErrorMsg = "Error while fludshing bytes"; break; case VP8_ENC_ERROR_FILE_TOO_BIG: pszErrorMsg = "File is bigger than 4G"; break; case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break; default: TIFFErrorExt(tif->tif_clientdata, module, "WebPEncode returned an unknown error code: %d", sp->sPicture.error_code); pszErrorMsg = "Unknown WebP error type."; break; } TIFFErrorExt(tif->tif_clientdata, module, "WebPEncode() failed : %s", pszErrorMsg); #else TIFFErrorExt(tif->tif_clientdata, module, "Error in WebPEncode()"); #endif return 0; } sp->sPicture.custom_ptr = NULL; if (!TIFFFlushData1(tif)) { TIFFErrorExt(tif->tif_clientdata, module, "Error flushing TIFF WebP encoder."); return 0; } return 1; }
static int TWebPSetupEncode(TIFF* tif) { static const char module[] = "WebPSetupEncode"; uint16 nBitsPerSample = tif->tif_dir.td_bitspersample; uint16 sampleFormat = tif->tif_dir.td_sampleformat; WebPState* sp = EncoderState(tif); assert(sp != NULL); sp->nSamples = tif->tif_dir.td_samplesperpixel; /* check band count */ if ( sp->nSamples != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 && sp->nSamples != 4 #endif ) { TIFFErrorExt(tif->tif_clientdata, module, "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 "or 4 (RGBA) " #endif "bands.", sp->nSamples ); return 0; } /* check bits per sample and data type */ if ((nBitsPerSample != 8) && (sampleFormat != 1)) { TIFFErrorExt(tif->tif_clientdata, module, "WEBP driver requires 8 bit unsigned data"); return 0; } if (sp->state & LSTATE_INIT_DECODE) { WebPIDelete(sp->psDecoder); WebPFreeDecBuffer(&sp->sDecBuffer); sp->psDecoder = NULL; sp->last_y = 0; sp->state = 0; } sp->state |= LSTATE_INIT_ENCODE; if (!WebPPictureInit(&sp->sPicture)) { TIFFErrorExt(tif->tif_clientdata, module, "Error initializing WebP picture."); return 0; } if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, sp->quality_level, WEBP_ENCODER_ABI_VERSION)) { TIFFErrorExt(tif->tif_clientdata, module, "Error creating WebP encoder configuration."); return 0; } // WebPConfigInitInternal above sets lossless to false #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sp->sEncoderConfig.lossless = sp->lossless; if (sp->lossless) { sp->sPicture.use_argb = 1; } #endif if (!WebPValidateConfig(&sp->sEncoderConfig)) { TIFFErrorExt(tif->tif_clientdata, module, "Error with WebP encoder configuration."); return 0; } 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); }
/* * Finish off an encoded strip by flushing it. */ static int LERCPostEncode(TIFF* tif) { lerc_status lerc_ret; static const char module[] = "LERCPostEncode"; LERCState *sp = EncoderState(tif); unsigned int numBytes = 0; unsigned int numBytesWritten = 0; TIFFDirectory *td = &tif->tif_dir; int use_mask = 0; unsigned dst_nbands = td->td_samplesperpixel; if( sp->uncompressed_offset != sp->uncompressed_size ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected number of bytes in the buffer"); return 0; } /* Extract alpha mask (if containing only 0 and 255 values, */ /* and compact array of regular bands */ if( td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && td->td_sampleinfo[td->td_extrasamples-1] == EXTRASAMPLE_UNASSALPHA && GetLercDataType(tif) == 1 ) { unsigned dst_stride = (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); unsigned src_stride = td->td_samplesperpixel * (td->td_bitspersample / 8); unsigned i = 0; unsigned nb_pixels = sp->segment_width * sp->segment_height; use_mask = 1; for( i = 0 ; i < nb_pixels; i++) { int v = sp->uncompressed_buffer[ i * src_stride + td->td_samplesperpixel - 1]; if( v != 0 && v != 255 ) { use_mask = 0; break; } } if( use_mask ) { dst_nbands --; /* First pixels must use memmove due to overlapping areas */ for( i = 0 ;i < dst_nbands && i < nb_pixels; i++) { memmove( sp->uncompressed_buffer + i * dst_stride, sp->uncompressed_buffer + i * src_stride, dst_stride ); sp->mask_buffer[i] = sp->uncompressed_buffer[ i * src_stride + td->td_samplesperpixel - 1]; } for(; i < nb_pixels; i++) { memcpy( sp->uncompressed_buffer + i * dst_stride, sp->uncompressed_buffer + i * src_stride, dst_stride ); sp->mask_buffer[i] = sp->uncompressed_buffer[ i * src_stride + td->td_samplesperpixel - 1]; } } } #if 0 lerc_ret = lerc_computeCompressedSize( sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif), td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1, sp->segment_width, sp->segment_height, 1, use_mask ? sp->mask_buffer : NULL, sp->maxzerror, &numBytes); if( lerc_ret != 0 ) { TIFFErrorExt(tif->tif_clientdata, module, "lerc_computeCompressedSize() failed"); return 0; } #else numBytes = sp->uncompressed_alloc; #endif if( sp->compressed_size < numBytes ) { _TIFFfree(sp->compressed_buffer); sp->compressed_buffer = _TIFFmalloc(numBytes); if( !sp->compressed_buffer ) { sp->compressed_size = 0; return 0; } sp->compressed_size = numBytes; } lerc_ret = lerc_encodeForVersion( sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif), td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1, sp->segment_width, sp->segment_height, 1, use_mask ? sp->mask_buffer : NULL, sp->maxzerror, sp->compressed_buffer, sp->compressed_size, &numBytesWritten); if( lerc_ret != 0 ) { TIFFErrorExt(tif->tif_clientdata, module, "lerc_encode() failed"); return 0; } assert( numBytesWritten < numBytes ); if( sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE ) { z_stream strm; int zlib_ret; memset(&strm, 0, sizeof(strm)); strm.zalloc = NULL; strm.zfree = NULL; strm.opaque = NULL; zlib_ret = deflateInit(&strm, sp->zipquality); if( zlib_ret != Z_OK ) { TIFFErrorExt(tif->tif_clientdata, module, "deflateInit() failed"); return 0; } strm.avail_in = numBytesWritten; strm.next_in = sp->compressed_buffer; strm.avail_out = sp->uncompressed_alloc; strm.next_out = sp->uncompressed_buffer; zlib_ret = deflate(&strm, Z_FINISH); if( zlib_ret != Z_STREAM_END ) { TIFFErrorExt(tif->tif_clientdata, module, "deflate() failed"); deflateEnd(&strm); return 0; } { int ret; uint8* tif_rawdata_backup = tif->tif_rawdata; tif->tif_rawdata = sp->uncompressed_buffer; tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out; ret = TIFFFlushData1(tif); tif->tif_rawdata = tif_rawdata_backup; if( !ret ) { deflateEnd(&strm); return 0; } } deflateEnd(&strm); } else if( sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD ) { #ifdef ZSTD_SUPPORT size_t zstd_ret = ZSTD_compress( sp->uncompressed_buffer, sp->uncompressed_alloc, sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level ); if( ZSTD_isError(zstd_ret) ) { TIFFErrorExt(tif->tif_clientdata, module, "Error in ZSTD_compress(): %s", ZSTD_getErrorName(zstd_ret)); return 0; } { int ret; uint8* tif_rawdata_backup = tif->tif_rawdata; tif->tif_rawdata = sp->uncompressed_buffer; tif->tif_rawcc = zstd_ret; ret = TIFFFlushData1(tif); tif->tif_rawdata = tif_rawdata_backup; if( !ret ) { return 0; } } #else TIFFErrorExt(tif->tif_clientdata, module, "ZSTD support missing"); return 0; #endif } else if( sp->additional_compression != LERC_ADD_COMPRESSION_NONE ) { TIFFErrorExt(tif->tif_clientdata, module, "Unhandled additional compression"); return 0; } else { int ret; uint8* tif_rawdata_backup = tif->tif_rawdata; tif->tif_rawdata = sp->compressed_buffer; tif->tif_rawcc = numBytesWritten; ret = TIFFFlushData1(tif); tif->tif_rawdata = tif_rawdata_backup; if( !ret ) return 0; } return 1; }
/* * Encode a row of 16-bit pixels. */ static int LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) { LogLuvState* sp = EncoderState(tif); int shft; tmsize_t i; tmsize_t j; tmsize_t npixels; uint8* op; int16* tp; int16 b; tmsize_t occ; int rc=0, mask; tmsize_t beg; assert(s == 0); assert(sp != NULL); npixels = cc / sp->pixel_size; if (sp->user_datafmt == SGILOGDATAFMT_16BIT) tp = (int16*) bp; else { tp = (int16*) sp->tbuf; assert(sp->tbuflen >= npixels); (*sp->tfunc)(sp, bp, npixels); } /* compress each byte string */ op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; for (shft = 2*8; (shft -= 8) >= 0; ) for (i = 0; i < npixels; i += rc) { if (occ < 4) { tif->tif_rawcp = op; tif->tif_rawcc = tif->tif_rawdatasize - occ; if (!TIFFFlushData1(tif)) return (-1); op = tif->tif_rawcp; occ = tif->tif_rawdatasize - tif->tif_rawcc; } mask = 0xff << shft; /* find next run */ for (beg = i; beg < npixels; beg += rc) { b = (int16) (tp[beg] & mask); rc = 1; while (rc < 127+2 && beg+rc < npixels && (tp[beg+rc] & mask) == b) rc++; if (rc >= MINRUN) break; /* long enough */ } if (beg-i > 1 && beg-i < MINRUN) { b = (int16) (tp[i] & mask);/*check short run */ j = i+1; while ((tp[j++] & mask) == b) if (j == beg) { *op++ = (uint8)(128-2+j-i); *op++ = (uint8)(b >> shft); occ -= 2; i = beg; break; } }