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
This commit is contained in:
Morgan Hardwood 2018-02-07 17:10:57 +01:00
parent 4579d4be14
commit 09c4572402

View File

@ -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;