diff --git a/rtdata/languages/default b/rtdata/languages/default
index 84b28c955..bda477f14 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -2061,6 +2061,7 @@ SAMPLEFORMAT_16;16-bit floating-point
SAMPLEFORMAT_32;24-bit floating-point
SAMPLEFORMAT_64;32-bit floating-point
SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists
+SAVEDLG_BIGTIFF;BigTIFF
SAVEDLG_FILEFORMAT;File format
SAVEDLG_FILEFORMAT_FLOAT; floating-point
SAVEDLG_FORCEFORMATOPTS;Force saving options
diff --git a/rtengine/iimage.h b/rtengine/iimage.h
index a544b454a..cdb7dd6eb 100644
--- a/rtengine/iimage.h
+++ b/rtengine/iimage.h
@@ -1882,7 +1882,13 @@ public:
* @param bps can be 8 or 16 depending on the bits per pixels the output file will have
* @param isFloat is true for saving float images. Will be ignored by file format not supporting float data
@return the error code, 0 if none */
- virtual int saveAsTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const = 0;
+ virtual int saveAsTIFF (
+ const Glib::ustring &fname,
+ int bps = -1,
+ bool isFloat = false,
+ bool uncompressed = false,
+ bool big = false
+ ) const = 0;
/** @brief Sets the progress listener if you want to follow the progress of the image saving operations (optional).
* @param pl is the pointer to the class implementing the ProgressListener interface */
virtual void setSaveProgressListener (ProgressListener* pl) = 0;
diff --git a/rtengine/image16.h b/rtengine/image16.h
index 25b777832..273ae63a1 100644
--- a/rtengine/image16.h
+++ b/rtengine/image16.h
@@ -81,7 +81,7 @@ public:
return saveJPEG(fname, quality, subSamp);
}
- int saveAsTIFF(const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const override
+ int saveAsTIFF(const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false, bool big = false) const override
{
return saveTIFF(fname, bps, isFloat, uncompressed);
}
diff --git a/rtengine/image8.h b/rtengine/image8.h
index 76a580bb6..416dc9143 100644
--- a/rtengine/image8.h
+++ b/rtengine/image8.h
@@ -79,9 +79,15 @@ public:
return saveJPEG (fname, quality, subSamp);
}
- int saveAsTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const override
+ int saveAsTIFF (
+ const Glib::ustring &fname,
+ int bps = -1,
+ bool isFloat = false,
+ bool uncompressed = false,
+ bool big = false
+ ) const override
{
- return saveTIFF (fname, bps, isFloat, uncompressed);
+ return saveTIFF (fname, bps, isFloat, uncompressed, big);
}
void setSaveProgressListener (ProgressListener* pl) override
diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h
index fc3ba318d..d69df9325 100644
--- a/rtengine/imagefloat.h
+++ b/rtengine/imagefloat.h
@@ -82,9 +82,15 @@ public:
{
return saveJPEG (fname, quality, subSamp);
}
- int saveAsTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const override
+ int saveAsTIFF (
+ const Glib::ustring &fname,
+ int bps = -1,
+ bool isFloat = false,
+ bool uncompressed = false,
+ bool big = false
+ ) const override
{
- return saveTIFF (fname, bps, isFloat, uncompressed);
+ return saveTIFF (fname, bps, isFloat, uncompressed, big);
}
void setSaveProgressListener (ProgressListener* pl) override
{
diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc
index ce44d1ff4..573a391aa 100644
--- a/rtengine/imageio.cc
+++ b/rtengine/imageio.cc
@@ -17,21 +17,17 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see .
*/
-#include
-#include
-#include
-#include
#include
#include
-#include
-#include
#include
-#include "rt_math.h"
-#include "procparams.h"
-#include "utils.h"
-#include "../rtgui/options.h"
-#include "../rtgui/version.h"
-#include "../rtexif/rtexif.h"
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
#ifdef WIN32
#include
@@ -39,12 +35,20 @@
#include
#endif
+#include "color.h"
+#include "iccjpeg.h"
#include "imageio.h"
#include "iptcpairs.h"
-#include "iccjpeg.h"
-#include "color.h"
-
#include "jpeg.h"
+#include "procparams.h"
+#include "rt_math.h"
+#include "utils.h"
+
+#include "../rtgui/options.h"
+#include "../rtgui/version.h"
+
+#include "../rtexif/rtexif.h"
+
using namespace std;
using namespace rtengine;
@@ -1328,7 +1332,13 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con
return IMIO_SUCCESS;
}
-int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool uncompressed) const
+int ImageIO::saveTIFF (
+ const Glib::ustring &fname,
+ int bps,
+ bool isFloat,
+ bool uncompressed,
+ bool big
+) const
{
if (getWidth() < 1 || getHeight() < 1) {
return IMIO_HEADERERROR;
@@ -1345,15 +1355,28 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u
int lineWidth = width * 3 * bps / 8;
unsigned char* linebuffer = new unsigned char[lineWidth];
+ std::string mode = "w";
+
// little hack to get libTiff to use proper byte order (see TIFFClienOpen()):
- const char *mode = !exifRoot ? "w" : (exifRoot->getOrder() == rtexif::INTEL ? "wl" : "wb");
+ if (exifRoot) {
+ if (exifRoot->getOrder() == rtexif::INTEL) {
+ mode += 'l';
+ } else {
+ mode += 'b';
+ }
+ }
+
+ if (big) {
+ mode += '8';
+ }
+
#ifdef WIN32
FILE *file = g_fopen_withBinaryAndLock (fname);
int fileno = _fileno(file);
int osfileno = _get_osfhandle(fileno);
- TIFF* out = TIFFFdOpen (osfileno, fname.c_str(), mode);
+ TIFF* out = TIFFFdOpen (osfileno, fname.c_str(), mode.c_str());
#else
- TIFF* out = TIFFOpen(fname.c_str(), mode);
+ TIFF* out = TIFFOpen(fname.c_str(), mode.c_str());
int fileno = TIFFFileno (out);
#endif
diff --git a/rtengine/imageio.h b/rtengine/imageio.h
index 566fef13b..e900feccd 100644
--- a/rtengine/imageio.h
+++ b/rtengine/imageio.h
@@ -113,7 +113,13 @@ public:
int savePNG (const Glib::ustring &fname, int bps = -1) const;
int saveJPEG (const Glib::ustring &fname, int quality = 100, int subSamp = 3) const;
- int saveTIFF (const Glib::ustring &fname, int bps = -1, bool isFloat = false, bool uncompressed = false) const;
+ int saveTIFF (
+ const Glib::ustring &fname,
+ int bps = -1,
+ bool isFloat = false,
+ bool uncompressed = false,
+ bool big = false
+ ) const;
cmsHPROFILE getEmbeddedProfile () const;
void getEmbeddedProfileData (int& length, unsigned char*& pdata) const;
diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc
index 19da96fb5..4e25475f0 100644
--- a/rtgui/batchqueue.cc
+++ b/rtgui/batchqueue.cc
@@ -264,6 +264,7 @@ bool BatchQueue::saveBatchQueue ()
<< saveFormat.tiffBits << '|' << (saveFormat.tiffFloat ? 1 : 0) << '|' << saveFormat.tiffUncompressed << '|'
<< saveFormat.saveParams << '|' << entry->forceFormatOpts << '|'
<< entry->fast_pipeline << '|'
+ << saveFormat.bigTiff << '|'
<< std::endl;
}
}
@@ -331,6 +332,7 @@ bool BatchQueue::loadBatchQueue ()
const auto saveParams = nextIntOr (options.saveFormat.saveParams);
const auto forceFormatOpts = nextIntOr (options.forceFormatOpts);
const auto fast = nextIntOr(false);
+ const auto bigTiff = nextIntOr (options.saveFormat.bigTiff);
rtengine::procparams::ProcParams pparams;
@@ -370,6 +372,7 @@ bool BatchQueue::loadBatchQueue ()
saveFormat.tiffBits = tiffBits;
saveFormat.tiffFloat = tiffFloat == 1;
saveFormat.tiffUncompressed = tiffUncompressed != 0;
+ saveFormat.bigTiff = bigTiff != 0;
saveFormat.saveParams = saveParams != 0;
entry->forceFormatOpts = forceFormatOpts != 0;
} else {
@@ -693,7 +696,13 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img)
int err = 0;
if (saveFormat.format == "tif") {
- err = img->saveAsTIFF (fname, saveFormat.tiffBits, saveFormat.tiffFloat, saveFormat.tiffUncompressed);
+ err = img->saveAsTIFF (
+ fname,
+ saveFormat.tiffBits,
+ saveFormat.tiffFloat,
+ saveFormat.tiffUncompressed,
+ saveFormat.bigTiff
+ );
} else if (saveFormat.format == "png") {
err = img->saveAsPNG (fname, saveFormat.pngBits);
} else if (saveFormat.format == "jpg") {
diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc
index 9fe4dd605..7499fb63b 100644
--- a/rtgui/batchqueueentry.cc
+++ b/rtgui/batchqueueentry.cc
@@ -201,6 +201,9 @@ std::tuple BatchQueueEntry::getToolTip (int x, int y) const
if (saveFormat.tiffUncompressed) {
tooltip += Glib::ustring::compose("\n%1", M("SAVEDLG_TIFFUNCOMPRESSED"));
}
+ if (saveFormat.bigTiff) {
+ tooltip += Glib::ustring::compose("\n%1", M("SAVEDLG_BIGTIFF"));
+ }
}
}
}
diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc
index 95808d4b0..ffe13fea3 100644
--- a/rtgui/editorpanel.cc
+++ b/rtgui/editorpanel.cc
@@ -2013,7 +2013,7 @@ bool EditorPanel::idle_saveImage (ProgressConnector *pc,
img->setSaveProgressListener (parent->getProgressListener());
if (sf.format == "tif")
- ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fname, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed),
+ ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fname, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed, sf.bigTiff),
sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_imageSaved), ld, img, fname, sf, pparams));
else if (sf.format == "png")
ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsPNG), fname, sf.pngBits),
@@ -2270,7 +2270,7 @@ bool EditorPanel::saveImmediately (const Glib::ustring &filename, const SaveForm
if (gimpPlugin) {
err = img->saveAsTIFF (filename, 32, true, true);
} else if (sf.format == "tif") {
- err = img->saveAsTIFF (filename, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed);
+ err = img->saveAsTIFF (filename, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed, sf.bigTiff);
} else if (sf.format == "png") {
err = img->saveAsPNG (filename, sf.pngBits);
} else if (sf.format == "jpg") {
@@ -2380,7 +2380,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p
ProgressConnector *ld = new ProgressConnector();
img->setSaveProgressListener (parent->getProgressListener());
- ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fileName, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed),
+ ld->startFunc (sigc::bind (sigc::mem_fun (img, &rtengine::IImagefloat::saveAsTIFF), fileName, sf.tiffBits, sf.tiffFloat, sf.tiffUncompressed, sf.bigTiff),
sigc::bind (sigc::mem_fun (*this, &EditorPanel::idle_sentToGimp), ld, img, fileName));
} else {
Glib::ustring msg_ = Glib::ustring (" Error during image processing\n");
diff --git a/rtgui/options.cc b/rtgui/options.cc
index 66b9e92a1..e230dcf8a 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -313,6 +313,7 @@ void Options::setDefaults()
saveFormat.tiffBits = 16;
saveFormat.tiffFloat = false;
saveFormat.tiffUncompressed = true;
+ saveFormat.bigTiff = false;
saveFormat.saveParams = true;
saveFormatBatch.format = "jpg";
@@ -1046,6 +1047,10 @@ void Options::readFromFile(Glib::ustring fname)
saveFormat.tiffUncompressed = keyFile.get_boolean("Output", "TiffUncompressed");
}
+ if (keyFile.has_key("Output", "BigTiff")) {
+ saveFormat.bigTiff = keyFile.get_boolean("Output", "BigTiff");
+ }
+
if (keyFile.has_key("Output", "SaveProcParams")) {
saveFormat.saveParams = keyFile.get_boolean("Output", "SaveProcParams");
}
@@ -2447,6 +2452,7 @@ void Options::saveToFile(Glib::ustring fname)
keyFile.set_integer("Output", "TiffBps", saveFormat.tiffBits);
keyFile.set_boolean("Output", "TiffFloat", saveFormat.tiffFloat);
keyFile.set_boolean("Output", "TiffUncompressed", saveFormat.tiffUncompressed);
+ keyFile.set_boolean("Output", "BigTiff", saveFormat.bigTiff);
keyFile.set_boolean("Output", "SaveProcParams", saveFormat.saveParams);
keyFile.set_string("Output", "FormatBatch", saveFormatBatch.format);
diff --git a/rtgui/options.h b/rtgui/options.h
index 286c64df0..5fb4e4f8b 100644
--- a/rtgui/options.h
+++ b/rtgui/options.h
@@ -72,6 +72,7 @@ struct SaveFormat {
int _tiff_bits,
bool _tiff_float,
bool _tiff_uncompressed,
+ bool _big_tiff,
bool _save_params
) :
format(_format),
@@ -81,6 +82,7 @@ struct SaveFormat {
tiffBits(_tiff_bits),
tiffFloat(_tiff_float),
tiffUncompressed(_tiff_uncompressed),
+ bigTiff(_big_tiff),
saveParams(_save_params)
{
}
@@ -98,6 +100,7 @@ struct SaveFormat {
_tiff_bits,
_tiff_float,
true,
+ false,
true
)
{
@@ -114,6 +117,7 @@ struct SaveFormat {
int tiffBits;
bool tiffFloat;
bool tiffUncompressed;
+ bool bigTiff;
bool saveParams;
};
diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc
index 00f6e7b2b..773ee9105 100644
--- a/rtgui/saveformatpanel.cc
+++ b/rtgui/saveformatpanel.cc
@@ -100,6 +100,11 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr)
tiffUncompressed->signal_toggled().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged));
tiffUncompressed->show_all();
+ bigTiff = new Gtk::CheckButton (M("SAVEDLG_BIGTIFF"));
+ setExpandAlignProperties(bigTiff, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
+ bigTiff->signal_toggled().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged));
+ bigTiff->show_all();
+
// --------------------- MAIN BOX
@@ -114,12 +119,14 @@ SaveFormatPanel::SaveFormatPanel () : listener (nullptr)
attach (*hb1, 0, 0, 1, 1);
attach (*jpegOpts, 0, 1, 1, 1);
attach (*tiffUncompressed, 0, 2, 1, 1);
+ attach (*bigTiff, 0, 3, 1, 1);
attach (*savesPP, 0, 4, 1, 2);
}
SaveFormatPanel::~SaveFormatPanel ()
{
delete jpegQual;
delete tiffUncompressed;
+ delete bigTiff;
}
void SaveFormatPanel::init (SaveFormat &sf)
@@ -158,6 +165,7 @@ void SaveFormatPanel::init (SaveFormat &sf)
jpegQual->setValue(sf.jpegQuality);
savesPP->set_active(sf.saveParams);
tiffUncompressed->set_active(sf.tiffUncompressed);
+ bigTiff->set_active(sf.bigTiff);
listener = tmp;
}
@@ -175,6 +183,7 @@ SaveFormat SaveFormatPanel::getFormat ()
sf.jpegQuality = jpegQual->getValue();
sf.jpegSubSamp = jpegSubSamp->get_active_row_number() + 1;
sf.tiffUncompressed = tiffUncompressed->get_active();
+ sf.bigTiff = bigTiff->get_active();
sf.saveParams = savesPP->get_active();
return sf;
@@ -193,12 +202,15 @@ void SaveFormatPanel::formatChanged ()
if (fr == "jpg") {
jpegOpts->show_all();
tiffUncompressed->hide();
+ bigTiff->hide();
} else if (fr == "png") {
jpegOpts->hide();
tiffUncompressed->hide();
+ bigTiff->hide();
} else if (fr == "tif") {
jpegOpts->hide();
tiffUncompressed->show_all();
+ bigTiff->show_all();
}
if (listener) {
diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h
index af9baa58a..9d9f6266e 100644
--- a/rtgui/saveformatpanel.h
+++ b/rtgui/saveformatpanel.h
@@ -39,6 +39,7 @@ class SaveFormatPanel : public Gtk::Grid, public AdjusterListener, public rtengi
protected:
Adjuster* jpegQual;
Gtk::CheckButton* tiffUncompressed;
+ Gtk::CheckButton* bigTiff;
MyComboBoxText* format;
MyComboBoxText* jpegSubSamp;
Gtk::Grid* formatOpts;