From 912f9f436b1163c2235426eca4d8830eebcd4966 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Mon, 20 Nov 2017 00:11:18 +0100 Subject: [PATCH] added support for 32-bit floating-point TIFF output --- rtengine/imageio.cc | 23 ++++++++++++++++------- rtexif/rtexif.cc | 2 ++ rtgui/saveformatpanel.cc | 12 +++++++++--- rtgui/saveformatpanel.h | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index ff9c9b559..e7a45ecf6 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1250,20 +1250,28 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) } #if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ - bool needsReverse = bps == 16 && exifRoot->getOrder() == rtexif::MOTOROLA; + bool needsReverse = (bps == 16 || bps == 32) && exifRoot->getOrder() == rtexif::MOTOROLA; #else - bool needsReverse = bps == 16 && exifRoot->getOrder() == rtexif::INTEL; + bool needsReverse = (bps == 16 || bps == 32) && exifRoot->getOrder() == rtexif::INTEL; #endif for (int i = 0; i < height; i++) { getScanline (i, linebuffer, bps); - if (needsReverse) - for (int i = 0; i < lineWidth; i += 2) { - char c = linebuffer[i]; - linebuffer[i] = linebuffer[i + 1]; - linebuffer[i + 1] = c; + if (needsReverse) { + if (bps == 16) { + for (int i = 0; i < lineWidth; i += 2) { + char c = linebuffer[i]; + linebuffer[i] = linebuffer[i + 1]; + linebuffer[i + 1] = c; + } + } else { + for (int i = 0; i < lineWidth; i += 4) { + std::swap(linebuffer[i], linebuffer[i+3]); + std::swap(linebuffer[i+1], linebuffer[i+2]); + } } + } fwrite (linebuffer, lineWidth, 1, file); @@ -1362,6 +1370,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_DEFLATE); + TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, bps == 32 ? SAMPLEFORMAT_IEEEFP : SAMPLEFORMAT_UINT); if (!uncompressed) { TIFFSetField (out, TIFFTAG_PREDICTOR, PREDICTOR_NONE); diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index bc0e2002f..1701b3058 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3240,6 +3240,8 @@ int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::pro Tag* stripOffs = new Tag (cl, lookupAttrib (ifdAttribs, "StripOffsets")); stripOffs->initInt (0, LONG, strips); cl->replaceTag (stripOffs); + Tag *sampleFormat = new Tag (cl, lookupAttrib (ifdAttribs, "SampleFormat"), bps == 32 ? 3 : 1, SHORT); + cl->replaceTag (sampleFormat); for (int i = 0; i < strips - 1; i++) { stripBC->setInt (rps * W * 3 * bps / 8, i * 4); diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc index 13e687595..fef05de23 100644 --- a/rtgui/saveformatpanel.cc +++ b/rtgui/saveformatpanel.cc @@ -40,14 +40,16 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr) format->append ("JPEG (8 bit)"); format->append ("TIFF (8 bit)"); format->append ("TIFF (16 bit)"); + format->append ("TIFF (32 bit float)"); format->append ("PNG (8 bit)"); format->append ("PNG (16 bit)"); fstr[0] = "jpg"; fstr[1] = "tif"; fstr[2] = "tif"; - fstr[3] = "png"; + fstr[3] = "tif"; fstr[4] = "png"; + fstr[5] = "png"; hb1->attach (*flab, 0, 0, 1, 1); hb1->attach (*format, 1, 0, 1, 1); @@ -121,8 +123,10 @@ void SaveFormatPanel::init (SaveFormat &sf) if (sf.format == "jpg") { format->set_active (0); } else if (sf.format == "png" && sf.pngBits == 16) { - format->set_active (4); + format->set_active (5); } else if (sf.format == "png" && sf.pngBits == 8) { + format->set_active (4); + } else if (sf.format == "tif" && sf.tiffBits == 32) { format->set_active (3); } else if (sf.format == "tif" && sf.tiffBits == 16) { format->set_active (2); @@ -146,7 +150,7 @@ SaveFormat SaveFormatPanel::getFormat () int sel = format->get_active_row_number(); sf.format = fstr[sel]; - if (sel == 4) { + if (sel == 5) { sf.pngBits = 16; } else { sf.pngBits = 8; @@ -154,6 +158,8 @@ SaveFormat SaveFormatPanel::getFormat () if (sel == 2) { sf.tiffBits = 16; + } else if (sel == 3) { + sf.tiffBits = 32; } else { sf.tiffBits = 8; } diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index 76ae7055d..8dc493051 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -44,7 +44,7 @@ protected: Gtk::Grid* jpegOpts; Gtk::Label* jpegSubSampLabel; FormatChangeListener* listener; - Glib::ustring fstr[5]; + Glib::ustring fstr[6]; Gtk::CheckButton* savesPP;