Commit 22d93099 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #16892 from alalek:update_libtiff

parents d2b09537 13c4dc0e
...@@ -126,30 +126,30 @@ endif() ...@@ -126,30 +126,30 @@ endif()
if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T) if(SIZEOF_UNSIGNED_INT EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned int") set(TIFF_SIZE_T "unsigned int")
set(TIFF_SIZE_FORMAT "%u") set(TIFF_SIZE_FORMAT "%u")
set(TIFF_SSIZE_T "signed int")
set(TIFF_SSIZE_FORMAT "%d")
elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T) elseif(SIZEOF_UNSIGNED_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned long") set(TIFF_SIZE_T "unsigned long")
set(TIFF_SIZE_FORMAT "%lu") set(TIFF_SIZE_FORMAT "%lu")
set(TIFF_SSIZE_T "signed long")
set(TIFF_SSIZE_FORMAT "%ld")
elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T) elseif(SIZEOF_UNSIGNED_LONG_LONG EQUAL SIZEOF_SIZE_T)
set(TIFF_SIZE_T "unsigned long") set(TIFF_SIZE_T "unsigned long")
if(MINGW) if(MINGW)
set(TIFF_SIZE_FORMAT "%I64u") set(TIFF_SIZE_FORMAT "%I64u")
set(TIFF_SSIZE_FORMAT "%I64d")
else() else()
set(TIFF_SIZE_FORMAT "%llu") set(TIFF_SIZE_FORMAT "%llu")
set(TIFF_SSIZE_FORMAT "%lld")
endif() endif()
endif() endif()
if(SIZEOF_SIGNED_INT EQUAL SIZEOF_UNSIGNED_CHAR_P) if(SIZEOF_SIGNED_INT EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed int")
set(TIFF_SSIZE_FORMAT "%d")
elseif(SIZEOF_SIGNED_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P) elseif(SIZEOF_SIGNED_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed long")
set(TIFF_SSIZE_FORMAT "%ld")
elseif(SIZEOF_SIGNED_LONG_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P) elseif(SIZEOF_SIGNED_LONG_LONG EQUAL SIZEOF_UNSIGNED_CHAR_P)
set(TIFF_SSIZE_T "signed long long") set(TIFF_SSIZE_T "signed long long")
if(MINGW) if(MINGW)
set(TIFF_SSIZE_FORMAT "%I64d")
else() else()
set(TIFF_SSIZE_FORMAT "%lld")
endif() endif()
endif() endif()
...@@ -216,6 +216,8 @@ endif() ...@@ -216,6 +216,8 @@ endif()
set(fillorder FILLORDER_MSB2LSB) set(fillorder FILLORDER_MSB2LSB)
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*" OR CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64.*" OR
# AMD64 on Windows
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64" OR
CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64.*") CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64.*")
set(fillorder FILLORDER_LSB2MSB) set(fillorder FILLORDER_LSB2MSB)
endif() endif()
......
...@@ -16,7 +16,11 @@ int _TIFF_vsnprintf_f(char* str, size_t size, const char* format, va_list ap) ...@@ -16,7 +16,11 @@ int _TIFF_vsnprintf_f(char* str, size_t size, const char* format, va_list ap)
int count = -1; int count = -1;
if (size != 0) if (size != 0)
#if _MSC_VER <= 1310
count = _vsnprintf(str, size, format, ap);
#else
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
#endif
if (count == -1) if (count == -1)
count = _vscprintf(format, ap); count = _vscprintf(format, ap);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "tiffiop.h" #include "tiffiop.h"
#include "tif_predict.h" #include "tif_predict.h"
#include <math.h> #include <math.h>
#include <float.h>
uint32 uint32
_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where) _TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
...@@ -357,6 +358,15 @@ _TIFFUInt64ToDouble(uint64 ui64) ...@@ -357,6 +358,15 @@ _TIFFUInt64ToDouble(uint64 ui64)
} }
} }
float _TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
int _TIFFSeekOK(TIFF* tif, toff_t off) int _TIFFSeekOK(TIFF* tif, toff_t off)
{ {
/* Huge offsets, especially -1 / UINT64_MAX, can cause issues */ /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
......
...@@ -216,7 +216,7 @@ ...@@ -216,7 +216,7 @@
#endif #endif
/* Number of bits in a file offset, on hosts where this is settable. */ /* Number of bits in a file offset, on hosts where this is settable. */
//disabled for OpenCV CMakeLists.txt: #define _FILE_OFFSET_BITS @FILE_OFFSET_BITS@ #define _FILE_OFFSET_BITS @FILE_OFFSET_BITS@
/* Define to `__inline__' or `__inline' if that's what the C compiler /* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */ calls it, or to nothing if 'inline' is not supported under any name. */
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
* (and also some miscellaneous stuff) * (and also some miscellaneous stuff)
*/ */
#include "tiffiop.h" #include "tiffiop.h"
#include <float.h>
/* /*
* These are used in the backwards compatibility code... * These are used in the backwards compatibility code...
...@@ -88,13 +87,15 @@ setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) ...@@ -88,13 +87,15 @@ setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
* Install extra samples information. * Install extra samples information.
*/ */
static int static int
setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) setExtraSamples(TIFF* tif, va_list ap, uint32* v)
{ {
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
#define EXTRASAMPLE_COREL_UNASSALPHA 999 #define EXTRASAMPLE_COREL_UNASSALPHA 999
uint16* va; uint16* va;
uint32 i; uint32 i;
TIFFDirectory* td = &tif->tif_dir;
static const char module[] = "setExtraSamples";
*v = (uint16) va_arg(ap, uint16_vap); *v = (uint16) va_arg(ap, uint16_vap);
if ((uint16) *v > td->td_samplesperpixel) if ((uint16) *v > td->td_samplesperpixel)
...@@ -116,6 +117,18 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) ...@@ -116,6 +117,18 @@ setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
return 0; return 0;
} }
} }
if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - *v > 1) &&
!(td->td_samplesperpixel - td->td_extrasamples > 1))
{
TIFFWarningExt(tif->tif_clientdata,module,
"ExtraSamples tag value is changing, "
"but TransferFunction was read with a different value. Cancelling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
}
td->td_extrasamples = (uint16) *v; td->td_extrasamples = (uint16) *v;
_TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
return 1; return 1;
...@@ -153,15 +166,6 @@ bad: ...@@ -153,15 +166,6 @@ bad:
return (0); return (0);
} }
static float TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
static int static int
_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
{ {
...@@ -285,6 +289,18 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) ...@@ -285,6 +289,18 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFfree(td->td_smaxsamplevalue); _TIFFfree(td->td_smaxsamplevalue);
td->td_smaxsamplevalue = NULL; td->td_smaxsamplevalue = NULL;
} }
/* Test if 3 transfer functions instead of just one are now needed
See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */
if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) &&
!(td->td_samplesperpixel - td->td_extrasamples > 1))
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag value is changing, "
"but TransferFunction was read with a different value. Cancelling it");
TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION);
_TIFFfree(td->td_transferfunction[0]);
td->td_transferfunction[0] = NULL;
}
} }
td->td_samplesperpixel = (uint16) v; td->td_samplesperpixel = (uint16) v;
break; break;
...@@ -320,13 +336,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) ...@@ -320,13 +336,13 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
dblval = va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 ) if( dblval < 0 )
goto badvaluedouble; goto badvaluedouble;
td->td_xresolution = TIFFClampDoubleToFloat( dblval ); td->td_xresolution = _TIFFClampDoubleToFloat( dblval );
break; break;
case TIFFTAG_YRESOLUTION: case TIFFTAG_YRESOLUTION:
dblval = va_arg(ap, double); dblval = va_arg(ap, double);
if( dblval < 0 ) if( dblval < 0 )
goto badvaluedouble; goto badvaluedouble;
td->td_yresolution = TIFFClampDoubleToFloat( dblval ); td->td_yresolution = _TIFFClampDoubleToFloat( dblval );
break; break;
case TIFFTAG_PLANARCONFIG: case TIFFTAG_PLANARCONFIG:
v = (uint16) va_arg(ap, uint16_vap); v = (uint16) va_arg(ap, uint16_vap);
...@@ -335,10 +351,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) ...@@ -335,10 +351,10 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
td->td_planarconfig = (uint16) v; td->td_planarconfig = (uint16) v;
break; break;
case TIFFTAG_XPOSITION: case TIFFTAG_XPOSITION:
td->td_xposition = TIFFClampDoubleToFloat( va_arg(ap, double) ); td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break; break;
case TIFFTAG_YPOSITION: case TIFFTAG_YPOSITION:
td->td_yposition = TIFFClampDoubleToFloat( va_arg(ap, double) ); td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) );
break; break;
case TIFFTAG_RESOLUTIONUNIT: case TIFFTAG_RESOLUTIONUNIT:
v = (uint16) va_arg(ap, uint16_vap); v = (uint16) va_arg(ap, uint16_vap);
...@@ -361,7 +377,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) ...@@ -361,7 +377,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
_TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
break; break;
case TIFFTAG_EXTRASAMPLES: case TIFFTAG_EXTRASAMPLES:
if (!setExtraSamples(td, ap, &v)) if (!setExtraSamples(tif, ap, &v))
goto badvalue; goto badvalue;
break; break;
case TIFFTAG_MATTEING: case TIFFTAG_MATTEING:
...@@ -684,7 +700,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) ...@@ -684,7 +700,7 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFF_SRATIONAL: case TIFF_SRATIONAL:
case TIFF_FLOAT: case TIFF_FLOAT:
{ {
float v2 = TIFFClampDoubleToFloat(va_arg(ap, double)); float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double));
_TIFFmemcpy(val, &v2, tv_size); _TIFFmemcpy(val, &v2, tv_size);
} }
break; break;
......
...@@ -164,6 +164,7 @@ static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover); ...@@ -164,6 +164,7 @@ static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp); static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
static void ChopUpSingleUncompressedStrip(TIFF*); static void ChopUpSingleUncompressedStrip(TIFF*);
static void TryChopUpUncompressedBigTiff(TIFF*);
static uint64 TIFFReadUInt64(const uint8 *value); static uint64 TIFFReadUInt64(const uint8 *value);
static int _TIFFGetMaxColorChannels(uint16 photometric); static int _TIFFGetMaxColorChannels(uint16 photometric);
...@@ -4246,6 +4247,19 @@ TIFFReadDirectory(TIFF* tif) ...@@ -4246,6 +4247,19 @@ TIFFReadDirectory(TIFF* tif)
ChopUpSingleUncompressedStrip(tif); ChopUpSingleUncompressedStrip(tif);
} }
/* There are also uncompressed stripped files with strips larger than */
/* 2 GB, which make them unfriendly with a lot of code. If possible, */
/* try to expose smaller "virtual" strips. */
if( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
tif->tif_dir.td_compression == COMPRESSION_NONE &&
(tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP &&
TIFFStripSize64(tif) > 0x7FFFFFFFUL )
{
if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
return 0;
TryChopUpUncompressedBigTiff(tif);
}
/* /*
* Clear the dirty directory flag. * Clear the dirty directory flag.
*/ */
...@@ -5699,6 +5713,63 @@ TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir) ...@@ -5699,6 +5713,63 @@ TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
} }
} }
static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips,
uint64 stripbytes, uint32 rowsperstrip)
{
TIFFDirectory *td = &tif->tif_dir;
uint64 bytecount;
uint64 offset;
uint32 i;
uint64 *newcounts;
uint64 *newoffsets;
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripByteCounts\" array");
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripOffsets\" array");
if (newcounts == NULL || newoffsets == NULL) {
/*
* Unable to allocate new strip information, give up and use
* the original one strip information.
*/
if (newcounts != NULL)
_TIFFfree(newcounts);
if (newoffsets != NULL)
_TIFFfree(newoffsets);
return;
}
/*
* Fill the strip information arrays with new bytecounts and offsets
* that reflect the broken-up format.
*/
offset = td->td_stripoffset[0];
bytecount = td->td_stripoffset[td->td_nstrips-1] +
td->td_stripbytecount[td->td_nstrips-1] - offset;
for (i = 0; i < nstrips; i++)
{
if (stripbytes > bytecount)
stripbytes = bytecount;
newcounts[i] = stripbytes;
newoffsets[i] = stripbytes ? offset : 0;
offset += stripbytes;
bytecount -= stripbytes;
}
/*
* Replace old single strip info with multi-strip info.
*/
td->td_stripsperimage = td->td_nstrips = nstrips;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
_TIFFfree(td->td_stripbytecount);
_TIFFfree(td->td_stripoffset);
td->td_stripbytecount = newcounts;
td->td_stripoffset = newoffsets;
td->td_stripbytecountsorted = 1;
}
/* /*
* Replace a single strip (tile) of uncompressed data by multiple strips * Replace a single strip (tile) of uncompressed data by multiple strips
* (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
...@@ -5714,11 +5785,8 @@ ChopUpSingleUncompressedStrip(TIFF* tif) ...@@ -5714,11 +5785,8 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint32 rowblock; uint32 rowblock;
uint64 rowblockbytes; uint64 rowblockbytes;
uint64 stripbytes; uint64 stripbytes;
uint32 strip;
uint32 nstrips; uint32 nstrips;
uint32 rowsperstrip; uint32 rowsperstrip;
uint64* newcounts;
uint64* newoffsets;
bytecount = td->td_stripbytecount[0]; bytecount = td->td_stripbytecount[0];
/* On a newly created file, just re-opened to be filled, we */ /* On a newly created file, just re-opened to be filled, we */
...@@ -5769,46 +5837,106 @@ ChopUpSingleUncompressedStrip(TIFF* tif) ...@@ -5769,46 +5837,106 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
return; return;
} }
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
"for chopped \"StripByteCounts\" array");
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripOffsets\" array");
if (newcounts == NULL || newoffsets == NULL) {
/*
* Unable to allocate new strip information, give up and use
* the original one strip information.
*/
if (newcounts != NULL)
_TIFFfree(newcounts);
if (newoffsets != NULL)
_TIFFfree(newoffsets);
return;
}
/*
* Fill the strip information arrays with new bytecounts and offsets
* that reflect the broken-up format.
*/
for (strip = 0; strip < nstrips; strip++) {
if (stripbytes > bytecount)
stripbytes = bytecount;
newcounts[strip] = stripbytes;
newoffsets[strip] = stripbytes ? offset : 0;
offset += stripbytes;
bytecount -= stripbytes;
}
/*
* Replace old single strip info with multi-strip info.
*/
td->td_stripsperimage = td->td_nstrips = nstrips;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
_TIFFfree(td->td_stripbytecount);
_TIFFfree(td->td_stripoffset);
td->td_stripbytecount = newcounts;
td->td_stripoffset = newoffsets;
td->td_stripbytecountsorted = 1;
} }
/*
* Replace a file with contiguous strips > 2 GB of uncompressed data by
* multiple smaller strips. This is useful for
* dealing with large images or for dealing with machines with a limited
* amount memory.
*/
static void TryChopUpUncompressedBigTiff( TIFF* tif )
{
TIFFDirectory *td = &tif->tif_dir;
uint32 rowblock;
uint64 rowblockbytes;
uint32 i;
uint64 stripsize;
uint32 rowblocksperstrip;
uint32 rowsperstrip;
uint64 stripbytes;
uint32 nstrips;
stripsize = TIFFStripSize64(tif);
assert( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG );
assert( tif->tif_dir.td_compression == COMPRESSION_NONE );
assert( (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP );
assert( stripsize > 0x7FFFFFFFUL );
/* On a newly created file, just re-opened to be filled, we */
/* don't want strip chop to trigger as it is going to cause issues */
/* later ( StripOffsets and StripByteCounts improperly filled) . */
if( td->td_stripbytecount[0] == 0 && tif->tif_mode != O_RDONLY )
return;
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
(!isUpSampled(tif)))
rowblock = td->td_ycbcrsubsampling[1];
else
rowblock = 1;
rowblockbytes = TIFFVStripSize64(tif, rowblock);
if( rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL )
{
/* In case of file with gigantic width */
return;
}
/* Check that the strips are contiguous and of the expected size */
for( i = 0; i < td->td_nstrips; i++ )
{
if( i == td->td_nstrips - 1 )
{
if( td->td_stripbytecount[i] < TIFFVStripSize64(
tif, td->td_imagelength - i * td->td_rowsperstrip ) )
{
return;
}
}
else
{
if( td->td_stripbytecount[i] != stripsize )
{
return;
}
if( i > 0 && td->td_stripoffset[i] !=
td->td_stripoffset[i-1] + td->td_stripbytecount[i - 1] )
{
return;
}
}
}
/* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
rowblocksperstrip = (uint32) (512 * 1024 * 1024 / rowblockbytes);
if( rowblocksperstrip == 0 )
rowblocksperstrip = 1;
rowsperstrip = rowblocksperstrip * rowblock;
stripbytes = rowblocksperstrip * rowblockbytes;
assert( stripbytes <= 0x7FFFFFFFUL );
nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
if( nstrips == 0 )
return;
/* If we are going to allocate a lot of memory, make sure that the */
/* file is as big as needed */
if( tif->tif_mode == O_RDONLY &&
nstrips > 1000000 &&
(td->td_stripoffset[td->td_nstrips-1] > TIFFGetFileSize(tif) ||
td->td_stripoffset[td->td_nstrips-1] +
td->td_stripbytecount[td->td_nstrips-1] > TIFFGetFileSize(tif)) )
{
return;
}
allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
}
int _TIFFFillStriles( TIFF *tif ) int _TIFFFillStriles( TIFF *tif )
{ {
return _TIFFFillStrilesInternal( tif, 1 ); return _TIFFFillStrilesInternal( tif, 1 );
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
* Directory Write Support Routines. * Directory Write Support Routines.
*/ */
#include "tiffiop.h" #include "tiffiop.h"
#include <float.h>
#ifdef HAVE_IEEEFP #ifdef HAVE_IEEEFP
#define TIFFCvtNativeToIEEEFloat(tif, n, fp) #define TIFFCvtNativeToIEEEFloat(tif, n, fp)
...@@ -946,15 +945,6 @@ bad: ...@@ -946,15 +945,6 @@ bad:
return(0); return(0);
} }
static float TIFFClampDoubleToFloat( double val )
{
if( val > FLT_MAX )
return FLT_MAX;
if( val < -FLT_MAX )
return -FLT_MAX;
return (float)val;
}
static int8 TIFFClampDoubleToInt8( double val ) static int8 TIFFClampDoubleToInt8( double val )
{ {
if( val > 127 ) if( val > 127 )
...@@ -1029,7 +1019,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di ...@@ -1029,7 +1019,7 @@ TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* di
if (tif->tif_dir.td_bitspersample<=32) if (tif->tif_dir.td_bitspersample<=32)
{ {
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
((float*)conv)[i] = TIFFClampDoubleToFloat(value[i]); ((float*)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
} }
else else
...@@ -1893,12 +1883,14 @@ TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir ...@@ -1893,12 +1883,14 @@ TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir
n=3; n=3;
if (n==3) if (n==3)
{ {
if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16))) if (tif->tif_dir.td_transferfunction[2] == NULL ||
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
n=2; n=2;
} }
if (n==2) if (n==2)
{ {
if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16))) if (tif->tif_dir.td_transferfunction[1] == NULL ||
!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
n=1; n=1;
} }
if (n==0) if (n==0)
......
...@@ -742,9 +742,14 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) ...@@ -742,9 +742,14 @@ LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
#undef exp2 /* Conflict with C'99 function */ #undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2*(x)) #define exp2(x) exp(M_LN2*(x))
#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \ static int itrunc(double x, int m)
(int)(x) : \ {
(int)((x) + rand()*(1./RAND_MAX) - .5)) if( m == SGILOGENCODE_NODITHER )
return (int)x;
/* Silence CoverityScan warning about bad crypto function */
/* coverity[dont_call] */
return (int)(x + rand()*(1./RAND_MAX) - .5);
}
#if !LOGLUV_PUBLIC #if !LOGLUV_PUBLIC
static static
......
...@@ -247,6 +247,8 @@ LZWSetupDecode(TIFF* tif) ...@@ -247,6 +247,8 @@ LZWSetupDecode(TIFF* tif)
/* /*
* Zero-out the unused entries * Zero-out the unused entries
*/ */
/* Silence false positive */
/* coverity[overrun-buffer-arg] */
_TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0, _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
(CODE_FIRST - CODE_CLEAR) * sizeof (code_t)); (CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
} }
......
...@@ -640,6 +640,7 @@ PixarLogGuessDataFmt(TIFFDirectory *td) ...@@ -640,6 +640,7 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
static tmsize_t static tmsize_t
multiply_ms(tmsize_t m1, tmsize_t m2) multiply_ms(tmsize_t m1, tmsize_t m2)
{ {
assert(m1 >= 0 && m2 >= 0);
if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
return 0; return 0;
return m1 * m2; return m1 * m2;
...@@ -648,6 +649,7 @@ multiply_ms(tmsize_t m1, tmsize_t m2) ...@@ -648,6 +649,7 @@ multiply_ms(tmsize_t m1, tmsize_t m2)
static tmsize_t static tmsize_t
add_ms(tmsize_t m1, tmsize_t m2) add_ms(tmsize_t m1, tmsize_t m2)
{ {
assert(m1 >= 0 && m2 >= 0);
/* if either input is zero, assume overflow already occurred */ /* if either input is zero, assume overflow already occurred */
if (m1 == 0 || m2 == 0) if (m1 == 0 || m2 == 0)
return 0; return 0;
...@@ -817,9 +819,7 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) ...@@ -817,9 +819,7 @@ PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s", "Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); (unsigned long) tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)");
if (inflateSync(&sp->stream) != Z_OK) return (0);
return (0);
continue;
} }
if (state != Z_OK) { if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s", TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
......
...@@ -103,6 +103,11 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size, ...@@ -103,6 +103,11 @@ static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
} }
tif->tif_rawdata = new_rawdata; tif->tif_rawdata = new_rawdata;
} }
if( tif->tif_rawdata == NULL )
{
/* should not happen in practice but helps CoverityScan */
return 0;
}
bytes_read = TIFFReadFile(tif, bytes_read = TIFFReadFile(tif,
tif->tif_rawdata + rawdata_offset + already_read, to_read); tif->tif_rawdata + rawdata_offset + already_read, to_read);
...@@ -1367,7 +1372,8 @@ TIFFFillTile(TIFF* tif, uint32 tile) ...@@ -1367,7 +1372,8 @@ TIFFFillTile(TIFF* tif, uint32 tile)
tif->tif_rawdataoff = 0; tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = bytecountm; tif->tif_rawdataloaded = bytecountm;
if (!isFillOrder(tif, td->td_fillorder) && if (tif->tif_rawdata != NULL &&
!isFillOrder(tif, td->td_fillorder) &&
(tif->tif_flags & TIFF_NOBITREV) == 0) (tif->tif_flags & TIFF_NOBITREV) == 0)
TIFFReverseBits(tif->tif_rawdata, TIFFReverseBits(tif->tif_rawdata,
tif->tif_rawdataloaded); tif->tif_rawdataloaded);
......
...@@ -349,6 +349,12 @@ TWebPSetupEncode(TIFF* tif) ...@@ -349,6 +349,12 @@ TWebPSetupEncode(TIFF* tif)
sp->state |= LSTATE_INIT_ENCODE; sp->state |= LSTATE_INIT_ENCODE;
if (!WebPPictureInit(&sp->sPicture)) {
TIFFErrorExt(tif->tif_clientdata, module,
"Error initializing WebP picture.");
return 0;
}
if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT,
sp->quality_level, sp->quality_level,
WEBP_ENCODER_ABI_VERSION)) { WEBP_ENCODER_ABI_VERSION)) {
...@@ -357,9 +363,13 @@ TWebPSetupEncode(TIFF* tif) ...@@ -357,9 +363,13 @@ TWebPSetupEncode(TIFF* tif)
return 0; return 0;
} }
#if WEBP_ENCODER_ABI_VERSION >= 0x0100 // WebPConfigInitInternal above sets lossless to false
sp->sEncoderConfig.lossless = sp->lossless; #if WEBP_ENCODER_ABI_VERSION >= 0x0100
#endif sp->sEncoderConfig.lossless = sp->lossless;
if (sp->lossless) {
sp->sPicture.use_argb = 1;
}
#endif
if (!WebPValidateConfig(&sp->sEncoderConfig)) { if (!WebPValidateConfig(&sp->sEncoderConfig)) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
...@@ -367,12 +377,6 @@ TWebPSetupEncode(TIFF* tif) ...@@ -367,12 +377,6 @@ TWebPSetupEncode(TIFF* tif)
return 0; return 0;
} }
if (!WebPPictureInit(&sp->sPicture)) {
TIFFErrorExt(tif->tif_clientdata, module,
"Error initializing WebP picture.");
return 0;
}
return 1; return 1;
} }
...@@ -415,6 +419,12 @@ TWebPPreEncode(TIFF* tif, uint16 s) ...@@ -415,6 +419,12 @@ TWebPPreEncode(TIFF* tif, uint16 s)
/* set up buffer for raw data */ /* set up buffer for raw data */
/* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */
sp->buffer_size = segment_width * segment_height * sp->nSamples; sp->buffer_size = segment_width * segment_height * sp->nSamples;
if (sp->pBuffer != NULL) {
_TIFFfree(sp->pBuffer);
sp->pBuffer = NULL;
}
sp->pBuffer = _TIFFmalloc(sp->buffer_size); sp->pBuffer = _TIFFmalloc(sp->buffer_size);
if( !sp->pBuffer) { if( !sp->pBuffer) {
TIFFErrorExt(tif->tif_clientdata, module, "Cannot allocate buffer"); TIFFErrorExt(tif->tif_clientdata, module, "Cannot allocate buffer");
...@@ -460,7 +470,7 @@ TWebPPostEncode(TIFF* tif) ...@@ -460,7 +470,7 @@ TWebPPostEncode(TIFF* tif)
"WebPPictureImportRGB() failed"); "WebPPictureImportRGB() failed");
return 0; return 0;
} }
if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) { if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) {
#if WEBP_ENCODER_ABI_VERSION >= 0x0100 #if WEBP_ENCODER_ABI_VERSION >= 0x0100
...@@ -540,15 +550,13 @@ TWebPCleanup(TIFF* tif) ...@@ -540,15 +550,13 @@ TWebPCleanup(TIFF* tif)
} }
if (sp->pBuffer != NULL) { if (sp->pBuffer != NULL) {
_TIFFfree(sp->pBuffer); _TIFFfree(sp->pBuffer);
sp->pBuffer = NULL; sp->pBuffer = NULL;
} }
if (tif->tif_data) { _TIFFfree(tif->tif_data);
_TIFFfree(tif->tif_data); tif->tif_data = NULL;
tif->tif_data = NULL;
}
_TIFFSetDefaultCompressionState(tif); _TIFFSetDefaultCompressionState(tif);
} }
...@@ -570,6 +578,9 @@ TWebPVSetField(TIFF* tif, uint32 tag, va_list ap) ...@@ -570,6 +578,9 @@ TWebPVSetField(TIFF* tif, uint32 tag, va_list ap)
case TIFFTAG_WEBP_LOSSLESS: case TIFFTAG_WEBP_LOSSLESS:
#if WEBP_ENCODER_ABI_VERSION >= 0x0100 #if WEBP_ENCODER_ABI_VERSION >= 0x0100
sp->lossless = va_arg(ap, int); sp->lossless = va_arg(ap, int);
if (sp->lossless){
sp->quality_level = 100.0f;
}
return 1; return 1;
#else #else
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
......
...@@ -124,7 +124,6 @@ ZIPSetupDecode(TIFF* tif) ...@@ -124,7 +124,6 @@ ZIPSetupDecode(TIFF* tif)
static int static int
ZIPPreDecode(TIFF* tif, uint16 s) ZIPPreDecode(TIFF* tif, uint16 s)
{ {
static const char module[] = "ZIPPreDecode";
ZIPState* sp = DecoderState(tif); ZIPState* sp = DecoderState(tif);
(void) s; (void) s;
...@@ -138,12 +137,7 @@ ZIPPreDecode(TIFF* tif, uint16 s) ...@@ -138,12 +137,7 @@ ZIPPreDecode(TIFF* tif, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated 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 to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */ appropriately even before we simplify it */
sp->stream.avail_in = (uInt) tif->tif_rawcc; sp->stream.avail_in = (uint64)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt) tif->tif_rawcc : 0xFFFFFFFFU;
if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
{
TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
return (0);
}
return (inflateReset(&sp->stream) == Z_OK); return (inflateReset(&sp->stream) == Z_OK);
} }
...@@ -158,46 +152,43 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) ...@@ -158,46 +152,43 @@ ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
assert(sp->state == ZSTATE_INIT_DECODE); assert(sp->state == ZSTATE_INIT_DECODE);
sp->stream.next_in = tif->tif_rawcp; sp->stream.next_in = tif->tif_rawcp;
sp->stream.avail_in = (uInt) tif->tif_rawcc;
sp->stream.next_out = op; sp->stream.next_out = op;
assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, 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 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 to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */ appropriately 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 { do {
int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); int state;
uInt avail_in_before = (uint64)tif->tif_rawcc <= 0xFFFFFFFFU ? (uInt)tif->tif_rawcc : 0xFFFFFFFFU;
uInt avail_out_before = (uint64)occ < 0xFFFFFFFFU ? (uInt) occ : 0xFFFFFFFFU;
sp->stream.avail_in = avail_in_before;
sp->stream.avail_out = avail_out_before;
state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
occ -= (avail_out_before - sp->stream.avail_out);
if (state == Z_STREAM_END) if (state == Z_STREAM_END)
break; break;
if (state == Z_DATA_ERROR) { if (state == Z_DATA_ERROR) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Decoding error at scanline %lu, %s", "Decoding error at scanline %lu, %s",
(unsigned long) tif->tif_row, SAFE_MSG(sp)); (unsigned long) tif->tif_row, SAFE_MSG(sp));
if (inflateSync(&sp->stream) != Z_OK) return (0);
return (0);
continue;
} }
if (state != Z_OK) { if (state != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"ZLib error: %s", SAFE_MSG(sp)); "ZLib error: %s", SAFE_MSG(sp));
return (0); return (0);
} }
} while (sp->stream.avail_out > 0); } while (occ > 0);
if (sp->stream.avail_out != 0) { if (occ != 0) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)", "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
(unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out); (unsigned long) tif->tif_row, (TIFF_UINT64_T) occ);
return (0); return (0);
} }
tif->tif_rawcp = sp->stream.next_in; tif->tif_rawcp = sp->stream.next_in;
tif->tif_rawcc = sp->stream.avail_in;
return (1); return (1);
} }
...@@ -229,7 +220,6 @@ ZIPSetupEncode(TIFF* tif) ...@@ -229,7 +220,6 @@ ZIPSetupEncode(TIFF* tif)
static int static int
ZIPPreEncode(TIFF* tif, uint16 s) ZIPPreEncode(TIFF* tif, uint16 s)
{ {
static const char module[] = "ZIPPreEncode";
ZIPState *sp = EncoderState(tif); ZIPState *sp = EncoderState(tif);
(void) s; (void) s;
...@@ -242,12 +232,7 @@ ZIPPreEncode(TIFF* tif, uint16 s) ...@@ -242,12 +232,7 @@ ZIPPreEncode(TIFF* tif, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated 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 to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */ appropriately even before we simplify it */
sp->stream.avail_out = (uInt)tif->tif_rawdatasize; sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
{
TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
return (0);
}
return (deflateReset(&sp->stream) == Z_OK); return (deflateReset(&sp->stream) == Z_OK);
} }
...@@ -269,13 +254,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) ...@@ -269,13 +254,9 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
we need to simplify this code to reflect a ZLib that is likely updated 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 to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */ appropriately even before we simplify it */
sp->stream.avail_in = (uInt) cc;
if ((tmsize_t)sp->stream.avail_in != cc)
{
TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
return (0);
}
do { do {
uInt avail_in_before = (uint64)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
sp->stream.avail_in = avail_in_before;
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
TIFFErrorExt(tif->tif_clientdata, module, TIFFErrorExt(tif->tif_clientdata, module,
"Encoder error: %s", "Encoder error: %s",
...@@ -286,9 +267,10 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) ...@@ -286,9 +267,10 @@ ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
tif->tif_rawcc = tif->tif_rawdatasize; tif->tif_rawcc = tif->tif_rawdatasize;
TIFFFlushData1(tif); TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata; sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
} }
} while (sp->stream.avail_in > 0); cc -= (avail_in_before - sp->stream.avail_in);
} while (cc > 0);
return (1); return (1);
} }
...@@ -314,7 +296,7 @@ ZIPPostEncode(TIFF* tif) ...@@ -314,7 +296,7 @@ ZIPPostEncode(TIFF* tif)
tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
TIFFFlushData1(tif); TIFFFlushData1(tif);
sp->stream.next_out = tif->tif_rawdata; sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
} }
break; break;
default: default:
......
...@@ -374,6 +374,8 @@ extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); ...@@ -374,6 +374,8 @@ extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
extern double _TIFFUInt64ToDouble(uint64); extern double _TIFFUInt64ToDouble(uint64);
extern float _TIFFUInt64ToFloat(uint64); extern float _TIFFUInt64ToFloat(uint64);
extern float _TIFFClampDoubleToFloat(double);
extern tmsize_t extern tmsize_t
_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip, _TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip,
void **buf, tmsize_t bufsizetoalloc, void **buf, tmsize_t bufsizetoalloc,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment