From: Dimitri Schoolwerth Date: Sun, 20 Mar 2011 19:48:03 +0000 (+0000) Subject: Made some TIFF reading adjustments. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/4d37f425ff99077796428e69fee69ebf9c2fc6a5?ds=sidebyside 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 --- diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 4994a0ae24..5e69ff9f5b 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -402,42 +402,78 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos alpha -= 2*w; } - // set the image resolution if it's available + + uint16 spp, bpp, compression; + /* + 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) ) + { + image->SetOption(wxIMAGE_OPTION_SAMPLESPERPIXEL, spp); + } + + 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 ( TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &tiffRes) ) + if ( TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &tiffRes) ) { - wxImageResolution res; - switch ( tiffRes ) + switch (tiffRes) { default: wxLogWarning(_("Unknown TIFF resolution unit %d ignored"), - tiffRes); + tiffRes); // fall through case RESUNIT_NONE: - res = wxIMAGE_RESOLUTION_NONE; + resUnit = wxIMAGE_RESOLUTION_NONE; break; case RESUNIT_INCH: - res = wxIMAGE_RESOLUTION_INCHES; + resUnit = wxIMAGE_RESOLUTION_INCHES; break; case RESUNIT_CENTIMETER: - res = wxIMAGE_RESOLUTION_CM; + resUnit = wxIMAGE_RESOLUTION_CM; break; } + } - if ( res != wxIMAGE_RESOLUTION_NONE ) - { - float xres, yres; - if ( TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) ) - image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, wxRound(xres)); + image->SetOption(wxIMAGE_OPTION_RESOLUTIONUNIT, resUnit); - if ( TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) ) - image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, wxRound(yres)); - } + /* + 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 );