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 ZIPSetupDecode(TIFF* tif) { ZIPState* sp = DecoderState(tif); static char module[] = "ZIPSetupDecode"; assert(sp != NULL); if (inflateInit2(&sp->stream, -DEF_WBITS) != Z_OK) { TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); return (0); } else return (1); }
static int TWebPSetupDecode(TIFF* tif) { static const char module[] = "WebPSetupDecode"; uint16 nBitsPerSample = tif->tif_dir.td_bitspersample; uint16 sampleFormat = tif->tif_dir.td_sampleformat; WebPState* sp = DecoderState(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 we were last encoding, terminate this mode */ if (sp->state & LSTATE_INIT_ENCODE) { WebPPictureFree(&sp->sPicture); if (sp->pBuffer != NULL) { _TIFFfree(sp->pBuffer); sp->pBuffer = NULL; } sp->buffer_offset = 0; sp->state = 0; } sp->state |= LSTATE_INIT_DECODE; 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 (LZWDecodeState)); if (tif->tif_data == NULL) goto bad; if (tif->tif_mode == O_RDONLY) { DecoderState(tif)->dec_codetab = NULL; DecoderState(tif)->dec_decode = NULL; } /* * 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 = _LZWtrue; tif->tif_preencode = _TIFFNoPreCode; tif->tif_postencode = _LZWtrue; tif->tif_encoderow = _TIFFNoRowEncode; tif->tif_encodestrip = _TIFFNoStripEncode; tif->tif_encodetile = _TIFFNoTileEncode; tif->tif_cleanup = LZWCleanup; /* * Setup predictor setup. */ (void) TIFFPredictorInit(tif); return (1); bad: TIFFError("TIFFInitLZW", "No space for LZW state block"); return (0); }
static int ZIPSetupDecode(TIFF* tif) { ZIPState* sp = DecoderState(tif); static const char module[] = "ZIPSetupDecode"; assert(sp != NULL); if (inflateInit(&sp->stream) != Z_OK) { TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); return (0); } else { sp->state |= ZSTATE_INIT; return (1); } }
/* * Decode a string of 24-bit pixels. */ static int LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "LogLuvDecode24"; LogLuvState* sp = DecoderState(tif); tmsize_t cc; tmsize_t i; tmsize_t npixels; unsigned char* bp; uint32* tp; assert(s == 0); assert(sp != NULL); npixels = occ / sp->pixel_size; if (sp->user_datafmt == SGILOGDATAFMT_RAW) tp = (uint32 *)op; else { assert(sp->tbuflen >= npixels); tp = (uint32 *) sp->tbuf; } /* copy to array of uint32 */ bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; for (i = 0; i < npixels && cc > 0; i++) { tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; bp += 3; cc -= 3; } tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; if (i != npixels) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at row %lu (short %I64d pixels)", (unsigned long) tif->tif_row, (unsigned __int64) (npixels - i)); #else TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at row %lu (short %llu pixels)", (unsigned long) tif->tif_row, (unsigned long long) (npixels - i)); #endif return (0); } (*sp->tfunc)(sp, op, npixels); return (1); }
/* * Setup state for decoding a strip. */ static int ZIPPreDecode(TIFF* tif, tsample_t s) { ZIPState* sp = DecoderState(tif); (void) s; assert(sp != NULL); if( (sp->state & ZSTATE_INIT_DECODE) == 0 ) tif->tif_setupdecode( tif ); sp->stream.next_in = tif->tif_rawdata; sp->stream.avail_in = tif->tif_rawcc; return (inflateReset(&sp->stream) == Z_OK); }
static int LERCSetupDecode(TIFF* tif) { LERCState* sp = DecoderState(tif); assert(sp != NULL); /* if we were last encoding, terminate this mode */ if (sp->state & LSTATE_INIT_ENCODE) { sp->state = 0; } sp->state |= LSTATE_INIT_DECODE; return 1; }
static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "ZIPDecode"; ZIPState* sp = DecoderState(tif); (void) s; assert(sp != NULL); assert(sp->state == ZSTATE_INIT_DECODE); sp->stream.next_out = op; 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 apropriately even before we simplify it */ sp->stream.avail_out = (uInt) occ; if ((tmsize_t)sp->stream.avail_out != occ) { TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); return (0); } do { int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); if (state == Z_STREAM_END) break; if (state == Z_DATA_ERROR) { TIFFErrorExt(tif->tif_clientdata, module, "Decoding error at scanline %lu, %s", (unsigned long) tif->tif_row, sp->stream.msg); if (inflateSync(&sp->stream) != Z_OK) return (0); continue; } if (state != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", sp->stream.msg); return (0); } } while (sp->stream.avail_out > 0); if (sp->stream.avail_out != 0) { TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at scanline %lu (short %llu bytes)", (unsigned long) tif->tif_row, (unsigned long long) sp->stream.avail_out); return (0); } return (1); }
static int ZIPSetupDecode(TIFF* tif) { ZIPState* sp = DecoderState(tif); static const char module[] = "ZIPSetupDecode"; assert(sp != NULL); /* if we were last encoding, terminate this mode */ if (sp->state & ZSTATE_INIT_ENCODE) { deflateEnd(&sp->stream); sp->state = 0; } if (inflateInit(&sp->stream) != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg); return (0); } else { sp->state |= ZSTATE_INIT_DECODE; return (1); } }
/* * Decode a string of 24-bit pixels. */ static int LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) { LogLuvState* sp = DecoderState(tif); int cc, i, npixels; u_char* bp; uint32* tp; assert(s == 0); assert(sp != NULL); npixels = occ / sp->pixel_size; if (sp->user_datafmt == SGILOGDATAFMT_RAW) tp = (uint32 *)op; else { assert(sp->tbuflen >= npixels); tp = (uint32 *) sp->tbuf; } _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0])); /* copy to array of uint32 */ bp = (u_char*) tif->tif_rawcp; cc = tif->tif_rawcc; for (i = 0; i < npixels && cc > 0; i++) { tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; bp += 3; cc -= 3; } tif->tif_rawcp = (tidata_t) bp; tif->tif_rawcc = cc; if (i != npixels) { TIFFError(tif->tif_name, "LogLuvDecode24: Not enough data at row %d (short %d pixels)", tif->tif_row, npixels - i); return (0); } (*sp->tfunc)(sp, op, npixels); return (1); }
static int ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) { ZIPState* sp = DecoderState(tif); static const char module[] = "ZIPDecode"; (void) s; assert(sp != NULL); assert(sp->state == ZSTATE_INIT_DECODE); sp->stream.next_out = op; sp->stream.avail_out = occ; do { int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); if (state == Z_STREAM_END) break; if (state == Z_DATA_ERROR) { TIFFErrorExt(tif->tif_clientdata, module, "%s: Decoding error at scanline %d, %s", tif->tif_name, tif->tif_row, sp->stream.msg); if (inflateSync(&sp->stream) != Z_OK) return (0); continue; } if (state != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s", tif->tif_name, sp->stream.msg); return (0); } } while (sp->stream.avail_out > 0); if (sp->stream.avail_out != 0) { TIFFErrorExt(tif->tif_clientdata, module, "%s: Not enough data at scanline %d (short %d bytes)", tif->tif_name, tif->tif_row, sp->stream.avail_out); return (0); } return (1); }
/* * Decode a string of 32-bit pixels. */ static int LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "LogLuvDecode32"; LogLuvState* sp; int shft; tmsize_t i; tmsize_t npixels; unsigned char* bp; uint32* tp; uint32 b; tmsize_t cc; int rc; assert(s == 0); sp = DecoderState(tif); assert(sp != NULL); npixels = occ / sp->pixel_size; if (sp->user_datafmt == SGILOGDATAFMT_RAW) tp = (uint32*) op; else { assert(sp->tbuflen >= npixels); tp = (uint32*) sp->tbuf; } _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; /* get each byte string */ for (shft = 4*8; (shft -= 8) >= 0; ) { for (i = 0; i < npixels && cc > 0; ) if (*bp >= 128) { /* run */ rc = *bp++ + (2-128); b = (uint32)*bp++ << shft; cc -= 2; /* TODO: potential input buffer overrun when decoding corrupt or truncated data */ while (rc-- && i < npixels) tp[i++] |= b; } else { /* non-run */ rc = *bp++; /* nul is noop */ while (--cc && rc-- && i < npixels) tp[i++] |= (uint32)*bp++ << shft; } if (i != npixels) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at row %lu (short %I64d pixels)", (unsigned long) tif->tif_row, (unsigned __int64) (npixels - i)); #else TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at row %lu (short %llu pixels)", (unsigned long) tif->tif_row, (unsigned long long) (npixels - i)); #endif tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (0); } } (*sp->tfunc)(sp, op, npixels); tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (1); }
/* * Decode a string of 16-bit gray pixels. */ static int LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "LogL16Decode"; LogLuvState* sp = DecoderState(tif); int shft; tmsize_t i; tmsize_t npixels; unsigned char* bp; int16* tp; int16 b; tmsize_t cc; int rc; assert(s == 0); assert(sp != NULL); npixels = occ / sp->pixel_size; if (sp->user_datafmt == SGILOGDATAFMT_16BIT) tp = (int16*) op; else { if(sp->tbuflen < npixels) { TIFFErrorExt(tif->tif_clientdata, module, "Translation buffer too short"); return (0); } tp = (int16*) sp->tbuf; } _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); bp = (unsigned char*) tif->tif_rawcp; cc = tif->tif_rawcc; /* get each byte string */ for (shft = 2*8; (shft -= 8) >= 0; ) { for (i = 0; i < npixels && cc > 0; ) { if (*bp >= 128) { /* run */ if( cc < 2 ) break; rc = *bp++ + (2-128); b = (int16)(*bp++ << shft); cc -= 2; while (rc-- && i < npixels) tp[i++] |= b; } else { /* non-run */ rc = *bp++; /* nul is noop */ while (--cc && rc-- && i < npixels) tp[i++] |= (int16)*bp++ << shft; } } if (i != npixels) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at row %lu (short %I64d pixels)", (unsigned long) tif->tif_row, (unsigned __int64) (npixels - i)); #else TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at row %lu (short %llu pixels)", (unsigned long) tif->tif_row, (unsigned long long) (npixels - i)); #endif tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (0); } } (*sp->tfunc)(sp, op, npixels); tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; return (1); }
static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "ZIPDecode"; ZIPState* sp = DecoderState(tif); (void) s; assert(sp != NULL); assert(sp->state == ZSTATE_INIT_DECODE); sp->stream.next_in = tif->tif_rawcp; sp->stream.avail_in = (uInt) tif->tif_rawcc; sp->stream.next_out = op; 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 apropriately even before we simplify it */ sp->stream.avail_out = (uInt) occ; if ((tmsize_t)sp->stream.avail_out != occ) { TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size"); return (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 { int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); if (state == Z_STREAM_END) break; if (state == Z_DATA_ERROR) { TIFFErrorExt(tif->tif_clientdata, module, "Decoding error at scanline %lu, %s", (unsigned long) tif->tif_row, sp->stream.msg); if (inflateSync(&sp->stream) != Z_OK) return (0); continue; } if (state != Z_OK) { TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", sp->stream.msg); return (0); } } while (sp->stream.avail_out > 0); if (sp->stream.avail_out != 0) { TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); return (0); } tif->tif_rawcp = sp->stream.next_in; tif->tif_rawcc = sp->stream.avail_in; return (1); }
static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) { static const char module[] = "LZWDecodeCompat"; LZWCodecState *sp = DecoderState(tif); char *op = (char*) op0; long occ = (long) occ0; char *tp; unsigned char *bp; int code, nbits; long nextbits, nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; (void) s; assert(sp != NULL); /* Fail if value does not fit in long. */ if ((tmsize_t) occ != occ0) return (0); /* * Restart interrupted output operation. */ if (sp->dec_restart) { long residue; codep = sp->dec_codep; residue = codep->length - sp->dec_restart; if (residue > occ) { /* * Residue from previous decode is sufficient * to satisfy decode request. Skip to the * start of the decoded string, place decoded * values in the output buffer, and return. */ sp->dec_restart += occ; do { codep = codep->next; } while (--residue > occ); tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); return (1); } /* * Residue satisfies only part of the decode request. */ op += residue; occ -= residue; tp = op; do { *--tp = codep->value; codep = codep->next; } while (--residue); sp->dec_restart = 0; } bp = (unsigned char *)tif->tif_rawcp; #ifdef LZW_CHECKEOS sp->dec_bitsleft = (((uint64)tif->tif_rawcc) << 3); #endif nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; nbitsmask = sp->dec_nbitsmask; oldcodep = sp->dec_oldcodep; free_entp = sp->dec_free_entp; maxcodep = sp->dec_maxcodep; while (occ > 0) { NextCode(tif, sp, bp, code, GetNextCodeCompat); if (code == CODE_EOI) break; if (code == CODE_CLEAR) { do { free_entp = sp->dec_codetab + CODE_FIRST; _TIFFmemset(free_entp, 0, (CSIZE - CODE_FIRST) * sizeof (code_t)); nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); maxcodep = sp->dec_codetab + nbitsmask; NextCode(tif, sp, bp, code, GetNextCodeCompat); } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ if (code == CODE_EOI) break; if (code > CODE_CLEAR) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "LZWDecode: Corrupted LZW table at scanline %d", tif->tif_row); return (0); } *op++ = (char)code; occ--; oldcodep = sp->dec_codetab + code; continue; } codep = sp->dec_codetab + code; /* * Add the new entry to the code table. */ if (free_entp < &sp->dec_codetab[0] || free_entp >= &sp->dec_codetab[CSIZE]) { TIFFErrorExt(tif->tif_clientdata, module, "Corrupted LZW table at scanline %d", tif->tif_row); return (0); } free_entp->next = oldcodep; if (free_entp->next < &sp->dec_codetab[0] || free_entp->next >= &sp->dec_codetab[CSIZE]) { TIFFErrorExt(tif->tif_clientdata, module, "Corrupted LZW table at scanline %d", tif->tif_row); return (0); } free_entp->firstchar = free_entp->next->firstchar; free_entp->length = free_entp->next->length+1; free_entp->value = (codep < free_entp) ? codep->firstchar : free_entp->firstchar; if (++free_entp > maxcodep) { if (++nbits > BITS_MAX) /* should not happen */ nbits = BITS_MAX; nbitsmask = MAXCODE(nbits); maxcodep = sp->dec_codetab + nbitsmask; } oldcodep = codep; if (code >= 256) { /* * Code maps to a string, copy string * value to output (written in reverse). */ if(codep->length == 0) { TIFFErrorExt(tif->tif_clientdata, module, "Wrong length of decoded " "string: data probably corrupted at scanline %d", tif->tif_row); return (0); } if (codep->length > occ) { /* * String is too long for decode buffer, * locate portion that will fit, copy to * the decode buffer, and setup restart * logic for the next decoding call. */ sp->dec_codep = codep; do { codep = codep->next; } while (codep->length > occ); sp->dec_restart = occ; tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); break; } assert(occ >= codep->length); op += codep->length; occ -= codep->length; tp = op; do { *--tp = codep->value; } while( (codep = codep->next) != NULL ); } else { *op++ = (char)code; occ--; } } tif->tif_rawcc -= (tmsize_t)( (uint8*) bp - tif->tif_rawcp ); tif->tif_rawcp = (uint8*) bp; sp->lzw_nbits = (unsigned short)nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->dec_nbitsmask = nbitsmask; sp->dec_oldcodep = oldcodep; sp->dec_free_entp = free_entp; sp->dec_maxcodep = maxcodep; if (occ > 0) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at scanline %d (short %I64d bytes)", tif->tif_row, (unsigned __int64) occ); #else TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at scanline %d (short %llu bytes)", tif->tif_row, (unsigned long long) occ); #endif return (0); } return (1); }
/* * Setup state for decoding a strip. */ static int LZWPreDecode(TIFF* tif, uint16 s) { static const char module[] = "LZWPreDecode"; LZWCodecState *sp = DecoderState(tif); (void) s; assert(sp != NULL); if( sp->dec_codetab == NULL ) { tif->tif_setupdecode( tif ); if( sp->dec_codetab == NULL ) return (0); } /* * Check for old bit-reversed codes. */ if (tif->tif_rawcc >= 2 && tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { #ifdef LZW_COMPAT if (!sp->dec_decode) { TIFFWarningExt(tif->tif_clientdata, module, "Old-style LZW codes, convert file"); /* * Override default decoding methods with * ones that deal with the old coding. * Otherwise the predictor versions set * above will call the compatibility routines * through the dec_decode method. */ tif->tif_decoderow = LZWDecodeCompat; tif->tif_decodestrip = LZWDecodeCompat; tif->tif_decodetile = LZWDecodeCompat; /* * If doing horizontal differencing, must * re-setup the predictor logic since we * switched the basic decoder methods... */ (*tif->tif_setupdecode)(tif); sp->dec_decode = LZWDecodeCompat; } sp->lzw_maxcode = MAXCODE(BITS_MIN); #else /* !LZW_COMPAT */ if (!sp->dec_decode) { TIFFErrorExt(tif->tif_clientdata, module, "Old-style LZW codes not supported"); sp->dec_decode = LZWDecode; } return (0); #endif/* !LZW_COMPAT */ } else { sp->lzw_maxcode = MAXCODE(BITS_MIN)-1; sp->dec_decode = LZWDecode; } sp->lzw_nbits = BITS_MIN; sp->lzw_nextbits = 0; sp->lzw_nextdata = 0; sp->dec_restart = 0; sp->dec_nbitsmask = MAXCODE(BITS_MIN); #ifdef LZW_CHECKEOS sp->dec_bitsleft = 0; #endif sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; /* * Zero entries that are not yet filled in. We do * this to guard against bogus input data that causes * us to index into undefined entries. If you can * come up with a way to safely bounds-check input codes * while decoding then you can remove this operation. */ _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t)); sp->dec_oldcodep = &sp->dec_codetab[-1]; sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; return (1); }
/* * Setup state for decoding a strip. */ static int LERCPreDecode(TIFF* tif, uint16 s) { static const char module[] = "LERCPreDecode"; lerc_status lerc_ret; TIFFDirectory *td = &tif->tif_dir; LERCState* sp = DecoderState(tif); int lerc_data_type; unsigned int infoArray[8]; unsigned nomask_bands = td->td_samplesperpixel; int ndims; int use_mask = 0; uint8* lerc_data = tif->tif_rawcp; unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc; (void) s; assert(sp != NULL); lerc_data_type = GetLercDataType(tif); if( lerc_data_type < 0 ) return 0; if( !SetupUncompressedBuffer(tif, sp, module) ) return 0; if( sp->additional_compression != LERC_ADD_COMPRESSION_NONE ) { if( sp->compressed_size < sp->uncompressed_alloc ) { _TIFFfree(sp->compressed_buffer); sp->compressed_buffer = _TIFFmalloc(sp->uncompressed_alloc); if( !sp->compressed_buffer ) { sp->compressed_size = 0; return 0; } sp->compressed_size = sp->uncompressed_alloc; } } 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 = inflateInit(&strm); if( zlib_ret != Z_OK ) { TIFFErrorExt(tif->tif_clientdata, module, "inflateInit() failed"); inflateEnd(&strm); return 0; } strm.avail_in = (uInt)tif->tif_rawcc; strm.next_in = tif->tif_rawcp; strm.avail_out = sp->compressed_size; strm.next_out = sp->compressed_buffer; zlib_ret = inflate(&strm, Z_FINISH); if( zlib_ret != Z_STREAM_END && zlib_ret != Z_OK ) { TIFFErrorExt(tif->tif_clientdata, module, "inflate() failed"); inflateEnd(&strm); return 0; } lerc_data = sp->compressed_buffer; lerc_data_size = sp->compressed_size - strm.avail_out; inflateEnd(&strm); } else if( sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD ) { #ifdef ZSTD_SUPPORT size_t zstd_ret; zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size, tif->tif_rawcp, tif->tif_rawcc); if( ZSTD_isError(zstd_ret) ) { TIFFErrorExt(tif->tif_clientdata, module, "Error in ZSTD_decompress(): %s", ZSTD_getErrorName(zstd_ret)); return 0; } lerc_data = sp->compressed_buffer; lerc_data_size = (unsigned int)zstd_ret; #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; } lerc_ret = lerc_getBlobInfo( lerc_data, lerc_data_size, infoArray, NULL, 8, 0); if( lerc_ret != 0 ) { TIFFErrorExt(tif->tif_clientdata, module, "lerc_getBlobInfo() failed"); return 0; } /* If the configuration is compatible of a LERC mask, and that the */ /* LERC info has dim == samplesperpixel - 1, then there is a LERC */ /* mask. */ if( td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && td->td_sampleinfo[td->td_extrasamples-1] == EXTRASAMPLE_UNASSALPHA && GetLercDataType(tif) == 1 && infoArray[2] == td->td_samplesperpixel - 1U ) { use_mask = 1; nomask_bands --; } ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1; /* Info returned in infoArray is { version, dataType, nDim, nCols, nRows, nBands, nValidPixels, blobSize } */ if( infoArray[0] != (unsigned)sp->lerc_version ) { TIFFWarningExt(tif->tif_clientdata, module, "Unexpected version number: %d. Expected: %d", infoArray[0], sp->lerc_version); } if( infoArray[1] != (unsigned)lerc_data_type ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected dataType: %d. Expected: %d", infoArray[1], lerc_data_type); return 0; } if( infoArray[2] != (unsigned)ndims ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected nDim: %d. Expected: %d", infoArray[2], ndims); return 0; } if( infoArray[3] != sp->segment_width ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected nCols: %d. Expected: %du", infoArray[3], sp->segment_width); return 0; } if( infoArray[4] != sp->segment_height ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected nRows: %d. Expected: %u", infoArray[4], sp->segment_height); return 0; } if( infoArray[5] != 1 ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected nBands: %d. Expected: %d", infoArray[5], 1); return 0; } if( infoArray[7] != lerc_data_size ) { TIFFErrorExt(tif->tif_clientdata, module, "Unexpected blobSize: %d. Expected: %u", infoArray[7], lerc_data_size); return 0; } lerc_ret = lerc_decode( lerc_data, lerc_data_size, use_mask ? sp->mask_buffer : NULL, ndims, sp->segment_width, sp->segment_height, 1, lerc_data_type, sp->uncompressed_buffer); if( lerc_ret != 0 ) { TIFFErrorExt(tif->tif_clientdata, module, "lerc_decode() failed"); return 0; } /* Interleave alpha mask with other samples. */ if( use_mask ) { unsigned src_stride = (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); unsigned dst_stride = td->td_samplesperpixel * (td->td_bitspersample / 8); unsigned i = sp->segment_width * sp->segment_height; /* Operate from end to begin to be able to move in place */ while( i > 0 && i > nomask_bands ) { i --; sp->uncompressed_buffer[ i * dst_stride + td->td_samplesperpixel - 1] = 255 * sp->mask_buffer[i]; memcpy( sp->uncompressed_buffer + i * dst_stride, sp->uncompressed_buffer + i * src_stride, src_stride ); } /* First pixels must use memmove due to overlapping areas */ while( i > 0 ) { i --; sp->uncompressed_buffer[ i * dst_stride + td->td_samplesperpixel - 1] = 255 * sp->mask_buffer[i]; memmove( sp->uncompressed_buffer + i * dst_stride, sp->uncompressed_buffer + i * src_stride, src_stride ); } } return 1; }
static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "LZMADecode"; LZMAState* sp = DecoderState(tif); (void) s; assert(sp != NULL); assert(sp->state == LSTATE_INIT_DECODE); sp->stream.next_in = tif->tif_rawcp; sp->stream.avail_in = (size_t) tif->tif_rawcc; sp->stream.next_out = op; sp->stream.avail_out = (size_t) occ; if ((tmsize_t)sp->stream.avail_out != occ) { TIFFErrorExt(tif->tif_clientdata, module, "Liblzma cannot deal with buffers this size"); return 0; } do { /* * Save the current stream state to properly recover from the * decoding errors later. */ const uint8_t *next_in = sp->stream.next_in; size_t avail_in = sp->stream.avail_in; lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); if (ret == LZMA_STREAM_END) break; if (ret == LZMA_MEMLIMIT_ERROR) { lzma_ret r = lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0); if (r != LZMA_OK) { TIFFErrorExt(tif->tif_clientdata, module, "Error initializing the stream decoder, %s", LZMAStrerror(r)); break; } sp->stream.next_in = next_in; sp->stream.avail_in = avail_in; continue; } if (ret != LZMA_OK) { TIFFErrorExt(tif->tif_clientdata, module, "Decoding error at scanline %lu, %s", (unsigned long) tif->tif_row, LZMAStrerror(ret)); break; } } while (sp->stream.avail_out > 0); if (sp->stream.avail_out != 0) { TIFFErrorExt(tif->tif_clientdata, module, "Not enough data at scanline %lu (short %lu bytes)", (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out); return 0; } tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */ tif->tif_rawcc = sp->stream.avail_in; return 1; }
static int LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) { LZWCodecState *sp = DecoderState(tif); char *op = (char*) op0; long occ = (long) occ0; char *tp; u_char *bp; int code, nbits; long nextbits, nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; (void) s; assert(sp != NULL); /* * Restart interrupted output operation. */ if (sp->dec_restart) { long residue; codep = sp->dec_codep; residue = codep->length - sp->dec_restart; if (residue > occ) { /* * Residue from previous decode is sufficient * to satisfy decode request. Skip to the * start of the decoded string, place decoded * values in the output buffer, and return. */ sp->dec_restart += occ; do { codep = codep->next; } while (--residue > occ); tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); return (1); } /* * Residue satisfies only part of the decode request. */ op += residue, occ -= residue; tp = op; do { *--tp = codep->value; codep = codep->next; } while (--residue); sp->dec_restart = 0; } bp = (u_char *)tif->tif_rawcp; nbits = sp->lzw_nbits; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; nbitsmask = sp->dec_nbitsmask; oldcodep = sp->dec_oldcodep; free_entp = sp->dec_free_entp; maxcodep = sp->dec_maxcodep; while (occ > 0) { NextCode(tif, sp, bp, code, GetNextCodeCompat); if (code == CODE_EOI) break; if (code == CODE_CLEAR) { free_entp = sp->dec_codetab + CODE_FIRST; nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); maxcodep = sp->dec_codetab + nbitsmask; NextCode(tif, sp, bp, code, GetNextCodeCompat); if (code == CODE_EOI) break; *op++ = (char) code, occ--; oldcodep = sp->dec_codetab + code; continue; } codep = sp->dec_codetab + code; /* * Add the new entry to the code table. */ if (free_entp < &sp->dec_codetab[0] || free_entp >= &sp->dec_codetab[CSIZE]) { TIFFError(tif->tif_name, "LZWDecodeCompat: Corrupted LZW table at scanline %d", tif->tif_row); return (0); } free_entp->next = oldcodep; if (free_entp->next < &sp->dec_codetab[0] || free_entp->next >= &sp->dec_codetab[CSIZE]) { TIFFError(tif->tif_name, "LZWDecodeCompat: Corrupted LZW table at scanline %d", tif->tif_row); return (0); } free_entp->firstchar = free_entp->next->firstchar; free_entp->length = free_entp->next->length+1; free_entp->value = (codep < free_entp) ? codep->firstchar : free_entp->firstchar; if (++free_entp > maxcodep) { if (++nbits > BITS_MAX) /* should not happen */ nbits = BITS_MAX; nbitsmask = MAXCODE(nbits); maxcodep = sp->dec_codetab + nbitsmask; } oldcodep = codep; if (code >= 256) { /* * Code maps to a string, copy string * value to output (written in reverse). */ if(codep->length == 0) { TIFFError(tif->tif_name, "LZWDecodeCompat: Wrong length of decoded " "string: data probably corrupted at scanline %d", tif->tif_row); return (0); } if (codep->length > occ) { /* * String is too long for decode buffer, * locate portion that will fit, copy to * the decode buffer, and setup restart * logic for the next decoding call. */ sp->dec_codep = codep; do { codep = codep->next; } while (codep->length > occ); sp->dec_restart = occ; tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); break; } op += codep->length, occ -= codep->length; tp = op; do { *--tp = codep->value; } while( (codep = codep->next) != NULL); } else *op++ = (char) code, occ--; } tif->tif_rawcp = (tidata_t) bp; sp->lzw_nbits = (u_short) nbits; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->dec_nbitsmask = nbitsmask; sp->dec_oldcodep = oldcodep; sp->dec_free_entp = free_entp; sp->dec_maxcodep = maxcodep; if (occ > 0) { TIFFError(tif->tif_name, "LZWDecodeCompat: Not enough data at scanline %d (short %d bytes)", tif->tif_row, occ); return (0); } return (1); }