Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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);
}
Exemple #5
0
/*
 * 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);
}
Exemple #6
0
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*/
}
Exemple #7
0
/*
* 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;
}
Exemple #8
0
/*
 * 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));
}
Exemple #9
0
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;
}