Made some TIFF reading adjustments.
Read a few TIFF tags that assist with having a similar TIFF file when saving the image again, instead of (by default) always saving as a 24-bit RGB image. Also, in accordance with libtiff, allow reading X and Y resolution values even if the resolution unit tag is not set. Applied (modified) patch by scottb. Closes #13015. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67264 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -402,42 +402,78 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
|
|||||||
alpha -= 2*w;
|
alpha -= 2*w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the image resolution if it's available
|
|
||||||
uint16 tiffRes;
|
uint16 spp, bpp, compression;
|
||||||
if ( TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &tiffRes) )
|
/*
|
||||||
|
Read some baseline TIFF tags which helps when re-saving a TIFF
|
||||||
|
to be similar to the original image.
|
||||||
|
*/
|
||||||
|
if ( TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp) )
|
||||||
{
|
{
|
||||||
wxImageResolution res;
|
image->SetOption(wxIMAGE_OPTION_SAMPLESPERPIXEL, spp);
|
||||||
switch ( tiffRes )
|
}
|
||||||
|
|
||||||
|
if ( TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bpp) )
|
||||||
|
{
|
||||||
|
image->SetOption(wxIMAGE_OPTION_BITSPERSAMPLE, bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compression) )
|
||||||
|
{
|
||||||
|
image->SetOption(wxIMAGE_OPTION_COMPRESSION, compression);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the resolution unit.
|
||||||
|
wxImageResolution resUnit = wxIMAGE_RESOLUTION_NONE;
|
||||||
|
uint16 tiffRes;
|
||||||
|
if ( TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &tiffRes) )
|
||||||
|
{
|
||||||
|
switch (tiffRes)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
wxLogWarning(_("Unknown TIFF resolution unit %d ignored"),
|
wxLogWarning(_("Unknown TIFF resolution unit %d ignored"),
|
||||||
tiffRes);
|
tiffRes);
|
||||||
// fall through
|
// fall through
|
||||||
|
|
||||||
case RESUNIT_NONE:
|
case RESUNIT_NONE:
|
||||||
res = wxIMAGE_RESOLUTION_NONE;
|
resUnit = wxIMAGE_RESOLUTION_NONE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESUNIT_INCH:
|
case RESUNIT_INCH:
|
||||||
res = wxIMAGE_RESOLUTION_INCHES;
|
resUnit = wxIMAGE_RESOLUTION_INCHES;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESUNIT_CENTIMETER:
|
case RESUNIT_CENTIMETER:
|
||||||
res = wxIMAGE_RESOLUTION_CM;
|
resUnit = wxIMAGE_RESOLUTION_CM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( res != wxIMAGE_RESOLUTION_NONE )
|
|
||||||
{
|
|
||||||
float xres, yres;
|
|
||||||
if ( TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) )
|
|
||||||
image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, wxRound(xres));
|
|
||||||
|
|
||||||
if ( TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) )
|
|
||||||
image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, wxRound(yres));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image->SetOption(wxIMAGE_OPTION_RESOLUTIONUNIT, resUnit);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the image resolution if it's available. Resolution tag is not
|
||||||
|
dependant on RESOLUTIONUNIT != RESUNIT_NONE (according to TIFF spec).
|
||||||
|
*/
|
||||||
|
float resX, resY;
|
||||||
|
|
||||||
|
if ( TIFFGetField(tif, TIFFTAG_XRESOLUTION, &resX) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Use a string value to not lose precision.
|
||||||
|
rounding to int as cm and then converting to inch may
|
||||||
|
result in whole integer rounding error, eg. 201 instead of 200 dpi.
|
||||||
|
If an app wants an int, GetOptionInt will convert and round down.
|
||||||
|
*/
|
||||||
|
image->SetOption(wxIMAGE_OPTION_RESOLUTIONX,
|
||||||
|
wxString::FromCDouble((double) resX));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( TIFFGetField(tif, TIFFTAG_YRESOLUTION, &resY) )
|
||||||
|
{
|
||||||
|
image->SetOption(wxIMAGE_OPTION_RESOLUTIONY,
|
||||||
|
wxString::FromCDouble((double) resY));
|
||||||
|
}
|
||||||
|
|
||||||
_TIFFfree( raster );
|
_TIFFfree( raster );
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user