From 09c457240219c4ebababd8862f8bd847bb58b8f2 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 7 Feb 2018 17:10:57 +0100 Subject: [PATCH] Fix corrupt 32-bit compressed TIFF Match endianness of pixel data with endianness of Exif metadata when saving compressed 32-bit float TIFF. Fixes #4377 --- rtengine/imageio.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 0e404fa91..306c95892 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1438,14 +1438,14 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) } } - if (iptcdata) { - rtexif::Tag iptcTag(nullptr, rtexif::lookupAttrib (rtexif::ifdAttribs, "IPTCData")); - iptcTag.initLongArray((char*)iptcdata, iptclen); #if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::MOTOROLA; #else bool needsReverse = exifRoot && exifRoot->getOrder() == rtexif::INTEL; #endif + if (iptcdata) { + rtexif::Tag iptcTag(nullptr, rtexif::lookupAttrib (rtexif::ifdAttribs, "IPTCData")); + iptcTag.initLongArray((char*)iptcdata, iptclen); if (needsReverse) { unsigned char *ptr = iptcTag.getValue(); for (int a = 0; a < iptcTag.getCount(); ++a) { @@ -1471,15 +1471,13 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) TIFFSetField (out, TIFFTAG_ROWSPERSTRIP, height); TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, bps); TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_DEFLATE); + TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_ADOBE_DEFLATE); TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, bps == 32 ? SAMPLEFORMAT_IEEEFP : SAMPLEFORMAT_UINT); if (!uncompressed) { TIFFSetField (out, TIFFTAG_PREDICTOR, bps == 32 ? PREDICTOR_FLOATINGPOINT : PREDICTOR_HORIZONTAL); } - if (profileData) { TIFFSetField (out, TIFFTAG_ICCPROFILE, profileLength, profileData); } @@ -1487,6 +1485,17 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) for (int row = 0; row < height; row++) { getScanline (row, linebuffer, bps); + if(needsReverse && !uncompressed && bps == 32) { + for(int i = 0; i < lineWidth; i += 4) { + char temp = linebuffer[i]; + linebuffer[i] = linebuffer[i + 3]; + linebuffer[i + 3] = temp; + temp = linebuffer[i + 1]; + linebuffer[i + 1] = linebuffer[i + 2]; + linebuffer[i + 2] = temp; + } + } + if (TIFFWriteScanline (out, linebuffer, row, 0) < 0) { TIFFClose (out); delete [] linebuffer;