static int PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) { char *bp; tsize_t cc; long n; int b; (void) s; bp = (char*) tif->tif_rawcp; cc = tif->tif_rawcc; while (cc > 0 && (long)occ > 0) { n = (long) *bp++, cc--; /* * Watch out for compilers that * don't sign extend chars... */ if (n >= 128) n -= 256; if (n < 0) { /* replicate next byte -n+1 times */ if (n == -128) /* nop */ continue; n = -n + 1; if( occ < n ) { TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "PackBitsDecode: discarding %d bytes " "to avoid buffer overrun", n - occ); n = occ; } occ -= n; b = *bp++, cc--; while (n-- > 0) *op++ = (tidataval_t) b; } else { /* copy next n+1 bytes literally */ if (occ < n + 1) { TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "PackBitsDecode: discarding %d bytes " "to avoid buffer overrun", n - occ + 1); n = occ - 1; } _TIFFmemcpy(op, bp, ++n); op += n; occ -= n; bp += n; cc -= n; } } tif->tif_rawcp = (tidata_t) bp; tif->tif_rawcc = cc; if (occ > 0) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "PackBitsDecode: Not enough data for scanline %ld", (long) tif->tif_row); return (0); } return (1); }
static int PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) { static const char module[] = "PackBitsDecode"; char *bp; tmsize_t cc; long n; int b; (void) s; bp = (char*) tif->tif_rawcp; cc = tif->tif_rawcc; while (cc > 0 && occ > 0) { n = (long) *bp++, cc--; /* * Watch out for compilers that * don't sign extend chars... */ if (n >= 128) n -= 256; if (n < 0) { /* replicate next byte -n+1 times */ if (n == -128) /* nop */ continue; n = -n + 1; if( occ < (tmsize_t)n ) { TIFFWarningExt(tif->tif_clientdata, module, "Discarding %lu bytes to avoid buffer overrun", (unsigned long) ((tmsize_t)n - occ)); n = (long)occ; } occ -= n; b = *bp++, cc--; /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */ while (n-- > 0) *op++ = (uint8) b; } else { /* copy next n+1 bytes literally */ if (occ < (tmsize_t)(n + 1)) { TIFFWarningExt(tif->tif_clientdata, module, "Discarding %lu bytes to avoid buffer overrun", (unsigned long) ((tmsize_t)n - occ + 1)); n = (long)occ - 1; } _TIFFmemcpy(op, bp, ++n); /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */ op += n; occ -= n; bp += n; cc -= n; } } tif->tif_rawcp = (uint8*) bp; tif->tif_rawcc = cc; if (occ > 0) { TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %lu", (unsigned long) tif->tif_row); return (0); } return (1); }
static int TWebPVSetField(TIFF* tif, uint32 tag, va_list ap) { static const char module[] = "WebPVSetField"; WebPState* sp = LState(tif); switch (tag) { case TIFFTAG_WEBP_LEVEL: sp->quality_level = (int) va_arg(ap, int); if( sp->quality_level <= 0 || sp->quality_level > 100.0f ) { TIFFWarningExt(tif->tif_clientdata, module, "WEBP_LEVEL should be between 1 and 100"); } return 1; case TIFFTAG_WEBP_LOSSLESS: #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sp->lossless = va_arg(ap, int); if (sp->lossless){ sp->quality_level = 100.0f; } return 1; #else TIFFErrorExt(tif->tif_clientdata, module, "Need to upgrade WEBP driver, this version doesn't support " "lossless compression."); return 0; #endif default: return (*sp->vsetparent)(tif, tag, ap); } /*NOTREACHED*/ }
/* * Setup a directory entry of an array of RATIONAL * or SRATIONAL and write the associated indirect values. */ static int TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) { uint32 i; uint32* t; int status; t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32)); if (t == NULL) { TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space to write RATIONAL array"); return (0); } for (i = 0; i < dir->tdir_count; i++) { float fv = v[i]; int sign = 1; uint32 den; if (fv < 0) { if (dir->tdir_type == TIFF_RATIONAL) { TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name, fv); fv = 0; } else fv = -fv, sign = -1; } den = 1L; if (fv > 0) { while (fv < 1L<<(31-3) && den < 1L<<(31-3)) fv *= 1<<3, den *= 1L<<3; } t[2*i+0] = (uint32) (sign * (fv + 0.5)); t[2*i+1] = den; } status = TIFFWriteData(tif, dir, (char *)t); _TIFFfree((char*) t); return (status); }
/* * 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); }
static int LERCVSetField(TIFF* tif, uint32 tag, va_list ap) { static const char module[] = "LERCVSetField"; LERCState* sp = LState(tif); switch (tag) { case TIFFTAG_LERC_PARAMETERS: { uint32 count = va_arg(ap, int); int* params = va_arg(ap, int*); if( count < 2 ) { TIFFErrorExt(tif->tif_clientdata, module, "Invalid count for LercParameters: %u", count); return 0; } sp->lerc_version = params[0]; sp->additional_compression = params[1]; return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count, params); } case TIFFTAG_LERC_MAXZERROR: sp->maxzerror = va_arg(ap, double); return 1; case TIFFTAG_LERC_VERSION: { int params[2] = {0, 0}; int version = va_arg(ap, int); if( version != LERC_VERSION_2_4 ) { TIFFErrorExt(tif->tif_clientdata, module, "Invalid value for LercVersion: %d", version); return 0; } sp->lerc_version = version; params[0] = sp->lerc_version; params[1] = sp->additional_compression; return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); } case TIFFTAG_LERC_ADD_COMPRESSION: { int params[2] = {0, 0}; int additional_compression = va_arg(ap, int); #ifndef ZSTD_SUPPORT if( additional_compression == LERC_ADD_COMPRESSION_ZSTD ) { TIFFErrorExt(tif->tif_clientdata, module, "LERC_ZSTD requested, but ZSTD not available"); return 0; } #endif if( additional_compression != LERC_ADD_COMPRESSION_NONE && additional_compression != LERC_ADD_COMPRESSION_DEFLATE && additional_compression != LERC_ADD_COMPRESSION_ZSTD ) { TIFFErrorExt(tif->tif_clientdata, module, "Invalid value for LercAdditionalCompression: %d", additional_compression); return 0; } sp->additional_compression = additional_compression; params[0] = sp->lerc_version; params[1] = sp->additional_compression; return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); } #ifdef ZSTD_SUPPORT case TIFFTAG_ZSTD_LEVEL: { sp->zstd_compress_level = (int) va_arg(ap, int); if( sp->zstd_compress_level <= 0 || sp->zstd_compress_level > ZSTD_maxCLevel() ) { TIFFWarningExt(tif->tif_clientdata, module, "ZSTD_LEVEL should be between 1 and %d", ZSTD_maxCLevel()); } return 1; } #endif case TIFFTAG_ZIPQUALITY: { sp->zipquality = (int) va_arg(ap, int); return (1); } default: return (*sp->vsetparent)(tif, tag, ap); } /*NOTREACHED*/ }
/* * 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; }
/* * Read the specified strip and setup for decoding. The data buffer is * expanded, as necessary, to hold the strip's data. */ int TIFFFillStrip(TIFF* tif, uint32 strip) { static const char module[] = "TIFFFillStrip"; TIFFDirectory *td = &tif->tif_dir; if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) return 0; if ((tif->tif_flags&TIFF_NOREADRAW)==0) { uint64 bytecount = td->td_stripbytecount[strip]; if ((int64)bytecount <= 0) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Invalid strip byte count %I64u, strip %lu", (unsigned __int64) bytecount, (unsigned long) strip); #else TIFFErrorExt(tif->tif_clientdata, module, "Invalid strip byte count %llu, strip %lu", (unsigned long long) bytecount, (unsigned long) strip); #endif return (0); } /* To avoid excessive memory allocations: */ /* Byte count should normally not be larger than a number of */ /* times the uncompressed size plus some margin */ if( bytecount > 1024 * 1024 ) { /* 10 and 4096 are just values that could be adjusted. */ /* Hopefully they are safe enough for all codecs */ tmsize_t stripsize = TIFFStripSize(tif); if( stripsize != 0 && (bytecount - 4096) / 10 > (uint64)stripsize ) { uint64 newbytecount = (uint64)stripsize * 10 + 4096; if( (int64)newbytecount >= 0 ) { #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFWarningExt(tif->tif_clientdata, module, "Too large strip byte count %I64u, strip %lu. Limiting to %I64u", (unsigned __int64) bytecount, (unsigned long) strip, (unsigned __int64) newbytecount); #else TIFFErrorExt(tif->tif_clientdata, module, "Too large strip byte count %llu, strip %lu. Limiting to %llu", (unsigned long long) bytecount, (unsigned long) strip, (unsigned long long) newbytecount); #endif bytecount = newbytecount; } } } if (isMapped(tif)) { /* * We must check for overflow, potentially causing * an OOB read. Instead of simple * * td->td_stripoffset[strip]+bytecount > tif->tif_size * * comparison (which can overflow) we do the following * two comparisons: */ if (bytecount > (uint64)tif->tif_size || td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) { /* * This error message might seem strange, but * it's what would happen if a read were done * instead. */ #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) TIFFErrorExt(tif->tif_clientdata, module, "Read error on strip %lu; " "got %I64u bytes, expected %I64u", (unsigned long) strip, (unsigned __int64) tif->tif_size - td->td_stripoffset[strip], (unsigned __int64) bytecount); #else TIFFErrorExt(tif->tif_clientdata, module, "Read error on strip %lu; " "got %llu bytes, expected %llu", (unsigned long) strip, (unsigned long long) tif->tif_size - td->td_stripoffset[strip], (unsigned long long) bytecount); #endif tif->tif_curstrip = NOSTRIP; return (0); } } if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { /* * The image is mapped into memory and we either don't * need to flip bits or the compression routine is * going to handle this operation itself. In this * case, avoid copying the raw data and instead just * reference the data from the memory mapped file * image. This assumes that the decompression * routines do not modify the contents of the raw data * buffer (if they try to, the application will get a * fault since the file is mapped read-only). */ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { _TIFFfree(tif->tif_rawdata); tif->tif_rawdata = NULL; tif->tif_rawdatasize = 0; } tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = (tmsize_t) bytecount; /* * When we have tif_rawdata reference directly into the memory mapped file * we need to be pretty careful about how we use the rawdata. It is not * a general purpose working buffer as it normally otherwise is. So we * keep track of this fact to avoid using it improperly. */ tif->tif_flags |= TIFF_BUFFERMMAP; } else { /* * Expand raw data buffer, if needed, to hold data * strip coming from file (perhaps should set upper * bound on the size of a buffer we'll use?). */ tmsize_t bytecountm; bytecountm=(tmsize_t)bytecount; if ((uint64)bytecountm!=bytecount) { TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); return(0); } if (bytecountm > tif->tif_rawdatasize) { tif->tif_curstrip = NOSTRIP; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { TIFFErrorExt(tif->tif_clientdata, module, "Data buffer too small to hold strip %lu", (unsigned long) strip); return (0); } } if (tif->tif_flags&TIFF_BUFFERMMAP) { tif->tif_curstrip = NOSTRIP; tif->tif_rawdata = NULL; tif->tif_rawdatasize = 0; tif->tif_flags &= ~TIFF_BUFFERMMAP; } if( isMapped(tif) ) { if (bytecountm > tif->tif_rawdatasize && !TIFFReadBufferSetup(tif, 0, bytecountm)) { return (0); } if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm, module) != bytecountm) { return (0); } } else { if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm, module) != bytecountm) { return (0); } } tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = bytecountm; if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) TIFFReverseBits(tif->tif_rawdata, bytecountm); } } return (TIFFStartStrip(tif, strip)); }
static int _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) { static const char module[] = "_TIFFVSetField"; TIFFDirectory* td = &tif->tif_dir; int status = 1; uint32 v32, i, v; char* s; switch (tag) { case TIFFTAG_SUBFILETYPE: td->td_subfiletype = va_arg(ap, uint32); break; case TIFFTAG_IMAGEWIDTH: td->td_imagewidth = va_arg(ap, uint32); break; case TIFFTAG_IMAGELENGTH: td->td_imagelength = va_arg(ap, uint32); break; case TIFFTAG_BITSPERSAMPLE: td->td_bitspersample = (uint16) va_arg(ap, int); /* * If the data require post-decoding processing to byte-swap * samples, set it up here. Note that since tags are required * to be ordered, compression code can override this behaviour * in the setup method if it wants to roll the post decoding * work in with its normal work. */ if (tif->tif_flags & TIFF_SWAB) { if (td->td_bitspersample == 8) tif->tif_postdecode = _TIFFNoPostDecode; else if (td->td_bitspersample == 16) tif->tif_postdecode = _TIFFSwab16BitData; else if (td->td_bitspersample == 24) tif->tif_postdecode = _TIFFSwab24BitData; else if (td->td_bitspersample == 32) tif->tif_postdecode = _TIFFSwab32BitData; else if (td->td_bitspersample == 64) tif->tif_postdecode = _TIFFSwab64BitData; else if (td->td_bitspersample == 128) /* two 64's */ tif->tif_postdecode = _TIFFSwab64BitData; } break; case TIFFTAG_COMPRESSION: v = va_arg(ap, uint32) & 0xffff; /* * If we're changing the compression scheme, the notify the * previous module so that it can cleanup any state it's * setup. */ if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { if (td->td_compression == v) break; (*tif->tif_cleanup)(tif); tif->tif_flags &= ~TIFF_CODERSETUP; } /* * Setup new compression routine state. */ if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) td->td_compression = (uint16) v; else status = 0; break; case TIFFTAG_PHOTOMETRIC: td->td_photometric = (uint16) va_arg(ap, int); break; case TIFFTAG_THRESHHOLDING: td->td_threshholding = (uint16) va_arg(ap, int); break; case TIFFTAG_FILLORDER: v = va_arg(ap, uint32); if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) goto badvalue; td->td_fillorder = (uint16) v; break; case TIFFTAG_ORIENTATION: v = va_arg(ap, uint32); if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) goto badvalue; else td->td_orientation = (uint16) v; break; case TIFFTAG_SAMPLESPERPIXEL: /* XXX should cross check -- e.g. if pallette, then 1 */ v = va_arg(ap, uint32); if (v == 0) goto badvalue; td->td_samplesperpixel = (uint16) v; break; case TIFFTAG_ROWSPERSTRIP: v32 = va_arg(ap, uint32); if (v32 == 0) goto badvalue32; td->td_rowsperstrip = v32; if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { td->td_tilelength = v32; td->td_tilewidth = td->td_imagewidth; } break; case TIFFTAG_MINSAMPLEVALUE: td->td_minsamplevalue = (uint16) va_arg(ap, int); break; case TIFFTAG_MAXSAMPLEVALUE: td->td_maxsamplevalue = (uint16) va_arg(ap, int); break; case TIFFTAG_SMINSAMPLEVALUE: td->td_sminsamplevalue = va_arg(ap, double); break; case TIFFTAG_SMAXSAMPLEVALUE: td->td_smaxsamplevalue = va_arg(ap, double); break; case TIFFTAG_XRESOLUTION: td->td_xresolution = (float) va_arg(ap, double); break; case TIFFTAG_YRESOLUTION: td->td_yresolution = (float) va_arg(ap, double); break; case TIFFTAG_PLANARCONFIG: v = va_arg(ap, uint32); if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) goto badvalue; td->td_planarconfig = (uint16) v; break; case TIFFTAG_XPOSITION: td->td_xposition = (float) va_arg(ap, double); break; case TIFFTAG_YPOSITION: td->td_yposition = (float) va_arg(ap, double); break; case TIFFTAG_RESOLUTIONUNIT: v = va_arg(ap, uint32); if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) goto badvalue; td->td_resolutionunit = (uint16) v; break; case TIFFTAG_PAGENUMBER: td->td_pagenumber[0] = (uint16) va_arg(ap, int); td->td_pagenumber[1] = (uint16) va_arg(ap, int); break; case TIFFTAG_HALFTONEHINTS: td->td_halftonehints[0] = (uint16) va_arg(ap, int); td->td_halftonehints[1] = (uint16) va_arg(ap, int); break; case TIFFTAG_COLORMAP: v32 = (uint32)(1L<<td->td_bitspersample); _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32); _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32); _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); break; case TIFFTAG_EXTRASAMPLES: if (!setExtraSamples(td, ap, &v)) goto badvalue; break; case TIFFTAG_MATTEING: td->td_extrasamples = (uint16) (va_arg(ap, int) != 0); if (td->td_extrasamples) { uint16 sv = EXTRASAMPLE_ASSOCALPHA; _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); } break; case TIFFTAG_TILEWIDTH: v32 = va_arg(ap, uint32); if (v32 % 16) { if (tif->tif_mode != O_RDONLY) goto badvalue32; TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "Nonstandard tile width %d, convert file", v32); } td->td_tilewidth = v32; tif->tif_flags |= TIFF_ISTILED; break; case TIFFTAG_TILELENGTH: v32 = va_arg(ap, uint32); if (v32 % 16) { if (tif->tif_mode != O_RDONLY) goto badvalue32; TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "Nonstandard tile length %d, convert file", v32); } td->td_tilelength = v32; tif->tif_flags |= TIFF_ISTILED; break; case TIFFTAG_TILEDEPTH: v32 = va_arg(ap, uint32); if (v32 == 0) goto badvalue32; td->td_tiledepth = v32; break; case TIFFTAG_DATATYPE: v = va_arg(ap, uint32); switch (v) { case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; default: goto badvalue; } td->td_sampleformat = (uint16) v; break; case TIFFTAG_SAMPLEFORMAT: v = va_arg(ap, uint32); if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) goto badvalue; td->td_sampleformat = (uint16) v; /* Try to fix up the SWAB function for complex data. */ if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT && td->td_bitspersample == 32 && tif->tif_postdecode == _TIFFSwab32BitData ) tif->tif_postdecode = _TIFFSwab16BitData; else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) && td->td_bitspersample == 64 && tif->tif_postdecode == _TIFFSwab64BitData ) tif->tif_postdecode = _TIFFSwab32BitData; break; case TIFFTAG_IMAGEDEPTH: td->td_imagedepth = va_arg(ap, uint32); break; case TIFFTAG_SUBIFD: if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { td->td_nsubifd = (uint16) va_arg(ap, int); _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*), (long) td->td_nsubifd); } else {
static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) { struct jbg_dec_state decoder; int decodeStatus = 0; unsigned char* pImage = NULL; unsigned long decodedSize; (void) s; if (isFillOrder(tif, tif->tif_dir.td_fillorder)) { TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); } jbg_dec_init(&decoder); #if defined(HAVE_JBG_NEWLEN) jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); /* * I do not check the return status of jbg_newlen because even if this * function fails it does not necessarily mean that decoding the image * will fail. It is generally only needed for received fax images * that do not contain the actual length of the image in the BIE * header. I do not log when an error occurs because that will cause * problems when converting JBIG encoded TIFF's to * PostScript. As long as the actual image length is contained in the * BIE header jbg_dec_in should succeed. */ #endif /* HAVE_JBG_NEWLEN */ decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, (size_t)tif->tif_rawcc, NULL); if (JBG_EOK != decodeStatus) { /* * XXX: JBG_EN constant was defined in pre-2.0 releases of the * JBIG-KIT. Since the 2.0 the error reporting functions were * changed. We will handle both cases here. */ TIFFErrorExt(tif->tif_clientdata, "JBIG", "Error (%d) decoding: %s", decodeStatus, #if defined(JBG_EN) jbg_strerror(decodeStatus, JBG_EN) #else jbg_strerror(decodeStatus) #endif ); jbg_dec_free(&decoder); return 0; } decodedSize = jbg_dec_getsize(&decoder); if( (tmsize_t)decodedSize < size ) { TIFFWarningExt(tif->tif_clientdata, "JBIG", "Only decoded %lu bytes, whereas %lu requested", decodedSize, (unsigned long)size); } else if( (tmsize_t)decodedSize > size ) { TIFFErrorExt(tif->tif_clientdata, "JBIG", "Decoded %lu bytes, whereas %lu were requested", decodedSize, (unsigned long)size); jbg_dec_free(&decoder); return 0; } pImage = jbg_dec_getimage(&decoder, 0); _TIFFmemcpy(buffer, pImage, decodedSize); jbg_dec_free(&decoder); tif->tif_rawcp += tif->tif_rawcc; tif->tif_rawcc = 0; return 1; }