added support for 32-bit floating-point TIFF output
This commit is contained in:
@@ -1250,20 +1250,28 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
|
#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
|
#else
|
||||||
bool needsReverse = bps == 16 && exifRoot->getOrder() == rtexif::INTEL;
|
bool needsReverse = (bps == 16 || bps == 32) && exifRoot->getOrder() == rtexif::INTEL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
getScanline (i, linebuffer, bps);
|
getScanline (i, linebuffer, bps);
|
||||||
|
|
||||||
if (needsReverse)
|
if (needsReverse) {
|
||||||
for (int i = 0; i < lineWidth; i += 2) {
|
if (bps == 16) {
|
||||||
char c = linebuffer[i];
|
for (int i = 0; i < lineWidth; i += 2) {
|
||||||
linebuffer[i] = linebuffer[i + 1];
|
char c = linebuffer[i];
|
||||||
linebuffer[i + 1] = c;
|
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);
|
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_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||||
TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||||
TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_DEFLATE);
|
TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_DEFLATE);
|
||||||
|
TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, bps == 32 ? SAMPLEFORMAT_IEEEFP : SAMPLEFORMAT_UINT);
|
||||||
|
|
||||||
if (!uncompressed) {
|
if (!uncompressed) {
|
||||||
TIFFSetField (out, TIFFTAG_PREDICTOR, PREDICTOR_NONE);
|
TIFFSetField (out, TIFFTAG_PREDICTOR, PREDICTOR_NONE);
|
||||||
|
@@ -3240,6 +3240,8 @@ int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::pro
|
|||||||
Tag* stripOffs = new Tag (cl, lookupAttrib (ifdAttribs, "StripOffsets"));
|
Tag* stripOffs = new Tag (cl, lookupAttrib (ifdAttribs, "StripOffsets"));
|
||||||
stripOffs->initInt (0, LONG, strips);
|
stripOffs->initInt (0, LONG, strips);
|
||||||
cl->replaceTag (stripOffs);
|
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++) {
|
for (int i = 0; i < strips - 1; i++) {
|
||||||
stripBC->setInt (rps * W * 3 * bps / 8, i * 4);
|
stripBC->setInt (rps * W * 3 * bps / 8, i * 4);
|
||||||
|
@@ -40,14 +40,16 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr)
|
|||||||
format->append ("JPEG (8 bit)");
|
format->append ("JPEG (8 bit)");
|
||||||
format->append ("TIFF (8 bit)");
|
format->append ("TIFF (8 bit)");
|
||||||
format->append ("TIFF (16 bit)");
|
format->append ("TIFF (16 bit)");
|
||||||
|
format->append ("TIFF (32 bit float)");
|
||||||
format->append ("PNG (8 bit)");
|
format->append ("PNG (8 bit)");
|
||||||
format->append ("PNG (16 bit)");
|
format->append ("PNG (16 bit)");
|
||||||
|
|
||||||
fstr[0] = "jpg";
|
fstr[0] = "jpg";
|
||||||
fstr[1] = "tif";
|
fstr[1] = "tif";
|
||||||
fstr[2] = "tif";
|
fstr[2] = "tif";
|
||||||
fstr[3] = "png";
|
fstr[3] = "tif";
|
||||||
fstr[4] = "png";
|
fstr[4] = "png";
|
||||||
|
fstr[5] = "png";
|
||||||
|
|
||||||
hb1->attach (*flab, 0, 0, 1, 1);
|
hb1->attach (*flab, 0, 0, 1, 1);
|
||||||
hb1->attach (*format, 1, 0, 1, 1);
|
hb1->attach (*format, 1, 0, 1, 1);
|
||||||
@@ -121,8 +123,10 @@ void SaveFormatPanel::init (SaveFormat &sf)
|
|||||||
if (sf.format == "jpg") {
|
if (sf.format == "jpg") {
|
||||||
format->set_active (0);
|
format->set_active (0);
|
||||||
} else if (sf.format == "png" && sf.pngBits == 16) {
|
} else if (sf.format == "png" && sf.pngBits == 16) {
|
||||||
format->set_active (4);
|
format->set_active (5);
|
||||||
} else if (sf.format == "png" && sf.pngBits == 8) {
|
} else if (sf.format == "png" && sf.pngBits == 8) {
|
||||||
|
format->set_active (4);
|
||||||
|
} else if (sf.format == "tif" && sf.tiffBits == 32) {
|
||||||
format->set_active (3);
|
format->set_active (3);
|
||||||
} else if (sf.format == "tif" && sf.tiffBits == 16) {
|
} else if (sf.format == "tif" && sf.tiffBits == 16) {
|
||||||
format->set_active (2);
|
format->set_active (2);
|
||||||
@@ -146,7 +150,7 @@ SaveFormat SaveFormatPanel::getFormat ()
|
|||||||
int sel = format->get_active_row_number();
|
int sel = format->get_active_row_number();
|
||||||
sf.format = fstr[sel];
|
sf.format = fstr[sel];
|
||||||
|
|
||||||
if (sel == 4) {
|
if (sel == 5) {
|
||||||
sf.pngBits = 16;
|
sf.pngBits = 16;
|
||||||
} else {
|
} else {
|
||||||
sf.pngBits = 8;
|
sf.pngBits = 8;
|
||||||
@@ -154,6 +158,8 @@ SaveFormat SaveFormatPanel::getFormat ()
|
|||||||
|
|
||||||
if (sel == 2) {
|
if (sel == 2) {
|
||||||
sf.tiffBits = 16;
|
sf.tiffBits = 16;
|
||||||
|
} else if (sel == 3) {
|
||||||
|
sf.tiffBits = 32;
|
||||||
} else {
|
} else {
|
||||||
sf.tiffBits = 8;
|
sf.tiffBits = 8;
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ protected:
|
|||||||
Gtk::Grid* jpegOpts;
|
Gtk::Grid* jpegOpts;
|
||||||
Gtk::Label* jpegSubSampLabel;
|
Gtk::Label* jpegSubSampLabel;
|
||||||
FormatChangeListener* listener;
|
FormatChangeListener* listener;
|
||||||
Glib::ustring fstr[5];
|
Glib::ustring fstr[6];
|
||||||
Gtk::CheckButton* savesPP;
|
Gtk::CheckButton* savesPP;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user