Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibTIFF4/tif_dirread.c view on Meta::CPAN
else
err=TIFFReadDirEntryShortArray(tif,dp,&value);
if (err!=TIFFReadDirEntryErrOk)
{
fip = TIFFFieldWithTag(tif,dp->tdir_tag);
TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
}
else
{
TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
_TIFFfree(value);
}
}
break;
/* BEGIN REV 4.0 COMPATIBILITY */
case TIFFTAG_OSUBFILETYPE:
{
uint16 valueo;
uint32 value;
if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
{
switch (valueo)
{
case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
default: value=0; break;
}
if (value!=0)
TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
}
}
break;
/* END REV 4.0 COMPATIBILITY */
default:
(void) TIFFFetchNormalTag(tif, dp, TRUE);
break;
}
}
/*
* OJPEG hack:
* - If a) compression is OJPEG, and b) photometric tag is missing,
* then we consistently find that photometric should be YCbCr
* - If a) compression is OJPEG, and b) photometric tag says it's RGB,
* then we consistently find that the buggy implementation of the
* buggy compression scheme matches photometric YCbCr instead.
* - If a) compression is OJPEG, and b) bitspersample tag is missing,
* then we consistently find bitspersample should be 8.
* - If a) compression is OJPEG, b) samplesperpixel tag is missing,
* and c) photometric is RGB or YCbCr, then we consistently find
* samplesperpixel should be 3
* - If a) compression is OJPEG, b) samplesperpixel tag is missing,
* and c) photometric is MINISWHITE or MINISBLACK, then we consistently
* find samplesperpixel should be 3
*/
if (tif->tif_dir.td_compression==COMPRESSION_OJPEG)
{
if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
{
TIFFWarningExt(tif->tif_clientdata, module,
"Photometric tag is missing, assuming data is YCbCr");
if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
goto bad;
}
else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
{
tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR;
TIFFWarningExt(tif->tif_clientdata, module,
"Photometric tag value assumed incorrect, "
"assuming data is YCbCr instead of RGB");
}
if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
{
TIFFWarningExt(tif->tif_clientdata,module,
"BitsPerSample tag is missing, assuming 8 bits per sample");
if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
goto bad;
}
if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
{
if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag is missing, "
"assuming correct SamplesPerPixel value is 3");
if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
goto bad;
}
if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
{
TIFFWarningExt(tif->tif_clientdata,module,
"SamplesPerPixel tag is missing, "
"applying correct SamplesPerPixel value of 3");
if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
goto bad;
}
else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
|| (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
{
/*
* SamplesPerPixel tag is missing, but is not required
* by spec. Assume correct SamplesPerPixel value of 1.
*/
if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
goto bad;
}
}
}
/*
* Verify Palette image has a Colormap.
*/
if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
!TIFFFieldSet(tif, FIELD_COLORMAP)) {
if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
else if (tif->tif_dir.td_bitspersample>=8)
tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
else {
MissingRequired(tif, "Colormap");
goto bad;
}
}
/*
* OJPEG hack:
* We do no further messing with strip/tile offsets/bytecounts in OJPEG
* TIFFs
*/
if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
{
/*
* Attempt to deal with a missing StripByteCounts tag.
*/
if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
/*
* Some manufacturers violate the spec by not giving
* the size of the strips. In this case, assume there
* is one uncompressed strip of data.
*/
if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
tif->tif_dir.td_nstrips > 1) ||
(tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) {
MissingRequired(tif, "StripByteCounts");
goto bad;
}
TIFFWarningExt(tif->tif_clientdata, module,
"TIFF directory is missing required "
"\"StripByteCounts\" field, calculating from imagelength");
if (EstimateStripByteCounts(tif, dir, dircount) < 0)
src/Source/LibTIFF4/tif_dirread.c view on Meta::CPAN
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabLong(&offset);
err=TIFFReadDirEntryData(tif,offset,8,m.i);
}
else
{
m.l=dir->tdir_offset.toff_long8;
err=TIFFReadDirEntryErrOk;
}
}
if (err==TIFFReadDirEntryErrOk)
{
double n;
if (tif->tif_flags&TIFF_SWAB)
TIFFSwabArrayOfLong(m.i,2);
if (m.i[0]==0)
n=0.0;
else if (m.i[0]==0xFFFFFFFF)
/*
* XXX: Numerator 0xFFFFFFFF means that we have infinite
* distance. Indicate that with a negative floating point
* SubjectDistance value.
*/
n=-1.0;
else
n=(double)m.i[0]/(double)m.i[1];
return(TIFFSetField(tif,dir->tdir_tag,n));
}
else
{
TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
return(0);
}
}
/*
* Replace a single strip (tile) of uncompressed data by multiple strips
* (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
* dealing with large images or for dealing with machines with a limited
* amount memory.
*/
static void
ChopUpSingleUncompressedStrip(TIFF* tif)
{
register TIFFDirectory *td = &tif->tif_dir;
uint64 bytecount;
uint64 offset;
uint32 rowblock;
uint64 rowblockbytes;
uint64 stripbytes;
uint32 strip;
uint64 nstrips64;
uint32 nstrips32;
uint32 rowsperstrip;
uint64* newcounts;
uint64* newoffsets;
bytecount = td->td_stripbytecount[0];
offset = td->td_stripoffset[0];
assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
(!isUpSampled(tif)))
rowblock = td->td_ycbcrsubsampling[1];
else
rowblock = 1;
rowblockbytes = TIFFVTileSize64(tif, rowblock);
/*
* Make the rows hold at least one scanline, but fill specified amount
* of data if possible.
*/
if (rowblockbytes > STRIP_SIZE_DEFAULT) {
stripbytes = rowblockbytes;
rowsperstrip = rowblock;
} else if (rowblockbytes > 0 ) {
uint32 rowblocksperstrip;
rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes);
rowsperstrip = rowblocksperstrip * rowblock;
stripbytes = rowblocksperstrip * rowblockbytes;
}
else
return;
/*
* never increase the number of strips in an image
*/
if (rowsperstrip >= td->td_rowsperstrip)
return;
nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
return;
nstrips32 = (uint32)nstrips64;
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
"for chopped \"StripByteCounts\" array");
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, 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 < nstrips32; strip++) {
if (stripbytes > bytecount)
stripbytes = bytecount;
newcounts[strip] = stripbytes;
newoffsets[strip] = offset;
offset += stripbytes;
bytecount -= stripbytes;
}
/*
* Replace old single strip info with multi-strip info.
( run in 0.330 second using v1.01-cache-2.11-cpan-8644d7adfcd )