Merge branch 'master' into 'gtk3'

This commit is contained in:
Adam Reichold 2016-03-05 09:21:34 +01:00
commit a04c7706db
119 changed files with 3006 additions and 3007 deletions

View File

@ -245,7 +245,6 @@ pkg_check_modules (LCMS REQUIRED lcms2>=2.6)
pkg_check_modules (EXPAT REQUIRED expat>=2.1) pkg_check_modules (EXPAT REQUIRED expat>=2.1)
pkg_check_modules (FFTW3F REQUIRED fftw3f) pkg_check_modules (FFTW3F REQUIRED fftw3f)
pkg_check_modules (IPTCDATA REQUIRED libiptcdata) pkg_check_modules (IPTCDATA REQUIRED libiptcdata)
pkg_check_modules(FFTW3 fftw3)
find_package (JPEG REQUIRED) find_package (JPEG REQUIRED)
find_package (PNG REQUIRED) find_package (PNG REQUIRED)
find_package (TIFF REQUIRED) find_package (TIFF REQUIRED)

View File

@ -1,23 +1,21 @@
![RawTherapee logo](http://rawtherapee.com/images/logos/rawtherapee_logo_discuss.png) ![RawTherapee logo](http://rawtherapee.com/images/logos/rawtherapee_logo_discuss.png)
RawTherapee is a powerful, cross-platform raw photo processing program, released under the GNU General Public License Version 3. It is written in C++ using a GTK+ front-end and a patched version of dcraw for reading raw files. It is notable for the advanced control it gives the user over the demosaicing and developing process. RawTherapee is a powerful, cross-platform raw photo processing program, released under the [GNU General Public License Version 3](https://opensource.org/licenses/gpl-3.0.html) and written in C++ using a [GTK+](http://www.gtk.org/) front-end. It uses a patched version of [dcraw](http://www.cybercom.net/~dcoffin/dcraw/) for reading raw files, with an in-house solution which adds the highest quality support for certain camera models unsupported by dcraw and enhances the accuracy of certain raw files already supported by dcraw. It is notable for the advanced control it gives the user over the demosaicing and development process.
## Target audience and feature set ## Target audience
Rawtherapee is a free software (as in free beer) aimed at developing raw files from a broad range of camera (all files than can be decoded by *dcraw* from Dave Coffin), but can also edit standard image files (jpeg, png, tiff) and some HDR files. The targeted user base ranges from the enthusiast photographer with some basic technical knowledge in color science (it's not mandatory, but it's better if you e.g. know what a color profile is) to semi-professional users. Rawtherapee is a [libre software](https://en.wikipedia.org/wiki/Free_software) designed for developing raw files from a broad range of digital cameras, as well as [HDR DNG](https://helpx.adobe.com/photoshop/digital-negative.html) files and non-raw image formats ([JPEG](https://en.wikipedia.org/wiki/JPEG), [TIFF](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) and [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics)). The target audience ranges from enthusiast newcomers who whish to broaden their understanding of how digital imaging works to semi-professional photographers. Knowledge in color science is not compulsory, but it is recommended that you are eager to learn and ready to read our documentation ([RawPedia](http://rawpedia.rawtherapee.com/)) as well as look up basic concepts which lie outside the scope of RawPedia, such as [color balance](https://en.wikipedia.org/wiki/Color_balance), elsewhere.
Of course, professionals can use RawTherapee (for free) too, but will probably lack some peripheral features like Digital Assets Management, printing, uploading, etc. RawTherapee is not and probably will not be an all-in-one software in the foreseeable future. But the Open Source community is sufficiently developed now to offer you all that missing peripheral features. Of course, professionals may use RawTherapee too while enjoying complete freedom, but will probably lack some peripheral features such as [Digital Asset Management](https://en.wikipedia.org/wiki/Digital_asset_management), printing, uploading, etc. RawTherapee is not aimed at being an inclusive all-in-one program, and the [open-source community](https://en.wikipedia.org/wiki/Open-source_movement) is sufficiently developed by now to offer all those peripheral features in other specialized software.
The general feature set includes :
* basic file handling (move, delete, review, ranking, tagging) through thumnails
* image editing through 32 bits floating points filters (called *Tools*) that affect the whole image uniformly (by opposition to local editing, which is planned but still on the TODO list)
* export to standard 8 bits image file, with possibility to automatically load the resulting image in you favorite image editor for local adjustment
## Links ## Links
Website: Website:
http://rawtherapee.com/ http://rawtherapee.com/
Features:
http://rawpedia.rawtherapee.com/Features
Official documentation: Official documentation:
http://rawpedia.rawtherapee.com/ http://rawpedia.rawtherapee.com/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -672,6 +672,7 @@ HISTORY_MSG_436;Retinex - M - Radius
HISTORY_MSG_437;Retinex - M - Method HISTORY_MSG_437;Retinex - M - Method
HISTORY_MSG_438;Retinex - M - Equalizer HISTORY_MSG_438;Retinex - M - Equalizer
HISTORY_MSG_439;Retinex - Preview HISTORY_MSG_439;Retinex - Preview
HISTORY_MSG_440;CbDL - method
HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b> HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOT;Snapshot HISTORY_SNAPSHOT;Snapshot
@ -1208,6 +1209,10 @@ TP_BWMIX_VAL;L
TP_CACORRECTION_BLUE;Blue TP_CACORRECTION_BLUE;Blue
TP_CACORRECTION_LABEL;Chromatic Aberration Correction TP_CACORRECTION_LABEL;Chromatic Aberration Correction
TP_CACORRECTION_RED;Red TP_CACORRECTION_RED;Red
TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space.
TP_CBDL_AFT;After Black-and-White
TP_CBDL_BEF;Before Black-and-White
TP_CBDL_METHOD;Process located
TP_CHMIXER_BLUE;Blue channel TP_CHMIXER_BLUE;Blue channel
TP_CHMIXER_GREEN;Green channel TP_CHMIXER_GREEN;Green channel
TP_CHMIXER_LABEL;Channel Mixer TP_CHMIXER_LABEL;Channel Mixer
@ -1613,6 +1618,7 @@ TP_PREPROCESS_NO_FOUND;None found
TP_PRSHARPENING_LABEL;Post-Resize Sharpening TP_PRSHARPENING_LABEL;Post-Resize Sharpening
TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions.
TP_RAWCACORR_AUTO;Auto-correction TP_RAWCACORR_AUTO;Auto-correction
TP_RAWCACORR_CASTR;Strength
TP_RAWCACORR_CABLUE;Blue TP_RAWCACORR_CABLUE;Blue
TP_RAWCACORR_CARED;Red TP_RAWCACORR_CARED;Red
TP_RAWEXPOS_BLACKS;Black Levels TP_RAWEXPOS_BLACKS;Black Levels

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ link_directories ("${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GTHREAD_LIBRA
set (CAMCONSTSFILE "camconst.json") set (CAMCONSTSFILE "camconst.json")
set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagonalcurves.cc dcraw.cc iccstore.cc color.cc set (RTENGINESOURCEFILES colortemp.cc curves.cc flatcurves.cc diagonalcurves.cc dcraw.cc iccstore.cc color.cc
dfmanager.cc ffmanager.cc gauss.cc rawimage.cc image8.cc image16.cc imagefloat.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc dfmanager.cc ffmanager.cc gauss.cc rawimage.cc image8.cc image16.cc imagefloat.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc
loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc
fast_demo.cc amaze_demosaic_RT.cc CA_correct_RT.cc cfa_linedn_RT.cc green_equil_RT.cc hilite_recon.cc expo_before_b.cc fast_demo.cc amaze_demosaic_RT.cc CA_correct_RT.cc cfa_linedn_RT.cc green_equil_RT.cc hilite_recon.cc expo_before_b.cc

View File

@ -52,6 +52,8 @@
* LUTf stands for LUT<float> * LUTf stands for LUT<float>
* LUTi stands for LUT<int> * LUTi stands for LUT<int>
* LUTu stands for LUT<unsigned int> * LUTu stands for LUT<unsigned int>
* LUTd stands for LUT<double>
* LUTuc stands for LUT<unsigned char>
*/ */
#ifndef LUT_H_ #ifndef LUT_H_
@ -65,6 +67,7 @@
#define LUTi LUT<int> #define LUTi LUT<int>
#define LUTu LUT<unsigned int> #define LUTu LUT<unsigned int>
#define LUTd LUT<double> #define LUTd LUT<double>
#define LUTuc LUT<unsigned char>
#include <cstring> #include <cstring>
#ifndef NDEBUG #ifndef NDEBUG

View File

@ -3,7 +3,6 @@
*/ */
#include "camconst.h" #include "camconst.h"
#include "settings.h" #include "settings.h"
#include "safegtk.h"
#include "rt_math.h" #include "rt_math.h"
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
@ -689,7 +688,7 @@ void CameraConstantsStore::init(Glib::ustring baseDir, Glib::ustring userSetting
Glib::ustring userFile(Glib::build_filename(userSettingsDir, "camconst.json")); Glib::ustring userFile(Glib::build_filename(userSettingsDir, "camconst.json"));
if (safe_file_test(userFile, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test(userFile, Glib::FILE_TEST_EXISTS)) {
parse_camera_constants_file(userFile); parse_camera_constants_file(userFile);
} }
} }

View File

@ -328,7 +328,7 @@ double Ciecam02::calculate_fl_from_la_ciecam02( double la )
k = k * k; k = k * k;
k = k * k; k = k * k;
return (0.2 * k * la5) + (0.1 * (1.0 - k) * (1.0 - k) * pow(la5, 1.0 / 3.0)); return (0.2 * k * la5) + (0.1 * (1.0 - k) * (1.0 - k) * std::cbrt(la5));
} }
float Ciecam02::calculate_fl_from_la_ciecam02float( float la ) float Ciecam02::calculate_fl_from_la_ciecam02float( float la )
@ -340,7 +340,7 @@ float Ciecam02::calculate_fl_from_la_ciecam02float( float la )
k = k * k; k = k * k;
k = k * k; k = k * k;
return (0.2f * k * la5) + (0.1f * (1.0f - k) * (1.0f - k) * pow_F(la5, 1.0f / 3.0f)); return (0.2f * k * la5) + (0.1f * (1.0f - k) * (1.0f - k) * std::cbrt(la5));
} }
double Ciecam02::achromatic_response_to_white( double x, double y, double z, double d, double fl, double nbb, int gamu ) double Ciecam02::achromatic_response_to_white( double x, double y, double z, double d, double fl, double nbb, int gamu )

View File

@ -1,7 +1,6 @@
#include "clutstore.h" #include "clutstore.h"
#include "rt_math.h" #include "rt_math.h"
#include "stdimagesource.h" #include "stdimagesource.h"
#include "safegtk.h"
#include "../rtgui/options.h" #include "../rtgui/options.h"
rtengine::CLUTStore clutStore; rtengine::CLUTStore clutStore;
@ -154,7 +153,7 @@ Imagefloat* HaldCLUT::loadFile( Glib::ustring filename, Glib::ustring workingCol
Imagefloat *result = 0; Imagefloat *result = 0;
StdImageSource imgSrc; StdImageSource imgSrc;
if ( !safe_file_test( filename, Glib::FILE_TEST_EXISTS ) || imgSrc.load(filename) ) { if ( !Glib::file_test( filename, Glib::FILE_TEST_EXISTS ) || imgSrc.load(filename) ) {
return result; return result;
} }

View File

@ -36,6 +36,7 @@ LUTf Color::cachef;
LUTf Color::gamma2curve; LUTf Color::gamma2curve;
LUTf Color::gammatab; LUTf Color::gammatab;
LUTuc Color::gammatabThumb;
LUTf Color::igammatab_srgb; LUTf Color::igammatab_srgb;
LUTf Color::gammatab_srgb; LUTf Color::gammatab_srgb;
// LUTf Color::igammatab_709; // LUTf Color::igammatab_709;
@ -133,129 +134,204 @@ void MunsellDebugInfo::reinitValues()
void Color::init () void Color::init ()
{ {
int maxindex = 65536;
cachef(maxindex, LUT_CLIP_BELOW);
gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
for (int i = 0; i < maxindex; i++) {
if (i > eps_max) {
cachef[i] = 327.68 * ( exp(1.0 / 3.0 * log((double)i / MAXVALF) ));
} else {
cachef[i] = 327.68 * ((kappa * i / MAXVALF + 16.0) / 116.0);
}
}
for (int i = 0; i < maxindex; i++) {
gamma2curve[i] = (gamma2(i / 65535.0) * 65535.0);
}
/*******************************************/ /*******************************************/
gammatab(65536, 0); constexpr auto maxindex = 65536;
igammatab_srgb(65536, 0);
gammatab_srgb(65536, 0);
// igammatab_709(65536,0);
// gammatab_709(65536,0);
igammatab_55(65536, 0);
gammatab_55(65536, 0);
igammatab_4(65536, 0);
gammatab_4(65536, 0);
igammatab_26_11(65536, 0); cachef(maxindex, LUT_CLIP_BELOW);
gammatab_26_11(65536, 0); gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
igammatab_24_17(65536, 0); gammatab(maxindex, 0);
gammatab_24_17a(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); gammatabThumb(maxindex, 0);
gammatab_13_2(65536, 0);
igammatab_13_2(65536, 0);
gammatab_115_2(65536, 0);
igammatab_115_2(65536, 0);
gammatab_145_3(65536, 0);
igammatab_145_3(65536, 0);
for (int i = 0; i < 65536; i++) { igammatab_srgb(maxindex, 0);
gammatab_srgb[i] = (65535.0 * gamma2 (i / 65535.0)); gammatab_srgb(maxindex, 0);
igammatab_55(maxindex, 0);
gammatab_55(maxindex, 0);
igammatab_4(maxindex, 0);
gammatab_4(maxindex, 0);
igammatab_26_11(maxindex, 0);
gammatab_26_11(maxindex, 0);
igammatab_24_17(maxindex, 0);
gammatab_24_17a(maxindex, LUT_CLIP_ABOVE | LUT_CLIP_BELOW);
gammatab_13_2(maxindex, 0);
igammatab_13_2(maxindex, 0);
gammatab_115_2(maxindex, 0);
igammatab_115_2(maxindex, 0);
gammatab_145_3(maxindex, 0);
igammatab_145_3(maxindex, 0);
#ifdef _OPENMP
#pragma omp parallel sections
#endif
{
#ifdef _OPENMP
#pragma omp section
#endif
{
int i = 0;
int epsmaxint = eps_max;
for (; i <= epsmaxint; i++)
{
cachef[i] = 327.68 * ((kappa * i / MAXVALF + 16.0) / 116.0);
} }
for (int i = 0; i < 65536; i++) { for(; i < maxindex; i++)
igammatab_srgb[i] = (65535.0 * igamma2 (i / 65535.0)); {
cachef[i] = 327.68 * std::cbrt((double)i / MAXVALF);
}
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_srgb[i] = gamma2curve[i] = 65535.0 * gamma2(i / 65535.0); // two lookup tables with same content but one clips and one does not clip
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
gammatab[i] = (65535.0 * pow (i / 65535.0, 0.454545)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_srgb[i] = 65535.0 * igamma2 (i / 65535.0);
} }
/* for (int i=0; i<65536; i++) #ifdef _OPENMP
gammatab_709[i] = (65535.0 * gamma709 (i/65535.0)); #pragma omp section
for (int i=0; i<65536; i++) #endif
igammatab_709[i] = (65535.0 * igamma709 (i/65535.0)); {
*/ double rsRGBGamma = 1.0 / sRGBGamma;
for (int i = 0; i < 65536; i++) {
gammatab_55[i] = (65535.0 * gamma55 (i / 65535.0)); for (int i = 0; i < maxindex; i++) {
double val = pow (i / 65535.0, rsRGBGamma);
gammatab[i] = 65535.0 * val;
gammatabThumb[i] = (unsigned char)(255.0 * val);
}
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_55[i] = 65535.0 * gamma55 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
igammatab_55[i] = (65535.0 * igamma55 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_55[i] = 65535.0 * igamma55 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
gammatab_4[i] = (65535.0 * gamma4 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_4[i] = 65535.0 * gamma4 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
igammatab_4[i] = (65535.0 * igamma4 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_4[i] = 65535.0 * igamma4 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
gammatab_13_2[i] = (65535.0 * gamma13_2 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_13_2[i] = 65535.0 * gamma13_2 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
igammatab_13_2[i] = (65535.0 * igamma13_2 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_13_2[i] = 65535.0 * igamma13_2 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
gammatab_115_2[i] = (65535.0 * gamma115_2 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_115_2[i] = 65535.0 * gamma115_2 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
igammatab_115_2[i] = (65535.0 * igamma115_2 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_115_2[i] = 65535.0 * igamma115_2 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
gammatab_145_3[i] = (65535.0 * gamma145_3 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_145_3[i] = 65535.0 * gamma145_3 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
igammatab_145_3[i] = (65535.0 * igamma145_3 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_145_3[i] = 65535.0 * igamma145_3 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
gammatab_26_11[i] = (65535.0 * gamma26_11 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_26_11[i] = 65535.0 * gamma26_11 (i / 65535.0);
} }
//gammatab_145_3 #ifdef _OPENMP
for (int i = 0; i < 65536; i++) { #pragma omp section
igammatab_26_11[i] = (65535.0 * igamma26_11 (i / 65535.0)); #endif
for (int i = 0; i < maxindex; i++) {
igammatab_26_11[i] = 65535.0 * igamma26_11 (i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
float j = (float)i / 65535.0f; #pragma omp section
gammatab_24_17a[i] = gamma24_17(j); #endif
for (int i = 0; i < maxindex; i++) {
gammatab_24_17a[i] = gamma24_17(i / 65535.0);
} }
for (int i = 0; i < 65536; i++) { #ifdef _OPENMP
igammatab_24_17[i] = (65535.0 * igamma24_17 (i / 65535.0)); #pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_24_17[i] = 65535.0 * igamma24_17 (i / 65535.0);
} }
/*FILE* f = fopen ("c.txt", "wt"); #ifdef _OPENMP
for (int i=0; i<256; i++) #pragma omp section
fprintf (f, "%g %g\n", i/255.0, clower (i/255.0, 2.0, 1.0)); #endif
fclose (f);*/
initMunsell(); initMunsell();
#ifdef _OPENMP
#pragma omp section
#endif
linearGammaTRC = cmsBuildGamma(NULL, 1.0); linearGammaTRC = cmsBuildGamma(NULL, 1.0);
}
} }
void Color::cleanup () void Color::cleanup ()
@ -808,6 +884,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
float somm; float somm;
float som = mixerRed + mixerGreen + mixerBlue; float som = mixerRed + mixerGreen + mixerBlue;
if(som >= 0.f && som < 1.f) {
som = 1.f;
}
if(som < 0.f && som > -1.f) {
som = -1.f;
}
// rM = mixerRed, gM = mixerGreen, bM = mixerBlue ! // rM = mixerRed, gM = mixerGreen, bM = mixerBlue !
//presets //presets
if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") {
@ -869,6 +954,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
bbm = mixerBlue; bbm = mixerBlue;
somm = mixerRed + mixerGreen + mixerBlue; somm = mixerRed + mixerGreen + mixerBlue;
if(somm >= 0.f && somm < 1.f) {
somm = 1.f;
}
if(somm < 0.f && somm > -1.f) {
somm = -1.f;
}
mixerRed = mixerRed / somm; mixerRed = mixerRed / somm;
mixerGreen = mixerGreen / somm; mixerGreen = mixerGreen / somm;
mixerBlue = mixerBlue / somm; mixerBlue = mixerBlue / somm;
@ -1084,6 +1178,10 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
mixerGreen = mixerGreen * filgreen; mixerGreen = mixerGreen * filgreen;
mixerBlue = mixerBlue * filblue; mixerBlue = mixerBlue * filblue;
if(mixerRed + mixerGreen + mixerBlue == 0) {
mixerRed += 1.f;
}
mixerRed = filcor * mixerRed / (mixerRed + mixerGreen + mixerBlue); mixerRed = filcor * mixerRed / (mixerRed + mixerGreen + mixerBlue);
mixerGreen = filcor * mixerGreen / (mixerRed + mixerGreen + mixerBlue); mixerGreen = filcor * mixerGreen / (mixerRed + mixerGreen + mixerBlue);
mixerBlue = filcor * mixerBlue / (mixerRed + mixerGreen + mixerBlue); mixerBlue = filcor * mixerBlue / (mixerRed + mixerGreen + mixerBlue);
@ -1091,6 +1189,14 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
if(filter != "None") { if(filter != "None") {
som = mixerRed + mixerGreen + mixerBlue; som = mixerRed + mixerGreen + mixerBlue;
if(som >= 0.f && som < 1.f) {
som = 1.f;
}
if(som < 0.f && som > -1.f) {
som = -1.f;
}
if(setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { if(setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") {
kcorec = kcorec * som; kcorec = kcorec * som;
} }
@ -1436,9 +1542,9 @@ void Color::Yuv2Lab(float Yin, float u, float v, float &L, float &a, float &b, d
gamutmap(X, Y, Z, wp); gamutmap(X, Y, Z, wp);
float fx = (X <= 65535.0 ? cachef[X] : (327.68 * exp(log(X / MAXVALF) / 3.0 ))); float fx = (X <= 65535.0 ? cachef[X] : (327.68 * std::cbrt(X / MAXVALF)));
float fy = (Y <= 65535.0 ? cachef[Y] : (327.68 * exp(log(Y / MAXVALF) / 3.0 ))); float fy = (Y <= 65535.0 ? cachef[Y] : (327.68 * std::cbrt(Y / MAXVALF)));
float fz = (Z <= 65535.0 ? cachef[Z] : (327.68 * exp(log(Z / MAXVALF) / 3.0 ))); float fz = (Z <= 65535.0 ? cachef[Z] : (327.68 * std::cbrt(Z / MAXVALF)));
L = (116.0 * fy - 5242.88); //5242.88=16.0*327.68; L = (116.0 * fy - 5242.88); //5242.88=16.0*327.68;
a = (500.0 * (fx - fy) ); a = (500.0 * (fx - fy) );
@ -1484,7 +1590,7 @@ void Color::XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v)
Z /= 65535.f; Z /= 65535.f;
if (Y > float(eps)) { if (Y > float(eps)) {
L = 116.f * pow(Y, 1.f / 3.f) - 16.f; L = 116.f * std::cbrt(Y) - 16.f;
} else { } else {
L = float(kappa) * Y; L = float(kappa) * Y;
} }

View File

@ -130,8 +130,6 @@ public:
// look-up tables for the standard srgb gamma and its inverse (filled by init()) // look-up tables for the standard srgb gamma and its inverse (filled by init())
static LUTf igammatab_srgb; static LUTf igammatab_srgb;
static LUTf gammatab_srgb; static LUTf gammatab_srgb;
// static LUTf igammatab_709;
// static LUTf gammatab_709;
static LUTf igammatab_55; static LUTf igammatab_55;
static LUTf gammatab_55; static LUTf gammatab_55;
static LUTf igammatab_4; static LUTf igammatab_4;
@ -150,6 +148,7 @@ public:
// look-up tables for the simple exponential gamma // look-up tables for the simple exponential gamma
static LUTf gammatab; static LUTf gammatab;
static LUTuc gammatabThumb; // for thumbnails
static void init (); static void init ();

View File

@ -1414,19 +1414,19 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
// xr, yr , zr > epsilon // xr, yr , zr > epsilon
if(xr[i] > epsilon) { if(xr[i] > epsilon) {
fx[i] = pow(xr[i], 0.333); fx[i] = std::cbrt(xr[i]);
} else { } else {
fx[i] = (903.3 * xr[i] + 16.0) / 116.0; fx[i] = (903.3 * xr[i] + 16.0) / 116.0;
} }
if(yr[i] > epsilon) { if(yr[i] > epsilon) {
fy[i] = pow(yr[i], 0.333); fy[i] = std::cbrt(yr[i]);
} else { } else {
fy[i] = (903.3 * yr[i] + 16.0) / 116.0; fy[i] = (903.3 * yr[i] + 16.0) / 116.0;
} }
if(zr[i] > epsilon) { if(zr[i] > epsilon) {
fz[i] = pow(zr[i], 0.333); fz[i] = std::cbrt(zr[i]);
} else { } else {
fz[i] = (903.3 * zr[i] + 16.0) / 116.0; fz[i] = (903.3 * zr[i] + 16.0) / 116.0;
} }
@ -1663,19 +1663,19 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
// xr, yr , zr > epsilon // xr, yr , zr > epsilon
if(xr[i] > epsilon) { if(xr[i] > epsilon) {
fx[i] = pow(xr[i], 0.333); fx[i] = std::cbrt(xr[i]);
} else { } else {
fx[i] = (903.3 * xr[i] + 16.0) / 116.0; fx[i] = (903.3 * xr[i] + 16.0) / 116.0;
} }
if(yr[i] > epsilon) { if(yr[i] > epsilon) {
fy[i] = pow(yr[i], 0.333); fy[i] = std::cbrt(yr[i]);
} else { } else {
fy[i] = (903.3 * yr[i] + 16.0) / 116.0; fy[i] = (903.3 * yr[i] + 16.0) / 116.0;
} }
if(zr[i] > epsilon) { if(zr[i] > epsilon) {
fz[i] = pow(zr[i], 0.333); fz[i] = std::cbrt(zr[i]);
} else { } else {
fz[i] = (903.3 * zr[i] + 16.0) / 116.0; fz[i] = (903.3 * zr[i] + 16.0) / 116.0;
} }
@ -1695,19 +1695,19 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul,
// //
if(xr[i] > epsilon) { if(xr[i] > epsilon) {
fx[i] = pow(xr[i], 0.333); fx[i] = std::cbrt(xr[i]);
} else { } else {
fx[i] = (903.3 * xr[i] + 16.0) / 116.0; fx[i] = (903.3 * xr[i] + 16.0) / 116.0;
} }
if(yr[i] > epsilon) { if(yr[i] > epsilon) {
fy[i] = pow(yr[i], 0.333); fy[i] = std::cbrt(yr[i]);
} else { } else {
fy[i] = (903.3 * yr[i] + 16.0) / 116.0; fy[i] = (903.3 * yr[i] + 16.0) / 116.0;
} }
if(zr[i] > epsilon) { if(zr[i] > epsilon) {
fz[i] = pow(zr[i], 0.333); fz[i] = std::cbrt(zr[i]);
} else { } else {
fz[i] = (903.3 * zr[i] + 16.0) / 116.0; fz[i] = (903.3 * zr[i] + 16.0) / 116.0;
} }

View File

@ -19,21 +19,49 @@
#include "coord.h" #include "coord.h"
#include "rt_math.h"
namespace rtengine namespace rtengine
{ {
void Coord::setFromPolar(PolarCoord polar) Coord& Coord::operator= (const PolarCoord& other)
{ {
while (polar.angle < 0.f) { const auto radius = other.radius;
polar.angle += 360.f; const auto angle = other.angle / 180.0 * M_PI;
}
while (polar.angle > 360.f) { x = radius * std::cos (angle);
polar.angle -= 360.f; y = radius * std::sin (angle);
}
x = polar.radius * cos(polar.angle / 180.f * M_PI); return *this;
y = polar.radius * sin(polar.angle / 180.f * M_PI); }
PolarCoord& PolarCoord::operator= (const Coord& other)
{
const double x = other.x;
const double y = other.y;
radius = rtengine::norm2 (x, y);
angle = std::atan2 (y, x) * 180.0 / M_PI;
return *this;
}
/// @brief Clip the coord to stay in the width x height bounds
/// @return true if the x or y coordinate has changed
bool Coord::clip (const int width, const int height)
{
const auto newX = rtengine::LIM<int> (x, 0, width);
const auto newY = rtengine::LIM<int> (y, 0, height);
if (x != newX || y != newY) {
x = newX;
y = newY;
return true;
} else {
return false;
}
} }
} }

View File

@ -16,205 +16,218 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __COORD__ #ifndef __COORD__
#define __COORD__ #define __COORD__
#include "rt_math.h"
namespace rtengine namespace rtengine
{ {
class PolarCoord; struct Coord;
struct PolarCoord;
// Do not confuse with rtengine::Coord2D, this one is for the GUI // Do not confuse with Coord2D, this one is used by the UI.
class Coord struct Coord
{ {
public: int x = 0;
int x; int y = 0;
int y;
Coord() : x(-1), y(-1) {} Coord () = default;
Coord(int x, int y) : x(x), y(y) {} Coord (const int x, const int y);
Coord (const Coord& other) = default;
Coord (const PolarCoord& other);
void set (int x, int y) Coord& operator= (const Coord& other) = default;
{ Coord& operator= (const PolarCoord& other);
void get (int& x, int& y) const;
void set (const int x, const int y);
bool clip (const int width, const int height);
Coord& operator+= (const Coord& other);
Coord& operator-= (const Coord& other);
Coord& operator*= (const double scale);
};
bool operator== (const Coord& lhs, const Coord& rhs);
bool operator!= (const Coord& lhs, const Coord& rhs);
const Coord operator+ (const Coord& lhs, const Coord& rhs);
const Coord operator- (const Coord& lhs, const Coord& rhs);
const Coord operator* (const Coord& lhs, const Coord& rhs);
struct PolarCoord
{
double radius = 0.0;
double angle = 0.0;
PolarCoord () = default;
PolarCoord (const double radius, const double angle);
PolarCoord (const PolarCoord& other) = default;
PolarCoord (const Coord& other);
PolarCoord& operator= (const PolarCoord& other) = default;
PolarCoord& operator= (const Coord& other);
void get (double& radius, double& angle) const;
void set (const double radius, const double angle);
PolarCoord& operator+= (const PolarCoord& other);
PolarCoord& operator-= (const PolarCoord& other);
PolarCoord& operator*= (const double scale);
};
bool operator== (const PolarCoord& lhs, const PolarCoord& rhs);
bool operator!= (const PolarCoord& lhs, const PolarCoord& rhs);
const PolarCoord operator+ (const PolarCoord& lhs, const PolarCoord& rhs);
const PolarCoord operator- (const PolarCoord& lhs, const PolarCoord& rhs);
const PolarCoord operator* (const PolarCoord& lhs, const double rhs);
const PolarCoord operator* (const double lhs, const PolarCoord& rhs);
inline Coord::Coord (const int x, const int y) : x (x), y (y)
{
}
inline Coord::Coord (const PolarCoord& other)
{
*this = other;
}
inline void Coord::get (int& x, int& y) const
{
x = this->x;
y = this->y;
}
inline void Coord::set (const int x, const int y)
{
this->x = x; this->x = x;
this->y = y; this->y = y;
} }
void setFromPolar(PolarCoord polar); inline Coord& Coord::operator+= (const Coord& other)
{
x += other.x;
y += other.y;
return *this;
}
/// @brief Clip the coord to stay in the width x height bounds inline Coord& Coord::operator-= (const Coord& other)
/// @return true if the x or y coordinate has changed {
bool clip(int width, int height) x -= other.x;
{ y -= other.y;
int trimmedX = rtengine::LIM<int>(x, 0, width); return *this;
int trimmedY = rtengine::LIM<int>(y, 0, height); }
bool retval = trimmedX != x || trimmedY != y;
x = trimmedX;
y = trimmedY;
return retval;
}
bool operator== (const Coord& other) const inline Coord& Coord::operator*= (const double scale)
{ {
return other.x == x && other.y == y;
}
bool operator!= (const Coord& other) const
{
return other.x != x || other.y != y;
}
void operator+=(const Coord & rhs)
{
x += rhs.x;
y += rhs.y;
}
void operator-=(const Coord & rhs)
{
x -= rhs.x;
y -= rhs.y;
}
void operator*=(double scale)
{
x *= scale; x *= scale;
y *= scale; y *= scale;
} return *this;
Coord operator+(Coord & rhs) }
{
Coord result(x + rhs.x, y + rhs.y);
return result;
}
Coord operator-(Coord & rhs)
{
Coord result(x - rhs.x, y - rhs.y);
return result;
}
Coord operator*(double scale)
{
Coord result(x * scale, y * scale);
return result;
}
};
class PolarCoord inline bool operator== (const Coord& lhs, const Coord& rhs)
{ {
public: return lhs.x == rhs.x && lhs.y == rhs.y;
double radius; }
double angle; // degree
PolarCoord() : radius(1.), angle(0.) {} inline bool operator!= (const Coord& lhs, const Coord& rhs)
PolarCoord(double radius, double angle) : radius(radius), angle(angle) {} {
PolarCoord(Coord start, Coord end) : radius(1.), angle(0.) return !(lhs == rhs);
{ }
setFromCartesian(start, end);
}
PolarCoord(Coord delta) : radius(1.), angle(0.)
{
setFromCartesian(delta);
}
void set (double radius, double angle) inline const Coord operator+ (const Coord& lhs, const Coord& rhs)
{ {
return Coord (lhs) += rhs;
}
inline const Coord operator- (const Coord& lhs, const Coord& rhs)
{
return Coord (lhs) -= rhs;
}
inline const Coord operator* (const Coord& lhs, const double rhs)
{
return Coord (lhs) *= rhs;
}
inline const Coord operator* (const double lhs, const Coord& rhs)
{
return Coord (rhs) *= lhs;
}
inline PolarCoord::PolarCoord (const double radius, const double angle) : radius (radius), angle (angle)
{
}
inline PolarCoord::PolarCoord (const Coord& other)
{
*this = other;
}
inline void PolarCoord::get (double& radius, double& angle) const
{
radius = this->radius;
angle = this->angle;
}
inline void PolarCoord::set (const double radius, const double angle)
{
this->radius = radius; this->radius = radius;
this->angle = angle; this->angle = angle;
} }
void setFromCartesian(Coord start, Coord end) inline PolarCoord& PolarCoord::operator+= (const PolarCoord& other)
{ {
Coord delta(end.x - start.x, end.y - start.y); *this = Coord (*this) + Coord (other);
setFromCartesian(delta); return *this;
} }
void setFromCartesian(Coord delta) inline PolarCoord &PolarCoord::operator-= (const PolarCoord &other)
{ {
if (!delta.x && !delta.y) { *this = Coord (*this) - Coord (other);
// null vector, we set to a default value return *this;
radius = 1.; }
angle = 0.;
return;
}
double x_ = double(delta.x); inline PolarCoord &PolarCoord::operator*= (const double scale)
double y_ = double(delta.y); {
radius = sqrt(x_ * x_ + y_ * y_);
if (delta.x > 0.) {
if (delta.y >= 0.) {
angle = atan(y_ / x_) / (2 * M_PI) * 360.;
} else if (delta.y < 0.) {
angle = (atan(y_ / x_) + 2 * M_PI) / (2 * M_PI) * 360.;
}
} else if (delta.x < 0.) {
angle = (atan(y_ / x_) + M_PI) / (2 * M_PI) * 360.;
} else if (delta.x == 0.) {
if (delta.y > 0.) {
angle = 90.;
} else {
angle = 270.;
}
}
}
bool operator== (const PolarCoord& other) const
{
return other.radius == radius && other.angle == angle;
}
bool operator!= (const PolarCoord& other) const
{
return other.radius != radius || other.angle != angle;
}
void operator+=(const PolarCoord & rhs)
{
Coord thisCoord, rhsCoord;
thisCoord.setFromPolar(*this);
rhsCoord.setFromPolar(rhs);
thisCoord += rhsCoord;
setFromCartesian(thisCoord);
}
void operator-=(const PolarCoord & rhs)
{
Coord thisCoord, rhsCoord;
thisCoord.setFromPolar(*this);
rhsCoord.setFromPolar(rhs);
thisCoord -= rhsCoord;
setFromCartesian(thisCoord);
}
void operator*=(double scale)
{
radius *= scale; radius *= scale;
} return *this;
PolarCoord operator+ (const PolarCoord& rhs) const }
{
PolarCoord result;
Coord thisCoord, rhsCoord;
thisCoord.setFromPolar(*this);
rhsCoord.setFromPolar(rhs);
thisCoord += rhsCoord;
result.setFromCartesian(thisCoord);
return result;
}
PolarCoord operator- (const PolarCoord& rhs) const
{
PolarCoord result;
Coord thisCoord, rhsCoord;
thisCoord.setFromPolar(*this);
rhsCoord.setFromPolar(rhs);
thisCoord -= rhsCoord;
result.setFromCartesian(thisCoord);
return result;
}
Coord operator*(double scale)
{
Coord result(radius * scale, angle);
return result;
}
}; inline bool operator== (const PolarCoord& lhs, const PolarCoord& rhs)
{
return lhs.radius == rhs.radius && lhs.angle == rhs.angle;
}
inline bool operator!= (const PolarCoord& lhs, const PolarCoord& rhs)
{
return !(lhs == rhs);
}
inline const PolarCoord operator+ (const PolarCoord& lhs, const PolarCoord& rhs)
{
return PolarCoord (lhs) += rhs;
}
inline const PolarCoord operator- (const PolarCoord& lhs, const PolarCoord& rhs)
{
return PolarCoord (lhs) -= rhs;
}
inline const PolarCoord operator* (const PolarCoord& lhs, const double rhs)
{
return PolarCoord (lhs) *= rhs;
}
inline const PolarCoord operator* (const double lhs, const PolarCoord& rhs)
{
return PolarCoord (rhs) *= lhs;
}
} }

View File

@ -34,6 +34,7 @@
#include "curves.h" #include "curves.h"
#include "opthelper.h" #include "opthelper.h"
#include "ciecam02.h" #include "ciecam02.h"
#include "color.h"
#undef CLIPD #undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
@ -2293,7 +2294,7 @@ void PerceptualToneCurve::Apply(float &r, float &g, float &b, PerceptualToneCurv
{ {
// increase chroma scaling slightly of shadows // increase chroma scaling slightly of shadows
float nL = gamma2curve[newLuminance]; // apply gamma so we make comparison and transition with a more perceptual lightness scale float nL = Color::gamma2curve[newLuminance]; // apply gamma so we make comparison and transition with a more perceptual lightness scale
float dark_scale_factor = 1.20f; float dark_scale_factor = 1.20f;
//float dark_scale_factor = 1.0 + state.debug.p2 / 100.0f; //float dark_scale_factor = 1.0 + state.debug.p2 / 100.0f;
const float lolim = 0.15f; const float lolim = 0.15f;
@ -2427,7 +2428,6 @@ void PerceptualToneCurve::Apply(float &r, float &g, float &b, PerceptualToneCurv
float PerceptualToneCurve::cf_range[2]; float PerceptualToneCurve::cf_range[2];
float PerceptualToneCurve::cf[1000]; float PerceptualToneCurve::cf[1000];
LUTf PerceptualToneCurve::gamma2curve;
float PerceptualToneCurve::f, PerceptualToneCurve::c, PerceptualToneCurve::nc, PerceptualToneCurve::yb, PerceptualToneCurve::la, PerceptualToneCurve::xw, PerceptualToneCurve::yw, PerceptualToneCurve::zw, PerceptualToneCurve::gamut; float PerceptualToneCurve::f, PerceptualToneCurve::c, PerceptualToneCurve::nc, PerceptualToneCurve::yb, PerceptualToneCurve::la, PerceptualToneCurve::xw, PerceptualToneCurve::yw, PerceptualToneCurve::zw, PerceptualToneCurve::gamut;
float PerceptualToneCurve::n, PerceptualToneCurve::d, PerceptualToneCurve::nbb, PerceptualToneCurve::ncb, PerceptualToneCurve::cz, PerceptualToneCurve::aw, PerceptualToneCurve::wh, PerceptualToneCurve::pfl, PerceptualToneCurve::fl, PerceptualToneCurve::pow1; float PerceptualToneCurve::n, PerceptualToneCurve::d, PerceptualToneCurve::nbb, PerceptualToneCurve::ncb, PerceptualToneCurve::cz, PerceptualToneCurve::aw, PerceptualToneCurve::wh, PerceptualToneCurve::pfl, PerceptualToneCurve::fl, PerceptualToneCurve::pow1;
@ -2490,12 +2490,6 @@ void PerceptualToneCurve::init()
cf_range[0] = in_x[0]; cf_range[0] = in_x[0];
cf_range[1] = in_x[in_len - 1]; cf_range[1] = in_x[in_len - 1];
} }
gamma2curve(65536, 0);
for (int i = 0; i < 65536; i++) {
gamma2curve[i] = CurveFactory::gamma2(i / 65535.0);
}
} }
void PerceptualToneCurve::initApplyState(PerceptualToneCurveState & state, Glib::ustring workingSpace) const void PerceptualToneCurve::initApplyState(PerceptualToneCurveState & state, Glib::ustring workingSpace) const

View File

@ -843,7 +843,6 @@ class PerceptualToneCurve : public ToneCurve
private: private:
static float cf_range[2]; static float cf_range[2];
static float cf[1000]; static float cf[1000];
static LUTf gamma2curve;
// for ciecam02 // for ciecam02
static float f, c, nc, yb, la, xw, yw, zw, gamut; static float f, c, nc, yb, la, xw, yw, zw, gamut;
static float n, d, nbb, ncb, cz, aw, wh, pfl, fl, pow1; static float n, d, nbb, ncb, cz, aw, wh, pfl, fl, pow1;

View File

@ -19,7 +19,6 @@
#include <cstring> #include <cstring>
#include "dcp.h" #include "dcp.h"
#include "safegtk.h"
#include "iccmatrices.h" #include "iccmatrices.h"
#include "iccstore.h" #include "iccstore.h"
#include "rawimagesource.h" #include "rawimagesource.h"
@ -828,7 +827,7 @@ DCPProfile::DCPProfile(Glib::ustring fname)
aDeltas1 = aDeltas2 = aLookTable = NULL; aDeltas1 = aDeltas2 = aLookTable = NULL;
FILE *pFile = safe_g_fopen(fname, "rb"); FILE *pFile = g_fopen(fname.c_str (), "rb");
TagDirectory *tagDir = ExifManager::parseTIFF(pFile, false); TagDirectory *tagDir = ExifManager::parseTIFF(pFile, false);
@ -1717,7 +1716,7 @@ void DCPStore::init (Glib::ustring rtProfileDir)
Glib::Dir* dir = NULL; Glib::Dir* dir = NULL;
try { try {
if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) { if (!Glib::file_test (dirname, Glib::FILE_TEST_IS_DIR)) {
return; return;
} }
@ -1733,7 +1732,7 @@ void DCPStore::init (Glib::ustring rtProfileDir)
Glib::ustring sname = *i; Glib::ustring sname = *i;
// ignore directories // ignore directories
if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) {
size_t lastdot = sname.find_last_of ('.'); size_t lastdot = sname.find_last_of ('.');
if (lastdot != Glib::ustring::npos && lastdot <= sname.size() - 4 && (!sname.casefold().compare (lastdot, 4, ".dcp"))) { if (lastdot != Glib::ustring::npos && lastdot <= sname.size() - 4 && (!sname.casefold().compare (lastdot, 4, ".dcp"))) {
@ -1781,7 +1780,7 @@ DCPProfile* DCPStore::getStdProfile(Glib::ustring camShortName)
bool DCPStore::isValidDCPFileName(Glib::ustring filename) const bool DCPStore::isValidDCPFileName(Glib::ustring filename) const
{ {
if (!safe_file_test (filename, Glib::FILE_TEST_EXISTS) || safe_file_test (filename, Glib::FILE_TEST_IS_DIR)) { if (!Glib::file_test (filename, Glib::FILE_TEST_EXISTS) || Glib::file_test (filename, Glib::FILE_TEST_IS_DIR)) {
return false; return false;
} }

View File

@ -705,6 +705,17 @@ void Crop::update (int todo)
transCrop = NULL; transCrop = NULL;
} }
if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
const int W = baseCrop->getWidth();
const int H = baseCrop->getHeight();
LabImage labcbdl(W, H);
parent->ipf.rgb2lab(*baseCrop, labcbdl, params.icm.working);
parent->ipf.dirpyrequalizer (&labcbdl, skip);
parent->ipf.lab2rgb(labcbdl, *baseCrop, params.icm.working);
}
// blurmap for shadow & highlights // blurmap for shadow & highlights
if ((todo & M_BLURMAP) && params.sh.enabled) { if ((todo & M_BLURMAP) && params.sh.enabled) {
double radius = sqrt (double(SKIPS(parent->fw, skip) * SKIPS(parent->fw, skip) + SKIPS(parent->fh, skip) * SKIPS(parent->fh, skip))) / 2.0; double radius = sqrt (double(SKIPS(parent->fw, skip) * SKIPS(parent->fw, skip) + SKIPS(parent->fh, skip) * SKIPS(parent->fh, skip))) / 2.0;
@ -725,6 +736,7 @@ void Crop::update (int todo)
} }
} }
// shadows & highlights & tone curve & convert to cielab // shadows & highlights & tone curve & convert to cielab
/*int xref,yref; /*int xref,yref;
xref=000;yref=000; xref=000;yref=000;
@ -831,11 +843,12 @@ void Crop::update (int todo)
// if (skip==1) { // if (skip==1) {
WaveletParams WaveParams = params.wavelet; WaveletParams WaveParams = params.wavelet;
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { if(params.dirpyrequalizer.cbdlMethod == "aft") {
if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) {
parent->ipf.dirpyrequalizer (labnCrop, skip); parent->ipf.dirpyrequalizer (labnCrop, skip);
// parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip);
} }
}
int kall = 0; int kall = 0;
int minwin = min(labnCrop->W, labnCrop->H); int minwin = min(labnCrop->W, labnCrop->H);

View File

@ -90,7 +90,7 @@ void RawImageSource::eahd_demosaic ()
threshold = (int)(0.008856 * MAXVALD); threshold = (int)(0.008856 * MAXVALD);
for (int i = 0; i < maxindex; i++) { for (int i = 0; i < maxindex; i++) {
cache[i] = exp(1.0 / 3.0 * log(double(i) / MAXVALD)); cache[i] = std::cbrt(double(i) / MAXVALD);
} }
// end of cielab preparation // end of cielab preparation
@ -2703,7 +2703,7 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh)
for (i = 0; i < 0x10000; i++) { for (i = 0; i < 0x10000; i++) {
r = (double)i / 65535.0; r = (double)i / 65535.0;
cbrt[i] = r > 0.008856 ? pow(r, 0.333333333) : 7.787 * r + 16 / 116.0; cbrt[i] = r > 0.008856 ? std::cbrt(r) : 7.787 * r + 16 / 116.0;
} }
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)

View File

@ -20,7 +20,6 @@
#include "../rtgui/options.h" #include "../rtgui/options.h"
#include <giomm.h> #include <giomm.h>
#include "../rtgui/guiutils.h" #include "../rtgui/guiutils.h"
#include "safegtk.h"
#include "rawimage.h" #include "rawimage.h"
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
@ -263,13 +262,21 @@ void dfInfo::updateBadPixelList( RawImage *df )
void DFManager::init( Glib::ustring pathname ) void DFManager::init( Glib::ustring pathname )
{ {
std::vector<Glib::ustring> names; std::vector<Glib::ustring> names;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (pathname);
if( dir && !dir->query_exists()) { auto dir = Gio::File::create_for_path (pathname);
if (!dir || !dir->query_exists()) {
return; return;
} }
safe_build_file_list (dir, names, pathname); try {
auto enumerator = dir->enumerate_children ("standard::name");
while (auto file = enumerator->next_file ()) {
names.emplace_back (Glib::build_filename (pathname, file->get_name ()));
}
} catch (Glib::Exception&) {}
dfList.clear(); dfList.clear();
bpList.clear(); bpList.clear();
@ -320,28 +327,48 @@ void DFManager::init( Glib::ustring pathname )
return; return;
} }
dfInfo *DFManager::addFileInfo(const Glib::ustring &filename , bool pool ) dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
{ {
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename); auto file = Gio::File::create_for_path (filename);
if (!file ) { if (!file) {
return 0; return 0;
} }
if( !file->query_exists()) { if (!file->query_exists ()) {
return 0; return 0;
} }
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info(file); try {
if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { auto info = file->query_info ();
size_t lastdot = info->get_name().find_last_of ('.');
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) { if (!info && info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
RawImage ri(filename); return 0;
int res = ri.loadRaw(false); // Read informations about shot }
if (!options.fbShowHidden && info->is_hidden ()) {
return 0;
}
Glib::ustring ext;
auto lastdot = info->get_name ().find_last_of ('.');
if (lastdot != Glib::ustring::npos) {
ext = info->get_name ().substr (lastdot + 1);
}
if (!options.is_extention_enabled (ext)) {
return 0;
}
RawImage ri (filename);
int res = ri.loadRaw (false); // Read informations about shot
if (res != 0) {
return 0;
}
if( !res ) {
dfList_t::iterator iter; dfList_t::iterator iter;
if(!pool) { if(!pool) {
@ -376,9 +403,8 @@ dfInfo *DFManager::addFileInfo(const Glib::ustring &filename , bool pool )
} }
return &(iter->second); return &(iter->second);
}
} } catch(Gio::Error&) {}
}
return 0; return 0;
} }

View File

@ -19,7 +19,6 @@
#include "ffmanager.h" #include "ffmanager.h"
#include "../rtgui/options.h" #include "../rtgui/options.h"
#include <giomm.h> #include <giomm.h>
#include "safegtk.h"
#include "rawimage.h" #include "rawimage.h"
#include <sstream> #include <sstream>
#include <cstdio> #include <cstdio>
@ -209,13 +208,21 @@ void ffInfo::updateRawImage()
void FFManager::init( Glib::ustring pathname ) void FFManager::init( Glib::ustring pathname )
{ {
std::vector<Glib::ustring> names; std::vector<Glib::ustring> names;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (pathname);
if( dir && !dir->query_exists()) { auto dir = Gio::File::create_for_path (pathname);
if (!dir || !dir->query_exists()) {
return; return;
} }
safe_build_file_list (dir, names, pathname); try {
auto enumerator = dir->enumerate_children ("standard::name");
while (auto file = enumerator->next_file ()) {
names.emplace_back (Glib::build_filename (pathname, file->get_name ()));
}
} catch (Glib::Exception&) {}
ffList.clear(); ffList.clear();
@ -253,28 +260,49 @@ void FFManager::init( Glib::ustring pathname )
return; return;
} }
ffInfo *FFManager::addFileInfo(const Glib::ustring &filename, bool pool ) ffInfo* FFManager::addFileInfo (const Glib::ustring& filename, bool pool)
{ {
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename); auto file = Gio::File::create_for_path (filename);
if (!file ) { if (!file ) {
return 0; return 0;
} }
if( !file->query_exists()) { if (!file->query_exists ()) {
return 0; return 0;
} }
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info(file); try {
if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { auto info = file->query_info ();
size_t lastdot = info->get_name().find_last_of ('.');
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) { if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
RawImage ri(filename); return 0;
int res = ri.loadRaw(false); // Read informations about shot }
if (!options.fbShowHidden && info->is_hidden ()) {
return 0;
}
Glib::ustring ext;
auto lastdot = info->get_name ().find_last_of ('.');
if (lastdot != Glib::ustring::npos) {
ext = info->get_name ().substr (lastdot + 1);
}
if (!options.is_extention_enabled (ext)) {
return 0;
}
RawImage ri (filename);
int res = ri.loadRaw (false); // Read informations about shot
if (res != 0) {
return 0;
}
if( !res ) {
ffList_t::iterator iter; ffList_t::iterator iter;
if(!pool) { if(!pool) {
@ -309,9 +337,8 @@ ffInfo *FFManager::addFileInfo(const Glib::ustring &filename, bool pool )
} }
return &(iter->second); return &(iter->second);
}
} } catch (Gio::Error&) {}
}
return 0; return 0;
} }

View File

@ -16,18 +16,21 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "iccstore.h"
#include <cstring>
#ifdef WIN32 #ifdef WIN32
#include <winsock2.h> #include <winsock2.h>
#else #else
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#include "iccstore.h"
#include "iccmatrices.h"
#include <glib/gstdio.h>
#include "safegtk.h"
#include "../rtgui/options.h"
#include <cstring> #include <glib/gstdio.h>
#include "iccmatrices.h"
#include "../rtgui/options.h"
namespace namespace
{ {
@ -59,7 +62,7 @@ void loadProfiles (const Glib::ustring& dirName,
const Glib::ustring filePath = Glib::build_filename (dirName, fileName); const Glib::ustring filePath = Glib::build_filename (dirName, fileName);
if (!safe_file_test (filePath, Glib::FILE_TEST_IS_REGULAR)) if (!Glib::file_test (filePath, Glib::FILE_TEST_IS_REGULAR))
continue; continue;
Glib::ustring name = fileName.substr (0, fileName.size() - 4); Glib::ustring name = fileName.substr (0, fileName.size() - 4);
@ -356,8 +359,9 @@ cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const
const ProfileMap::const_iterator r = fileProfiles.find (name); const ProfileMap::const_iterator r = fileProfiles.find (name);
if (r != fileProfiles.end ()) if (r != fileProfiles.end ()) {
return r->second; return r->second;
}
if (name.compare (0, 5, "file:") == 0) { if (name.compare (0, 5, "file:") == 0) {
const ProfileContent content (name.substr (5)); const ProfileContent content (name.substr (5));
@ -371,7 +375,7 @@ cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const
} }
} }
return NULL; return nullptr;
} }
cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const
@ -418,7 +422,6 @@ ProfileContent ICCStore::getContent (const Glib::ustring& name) const
std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
{ {
MyMutex::MyLock lock (mutex_); MyMutex::MyLock lock (mutex_);
return getSupportedIntents (profile, LCMS_USED_AS_INPUT); return getSupportedIntents (profile, LCMS_USED_AS_INPUT);
@ -426,7 +429,6 @@ std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const
{ {
MyMutex::MyLock lock (mutex_); MyMutex::MyLock lock (mutex_);
return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT); return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT);
@ -434,7 +436,6 @@ std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const
std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const
{ {
MyMutex::MyLock lock (mutex_); MyMutex::MyLock lock (mutex_);
return getSupportedIntents (profile, LCMS_USED_AS_PROOF); return getSupportedIntents (profile, LCMS_USED_AS_PROOF);
@ -503,7 +504,7 @@ void ICCStore::findDefaultMonitorProfile ()
ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(NULL), length(0) ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(NULL), length(0)
{ {
FILE* f = safe_g_fopen (fileName, "rb"); FILE* f = g_fopen (fileName.c_str (), "rb");
if (!f) { if (!f) {
return; return;

View File

@ -19,12 +19,25 @@
#include "imagedata.h" #include "imagedata.h"
#include "iptcpairs.h" #include "iptcpairs.h"
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include "safegtk.h"
using namespace rtengine; using namespace rtengine;
extern "C" IptcData *iptc_data_new_from_jpeg_file (FILE* infile); extern "C" IptcData *iptc_data_new_from_jpeg_file (FILE* infile);
namespace
{
Glib::ustring to_utf8 (const std::string& str)
{
try {
return Glib::locale_to_utf8 (str);
} catch (Glib::Error&) {
return Glib::convert_with_fallback (str, "UTF-8", "ISO-8859-1", "?");
}
}
}
ImageMetaData* ImageMetaData::fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml) ImageMetaData* ImageMetaData::fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml)
{ {
@ -39,7 +52,7 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri)
iptc = NULL; iptc = NULL;
if (ri && (ri->exifBase >= 0 || ri->ciffBase >= 0)) { if (ri && (ri->exifBase >= 0 || ri->ciffBase >= 0)) {
FILE* f = safe_g_fopen (fname, "rb"); FILE* f = g_fopen (fname.c_str (), "rb");
if (f) { if (f) {
if (ri->exifBase >= 0) { if (ri->exifBase >= 0) {
@ -60,18 +73,18 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri)
extractInfo (); extractInfo ();
} }
} else if ((dotpos < fname.size() - 3 && !fname.casefold().compare (dotpos, 4, ".jpg")) || (dotpos < fname.size() - 4 && !fname.casefold().compare (dotpos, 5, ".jpeg"))) { } else if ((dotpos < fname.size() - 3 && !fname.casefold().compare (dotpos, 4, ".jpg")) || (dotpos < fname.size() - 4 && !fname.casefold().compare (dotpos, 5, ".jpeg"))) {
FILE* f = safe_g_fopen (fname, "rb"); FILE* f = g_fopen (fname.c_str (), "rb");
if (f) { if (f) {
root = rtexif::ExifManager::parseJPEG (f); root = rtexif::ExifManager::parseJPEG (f);
extractInfo (); extractInfo ();
fclose (f); fclose (f);
FILE* ff = safe_g_fopen (fname, "rb"); FILE* ff = g_fopen (fname.c_str (), "rb");
iptc = iptc_data_new_from_jpeg_file (ff); iptc = iptc_data_new_from_jpeg_file (ff);
fclose (ff); fclose (ff);
} }
} else if ((dotpos < fname.size() - 3 && !fname.casefold().compare (dotpos, 4, ".tif")) || (dotpos < fname.size() - 4 && !fname.casefold().compare (dotpos, 5, ".tiff"))) { } else if ((dotpos < fname.size() - 3 && !fname.casefold().compare (dotpos, 4, ".tif")) || (dotpos < fname.size() - 4 && !fname.casefold().compare (dotpos, 5, ".tiff"))) {
FILE* f = safe_g_fopen (fname, "rb"); FILE* f = g_fopen (fname.c_str (), "rb");
if (f) { if (f) {
root = rtexif::ExifManager::parseTIFF (f); root = rtexif::ExifManager::parseTIFF (f);
@ -271,13 +284,19 @@ void ImageData::extractInfo ()
} else if(!make.compare (0, 4, "SONY")) { } else if(!make.compare (0, 4, "SONY")) {
if (iso_speed == 65535 || iso_speed == 0) { if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* isoTag = exif->getTag ("RecommendedExposureIndex"); rtexif::Tag* isoTag = exif->getTag ("RecommendedExposureIndex");
if(isoTag)
if(isoTag) {
iso_speed = isoTag->toDouble(); iso_speed = isoTag->toDouble();
} }
}
} }
else if (root->findTag("MakerNote")) {
rtexif::TagDirectory* mnote = root->findTag("MakerNote")->getDirectory(); if (lens == "Unknown") {
rtexif::Tag* mnoteTag = root->findTag("MakerNote");
if (mnoteTag) {
rtexif::TagDirectory* mnote = mnoteTag->getDirectory();
if (mnote && !make.compare (0, 5, "NIKON")) { if (mnote && !make.compare (0, 5, "NIKON")) {
// ISO at max value supported, check manufacturer specific // ISO at max value supported, check manufacturer specific
@ -443,6 +462,7 @@ void ImageData::extractInfo ()
lens = exif->getTag ("LensInfo")->valueToString (); lens = exif->getTag ("LensInfo")->valueToString ();
} }
} }
}
} }
ImageData::~ImageData () ImageData::~ImageData ()
@ -472,7 +492,7 @@ const procparams::IPTCPairs ImageData::getIPTCData () const
if (ds) { if (ds) {
iptc_dataset_get_data (ds, buffer, 2100); iptc_dataset_get_data (ds, buffer, 2100);
std::vector<Glib::ustring> icValues; std::vector<Glib::ustring> icValues;
icValues.push_back (safe_locale_to_utf8((char*)buffer)); icValues.push_back (to_utf8((char*)buffer));
iptcc[strTags[i].field] = icValues; iptcc[strTags[i].field] = icValues;
iptc_dataset_unref (ds); iptc_dataset_unref (ds);
@ -484,7 +504,7 @@ const procparams::IPTCPairs ImageData::getIPTCData () const
while ((ds = iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS))) { while ((ds = iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS))) {
iptc_dataset_get_data (ds, buffer, 2100); iptc_dataset_get_data (ds, buffer, 2100);
keywords.push_back (safe_locale_to_utf8((char*)buffer)); keywords.push_back (to_utf8((char*)buffer));
} }
iptcc["Keywords"] = keywords; iptcc["Keywords"] = keywords;
@ -493,7 +513,7 @@ const procparams::IPTCPairs ImageData::getIPTCData () const
while ((ds = iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY))) { while ((ds = iptc_data_get_next_dataset (iptc, ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY))) {
iptc_dataset_get_data (ds, buffer, 2100); iptc_dataset_get_data (ds, buffer, 2100);
suppCategories.push_back (safe_locale_to_utf8((char*)buffer)); suppCategories.push_back (to_utf8((char*)buffer));
iptc_dataset_unref (ds); iptc_dataset_unref (ds);
} }

View File

@ -48,11 +48,11 @@ public:
{ {
return height; return height;
} }
int getWidth () int getWidth () const
{ {
return width; return width;
} }
int getHeight () int getHeight () const
{ {
return height; return height;
} }

View File

@ -36,7 +36,6 @@
#endif #endif
#include "imageio.h" #include "imageio.h"
#include "safegtk.h"
#include "iptcpairs.h" #include "iptcpairs.h"
#include "iccjpeg.h" #include "iccjpeg.h"
#include "color.h" #include "color.h"
@ -47,9 +46,46 @@ using namespace std;
using namespace rtengine; using namespace rtengine;
using namespace rtengine::procparams; using namespace rtengine::procparams;
Glib::ustring safe_locale_to_utf8 (const std::string& src); namespace
Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."}; {
// Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking)
FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname)
{
FILE* f = NULL;
#ifdef WIN32
// Use native function to disallow sharing, i.e. lock the file for exclusive access.
// This is important to e.g. prevent Windows Explorer from crashing RT due to concurrently scanning an image file.
std::unique_ptr<wchar_t, GFreeFunc> wfname (reinterpret_cast<wchar_t*>(g_utf8_to_utf16 (fname.c_str (), -1, NULL, NULL, NULL)), g_free);
HANDLE hFile = CreateFileW ( wfname.get (), GENERIC_READ | GENERIC_WRITE, 0 /* no sharing allowed */, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
f = _fdopen (_open_osfhandle ((intptr_t)hFile, 0), "wb");
}
#else
f = ::g_fopen (fname.c_str (), "wb");
#endif
return f;
}
Glib::ustring to_utf8 (const std::string& str)
{
try {
return Glib::locale_to_utf8 (str);
} catch (Glib::Error&) {
return Glib::convert_with_fallback (str, "UTF-8", "ISO-8859-1", "?");
}
}
}
Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."};
// For only copying the raw input data // For only copying the raw input data
void ImageIO::setMetadata (const rtexif::TagDirectory* eroot) void ImageIO::setMetadata (const rtexif::TagDirectory* eroot)
@ -77,12 +113,6 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr
// store exif info // store exif info
exifChange.clear(); exifChange.clear();
exifChange = exif; exifChange = exif;
/*unsigned int j=0;
for (rtengine::procparams::ExifPairs::const_iterator i=exif.begin(); i!=exif.end(); i++) {
exifChange.at(j).first = i->first;
exifChange.at(j).second = i->second;
j++;
}*/
if (exifRoot != NULL) { if (exifRoot != NULL) {
delete exifRoot; delete exifRoot;
@ -110,7 +140,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr
for (unsigned int j = 0; j < i->second.size(); j++) { for (unsigned int j = 0; j < i->second.size(); j++) {
IptcDataSet * ds = iptc_dataset_new (); IptcDataSet * ds = iptc_dataset_new ();
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS);
std::string loc = safe_locale_to_utf8(i->second.at(j)); std::string loc = to_utf8(i->second.at(j));
iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(static_cast<size_t>(64), loc.size()), IPTC_DONT_VALIDATE); iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(static_cast<size_t>(64), loc.size()), IPTC_DONT_VALIDATE);
iptc_data_add_dataset (iptc, ds); iptc_data_add_dataset (iptc, ds);
iptc_dataset_unref (ds); iptc_dataset_unref (ds);
@ -121,7 +151,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr
for (unsigned int j = 0; j < i->second.size(); j++) { for (unsigned int j = 0; j < i->second.size(); j++) {
IptcDataSet * ds = iptc_dataset_new (); IptcDataSet * ds = iptc_dataset_new ();
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY);
std::string loc = safe_locale_to_utf8(i->second.at(j)); std::string loc = to_utf8(i->second.at(j));
iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(static_cast<size_t>(32), loc.size()), IPTC_DONT_VALIDATE); iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(static_cast<size_t>(32), loc.size()), IPTC_DONT_VALIDATE);
iptc_data_add_dataset (iptc, ds); iptc_data_add_dataset (iptc, ds);
iptc_dataset_unref (ds); iptc_dataset_unref (ds);
@ -134,7 +164,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr
if (i->first == strTags[j].field && !(i->second.empty())) { if (i->first == strTags[j].field && !(i->second.empty())) {
IptcDataSet * ds = iptc_dataset_new (); IptcDataSet * ds = iptc_dataset_new ();
iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag);
std::string loc = safe_locale_to_utf8(i->second.at(0)); std::string loc = to_utf8(i->second.at(0));
iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(strTags[j].size, loc.size()), IPTC_DONT_VALIDATE); iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(strTags[j].size, loc.size()), IPTC_DONT_VALIDATE);
iptc_data_add_dataset (iptc, ds); iptc_data_add_dataset (iptc, ds);
iptc_dataset_unref (ds); iptc_dataset_unref (ds);
@ -177,7 +207,7 @@ void png_flush(png_struct_def *png_ptr);
int ImageIO::getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement) int ImageIO::getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement)
{ {
FILE *file = safe_g_fopen (fname, "rb"); FILE *file = g_fopen (fname.c_str (), "rb");
if (!file) { if (!file) {
return IMIO_CANNOTREADFILE; return IMIO_CANNOTREADFILE;
@ -251,7 +281,7 @@ int ImageIO::getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat,
int ImageIO::loadPNG (Glib::ustring fname) int ImageIO::loadPNG (Glib::ustring fname)
{ {
FILE *file = safe_g_fopen (fname, "rb"); FILE *file = g_fopen (fname.c_str (), "rb");
if (!file) { if (!file) {
return IMIO_CANNOTREADFILE; return IMIO_CANNOTREADFILE;
@ -500,7 +530,7 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
int ImageIO::loadJPEG (Glib::ustring fname) int ImageIO::loadJPEG (Glib::ustring fname)
{ {
FILE *file = safe_g_fopen(fname, "rb"); FILE *file = g_fopen(fname.c_str (), "rb");
if (!file) { if (!file) {
return IMIO_CANNOTREADFILE; return IMIO_CANNOTREADFILE;
@ -888,7 +918,7 @@ int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool s
int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps) int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps)
{ {
FILE *file = safe_g_fopen_WriteBinLock (fname); FILE *file = g_fopen_withBinaryAndLock (fname);
if (!file) { if (!file) {
return IMIO_CANNOTWRITEFILE; return IMIO_CANNOTWRITEFILE;
@ -982,7 +1012,7 @@ int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps)
int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp) int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
{ {
FILE *file = safe_g_fopen_WriteBinLock (fname); FILE *file = g_fopen_withBinaryAndLock (fname);
if (!file) { if (!file) {
return IMIO_CANNOTWRITEFILE; return IMIO_CANNOTWRITEFILE;
@ -1011,7 +1041,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
*/ */
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
fclose(file); fclose(file);
safe_g_remove(fname); g_remove (fname.c_str());
return IMIO_CANNOTWRITEFILE; return IMIO_CANNOTWRITEFILE;
} }
@ -1130,7 +1160,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
delete [] row; delete [] row;
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
fclose(file); fclose(file);
safe_g_remove(fname); g_remove (fname.c_str());
return IMIO_CANNOTWRITEFILE; return IMIO_CANNOTWRITEFILE;
} }
@ -1142,7 +1172,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
jpeg_destroy_compress (&cinfo); jpeg_destroy_compress (&cinfo);
delete [] row; delete [] row;
fclose (file); fclose (file);
safe_g_remove(fname); g_remove (fname.c_str());
return IMIO_CANNOTWRITEFILE; return IMIO_CANNOTWRITEFILE;
} }
@ -1183,7 +1213,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed)
// TODO the following needs to be looked into - do we really need two ways to write a Tiff file ? // TODO the following needs to be looked into - do we really need two ways to write a Tiff file ?
if (exifRoot && uncompressed) { if (exifRoot && uncompressed) {
FILE *file = safe_g_fopen_WriteBinLock (fname); FILE *file = g_fopen_withBinaryAndLock (fname);
if (!file) { if (!file) {
delete [] linebuffer; delete [] linebuffer;
@ -1370,7 +1400,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed)
if(writeOk) { if(writeOk) {
return IMIO_SUCCESS; return IMIO_SUCCESS;
} else { } else {
safe_g_remove(fname); g_remove (fname.c_str());
return IMIO_CANNOTWRITEFILE; return IMIO_CANNOTWRITEFILE;
} }
} }

View File

@ -242,7 +242,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
} }
} }
if ((todo & (M_RETINEX|M_INIT)) && params.retinex.enabled) { if ((todo & (M_RETINEX | M_INIT)) && params.retinex.enabled) {
bool dehacontlutili = false; bool dehacontlutili = false;
bool mapcontlutili = false; bool mapcontlutili = false;
bool useHsl = false; bool useHsl = false;
@ -388,8 +388,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(), ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(),
imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false); imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false);
readyphase++; if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
const int W = oprevi->getWidth();
const int H = oprevi->getHeight();
LabImage labcbdl(W, H);
ipf.rgb2lab(*oprevi, labcbdl, params.icm.working);
ipf.dirpyrequalizer (&labcbdl, scale);
ipf.lab2rgb(labcbdl, *oprevi, params.icm.working);
}
readyphase++;
progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases);
if ((todo & M_BLURMAP) && params.sh.enabled) { if ((todo & M_BLURMAP) && params.sh.enabled) {
@ -407,6 +415,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale); shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale);
} }
readyphase++; readyphase++;
if (todo & M_AUTOEXP) { if (todo & M_AUTOEXP) {
@ -439,6 +449,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale == 1 ? 1 : 1); CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale == 1 ? 1 : 1);
CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = { double wp[3][3] = {
{wprof[0][0], wprof[0][1], wprof[0][2]}, {wprof[0][0], wprof[0][1], wprof[0][2]},
@ -656,15 +667,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
} }
} }
*/ */
//if (scale==1) { if(params.dirpyrequalizer.cbdlMethod == "aft") {
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ) {
progress ("Pyramid wavelet...", 100 * readyphase / numofphases); progress ("Pyramid wavelet...", 100 * readyphase / numofphases);
ipf.dirpyrequalizer (nprevl, scale); ipf.dirpyrequalizer (nprevl, scale);
//ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale); //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale);
readyphase++; readyphase++;
} }
}
//}
wavcontlutili = false; wavcontlutili = false;
//CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip);
@ -782,6 +793,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
} }
} }
} }
// Update the monitor color transform if necessary // Update the monitor color transform if necessary
if (todo & M_MONITOR) { if (todo & M_MONITOR) {
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);

View File

@ -52,45 +52,7 @@ namespace rtengine
using namespace procparams; using namespace procparams;
#undef ABS
#undef CLIPS
#undef CLIPC
#define ABS(a) ((a)<0?-(a):(a))
#define CLIPS(a) ((a)>-32768?((a)<32767?(a):32767):-32768)
#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000)
#define CLIP2(a) ((a)<MAXVAL ? a : MAXVAL )
#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0)
extern const Settings* settings; extern const Settings* settings;
LUTf ImProcFunctions::cachef;
LUTf ImProcFunctions::gamma2curve;
void ImProcFunctions::initCache ()
{
const int maxindex = 65536;
cachef(maxindex, 0/*LUT_CLIP_BELOW*/);
gamma2curve(maxindex, 0);
for (int i = 0; i < maxindex; i++) {
if (i > Color::eps_max) {
cachef[i] = 327.68 * ( exp(1.0 / 3.0 * log((double)i / MAXVALD) ));
} else {
cachef[i] = 327.68 * ((Color::kappa * i / MAXVALD + 16.0) / 116.0);
}
}
for (int i = 0; i < maxindex; i++) {
gamma2curve[i] = (CurveFactory::gamma2(i / 65535.0) * 65535.0);
}
}
void ImProcFunctions::cleanupCache ()
{
}
ImProcFunctions::~ImProcFunctions () ImProcFunctions::~ImProcFunctions ()
{ {
@ -3421,10 +3383,22 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
fGammaLUTf[i] = CurveFactory::gamma2 (float(i) / 65535.f) * 65535.f; fGammaLUTf[i] = CurveFactory::gamma2 (float(i) / 65535.f) * 65535.f;
} }
if (hasColorToning || blackwhite) { if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) {
tmpImage = new Imagefloat(working->width, working->height); tmpImage = new Imagefloat(working->width, working->height);
} }
int W = working->width;
int H = working->height;
#define TS 112 #define TS 112
#ifdef _OPENMP #ifdef _OPENMP
@ -3806,9 +3780,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
y = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1; y = toxyz[1][0] * r1 + toxyz[1][1] * g1 + toxyz[1][2] * b1;
z = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1; z = toxyz[2][0] * r1 + toxyz[2][1] * g1 + toxyz[2][2] * b1;
fx = (x < 65535.0f ? cachef[std::max(x, 0.f)] : (327.68f * float(exp(log(x / MAXVALF) / 3.0f )))); fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? cachef[std::max(y, 0.f)] : (327.68f * float(exp(log(y / MAXVALF) / 3.0f )))); fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
fz = (z < 65535.0f ? cachef[std::max(z, 0.f)] : (327.68f * float(exp(log(z / MAXVALF) / 3.0f )))); fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF));
L_1 = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; L_1 = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68;
a_1 = (500.0f * (fx - fy) ); a_1 = (500.0f * (fx - fy) );
@ -3836,7 +3810,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
// Luminosity after // Luminosity after
// only Luminance in Lab // only Luminance in Lab
yy = toxyz[1][0] * r2 + toxyz[1][1] * g2 + toxyz[1][2] * b2; yy = toxyz[1][0] * r2 + toxyz[1][1] * g2 + toxyz[1][2] * b2;
fyy = (yy < 65535.0f ? cachef[std::max(yy, 0.f)] : (327.68f * float(exp(log(yy / MAXVALF) / 3.0f )))); fyy = (yy < 65535.0f ? Color::cachef[std::max(yy, 0.f)] : 327.68f * std::cbrt(yy / MAXVALF));
L_2 = (116.0f * fyy - 5242.88f); L_2 = (116.0f * fyy - 5242.88f);
//gamut control //gamut control
@ -4217,48 +4191,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
} }
} }
//Film Simulations
if ( colorLUT ) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
float &sourceR = rtemp[ti * TS + tj];
float &sourceG = gtemp[ti * TS + tj];
float &sourceB = btemp[ti * TS + tj];
if (!clutAndWorkingProfilesAreSame) {
//convert from working to clut profile
float x, y, z;
Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz );
Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut );
}
//appply gamma sRGB (default RT)
sourceR = CLIP<float>( Color::gamma_srgb( sourceR ) );
sourceG = CLIP<float>( Color::gamma_srgb( sourceG ) );
sourceB = CLIP<float>( Color::gamma_srgb( sourceB ) );
float r, g, b;
colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b );
// apply strength
sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength;
sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength;
sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength;
// apply inverse gamma sRGB
sourceR = Color::igamma_srgb( sourceR );
sourceG = Color::igamma_srgb( sourceG );
sourceB = Color::igamma_srgb( sourceB );
if (!clutAndWorkingProfilesAreSame) {
//convert from clut to working profile
float x, y, z;
Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz );
Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work );
}
}
}
}
//black and white //black and white
if(blackwhite) { if(blackwhite) {
if (hasToneCurvebw1) { if (hasToneCurvebw1) {
@ -4405,6 +4337,50 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
} }
} }
//Film Simulations
if ( colorLUT ) {
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
float &sourceR = rtemp[ti * TS + tj];
float &sourceG = gtemp[ti * TS + tj];
float &sourceB = btemp[ti * TS + tj];
if (!clutAndWorkingProfilesAreSame) {
//convert from working to clut profile
float x, y, z;
Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz );
Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut );
}
//appply gamma sRGB (default RT)
sourceR = CLIP<float>( Color::gamma_srgb( sourceR ) );
sourceG = CLIP<float>( Color::gamma_srgb( sourceG ) );
sourceB = CLIP<float>( Color::gamma_srgb( sourceB ) );
float r, g, b;
colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b );
// apply strength
sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength;
sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength;
sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength;
// apply inverse gamma sRGB
sourceR = Color::igamma_srgb( sourceR );
sourceG = Color::igamma_srgb( sourceG );
sourceB = Color::igamma_srgb( sourceB );
if (!clutAndWorkingProfilesAreSame) {
//convert from clut to working profile
float x, y, z;
Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz );
Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work );
}
}
}
}
if(!blackwhite) { if(!blackwhite) {
// ready, fill lab // ready, fill lab
for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int i = istart, ti = 0; i < tH; i++, ti++) {
@ -4429,9 +4405,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
float fx, fy, fz; float fx, fy, fz;
fx = (x < 65535.0f ? cachef[std::max(x, 0.f)] : (327.68f * float(exp(log(x / MAXVALF) / 3.0f )))); fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? cachef[std::max(y, 0.f)] : (327.68f * float(exp(log(y / MAXVALF) / 3.0f )))); fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
fz = (z < 65535.0f ? cachef[std::max(z, 0.f)] : (327.68f * float(exp(log(z / MAXVALF) / 3.0f )))); fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF));
lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68;
lab->a[i][j] = (500.0f * (fx - fy) ); lab->a[i][j] = (500.0f * (fx - fy) );
@ -4879,9 +4855,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
float fx, fy, fz; float fx, fy, fz;
fx = (x < 65535.0f ? cachef[std::max(x, 0.f)] : (327.68f * float(exp(log(x / MAXVALF) / 3.0f )))); fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? cachef[std::max(y, 0.f)] : (327.68f * float(exp(log(y / MAXVALF) / 3.0f )))); fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
fz = (z < 65535.0f ? cachef[std::max(z, 0.f)] : (327.68f * float(exp(log(z / MAXVALF) / 3.0f )))); fz = (z < 65535.0f ? Color::cachef[std::max(z, 0.f)] : 327.68f * std::cbrt(z / MAXVALF));
lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68;
lab->a[i][j] = (500.0f * (fx - fy) ); lab->a[i][j] = (500.0f * (fx - fy) );
@ -6483,7 +6459,6 @@ void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, fl
void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale)
{ {
if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) { if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) {
float b_l = static_cast<float>(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float b_l = static_cast<float>(params->dirpyrequalizer.hueskin.value[0]) / 100.0f;
float t_l = static_cast<float>(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; float t_l = static_cast<float>(params->dirpyrequalizer.hueskin.value[1]) / 100.0f;
@ -7091,8 +7066,79 @@ double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_si
} }
} }
void ImProcFunctions::rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace)
{
TMatrix wprof = iccStore->workingSpaceMatrix( workingSpace );
const float wp[3][3] = {
{static_cast<float>(wprof[0][0]), static_cast<float>(wprof[0][1]), static_cast<float>(wprof[0][2])},
{static_cast<float>(wprof[1][0]), static_cast<float>(wprof[1][1]), static_cast<float>(wprof[1][2])},
{static_cast<float>(wprof[2][0]), static_cast<float>(wprof[2][1]), static_cast<float>(wprof[2][2])}
};
const int W = src.getWidth();
const int H = src.getHeight();
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
#endif
for(int i = 0; i < H; i++) {
for(int j = 0; j < W; j++) {
float X, Y, Z;
Color::rgbxyz(src.r(i, j), src.g(i, j), src.b(i, j), X, Y, Z, wp);
//convert Lab
Color::XYZ2Lab(X, Y, Z, dst.L[i][j], dst.a[i][j], dst.b[i][j]);
}
}
}
SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace)
{
TMatrix wiprof = iccStore->workingSpaceInverseMatrix( workingSpace );
const float wip[3][3] = {
{static_cast<float>(wiprof[0][0]), static_cast<float>(wiprof[0][1]), static_cast<float>(wiprof[0][2])},
{static_cast<float>(wiprof[1][0]), static_cast<float>(wiprof[1][1]), static_cast<float>(wiprof[1][2])},
{static_cast<float>(wiprof[2][0]), static_cast<float>(wiprof[2][1]), static_cast<float>(wiprof[2][2])}
};
const int W = dst.getWidth();
const int H = dst.getHeight();
#ifdef __SSE2__
vfloat wipv[3][3];
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
wipv[i][j] = F2V(wiprof[i][j]);
}
}
#endif
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
#endif
for(int i = 0; i < H; i++) {
int j = 0;
#ifdef __SSE2__
for(; j < W - 3; j += 4) {
vfloat X, Y, Z;
vfloat R,G,B;
Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z);
Color::xyz2rgb(X, Y, Z, R, G, B, wipv);
STVFU(dst.r(i, j), R);
STVFU(dst.g(i, j), G);
STVFU(dst.b(i, j), B);
}
#endif
for(; j < W; j++) {
float X, Y, Z;
Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z);
Color::xyz2rgb(X, Y, Z, dst.r(i, j), dst.g(i, j), dst.b(i, j), wip);
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
} }
#undef PIX_SORT
#undef med3x3

View File

@ -57,7 +57,6 @@ using namespace procparams;
class ImProcFunctions class ImProcFunctions
{ {
static LUTf gamma2curve;
cmsHTRANSFORM monitorTransform; cmsHTRANSFORM monitorTransform;
cmsHTRANSFORM lab2outputTransform; cmsHTRANSFORM lab2outputTransform;
@ -201,7 +200,6 @@ class ImProcFunctions
public: public:
static LUTf cachef;
double lumimul[3]; double lumimul[3];
// float chau; // float chau;
// float chred; // float chred;
@ -221,8 +219,6 @@ public:
// float maxblueresid;//used by noise_residual // float maxblueresid;//used by noise_residual
// int comptlevel; // int comptlevel;
static void initCache ();
static void cleanupCache ();
ImProcFunctions (const ProcParams* iparams, bool imultiThread = true) ImProcFunctions (const ProcParams* iparams, bool imultiThread = true)
: monitorTransform(NULL), lab2outputTransform(NULL), output2monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {} : monitorTransform(NULL), lab2outputTransform(NULL), output2monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {}
@ -286,6 +282,7 @@ public:
void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise
void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet
void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0);
float *CompressDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed); float *CompressDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed);
void ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params &cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx); void ContrastResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params &cp, int W_L, int H_L, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx);
@ -383,6 +380,8 @@ public:
static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh);
static double getAutoDistor (const Glib::ustring& fname, int thumb_size); static double getAutoDistor (const Glib::ustring& fname, int thumb_size);
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL); double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL);
void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace);
void lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace);
}; };
} }
#endif #endif

View File

@ -39,11 +39,9 @@ MyMutex* lcmsMutex = NULL;
int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir) int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir)
{ {
settings = s; settings = s;
iccStore->init (s->iccDirectory, baseDir + "/iccprofiles"); iccStore->init (s->iccDirectory, baseDir + "/iccprofiles");
iccStore->findDefaultMonitorProfile(); iccStore->findDefaultMonitorProfile();
dcpStore->init (baseDir + "/dcpprofiles"); dcpStore->init (baseDir + "/dcpprofiles");
CameraConstantsStore::getInstance ()->init (baseDir, userSettingsDir); CameraConstantsStore::getInstance ()->init (baseDir, userSettingsDir);
@ -52,8 +50,6 @@ int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDi
Color::init (); Color::init ();
PerceptualToneCurve::init (); PerceptualToneCurve::init ();
RawImageSource::init (); RawImageSource::init ();
ImProcFunctions::initCache ();
Thumbnail::initGamma ();
delete lcmsMutex; delete lcmsMutex;
lcmsMutex = new MyMutex; lcmsMutex = new MyMutex;
dfm.init( s->darkFramesPath ); dfm.init( s->darkFramesPath );
@ -66,8 +62,6 @@ void cleanup ()
ProcParams::cleanup (); ProcParams::cleanup ();
Color::cleanup (); Color::cleanup ();
ImProcFunctions::cleanupCache ();
Thumbnail::cleanupGamma ();
RawImageSource::cleanup (); RawImageSource::cleanup ();
} }

View File

@ -117,9 +117,9 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
/* copy RGB */ /* copy RGB */
//int R1=((int)gamma2curve[(R)]) //int R1=((int)gamma2curve[(R)])
data[ix++] = ((int)gamma2curve[CLIP(R)]) >> 8; data[ix++] = ((int)Color::gamma2curve[CLIP(R)]) >> 8;
data[ix++] = ((int)gamma2curve[CLIP(G)]) >> 8; data[ix++] = ((int)Color::gamma2curve[CLIP(G)]) >> 8;
data[ix++] = ((int)gamma2curve[CLIP(B)]) >> 8; data[ix++] = ((int)Color::gamma2curve[CLIP(B)]) >> 8;
} }
} }
} }
@ -229,9 +229,9 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch,
Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyz); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyz);
image->data[ix++] = (int)gamma2curve[CLIP(R)] >> 8; image->data[ix++] = (int)Color::gamma2curve[CLIP(R)] >> 8;
image->data[ix++] = (int)gamma2curve[CLIP(G)] >> 8; image->data[ix++] = (int)Color::gamma2curve[CLIP(G)] >> 8;
image->data[ix++] = (int)gamma2curve[CLIP(B)] >> 8; image->data[ix++] = (int)Color::gamma2curve[CLIP(B)] >> 8;
} }
} }
} }
@ -331,9 +331,9 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int
Color::xyz2srgb(x_, y_, z_, R, G, B); Color::xyz2srgb(x_, y_, z_, R, G, B);
image->r(i - cy, j - cx) = (int)gamma2curve[CLIP(R)]; image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)gamma2curve[CLIP(G)]; image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
image->b(i - cy, j - cx) = (int)gamma2curve[CLIP(B)]; image->b(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(B)];
} }
} }
} }
@ -601,9 +601,9 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int
Color::xyz2srgb(x_, y_, z_, R, G, B); Color::xyz2srgb(x_, y_, z_, R, G, B);
image->r(i - cy, j - cx) = (int)gamma2curve[CLIP(R)]; image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)gamma2curve[CLIP(G)]; image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
image->b(i - cy, j - cx) = (int)gamma2curve[CLIP(B)]; image->b(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(B)];
} }
} }
} }

View File

@ -45,7 +45,7 @@
#include "rawimagesource.h" #include "rawimagesource.h"
#include "improcfun.h" #include "improcfun.h"
#include "opthelper.h" #include "opthelper.h"
#define BENCHMARK //#define BENCHMARK
#include "StopWatch.h" #include "StopWatch.h"
#define MAX_RETINEX_SCALES 8 #define MAX_RETINEX_SCALES 8

View File

@ -19,7 +19,6 @@
#include <cstring> #include <cstring>
#include "lcp.h" #include "lcp.h"
#include "safegtk.h"
#include "iccmatrices.h" #include "iccmatrices.h"
#include "iccstore.h" #include "iccstore.h"
#include "rawimagesource.h" #include "rawimagesource.h"
@ -303,7 +302,7 @@ LCPProfile::LCPProfile(Glib::ustring fname)
persModelCount = 0; persModelCount = 0;
*inInvalidTag = 0; *inInvalidTag = 0;
FILE *pFile = safe_g_fopen(fname, "rb"); FILE *pFile = g_fopen(fname.c_str (), "rb");
bool done; bool done;
@ -807,7 +806,7 @@ LCPProfile* LCPStore::getProfile (Glib::ustring filename)
bool LCPStore::isValidLCPFileName(Glib::ustring filename) const bool LCPStore::isValidLCPFileName(Glib::ustring filename) const
{ {
if (!safe_file_test (filename, Glib::FILE_TEST_EXISTS) || safe_file_test (filename, Glib::FILE_TEST_IS_DIR)) { if (!Glib::file_test (filename, Glib::FILE_TEST_EXISTS) || Glib::file_test (filename, Glib::FILE_TEST_IS_DIR)) {
return false; return false;
} }
@ -828,7 +827,7 @@ Glib::ustring LCPStore::getDefaultCommonDirectory() const
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0); WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
Glib::ustring fullDir = Glib::ustring(pathA) + Glib::ustring("\\Adobe\\CameraRaw\\LensProfiles\\1.0"); Glib::ustring fullDir = Glib::ustring(pathA) + Glib::ustring("\\Adobe\\CameraRaw\\LensProfiles\\1.0");
if (safe_file_test(fullDir, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (fullDir, Glib::FILE_TEST_IS_DIR)) {
dir = fullDir; dir = fullDir;
} }
} }

View File

@ -19,7 +19,6 @@
#include "myfile.h" #include "myfile.h"
#include <cstdarg> #include <cstdarg>
#include <glibmm.h> #include <glibmm.h>
#include "safegtk.h"
#ifdef BZIP_SUPPORT #ifdef BZIP_SUPPORT
#include <bzlib.h> #include <bzlib.h>
#endif #endif
@ -58,6 +57,7 @@ int munmap(void *start, size_t length)
#else // WIN32 #else // WIN32
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -68,7 +68,25 @@ int munmap(void *start, size_t length)
IMFILE* fopen (const char* fname) IMFILE* fopen (const char* fname)
{ {
int fd = safe_open_ReadOnly(fname); int fd = -1;
#ifdef WIN32
{
// First convert UTF8 to UTF16, then use Windows function to open the file and convert back to file descriptor.
std::unique_ptr<wchar_t, GFreeFunc> wfname (reinterpret_cast<wchar_t*>(g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL)), g_free);
HANDLE hFile = CreateFileW (wfname.get (), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
fd = _open_osfhandle((intptr_t)hFile, 0);
}
}
#else
fd = ::g_open (fname, O_RDONLY);
#endif
if ( fd < 0 ) { if ( fd < 0 ) {
return 0; return 0;
@ -78,7 +96,7 @@ IMFILE* fopen (const char* fname)
if ( fstat(fd, &stat_buffer) < 0 ) { if ( fstat(fd, &stat_buffer) < 0 ) {
printf("no stat\n"); printf("no stat\n");
close(fd); close (fd);
return 0; return 0;
} }

View File

@ -23,8 +23,6 @@
#include "iimage.h" #include "iimage.h"
#include "rtthumbnail.h" #include "rtthumbnail.h"
#include "rawimagesource.h" #include "rawimagesource.h"
#include "StopWatch.h"
#include "utils.h"
using namespace rtengine; using namespace rtengine;
using namespace procparams; using namespace procparams;
@ -135,9 +133,7 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext
rawImage.getImage (wb, TR_NONE, image, pp, params.toneCurve, params.icm, params.raw); rawImage.getImage (wb, TR_NONE, image, pp, params.toneCurve, params.icm, params.raw);
output = new Image8(fw, fh); output = new Image8(fw, fh);
rawImage.convertColorSpace(image, params.icm, wb); rawImage.convertColorSpace(image, params.icm, wb);
StopWatch Stop1("inspector loop");
#pragma omp parallel for schedule(dynamic, 10) #pragma omp parallel for schedule(dynamic, 10)
for (int i = 0; i < fh; ++i) for (int i = 0; i < fh; ++i)
for (int j = 0; j < fw; ++j) { for (int j = 0; j < fw; ++j) {
image->r(i, j) = Color::gamma2curve[image->r(i, j)]; image->r(i, j) = Color::gamma2curve[image->r(i, j)];
@ -145,7 +141,6 @@ PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext
image->b(i, j) = Color::gamma2curve[image->b(i, j)]; image->b(i, j) = Color::gamma2curve[image->b(i, j)];
} }
Stop1.stop();
image->resizeImgTo<Image8>(fw, fh, TI_Nearest, output); image->resizeImgTo<Image8>(fw, fh, TI_Nearest, output);
data = output->getData(); data = output->getData();

View File

@ -466,7 +466,9 @@ enum ProcEvent {
EvmapMethod = 436, EvmapMethod = 436,
EvRetinexmapcurve = 437, EvRetinexmapcurve = 437,
EvviewMethod = 438, EvviewMethod = 438,
EvcbdlMethod = 439,
NUMOFEVENTS NUMOFEVENTS
}; };
} }
#endif #endif

View File

@ -16,11 +16,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
//#include <glib/gstdio.h> #include <glib/gstdio.h>
#include "procparams.h" #include "procparams.h"
#include "rt_math.h" #include "rt_math.h"
#include "safegtk.h"
#include "safekeyfile.h"
#include "dcp.h" #include "dcp.h"
#include "../rtgui/multilangmgr.h" #include "../rtgui/multilangmgr.h"
#include "../rtgui/version.h" #include "../rtgui/version.h"
@ -890,6 +888,7 @@ void RAWParams::setDefaults()
ff_clipControl = 0; ff_clipControl = 0;
cared = 0; cared = 0;
cablue = 0; cablue = 0;
caautostrength = 6;
ca_autocorrect = false; ca_autocorrect = false;
hotPixelFilter = false; hotPixelFilter = false;
deadPixelFilter = false; deadPixelFilter = false;
@ -1219,6 +1218,8 @@ void ProcParams::setDefaults ()
dirpyrequalizer.enabled = false; dirpyrequalizer.enabled = false;
dirpyrequalizer.gamutlab = false; dirpyrequalizer.gamutlab = false;
dirpyrequalizer.cbdlMethod = "bef";
for(int i = 0; i < 6; i ++) { for(int i = 0; i < 6; i ++) {
dirpyrequalizer.mult[i] = 1.0; dirpyrequalizer.mult[i] = 1.0;
@ -1303,11 +1304,15 @@ static Glib::ustring relativePathIfInside(Glib::ustring procparams_fname, bool f
int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsolute, ParamsEdited* pedited) int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsolute, ParamsEdited* pedited)
{ {
if (!fname.length() && !fname2.length()) { if (fname.empty () && fname2.empty ()) {
return 0; return 0;
} }
SafeKeyFile keyFile; Glib::ustring sPParams;
try {
Glib::KeyFile keyFile;
keyFile.set_string ("Version", "AppVersion", APPVERSION); keyFile.set_string ("Version", "AppVersion", APPVERSION);
keyFile.set_integer ("Version", "Version", PPVERSION); keyFile.set_integer ("Version", "Version", PPVERSION);
@ -3028,6 +3033,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab); keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab);
} }
if (!pedited || pedited->dirpyrequalizer.cbdlMethod) {
keyFile.set_string ("Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod);
}
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
std::stringstream ss; std::stringstream ss;
ss << "Mult" << i; ss << "Mult" << i;
@ -3248,6 +3257,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect );
} }
if (!pedited || pedited->raw.caAutoStrength) {
keyFile.set_double ("RAW", "CAAutoStrength", raw.caautostrength );
}
if (!pedited || pedited->raw.caRed) { if (!pedited || pedited->raw.caRed) {
keyFile.set_double ("RAW", "CARed", raw.cared ); keyFile.set_double ("RAW", "CARed", raw.cared );
} }
@ -3363,12 +3376,18 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
} }
} }
Glib::ustring sPParams = keyFile.to_data(); sPParams = keyFile.to_data();
} catch(Glib::KeyFileError&) {}
if (sPParams.empty ()) {
return 1;
}
int error1, error2; int error1, error2;
error1 = write (fname , sPParams); error1 = write (fname, sPParams);
if (fname2.length()) { if (!fname2.empty ()) {
error2 = write (fname2, sPParams); error2 = write (fname2, sPParams);
// If at least one file has been saved, it's a success // If at least one file has been saved, it's a success
@ -3385,7 +3404,7 @@ int ProcParams::write (Glib::ustring &fname, Glib::ustring &content) const
if (fname.length()) { if (fname.length()) {
FILE *f; FILE *f;
f = safe_g_fopen (fname, "wt"); f = g_fopen (fname.c_str (), "wt");
if (f == NULL) { if (f == NULL) {
error = 1; error = 1;
@ -3406,15 +3425,15 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
return 1; return 1;
} }
SafeKeyFile keyFile; Glib::KeyFile keyFile;
try { try {
//setDefaults ();
if (pedited) { if (pedited) {
pedited->set(false); pedited->set(false);
} }
FILE* f = safe_g_fopen (fname, "rt"); FILE* f = g_fopen (fname.c_str (), "rt");
if (!f) { if (!f) {
return 1; return 1;
@ -3450,8 +3469,6 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
} }
} }
//printf("ProcParams::load called ppVersion=%i\n",ppVersion);
if (keyFile.has_group ("General")) { if (keyFile.has_group ("General")) {
if (keyFile.has_key ("General", "Rank")) { if (keyFile.has_key ("General", "Rank")) {
rank = keyFile.get_integer ("General", "Rank"); rank = keyFile.get_integer ("General", "Rank");
@ -6610,6 +6627,16 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
} }
} }
if (keyFile.has_key ("Directional Pyramid Equalizer", "cbdlMethod")) {
dirpyrequalizer.cbdlMethod = keyFile.get_string ("Directional Pyramid Equalizer", "cbdlMethod");
if (pedited) {
pedited->dirpyrequalizer.cbdlMethod = true;
}
}
// if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; } // if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; }
if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) { if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) {
Glib::ArrayHandle<int> thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin"); Glib::ArrayHandle<int> thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin");
@ -7058,6 +7085,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
} }
} }
if (keyFile.has_key ("RAW", "CAAutoStrength")) {
raw.caautostrength = keyFile.get_double ("RAW", "CAAutoStrength" );
if (pedited) {
pedited->raw.caAutoStrength = true;
}
}
if (keyFile.has_key ("RAW", "CARed")) { if (keyFile.has_key ("RAW", "CARed")) {
raw.cared = keyFile.get_double ("RAW", "CARed" ); raw.cared = keyFile.get_double ("RAW", "CARed" );
@ -7427,9 +7462,11 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
return 0; return 0;
} catch (const Glib::Error& e) { } catch (const Glib::Error& e) {
printf ("-->%s\n", e.what().c_str()); printf ("-->%s\n", e.what().c_str());
setDefaults ();
return 1; return 1;
} catch (...) { } catch (...) {
printf ("-->unknown exception!\n"); printf ("-->unknown exception!\n");
setDefaults ();
return 1; return 1;
} }
@ -7777,6 +7814,7 @@ bool ProcParams::operator== (const ProcParams& other)
&& raw.expos == other.raw.expos && raw.expos == other.raw.expos
&& raw.preser == other.raw.preser && raw.preser == other.raw.preser
&& raw.ca_autocorrect == other.raw.ca_autocorrect && raw.ca_autocorrect == other.raw.ca_autocorrect
&& raw.caautostrength == other.raw.caautostrength
&& raw.cared == other.raw.cared && raw.cared == other.raw.cared
&& raw.cablue == other.raw.cablue && raw.cablue == other.raw.cablue
&& raw.hotPixelFilter == other.raw.hotPixelFilter && raw.hotPixelFilter == other.raw.hotPixelFilter
@ -7880,6 +7918,7 @@ bool ProcParams::operator== (const ProcParams& other)
// && dirpyrequalizer.algo == other.dirpyrequalizer.algo // && dirpyrequalizer.algo == other.dirpyrequalizer.algo
&& dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin && dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin
&& dirpyrequalizer.threshold == other.dirpyrequalizer.threshold && dirpyrequalizer.threshold == other.dirpyrequalizer.threshold
&& dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod
&& dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect && dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect
&& hsvequalizer.hcurve == other.hsvequalizer.hcurve && hsvequalizer.hcurve == other.hsvequalizer.hcurve
&& hsvequalizer.scurve == other.hsvequalizer.scurve && hsvequalizer.scurve == other.hsvequalizer.scurve

View File

@ -1106,7 +1106,7 @@ public:
double skinprotect; double skinprotect;
Threshold<int> hueskin; Threshold<int> hueskin;
//Glib::ustring algo; //Glib::ustring algo;
Glib::ustring cbdlMethod;
DirPyrEqualizerParams() : hueskin(20, 80, 2000, 1200, false) {}; DirPyrEqualizerParams() : hueskin(20, 80, 2000, 1200, false) {};
}; };
@ -1218,6 +1218,7 @@ public:
int ff_clipControl; int ff_clipControl;
bool ca_autocorrect; bool ca_autocorrect;
double caautostrength;
double cared; double cared;
double cablue; double cablue;

View File

@ -13,7 +13,6 @@
#else #else
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
#include "safegtk.h"
namespace rtengine namespace rtengine
{ {

View File

@ -1422,6 +1422,7 @@ SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thres
} }
#else #else
// 25 fabs function calls and 25 float additions without SSE // 25 fabs function calls and 25 float additions without SSE
for (int mm = rr - 2; mm <= rr + 2; mm++) { for (int mm = rr - 2; mm <= rr + 2; mm++) {
for (int nn = cc - 2; nn <= cc + 2; nn++) { for (int nn = cc - 2; nn <= cc + 2; nn++) {
@ -1865,7 +1866,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
plistener->setProgress (0.0); plistener->setProgress (0.0);
} }
CA_correct_RT(raw.cared, raw.cablue); CA_correct_RT(raw.cared, raw.cablue, 10.0 - raw.caautostrength);
} }
if ( raw.expos != 1 ) { if ( raw.expos != 1 ) {
@ -4209,14 +4210,14 @@ void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, floa
float go = min(g, maxval); float go = min(g, maxval);
float bo = min(b, maxval); float bo = min(b, maxval);
float yy = xyz_cam[1][0] * r + xyz_cam[1][1] * g + xyz_cam[1][2] * b; float yy = xyz_cam[1][0] * r + xyz_cam[1][1] * g + xyz_cam[1][2] * b;
float fy = (yy < 65535.0 ? ImProcFunctions::cachef[yy] / 327.68 : (exp(log(yy / MAXVALD) / 3.0 ))); float fy = (yy < 65535.0 ? Color::cachef[yy] / 327.68 : std::cbrt(yy / MAXVALD));
// compute LCH decompostion of the clipped pixel (only color information, thus C and H will be used) // compute LCH decompostion of the clipped pixel (only color information, thus C and H will be used)
float x = xyz_cam[0][0] * ro + xyz_cam[0][1] * go + xyz_cam[0][2] * bo; float x = xyz_cam[0][0] * ro + xyz_cam[0][1] * go + xyz_cam[0][2] * bo;
float y = xyz_cam[1][0] * ro + xyz_cam[1][1] * go + xyz_cam[1][2] * bo; float y = xyz_cam[1][0] * ro + xyz_cam[1][1] * go + xyz_cam[1][2] * bo;
float z = xyz_cam[2][0] * ro + xyz_cam[2][1] * go + xyz_cam[2][2] * bo; float z = xyz_cam[2][0] * ro + xyz_cam[2][1] * go + xyz_cam[2][2] * bo;
x = (x < 65535.0 ? ImProcFunctions::cachef[x] / 327.68 : (exp(log(x / MAXVALD) / 3.0 ))); x = (x < 65535.0 ? Color::cachef[x] / 327.68 : std::cbrt(x / MAXVALD));
y = (y < 65535.0 ? ImProcFunctions::cachef[y] / 327.68 : (exp(log(y / MAXVALD) / 3.0 ))); y = (y < 65535.0 ? Color::cachef[y] / 327.68 : std::cbrt(y / MAXVALD));
z = (z < 65535.0 ? ImProcFunctions::cachef[z] / 327.68 : (exp(log(z / MAXVALD) / 3.0 ))); z = (z < 65535.0 ? Color::cachef[z] / 327.68 : std::cbrt(z / MAXVALD));
// convert back to rgb // convert back to rgb
double fz = fy - y + z; double fz = fy - y + z;
double fx = fy + x - y; double fx = fy + x - y;

View File

@ -215,8 +215,7 @@ protected:
inline void interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i); inline void interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i);
inline void interpolate_row_rb_mul_pp (float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip); inline void interpolate_row_rb_mul_pp (float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip);
int LinEqSolve( int nDim, double* pfMatr, double* pfVect, double* pfSolution);//Emil's CA auto correction void CA_correct_RT (const double cared, const double cablue, const double caautostrength);
void CA_correct_RT (double cared, double cablue);
void ddct8x8s(int isgn, float a[8][8]); void ddct8x8s(int isgn, float a[8][8]);
void processRawWhitepoint (float expos, float preser); // exposure before interpolation void processRawWhitepoint (float expos, float preser); // exposure before interpolation

View File

@ -119,8 +119,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
ALLNORAW, // EvDPDNLuma, ALLNORAW, // EvDPDNLuma,
ALLNORAW, // EvDPDNChroma, ALLNORAW, // EvDPDNChroma,
ALLNORAW, // EvDPDNGamma, ALLNORAW, // EvDPDNGamma,
DIRPYREQUALIZER, // EvDirPyrEqualizer, ALLNORAW, // EvDirPyrEqualizer,
DIRPYREQUALIZER, // EvDirPyrEqlEnabled, ALLNORAW, // EvDirPyrEqlEnabled,
LUMINANCECURVE, // EvLSaturation, LUMINANCECURVE, // EvLSaturation,
LUMINANCECURVE, // EvLaCurve, LUMINANCECURVE, // EvLaCurve,
LUMINANCECURVE, // EvLbCurve, LUMINANCECURVE, // EvLbCurve,
@ -200,7 +200,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // EvLLCCurve LUMINANCECURVE, // EvLLCCurve
LUMINANCECURVE, // EvLLCredsk LUMINANCECURVE, // EvLLCredsk
ALLNORAW, // EvDPDNLdetail ALLNORAW, // EvDPDNLdetail
LUMINANCECURVE, // EvCATEnabled ALLNORAW, // EvCATEnabled
LUMINANCECURVE, // EvCATDegree LUMINANCECURVE, // EvCATDegree
LUMINANCECURVE, // EvCATMethodsur LUMINANCECURVE, // EvCATMethodsur
LUMINANCECURVE, // EvCATAdapscen LUMINANCECURVE, // EvCATAdapscen
@ -275,12 +275,12 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, // EvLCLCurve LUMINANCECURVE, // EvLCLCurve
LUMINANCECURVE, // EvLLHCurve LUMINANCECURVE, // EvLLHCurve
LUMINANCECURVE, // EvLHHCurve LUMINANCECURVE, // EvLHHCurve
DIRPYREQUALIZER, // EvDirPyrEqualizerThreshold ALLNORAW, // EvDirPyrEqualizerThreshold
ALLNORAW, // EvDPDNenhance ALLNORAW, // EvDPDNenhance
RGBCURVE, // EvBWMethodalg RGBCURVE, // EvBWMethodalg
DIRPYREQUALIZER, // EvDirPyrEqualizerSkin ALLNORAW, // EvDirPyrEqualizerSkin
DIRPYREQUALIZER, // EvDirPyrEqlgamutlab ALLNORAW, // EvDirPyrEqlgamutlab
DIRPYREQUALIZER, // EvDirPyrEqualizerHueskin ALLNORAW, // EvDirPyrEqualizerHueskin
ALLNORAW, // EvDPDNmedian ALLNORAW, // EvDPDNmedian
ALLNORAW, // EvDPDNmedmet ALLNORAW, // EvDPDNmedmet
RGBCURVE, // EvColorToningEnabled RGBCURVE, // EvColorToningEnabled
@ -465,6 +465,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
RETINEX, // EvLradius RETINEX, // EvLradius
RETINEX, // EvmapMethod RETINEX, // EvmapMethod
DEMOSAIC, // EvRetinexmapcurve DEMOSAIC, // EvRetinexmapcurve
DEMOSAIC // EvviewMethod DEMOSAIC, // EvviewMethod
ALLNORAW // EvcbdlMethod
}; };

View File

@ -33,8 +33,6 @@
#include "stdimagesource.h" #include "stdimagesource.h"
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <csetjmp> #include <csetjmp>
#include "safekeyfile.h"
#include "safegtk.h"
#include "rawimage.h" #include "rawimage.h"
#include "jpeg.h" #include "jpeg.h"
#include "../rtgui/ppversion.h" #include "../rtgui/ppversion.h"
@ -720,30 +718,6 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
#undef FISGREEN #undef FISGREEN
#undef FISBLUE #undef FISBLUE
unsigned short *Thumbnail::igammatab = 0;
unsigned char *Thumbnail::gammatab = 0;
void Thumbnail::initGamma ()
{
igammatab = new unsigned short[256];
gammatab = new unsigned char[65536];
for (int i = 0; i < 256; i++) {
igammatab[i] = (unsigned short)(255.0 * pow((double)i / 255.0, Color::sRGBGamma));
}
for (int i = 0; i < 65536; i++) {
gammatab[i] = (unsigned char)(255.0 * pow((double)i / 65535.0, 1.f / Color::sRGBGamma));
}
}
void Thumbnail::cleanupGamma ()
{
delete [] igammatab;
delete [] gammatab;
}
void Thumbnail::init () void Thumbnail::init ()
{ {
@ -1456,9 +1430,9 @@ unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width)
image->convertTo(image->r(i, j), r_); image->convertTo(image->r(i, j), r_);
image->convertTo(image->g(i, j), g_); image->convertTo(image->g(i, j), g_);
image->convertTo(image->b(i, j), b_); image->convertTo(image->b(i, j), b_);
int r = gammatab[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int r = Color::gammatabThumb[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = gammatab[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int g = Color::gammatabThumb[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int b = gammatab[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int b = Color::gammatabThumb[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
tmpdata[ix++] = (r * 19595 + g * 38469 + b * 7472) >> 16; tmpdata[ix++] = (r * 19595 + g * 38469 + b * 7472) >> 16;
} }
} else if (thumbImg->getType() == sImage16) { } else if (thumbImg->getType() == sImage16) {
@ -1470,9 +1444,9 @@ unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width)
image->convertTo(image->r(i, j), r_); image->convertTo(image->r(i, j), r_);
image->convertTo(image->g(i, j), g_); image->convertTo(image->g(i, j), g_);
image->convertTo(image->b(i, j), b_); image->convertTo(image->b(i, j), b_);
int r = gammatab[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int r = Color::gammatabThumb[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = gammatab[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int g = Color::gammatabThumb[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int b = gammatab[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int b = Color::gammatabThumb[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
tmpdata[ix++] = (r * 19595 + g * 38469 + b * 7472) >> 16; tmpdata[ix++] = (r * 19595 + g * 38469 + b * 7472) >> 16;
} }
} else if (thumbImg->getType() == sImagefloat) { } else if (thumbImg->getType() == sImagefloat) {
@ -1484,9 +1458,9 @@ unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width)
image->convertTo(image->r(i, j), r_); image->convertTo(image->r(i, j), r_);
image->convertTo(image->g(i, j), g_); image->convertTo(image->g(i, j), g_);
image->convertTo(image->b(i, j), b_); image->convertTo(image->b(i, j), b_);
int r = gammatab[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int r = Color::gammatabThumb[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = gammatab[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int g = Color::gammatabThumb[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int b = gammatab[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13]; int b = Color::gammatabThumb[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
tmpdata[ix++] = (r * 19595 + g * 38469 + b * 7472) >> 16; tmpdata[ix++] = (r * 19595 + g * 38469 + b * 7472) >> 16;
} }
} }
@ -1653,7 +1627,7 @@ bool Thumbnail::writeImage (const Glib::ustring& fname, int format)
Glib::ustring fullFName = fname + ".rtti"; Glib::ustring fullFName = fname + ".rtti";
FILE* f = safe_g_fopen (fullFName, "wb"); FILE* f = g_fopen (fullFName.c_str (), "wb");
if (!f) { if (!f) {
return false; return false;
@ -1692,11 +1666,11 @@ bool Thumbnail::readImage (const Glib::ustring& fname)
Glib::ustring fullFName = fname + ".rtti"; Glib::ustring fullFName = fname + ".rtti";
if (!safe_file_test (fullFName, Glib::FILE_TEST_EXISTS)) { if (!Glib::file_test (fullFName, Glib::FILE_TEST_EXISTS)) {
return false; return false;
} }
FILE* f = safe_g_fopen (fullFName, "rb"); FILE* f = g_fopen (fullFName.c_str (), "rb");
if (!f) { if (!f) {
return false; return false;
@ -1738,12 +1712,14 @@ bool Thumbnail::readImage (const Glib::ustring& fname)
bool Thumbnail::readData (const Glib::ustring& fname) bool Thumbnail::readData (const Glib::ustring& fname)
{ {
setlocale(LC_NUMERIC, "C"); // to set decimal point to "." setlocale(LC_NUMERIC, "C"); // to set decimal point to "."
SafeKeyFile keyFile; Glib::KeyFile keyFile;
try { try {
MyMutex::MyLock thmbLock(thumbMutex); MyMutex::MyLock thmbLock(thumbMutex);
if (!keyFile.load_from_file (fname)) { try {
keyFile.load_from_file (fname);
} catch (Glib::Error&) {
return false; return false;
} }
@ -1831,24 +1807,17 @@ bool Thumbnail::readData (const Glib::ustring& fname)
bool Thumbnail::writeData (const Glib::ustring& fname) bool Thumbnail::writeData (const Glib::ustring& fname)
{ {
SafeKeyFile keyFile;
MyMutex::MyLock thmbLock(thumbMutex); MyMutex::MyLock thmbLock(thumbMutex);
Glib::ustring keyData;
try {
Glib::KeyFile keyFile;
try { try {
if( safe_file_test(fname, Glib::FILE_TEST_EXISTS) ) {
keyFile.load_from_file (fname); keyFile.load_from_file (fname);
} } catch (Glib::Error&) {}
} catch (Glib::Error &err) {
if (options.rtSettings.verbose) {
printf("Thumbnail::writeData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
}
} catch (...) {
if (options.rtSettings.verbose) {
printf("Thumbnail::writeData / Unknown exception while trying to save \"%s\"!\n", fname.c_str());
}
}
keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed); keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed);
keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen); keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen);
@ -1867,7 +1836,23 @@ bool Thumbnail::writeData (const Glib::ustring& fname)
Glib::ArrayHandle<double> cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE); Glib::ArrayHandle<double> cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm); keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm);
FILE *f = safe_g_fopen (fname, "wt"); keyData = keyFile.to_data ();
} catch (Glib::Error& err) {
if (options.rtSettings.verbose) {
printf("Thumbnail::writeData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
}
} catch (...) {
if (options.rtSettings.verbose) {
printf("Thumbnail::writeData / Unknown exception while trying to save \"%s\"!\n", fname.c_str());
}
}
if (keyData.empty ()) {
return false;
}
FILE *f = g_fopen (fname.c_str (), "wt");
if (!f) { if (!f) {
if (options.rtSettings.verbose) { if (options.rtSettings.verbose) {
@ -1876,7 +1861,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname)
return false; return false;
} else { } else {
fprintf (f, "%s", keyFile.to_data().c_str()); fprintf (f, "%s", keyData.c_str ());
fclose (f); fclose (f);
} }
@ -1886,7 +1871,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname)
bool Thumbnail::readEmbProfile (const Glib::ustring& fname) bool Thumbnail::readEmbProfile (const Glib::ustring& fname)
{ {
FILE* f = safe_g_fopen (fname, "rb"); FILE* f = g_fopen (fname.c_str (), "rb");
if (!f) { if (!f) {
embProfileData = NULL; embProfileData = NULL;
@ -1910,7 +1895,7 @@ bool Thumbnail::writeEmbProfile (const Glib::ustring& fname)
{ {
if (embProfileData) { if (embProfileData) {
FILE* f = safe_g_fopen(fname, "wb"); FILE* f = g_fopen(fname.c_str (), "wb");
if (f) { if (f) {
fwrite (embProfileData, 1, embProfileLength, f); fwrite (embProfileData, 1, embProfileLength, f);
@ -1925,7 +1910,7 @@ bool Thumbnail::writeEmbProfile (const Glib::ustring& fname)
bool Thumbnail::readAEHistogram (const Glib::ustring& fname) bool Thumbnail::readAEHistogram (const Glib::ustring& fname)
{ {
FILE* f = safe_g_fopen (fname, "rb"); FILE* f = g_fopen (fname.c_str (), "rb");
if (!f) { if (!f) {
aeHistogram(0); aeHistogram(0);
@ -1943,7 +1928,7 @@ bool Thumbnail::writeAEHistogram (const Glib::ustring& fname)
{ {
if (aeHistogram) { if (aeHistogram) {
FILE* f = safe_g_fopen (fname, "wb"); FILE* f = g_fopen (fname.c_str (), "wb");
if (f) { if (f) {
fwrite (&aeHistogram[0], 1, (65536 >> aeHistCompression)*sizeof(aeHistogram[0]), f); fwrite (&aeHistogram[0], 1, (65536 >> aeHistCompression)*sizeof(aeHistogram[0]), f);

View File

@ -42,9 +42,6 @@ class Thumbnail
void transformPixel (int x, int y, int tran, int& tx, int& ty); void transformPixel (int x, int y, int tran, int& tx, int& ty);
static unsigned short *igammatab;
static unsigned char *gammatab;
ImageIO* thumbImg; ImageIO* thumbImg;
double camwbRed; double camwbRed;
double camwbGreen; double camwbGreen;
@ -72,8 +69,6 @@ public:
~Thumbnail (); ~Thumbnail ();
Thumbnail (); Thumbnail ();
static void initGamma ();
static void cleanupGamma ();
void init (); void init ();
IImage8* processImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp, std::string camName, IImage8* processImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp, std::string camName,

View File

@ -1,437 +0,0 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
* Copyright (c) 2010 Sasha Vasko <sasha@aftercode.net>
* Copyright (c) 2010 Oliver Duis <www.oliverduis.de>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "safegtk.h"
#include "../rtgui/guiutils.h"
#include <glib/gstdio.h>
#include <fcntl.h>
#ifdef WIN32
#include <windows.h>
// for GCC32
#ifndef _WIN32_IE
#define _WIN32_IE 0x0600
#endif
#include <shlobj.h>
#include <Shlwapi.h>
#else
#include <cstdio>
#endif
#include "../rtgui/rtimage.h"
#include <memory>
Glib::RefPtr<Gdk::Pixbuf> safe_create_from_file(const Glib::ustring& filename)
{
Glib::RefPtr<Gdk::Pixbuf> res;
Glib::ustring path = RTImage::findIconAbsolutePath(filename);
if (path.length()) {
try {
res = Gdk::Pixbuf::create_from_file (path);
} catch (Glib::Exception& ex) {
printf ("ERROR: (ustring) File \"%s\" not found.\n", ex.what().c_str());
}
}
return res;
}
Cairo::RefPtr<Cairo::ImageSurface> safe_create_from_png(const Glib::ustring& filename)
{
Cairo::RefPtr<Cairo::ImageSurface> res;
Glib::ustring path = RTImage::findIconAbsolutePath(filename);
if (path.length()) {
// files_test need a std::string which (as stated in its proto) but will only work if
// we use the Glib::ustring filename !?
try {
// create_from_png need a std::string converted from UTF8 with safe_locale_from_utf8
res = Cairo::ImageSurface::create_from_png (safe_locale_from_utf8(path));
} catch (...) {
printf("ERROR: (ustring) File \"%s\" not found.\n", path.c_str());
}
}
return res;
}
Glib::RefPtr<Gio::FileInfo> safe_query_file_info (Glib::RefPtr<Gio::File> &file)
{
Glib::RefPtr<Gio::FileInfo> info;
try {
info = file->query_info();
} catch (...) { }
return info;
}
Glib::RefPtr<Gio::FileInfo> safe_next_file (Glib::RefPtr<Gio::FileEnumerator> &dirList)
{
Glib::RefPtr<Gio::FileInfo> info;
bool retry;
Glib::ustring last_error = "";
do {
retry = false;
try {
info = dirList->next_file();
} catch (Glib::Exception& ex) {
printf ("%s\n", ex.what().c_str());
// API problem: not possible to differ between error looking at particular entry or
// general error scanning the directory. We do a hack by retrying and see if the
// error changes, if it does we can assume it's about the current filename and we
// should look at the next. More likely if a single file error is that the next
// retry is okay of course.
retry = (ex.what() != last_error);
last_error = ex.what();
}
} while (retry);
return info;
}
# define SAFE_ENUMERATOR_CODE_START(attributes) \
do{try { if ((dirList = dir->enumerate_children ((attributes)))) \
for (Glib::RefPtr<Gio::FileInfo> info = safe_next_file(dirList); info; info = safe_next_file(dirList)) {
# define SAFE_ENUMERATOR_CODE_END \
}} catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }}while(0)
/*
* safe_build_file_list can now filter out at the source all files that don't have the extensions specified (if provided)
*/
void safe_build_file_list (Glib::RefPtr<Gio::File> &dir, std::vector<Glib::ustring> &names, const Glib::ustring &directory, const std::vector<Glib::ustring> *extensions)
{
Glib::RefPtr<Gio::FileEnumerator> dirList;
if (dir) {
if (!extensions) {
SAFE_ENUMERATOR_CODE_START("standard::name")
names.push_back (Glib::build_filename (directory, info->get_name()));
SAFE_ENUMERATOR_CODE_END;
} else {
// convert extensions to lowercase in a new vector list
std::vector<Glib::ustring> lcExtensions;
for (unsigned int i = 0; i < extensions->size(); i++) {
lcExtensions.push_back ((*extensions)[i].lowercase());
}
SAFE_ENUMERATOR_CODE_START("standard::name")
// convert the current filename to lowercase in a new ustring
Glib::ustring fname = Glib::ustring(info->get_name()).lowercase();
size_t pos = fname.find_last_of('.');
if (pos < (fname.length() - 1)) {
// there is an extension to the filename
Glib::ustring lcFileExt = fname.substr(pos + 1).lowercase();
// look out if it has one of the retained extensions
for (size_t i = 0; i < lcExtensions.size(); i++) {
if (lcFileExt == lcExtensions[i]) {
names.push_back (Glib::build_filename (directory, info->get_name()));
break;
}
}
}
SAFE_ENUMERATOR_CODE_END;
}
}
}
void safe_build_subdir_list (Glib::RefPtr<Gio::File> &dir, std::vector<Glib::ustring> &subDirs, bool add_hidden)
{
Glib::RefPtr<Gio::FileEnumerator> dirList;
if (dir) {
// CD-ROMs with no drive inserted are reported, but do not exist, causing RT to crash
if (!safe_file_test(dir->get_path(), Glib::FILE_TEST_EXISTS)) {
return;
}
SAFE_ENUMERATOR_CODE_START("standard::name,standard::type,standard::is-hidden")
if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || add_hidden)) {
subDirs.push_back (info->get_name());
}
SAFE_ENUMERATOR_CODE_END;
}
}
/*
* For an unknown reason, Glib::filename_to_utf8 doesn't work on Windows, so we're using
* Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows
*/
Glib::ustring safe_filename_to_utf8 (const std::string& src)
{
Glib::ustring utf8_str;
#ifdef WIN32
try {
utf8_str = Glib::locale_to_utf8(src);
} catch (const Glib::Error& e) {
utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1", "?");
}
#else
utf8_str = Glib::filename_to_utf8(src);
#endif
return utf8_str;
}
Glib::ustring safe_locale_to_utf8 (const std::string& src)
{
Glib::ustring utf8_str;
try {
utf8_str = Glib::locale_to_utf8(src);
} catch (const Glib::Error& e) {
utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1", "?");
}
return utf8_str;
}
std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str)
{
std::string str;
try {
str = Glib::locale_from_utf8(utf8_str);
} catch (Glib::Error&) {}
return str;
}
bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8)
{
std::string cmd;
bool success = false;
try {
cmd = Glib::filename_from_utf8(cmd_utf8);
printf ("command line: %s\n", cmd.c_str());
Glib::spawn_command_line_async (cmd.c_str());
success = true;
} catch (Glib::Exception& ex) {
printf ("%s\n", ex.what().c_str());
}
return success;
}
bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8)
{
int exitStatus = -1;
try {
//cmd = Glib::filename_from_utf8(cmd_utf8);
printf ("command line: %s\n", cmd_utf8.c_str());
// if it crashes here on windows, make sure you have the GTK runtime files gspawn-win32-helper*.exe files in RT directory
Glib::spawn_command_line_sync (cmd_utf8, NULL, NULL, &exitStatus);
} catch (Glib::Exception& ex) {
printf ("%s\n", ex.what().c_str());
}
return (exitStatus == 0);
}
// Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking)
// (Important on Windows to prevent Explorer to crash RT when parallel scanning e.g. a currently written image file)
FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname)
{
FILE* f = NULL;
#ifdef WIN32
// g_fopen just uses _wfopen internally on Windows, does not lock access and has no options to set this
// so use a native function to work around this problem
wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL);
HANDLE hFile = CreateFileW(wFname, GENERIC_READ | GENERIC_WRITE, 0 /* no sharing allowed */, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
g_free(wFname);
if (hFile == INVALID_HANDLE_VALUE) {
f = NULL;
} else {
f = _fdopen( _open_osfhandle((intptr_t)hFile, 0) , "wb");
}
#else
f = safe_g_fopen(fname, "wb");
#endif
return f;
}
// Covers old UNIX ::open, which expects ANSI instead of UTF8 on Windows
int safe_open_ReadOnly(const char *fname)
{
int fd = -1;
#ifdef WIN32
// First convert UTF8 to UTF16, then use Windows function to open
wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL);
HANDLE hFile = CreateFileW(wFname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
g_free(wFname);
// convert back to old file descriptor format
if (hFile != INVALID_HANDLE_VALUE) {
fd = _open_osfhandle((intptr_t)hFile, 0);
}
#else
fd = ::open(fname, O_RDONLY);
#endif
return fd;
}
FILE * safe_g_fopen(const Glib::ustring& src, const gchar *mode)
{
return g_fopen(src.c_str(), mode);
}
bool safe_file_test (const Glib::ustring& filename, Glib::FileTest test)
{
return Glib::file_test (filename, test);
}
int safe_g_remove(const Glib::ustring& filename)
{
return ::g_remove(filename.c_str());
}
int safe_g_rename(const Glib::ustring& oldFilename, const Glib::ustring& newFilename)
{
return ::g_rename(oldFilename.c_str(), newFilename.c_str());
}
int safe_g_mkdir_with_parents(const Glib::ustring& dirName, int mode)
{
return ::g_mkdir_with_parents(dirName.c_str(), mode);
}
Glib::ustring safe_get_user_picture_dir()
{
#ifdef WIN32
// get_user_special_dir/pictures crashes on some Windows configurations.
// so we use the safe native functions here
WCHAR pathW[MAX_PATH] = {0};
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_MYPICTURES, false)) {
char pathA[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
return Glib::ustring(pathA);
} else {
return Glib::ustring("C:\\");
}
#else
return Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES);
#endif
}
Glib::ustring safe_get_user_home_dir()
{
#ifdef WIN32
// get_user_special_dir/pictures crashes on some Windows configurations.
// so we use the safe native functions here
WCHAR pathW[MAX_PATH] = {0};
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PERSONAL, false)) {
char pathA[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
return Glib::ustring(pathA);
} else {
return Glib::ustring("C:\\");
}
#else
return Glib::get_home_dir();
#endif
}
#ifdef WIN32
Glib::ustring safe_get_user_profile_dir()
{
WCHAR pathW[MAX_PATH] = {0};
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PROFILE, false)) {
char pathA[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
return Glib::ustring(pathA);
} else {
return Glib::ustring("C:\\");
}
}
#endif
Glib::ustring safe_get_user_desktop_dir()
{
#ifdef WIN32
// get_user_special_dir/pictures crashes on some Windows configurations.
// so we use the safe native functions here
WCHAR pathW[MAX_PATH] = {0};
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_DESKTOP, false)) {
char pathA[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
return Glib::ustring(pathA);
} else {
return Glib::ustring("C:\\");
}
#else
return Glib::get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
#endif
}
#ifdef WIN32
/*
* Test if the path is a root path based on the content of the string
*
* Warning: this function is a workaround for Windows platform, and not necessarily bullet proof
*/
bool safe_is_shortcut_dir (const Glib::ustring& path)
{
return PathIsRootA(path.c_str()) || safe_get_user_home_dir() == path || safe_get_user_desktop_dir() == path || safe_get_user_profile_dir() == path; // || safe_get_user_picture_dir() == path;
}
#endif

View File

@ -1,41 +0,0 @@
#ifndef SAFE_GTK_H_INCLUDED
#define SAFE_GTK_H_INCLUDED
#include <gtkmm.h>
#include <glibmm.h>
#include <giomm.h>
Glib::RefPtr<Gdk::Pixbuf> safe_create_from_file(const Glib::ustring& filename);
Cairo::RefPtr<Cairo::ImageSurface> safe_create_from_png(const Glib::ustring& filename);
Glib::RefPtr<Gio::FileInfo> safe_query_file_info (Glib::RefPtr<Gio::File> &file);
void safe_build_file_list (Glib::RefPtr<Gio::File> &dir, std::vector<Glib::ustring> &names, const Glib::ustring &directory = "", const std::vector<Glib::ustring> *extensions = NULL);
void safe_build_subdir_list (Glib::RefPtr<Gio::File> &dir, std::vector<Glib::ustring> &subDirs, bool add_hidden);
bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8);
bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8);
Glib::ustring safe_filename_to_utf8 (const std::string& src);
Glib::ustring safe_locale_to_utf8 (const std::string& src); // from rtengine
std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str);
std::string safe_filename_from_utf8 (const Glib::ustring& utf8_str);
FILE * safe_g_fopen(const Glib::ustring& src, const gchar *mode);
FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname);
int safe_open_ReadOnly(const char *fname);
bool safe_file_test (const Glib::ustring& filename, Glib::FileTest test);
int safe_g_remove(const Glib::ustring& filename);
int safe_g_rename(const Glib::ustring& oldFilename, const Glib::ustring& newFilename);
int safe_g_mkdir_with_parents(const Glib::ustring& dirName, int mode);
Glib::ustring safe_get_user_picture_dir();
Glib::ustring safe_get_user_home_dir();
Glib::ustring safe_get_user_desktop_dir();
#ifdef WIN32
Glib::ustring safe_get_user_profile_dir();
bool safe_is_shortcut_dir (const Glib::ustring& filename);
#endif
#endif

View File

@ -1,117 +0,0 @@
#ifndef SAFE_KEY_FILE_H_INCLUDED
#define SAFE_KEY_FILE_H_INCLUDED
#include <glibmm.h>
namespace rtengine
{
class SafeKeyFile : public Glib::KeyFile
{
public :
#ifdef GLIBMM_EXCEPTIONS_ENABLED
#define SAFE_KEY_FILE_METHOD_CODE(method,method_err) \
do { try { res = Glib::KeyFile::method; }catch (const Glib::KeyFileError& e) { } ; \
return res; }while(0)
#else
#define SAFE_KEY_FILE_METHOD_CODE(method,method_err) \
do { std::auto_ptr<Glib::Error> error; \
res = Glib::KeyFile::method_err; \
if (error.get()){/* TODO */}; \
return res;} while(0)
#endif //GLIBMM_EXCEPTIONS_ENABLED
#define SAFE_KEY_FILE_METHOD(method,method_err,ret_type) \
{ ret_type res = (ret_type)0; SAFE_KEY_FILE_METHOD_CODE(method,method_err);}
#define SAFE_KEY_FILE_METHOD_NOINIT(method,method_err,ret_type) \
{ ret_type res; SAFE_KEY_FILE_METHOD_CODE(method,method_err);}
Glib::ustring to_data()
SAFE_KEY_FILE_METHOD_NOINIT(to_data(), to_data(error), Glib::ustring);
bool load_from_data(const Glib::ustring& data, Glib::KeyFileFlags flags = Glib::KEY_FILE_NONE)
SAFE_KEY_FILE_METHOD(load_from_data(data, flags), load_from_data(data, flags, error), bool);
bool load_from_file(const std::string& filename, Glib::KeyFileFlags flags = Glib::KEY_FILE_NONE)
SAFE_KEY_FILE_METHOD(load_from_file(filename, flags), load_from_file(filename, flags, error), bool);
bool has_key(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD(has_key(group_name, key), has_key(group_name, key, error), bool);
bool get_boolean(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD(get_boolean(group_name, key), get_boolean(group_name, key, error), bool);
int get_integer(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD(get_integer(group_name, key), get_integer(group_name, key, error), int);
double get_double(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD(get_double(group_name, key), get_double(group_name, key, error), double);
typedef std::vector<double> DoubleArrayType;
DoubleArrayType get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD_NOINIT(get_double_list(group_name, key), get_double_list(group_name, key, error), DoubleArrayType);
typedef std::vector<int> IntArrayType;
IntArrayType get_integer_list(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD_NOINIT(get_integer_list(group_name, key), get_integer_list(group_name, key, error), IntArrayType);
Glib::ustring get_string(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD_NOINIT(get_string(group_name, key), get_string(group_name, key, error), Glib::ustring);
/*
double get_double(const Glib::ustring& group_name, const Glib::ustring& key) const {
Glib::ustring temp = get_string( group_name, key);
if(!temp.empty()) {
double tmpdbl;
if(sscanf(temp.c_str(), "%lf", &tmpdbl))
return tmpdbl;
else
return 0.0;
}
return 0.0;
}
*/
typedef std::vector<Glib::ustring> StringArrayType;
StringArrayType get_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const
SAFE_KEY_FILE_METHOD_NOINIT(get_string_list(group_name, key), get_string_list(group_name, key, error), StringArrayType);
/*
typedef std::vector<double> DoubleArrayType;
DoubleArrayType get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const {
StringArrayType temp = get_string_list(group_name, key);
DoubleArrayType tempdouble;
unsigned int n = temp.size();
if(n) {
tempdouble.reserve(n);
for (unsigned int i=0; i<n; i++) {
if(!temp[i].empty()) {
double tmpdbl;
if(sscanf(temp[i].c_str(), "%lf", &tmpdbl))
tempdouble.push_back(tmpdbl);
else
tempdouble.push_back(0.0);
} else {
tempdouble.push_back(0.0);
}
}
}
return tempdouble;
}
*/
StringArrayType get_keys(const Glib::ustring& group_name) const
SAFE_KEY_FILE_METHOD_NOINIT(get_keys(group_name), get_keys(group_name, error), StringArrayType);
#undef SAFE_KEY_FILE_METHOD_CODE
#undef SAFE_KEY_FILE_METHOD
#undef SAFE_KEY_FILE_METHOD_NOINIT
};
}
#endif

View File

@ -739,6 +739,16 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
baseImg = trImg; baseImg = trImg;
} }
if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
const int W = baseImg->getWidth();
const int H = baseImg->getHeight();
LabImage labcbdl(W, H);
ipf.rgb2lab(*baseImg, labcbdl, params.icm.working);
ipf.dirpyrequalizer (&labcbdl, 1);
ipf.lab2rgb(labcbdl, *baseImg, params.icm.working);
}
// update blurmap // update blurmap
SHMap* shmap = NULL; SHMap* shmap = NULL;
@ -982,10 +992,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL ); params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL );
// directional pyramid wavelet // directional pyramid wavelet
if(params.dirpyrequalizer.cbdlMethod == "aft") {
if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) {
ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one
} }
}
int kall = 2; int kall = 2;
bool wavcontlutili = false; bool wavcontlutili = false;

View File

@ -25,9 +25,11 @@
#include <sstream> #include <sstream>
#include <stdint.h> #include <stdint.h>
#include "../rtgui/cacheimagedata.h" #include <glib/gstdio.h>
#include "rtexif.h" #include "rtexif.h"
#include "../rtengine/safegtk.h"
#include "../rtgui/cacheimagedata.h"
#include "../rtgui/version.h" #include "../rtgui/version.h"
#include "../rtgui/ppversion.h" #include "../rtgui/ppversion.h"
@ -247,17 +249,10 @@ void TagDirectory::printAll (unsigned int level) const
* *
* @return True if everything went fine, false otherwise * @return True if everything went fine, false otherwise
*/ */
bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, const CacheImageData* cfs, const bool flagMode, bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams,
rtengine::SafeKeyFile *keyFile, Glib::ustring tagDirName) const const CacheImageData* cfs, const bool flagMode, Glib::KeyFile *keyFile, Glib::ustring tagDirName) const
{ {
const auto kf = keyFile ? keyFile : new Glib::KeyFile;
rtengine::SafeKeyFile *kf;
if (!keyFile) {
kf = new rtengine::SafeKeyFile();
} else {
kf = keyFile;
}
if (!kf) { if (!kf) {
return false; return false;
@ -274,7 +269,7 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
if (!keyFile) { if (!keyFile) {
// open the file in write mode // open the file in write mode
f = safe_g_fopen (commFName, "wt"); f = g_fopen (commFName.c_str (), "wt");
if (f == NULL) { if (f == NULL) {
printf("TagDirectory::keyFileDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str()); printf("TagDirectory::keyFileDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str());
@ -282,6 +277,8 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
return false; return false;
} }
try {
kf->set_string ("RT General", "CachePath", options.cacheBaseDir); kf->set_string ("RT General", "CachePath", options.cacheBaseDir);
kf->set_string ("RT General", "AppVersion", VERSION); kf->set_string ("RT General", "AppVersion", VERSION);
kf->set_integer("RT General", "ProcParamsVersion", PPVERSION); kf->set_integer("RT General", "ProcParamsVersion", PPVERSION);
@ -297,6 +294,8 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
kf->set_string ("Common Data", "Lens", cfs->lens); kf->set_string ("Common Data", "Lens", cfs->lens);
kf->set_string ("Common Data", "Make", cfs->camMake); kf->set_string ("Common Data", "Make", cfs->camMake);
kf->set_string ("Common Data", "Model", cfs->camModel); kf->set_string ("Common Data", "Model", cfs->camModel);
} catch (Glib::KeyFileError&) {}
} }
// recursively iterate over the tag list // recursively iterate over the tag list
@ -308,10 +307,15 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
// Accumulating the TagDirectories to dump later // Accumulating the TagDirectories to dump later
tagDirPaths.push_back( Glib::ustring( tagDirName + "/" + getDumpKey(tags[i]->getID(), tagName) ) ); tagDirPaths.push_back( Glib::ustring( tagDirName + "/" + getDumpKey(tags[i]->getID(), tagName) ) );
tagDirList.push_back(tags[i]->getDirectory(j)); tagDirList.push_back(tags[i]->getDirectory(j));
try {
kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), "$subdir"); kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), "$subdir");
} catch (Glib::KeyFileError&) {}
} }
else { else {
try {
kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), tags[i]->valueToString()); kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), tags[i]->valueToString());
} catch (Glib::KeyFileError&) {}
} }
} }
@ -321,7 +325,10 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
} }
if (!keyFile) { if (!keyFile) {
try {
fprintf (f, "%s", kf->to_data().c_str()); fprintf (f, "%s", kf->to_data().c_str());
} catch (Glib::KeyFileError&) {}
fclose (f); fclose (f);
delete kf; delete kf;
} }

View File

@ -29,7 +29,6 @@
#include <cmath> #include <cmath>
#include <glibmm.h> #include <glibmm.h>
#include "../rtengine/procparams.h" #include "../rtengine/procparams.h"
#include "../rtengine/safekeyfile.h"
class CacheImageData; class CacheImageData;
@ -156,7 +155,7 @@ public:
virtual void printAll (unsigned int level = 0) const; // reentrant debug function, keep level=0 on first call ! virtual void printAll (unsigned int level = 0) const; // reentrant debug function, keep level=0 on first call !
virtual bool CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, virtual bool CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams,
const CacheImageData* cfs, const bool flagMode, rtengine::SafeKeyFile *keyFile = NULL, Glib::ustring tagDirName = "") const; const CacheImageData* cfs, const bool flagMode, Glib::KeyFile *keyFile = NULL, Glib::ustring tagDirName = "") const;
virtual void sort (); virtual void sort ();
}; };

View File

@ -32,7 +32,6 @@
#include "filecatalog.h" #include "filecatalog.h"
#include "batchqueuebuttonset.h" #include "batchqueuebuttonset.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
using namespace std; using namespace std;
@ -372,7 +371,7 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename
strftime (stringTimestamp, sizeof(stringTimestamp), "_%Y%m%d%H%M%S_", timeinfo); strftime (stringTimestamp, sizeof(stringTimestamp), "_%Y%m%d%H%M%S_", timeinfo);
Glib::ustring savedParamPath; Glib::ustring savedParamPath;
savedParamPath = options.rtdir + "/batch/"; savedParamPath = options.rtdir + "/batch/";
safe_g_mkdir_with_parents (savedParamPath, 0755); g_mkdir_with_parents (savedParamPath.c_str (), 0755);
savedParamPath += Glib::path_get_basename (filename); savedParamPath += Glib::path_get_basename (filename);
savedParamPath += stringTimestamp; savedParamPath += stringTimestamp;
savedParamPath += paramFileExtension; savedParamPath += paramFileExtension;
@ -381,8 +380,11 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename
int cancelItemUI (void* data) int cancelItemUI (void* data)
{ {
safe_g_remove( (static_cast<BatchQueueEntry*>(data))->savedParamsFile ); const auto bqe = static_cast<BatchQueueEntry*>(data);
delete static_cast<BatchQueueEntry*>(data);
g_remove (bqe->savedParamsFile.c_str ());
delete bqe;
return 0; return 0;
} }
@ -667,24 +669,31 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img)
processing->removeButtonSet (); processing->removeButtonSet ();
} }
if (saveBatchQueue( )) { if (saveBatchQueue ()) {
safe_g_remove( processedParams ); ::g_remove (processedParams.c_str ());
// Delete all files in directory \batch when finished, just to be sure to remove zombies
// Not sure that locking is necessary, but it should be safer // Delete all files in directory batch when finished, just to be sure to remove zombies
auto isEmpty = false;
{
MYREADERLOCK(l, entryRW); MYREADERLOCK(l, entryRW);
isEmpty = fd.empty();
if( fd.empty() ) {
MYREADERLOCK_RELEASE(l);
std::vector<Glib::ustring> names;
Glib::ustring batchdir = Glib::build_filename(options.rtdir, "batch");
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (batchdir);
safe_build_file_list (dir, names, batchdir);
for(std::vector<Glib::ustring>::iterator iter = names.begin(); iter != names.end(); iter++ ) {
safe_g_remove( *iter );
} }
if (isEmpty) {
const auto batchdir = Glib::build_filename (options.rtdir, "batch");
try {
auto dir = Gio::File::create_for_path (batchdir);
auto enumerator = dir->enumerate_children ("standard::name");
while (auto file = enumerator->next_file ()) {
::g_remove (Glib::build_filename (batchdir, file->get_name ()).c_str ());
}
} catch (Glib::Exception&) {}
} }
} }
@ -830,8 +839,8 @@ Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, c
Glib::ustring fname; Glib::ustring fname;
// create directory, if does not exist // create directory, if does not exist
if (safe_g_mkdir_with_parents (dstdir, 0755) ) { if (g_mkdir_with_parents (dstdir.c_str (), 0755)) {
return ""; return Glib::ustring ();
} }
// In overwrite mode we TRY to delete the old file first. // In overwrite mode we TRY to delete the old file first.
@ -845,10 +854,10 @@ Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, c
fname = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, format); fname = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, format);
} }
int fileExists = safe_file_test (fname, Glib::FILE_TEST_EXISTS); int fileExists = Glib::file_test (fname, Glib::FILE_TEST_EXISTS);
if (inOverwriteMode && fileExists) { if (inOverwriteMode && fileExists) {
if (safe_g_remove(fname) == -1) { if (::g_remove (fname.c_str ()) != 0) {
inOverwriteMode = false; // failed to delete- revert to old naming scheme inOverwriteMode = false; // failed to delete- revert to old naming scheme
} else { } else {
fileExists = false; // deleted now fileExists = false; // deleted now

View File

@ -17,8 +17,9 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "batchqueuebuttonset.h" #include "batchqueuebuttonset.h"
#include "multilangmgr.h" #include "multilangmgr.h"
#include "../rtengine/safegtk.h" #include "rtimage.h"
bool BatchQueueButtonSet::iconsLoaded = false; bool BatchQueueButtonSet::iconsLoaded = false;
@ -30,9 +31,9 @@ BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry)
{ {
if (!iconsLoaded) { if (!iconsLoaded) {
cancelIcon = safe_create_from_png ("gtk-close.png"); cancelIcon = RTImage::createFromPng ("gtk-close.png");
headIcon = safe_create_from_png ("toleftend.png"); headIcon = RTImage::createFromPng ("toleftend.png");
tailIcon = safe_create_from_png ("torightend.png"); tailIcon = RTImage::createFromPng ("torightend.png");
iconsLoaded = true; iconsLoaded = true;
} }

View File

@ -17,13 +17,14 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "batchqueueentry.h" #include "batchqueueentry.h"
#include "thumbbrowserbase.h"
#include <cstring> #include <cstring>
#include "guiutils.h" #include "guiutils.h"
#include "threadutils.h" #include "threadutils.h"
#include "../rtengine/safegtk.h" #include "rtimage.h"
#include "multilangmgr.h" #include "multilangmgr.h"
#include "thumbbrowserbase.h"
bool BatchQueueEntry::iconsLoaded(false); bool BatchQueueEntry::iconsLoaded(false);
Glib::RefPtr<Gdk::Pixbuf> BatchQueueEntry::savedAsIcon; Glib::RefPtr<Gdk::Pixbuf> BatchQueueEntry::savedAsIcon;
@ -46,7 +47,7 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine:
#endif #endif
if (!iconsLoaded) { if (!iconsLoaded) {
savedAsIcon = safe_create_from_file ("gtk-save.png"); savedAsIcon = RTImage::createFromFile ("gtk-save.png");
iconsLoaded = true; iconsLoaded = true;
} }

View File

@ -22,7 +22,6 @@
#include "multilangmgr.h" #include "multilangmgr.h"
#include "rtwindow.h" #include "rtwindow.h"
#include "soundman.h" #include "soundman.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
struct BQProcessLoaded { struct BQProcessLoaded {
@ -39,7 +38,7 @@ int processLoadedBatchQueueUIThread (void* data)
static Glib::ustring makeFolderLabel(Glib::ustring path) static Glib::ustring makeFolderLabel(Glib::ustring path)
{ {
if (!safe_file_test (path, Glib::FILE_TEST_IS_DIR)) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
return "(" + M("GENERAL_NONE") + ")"; return "(" + M("GENERAL_NONE") + ")";
} }
@ -116,7 +115,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog)
outdirFolder->signal_current_folder_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::pathFolderChanged)); outdirFolder->signal_current_folder_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::pathFolderChanged));
outdirFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); outdirFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT"));
if (safe_file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) {
outdirFolder->set_current_folder (options.savePathFolder); outdirFolder->set_current_folder (options.savePathFolder);
} }
@ -347,8 +346,8 @@ void BatchQueuePanel::pathFolderButtonPressed ()
int result = fc.run(); int result = fc.run();
if (result == Gtk::RESPONSE_OK) { if (result == Gtk::RESPONSE_OK) {
if (safe_file_test(fc.get_filename(), Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test(fc.get_current_folder(), Glib::FILE_TEST_IS_DIR)) {
options.savePathFolder = fc.get_filename(); options.savePathFolder = fc.get_filename ();
outdirFolderButton->set_label(makeFolderLabel(options.savePathFolder)); outdirFolderButton->set_label(makeFolderLabel(options.savePathFolder));
} }
} }

View File

@ -18,7 +18,6 @@
*/ */
#include "bayerpreprocess.h" #include "bayerpreprocess.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream> #include <sstream>
using namespace rtengine; using namespace rtengine;

View File

@ -18,7 +18,6 @@
*/ */
#include "bayerrawexposure.h" #include "bayerrawexposure.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream> #include <sstream>
using namespace rtengine; using namespace rtengine;

View File

@ -19,8 +19,6 @@
#include "cacheimagedata.h" #include "cacheimagedata.h"
#include <vector> #include <vector>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include "../rtengine/safekeyfile.h"
#include "../rtengine/safegtk.h"
#include "version.h" #include "version.h"
#include <locale.h> #include <locale.h>
@ -36,7 +34,8 @@ CacheImageData::CacheImageData ()
int CacheImageData::load (const Glib::ustring& fname) int CacheImageData::load (const Glib::ustring& fname)
{ {
setlocale(LC_NUMERIC, "C"); // to set decimal point to "." setlocale(LC_NUMERIC, "C"); // to set decimal point to "."
rtengine::SafeKeyFile keyFile;
Glib::KeyFile keyFile;
try { try {
if (keyFile.load_from_file (fname)) { if (keyFile.load_from_file (fname)) {
@ -165,10 +164,6 @@ int CacheImageData::load (const Glib::ustring& fname)
if (keyFile.has_key ("ExtraRawInfo", "ThumbImageType")) { if (keyFile.has_key ("ExtraRawInfo", "ThumbImageType")) {
thumbImgType = keyFile.get_integer ("ExtraRawInfo", "ThumbImageType"); thumbImgType = keyFile.get_integer ("ExtraRawInfo", "ThumbImageType");
} }
if (keyFile.has_key ("ExtraRawInfo", "ThumbImageOffset")) {
thumbOffset = keyFile.get_integer ("ExtraRawInfo", "ThumbImageOffset");
}
} else { } else {
rotate = 0; rotate = 0;
thumbImgType = 0; thumbImgType = 0;
@ -195,21 +190,15 @@ int CacheImageData::load (const Glib::ustring& fname)
int CacheImageData::save (const Glib::ustring& fname) int CacheImageData::save (const Glib::ustring& fname)
{ {
rtengine::SafeKeyFile keyFile; Glib::ustring keyData;
try {
Glib::KeyFile keyFile;
if (safe_file_test(fname, Glib::FILE_TEST_EXISTS)) {
try { try {
keyFile.load_from_file (fname); keyFile.load_from_file (fname);
} catch (Glib::Error &err) { } catch (Glib::Error&) {}
if (options.rtSettings.verbose) {
printf("CacheImageData::save / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
}
} catch (...) {
if (options.rtSettings.verbose) {
printf("CacheImageData::save / Unknown exception while trying to save \"%s\"!\n", fname.c_str());
}
}
}
keyFile.set_string ("General", "MD5", md5); keyFile.set_string ("General", "MD5", md5);
keyFile.set_string ("General", "Version", VERSION); // Application's version keyFile.set_string ("General", "Version", VERSION); // Application's version
@ -254,10 +243,25 @@ int CacheImageData::save (const Glib::ustring& fname)
if (format == FT_Raw) { if (format == FT_Raw) {
keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType); keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType);
keyFile.set_integer ("ExtraRawInfo", "ThumbImageOffset", thumbOffset);
} }
FILE *f = safe_g_fopen (fname, "wt"); keyData = keyFile.to_data ();
} catch (Glib::Error &err) {
if (options.rtSettings.verbose) {
printf("CacheImageData::save / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
}
} catch (...) {
if (options.rtSettings.verbose) {
printf("CacheImageData::save / Unknown exception while trying to save \"%s\"!\n", fname.c_str());
}
}
if (keyData.empty ()) {
return 1;
}
FILE *f = g_fopen (fname.c_str (), "wt");
if (!f) { if (!f) {
if (options.rtSettings.verbose) { if (options.rtSettings.verbose) {
@ -266,7 +270,7 @@ int CacheImageData::save (const Glib::ustring& fname)
return 1; return 1;
} else { } else {
fprintf (f, "%s", keyFile.to_data().c_str()); fprintf (f, "%s", keyData.c_str ());
fclose (f); fclose (f);
return 0; return 0;
} }

View File

@ -65,7 +65,6 @@ public:
// additional info on raw images // additional info on raw images
int rotate; int rotate;
int thumbImgType; int thumbImgType;
int thumbOffset;
enum { enum {
FULL_THUMBNAIL = 0, // was the thumbnail generated from whole file FULL_THUMBNAIL = 0, // was the thumbnail generated from whole file

View File

@ -16,19 +16,21 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "cropwindow.h"
#include <iomanip> #include <iomanip>
#include "cropwindow.h"
#include "options.h"
#include "guiutils.h"
#include "threadutils.h"
#include "../rtengine/mytime.h" #include "../rtengine/mytime.h"
#include "imagearea.h"
#include "cursormanager.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/rt_math.h" #include "../rtengine/rt_math.h"
#include "../rtengine/dcrop.h" #include "../rtengine/dcrop.h"
#include "guiutils.h"
#include "threadutils.h"
#include "rtimage.h"
#include "cursormanager.h"
#include "options.h"
#include "imagearea.h"
using namespace rtengine; using namespace rtengine;
struct ZoomStep { struct ZoomStep {
@ -84,11 +86,11 @@ CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_,
titleHeight = ih; titleHeight = ih;
bZoomOut = new LWButton (safe_create_from_png ("gtk-zoom-out-small.png"), 0, NULL, LWButton::Left, LWButton::Center, "Zoom Out"); bZoomOut = new LWButton (RTImage::createFromPng ("gtk-zoom-out-small.png"), 0, NULL, LWButton::Left, LWButton::Center, "Zoom Out");
bZoomIn = new LWButton (safe_create_from_png ("gtk-zoom-in-small.png"), 1, NULL, LWButton::Left, LWButton::Center, "Zoom In"); bZoomIn = new LWButton (RTImage::createFromPng ("gtk-zoom-in-small.png"), 1, NULL, LWButton::Left, LWButton::Center, "Zoom In");
bZoom100 = new LWButton (safe_create_from_png ("gtk-zoom-100-small.png"), 2, NULL, LWButton::Left, LWButton::Center, "Zoom 100/%"); bZoom100 = new LWButton (RTImage::createFromPng ("gtk-zoom-100-small.png"), 2, NULL, LWButton::Left, LWButton::Center, "Zoom 100/%");
//bZoomFit = new LWButton (safe_create_from_png ("gtk-zoom-fit.png"), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); //bZoomFit = new LWButton (RTImage::createFromPng ("gtk-zoom-fit.png"), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit");
bClose = new LWButton (safe_create_from_png ("gtk-close-small.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close"); bClose = new LWButton (RTImage::createFromPng ("gtk-close-small.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close");
buttonSet.add (bZoomOut); buttonSet.add (bZoomOut);
buttonSet.add (bZoomIn); buttonSet.add (bZoomIn);

View File

@ -17,8 +17,8 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "cursormanager.h" #include "cursormanager.h"
#include "options.h" #include "options.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
CursorManager mainWindowCursorManager; CursorManager mainWindowCursorManager;
@ -51,14 +51,14 @@ void CursorManager::init (Glib::RefPtr<Gdk::Window> mainWindow)
cAdd = Gdk::Cursor::create (display, Gdk::PLUS); cAdd = Gdk::Cursor::create (display, Gdk::PLUS);
cWait = Gdk::Cursor::create (display, Gdk::CLOCK); cWait = Gdk::Cursor::create (display, Gdk::CLOCK);
Glib::RefPtr<Gdk::Pixbuf> hand = safe_create_from_file("cross.png"); Glib::RefPtr<Gdk::Pixbuf> hand = RTImage::createFromFile ("cross.png");
Glib::RefPtr<Gdk::Pixbuf> close_hand = safe_create_from_file("closedhand.png"); Glib::RefPtr<Gdk::Pixbuf> close_hand = RTImage::createFromFile ("closedhand.png");
Glib::RefPtr<Gdk::Pixbuf> wbpick = safe_create_from_file("gtk-color-picker-small.png"); Glib::RefPtr<Gdk::Pixbuf> wbpick = RTImage::createFromFile ("gtk-color-picker-small.png");
Glib::RefPtr<Gdk::Pixbuf> empty = safe_create_from_file("empty.png"); Glib::RefPtr<Gdk::Pixbuf> empty = RTImage::createFromFile ("empty.png");
Glib::RefPtr<Gdk::Pixbuf> move2D = safe_create_from_file("move-2D.png"); Glib::RefPtr<Gdk::Pixbuf> move2D = RTImage::createFromFile ("move-2D.png");
Glib::RefPtr<Gdk::Pixbuf> move1DH = safe_create_from_file("move-1D-h.png"); Glib::RefPtr<Gdk::Pixbuf> move1DH = RTImage::createFromFile ("move-1D-h.png");
Glib::RefPtr<Gdk::Pixbuf> move1DV = safe_create_from_file("move-1D-v.png"); Glib::RefPtr<Gdk::Pixbuf> move1DV = RTImage::createFromFile ("move-1D-v.png");
Glib::RefPtr<Gdk::Pixbuf> moveRotate = safe_create_from_file("move-rotate.png"); Glib::RefPtr<Gdk::Pixbuf> moveRotate = RTImage::createFromFile ("move-rotate.png");
cHand = hand ? Gdk::Cursor::create (cAdd->get_display(), hand, 10, 10) : Gdk::Cursor::create (cAdd->get_display(), Gdk::HAND2); cHand = hand ? Gdk::Cursor::create (cAdd->get_display(), hand, 10, 10) : Gdk::Cursor::create (cAdd->get_display(), Gdk::HAND2);
cClosedHand = close_hand ? Gdk::Cursor::create (cAdd->get_display(), close_hand, 10, 10) : Gdk::Cursor::create (cAdd->get_display(), Gdk::HAND2); cClosedHand = close_hand ? Gdk::Cursor::create (cAdd->get_display(), close_hand, 10, 10) : Gdk::Cursor::create (cAdd->get_display(), Gdk::HAND2);

View File

@ -24,7 +24,6 @@
#include "diagonalcurveeditorsubgroup.h" #include "diagonalcurveeditorsubgroup.h"
#include "flatcurveeditorsubgroup.h" #include "flatcurveeditorsubgroup.h"
#include "multilangmgr.h" #include "multilangmgr.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), curve_reset(NULL), CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), curve_reset(NULL),

View File

@ -19,7 +19,6 @@
#include "darkframe.h" #include "darkframe.h"
#include "options.h" #include "options.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream> #include <sstream>
#include "rtimage.h" #include "rtimage.h"
@ -81,7 +80,7 @@ void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi
dfAuto->set_inconsistent(!pedited->raw.dfAuto ); dfAuto->set_inconsistent(!pedited->raw.dfAuto );
} }
if (safe_file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) {
darkFrameFile->set_filename (pp->raw.dark_frame); darkFrameFile->set_filename (pp->raw.dark_frame);
} else { } else {
darkFrameReset(); darkFrameReset();

View File

@ -17,27 +17,57 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "dirbrowser.h" #include "dirbrowser.h"
#include <cstring>
#ifdef WIN32 #ifdef WIN32
#define _WIN32_WINNT 0x0600 #define _WIN32_WINNT 0x0600
#include <windows.h> #include <windows.h>
#endif #endif
#include "options.h"
#include "multilangmgr.h"
#include "../rtengine/safegtk.h"
#include <cstring>
#include "guiutils.h" #include "guiutils.h"
#include "rtimage.h" #include "rtimage.h"
#include "multilangmgr.h"
#include "options.h"
#define CHECKTIME 5000 namespace
{
struct DirNameComparator { std::vector<Glib::ustring> listSubDirs (const Glib::RefPtr<Gio::File>& dir, bool addHidden)
template<class T> {
bool operator()(T const &firstDir, T const &secondDir) const std::vector<Glib::ustring> subDirs;
{
return options.dirBrowserSortType == Gtk::SORT_ASCENDING ? firstDir < secondDir : firstDir > secondDir; try {
// CD-ROM with no disc inserted are reported, but do not exist.
if (!Glib::file_test (dir->get_path (), Glib::FILE_TEST_EXISTS)) {
return subDirs;
} }
};
auto enumerator = dir->enumerate_children ("standard::name,standard::type,standard::is-hidden");
while (auto file = enumerator->next_file ()) {
if (file->get_file_type () != Gio::FILE_TYPE_DIRECTORY) {
continue;
}
if (!addHidden && file->is_hidden ()) {
continue;
}
subDirs.push_back (file->get_name ());
}
} catch (const Glib::Exception& exception) {
if (options.rtSettings.verbose) {
std::cerr << "Failed to list subdirectories of \"" << dir << "\": " << exception.what () << std::endl;
}
}
return subDirs;
}
}
DirBrowser::DirBrowser () : dirTreeModel(), DirBrowser::DirBrowser () : dirTreeModel(),
dtColumns(), dtColumns(),
@ -71,13 +101,13 @@ DirBrowser::DirBrowser () : dirTreeModel(),
void DirBrowser::fillDirTree () void DirBrowser::fillDirTree ()
{ {
openfolder = safe_create_from_file ("gtk-open.png"); openfolder = RTImage::createFromFile ("gtk-open.png");
closedfolder = safe_create_from_file ("folder.png"); closedfolder = RTImage::createFromFile ("folder.png");
icdrom = safe_create_from_file ("drive-optical.png"); icdrom = RTImage::createFromFile ("drive-optical.png");
ifloppy = safe_create_from_file ("drive-removable-media.png"); ifloppy = RTImage::createFromFile ("drive-removable-media.png");
ihdd = safe_create_from_file ("drive-harddisk.png"); ihdd = RTImage::createFromFile ("drive-harddisk.png");
iremovable = safe_create_from_file ("media-usb.png"); iremovable = RTImage::createFromFile ("media-usb.png");
inetwork = safe_create_from_file ("network.png"); inetwork = RTImage::createFromFile ("network.png");
//Create the Tree model: //Create the Tree model:
dirTreeModel = Gtk::TreeStore::create(dtColumns); dirTreeModel = Gtk::TreeStore::create(dtColumns);
@ -220,7 +250,7 @@ void DirBrowser::fillRoot ()
} }
// since sigc++ is not thread safe, we have to use the glib function // since sigc++ is not thread safe, we have to use the glib function
g_timeout_add (CHECKTIME, updateVolumesUI, this); g_timeout_add (5000, updateVolumesUI, this);
#else #else
Gtk::TreeModel::Row rootRow = *(dirTreeModel->append()); Gtk::TreeModel::Row rootRow = *(dirTreeModel->append());
rootRow[dtColumns.filename] = "/"; rootRow[dtColumns.filename] = "/";
@ -243,19 +273,15 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::
// We will disable model's sorting because it decreases speed of inserting new items // We will disable model's sorting because it decreases speed of inserting new items
// in list tree dramatically. Therefore will do: // in list tree dramatically. Therefore will do:
// 1) Disable sorting in model // 1) Disable sorting in model
// 2) Manually sort data by DirNameComparator // 2) Manually sort data in the order determined by the options
// 3) Enable sorting in model again for UI (sorting by click on header) // 3) Enable sorting in model again for UI (sorting by click on header)
int prevSortColumn; int prevSortColumn;
Gtk::SortType prevSortType; Gtk::SortType prevSortType;
dirTreeModel->get_sort_column_id(prevSortColumn, prevSortType); dirTreeModel->get_sort_column_id(prevSortColumn, prevSortType);
dirTreeModel->set_sort_column(Gtk::TreeSortable::DEFAULT_UNSORTED_COLUMN_ID, Gtk::SORT_ASCENDING); dirTreeModel->set_sort_column(Gtk::TreeSortable::DEFAULT_UNSORTED_COLUMN_ID, Gtk::SORT_ASCENDING);
typedef std::vector<Glib::ustring> DirPathType; auto dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
auto subDirs = listSubDirs (dir, options.fbShowHidden);
DirPathType subDirs;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
safe_build_subdir_list (dir, subDirs, options.fbShowHidden);
if (subDirs.empty()) { if (subDirs.empty()) {
dirtree->collapse_row(path); dirtree->collapse_row(path);
@ -263,14 +289,22 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::
Gtk::TreeNodeChildren children = iter->children(); Gtk::TreeNodeChildren children = iter->children();
std::list<Gtk::TreeIter> forErase(children.begin(), children.end()); std::list<Gtk::TreeIter> forErase(children.begin(), children.end());
DirNameComparator comparator; std::sort (subDirs.begin (), subDirs.end (), [] (const Glib::ustring& firstDir, const Glib::ustring& secondDir)
sort(subDirs.begin(), subDirs.end(), comparator); {
switch (options.dirBrowserSortType) {
default:
case Gtk::SORT_ASCENDING:
return firstDir < secondDir;
case Gtk::SORT_DESCENDING:
return firstDir > secondDir;
}
});
for (DirPathType::const_iterator it = subDirs.begin(), end = subDirs.end(); it != end; ++it) { for (auto it = subDirs.begin(), end = subDirs.end(); it != end; ++it) {
addDir(iter, *it); addDir(iter, *it);
} }
for (std::list<Gtk::TreeIter>::const_iterator it = forErase.begin(), end = forErase.end(); it != end; ++it) { for (auto it = forErase.begin(), end = forErase.end(); it != end; ++it) {
dirTreeModel->erase(*it); dirTreeModel->erase(*it);
} }
@ -299,8 +333,8 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter)
change = false; change = false;
for (Gtk::TreeModel::iterator it = iter->children().begin(); it != iter->children().end(); it++) for (Gtk::TreeModel::iterator it = iter->children().begin(); it != iter->children().end(); it++)
if (!safe_file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS) if (!Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS)
|| !safe_file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) { || !Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) {
GThreadLock lock; GThreadLock lock;
dirTreeModel->erase (it); dirTreeModel->erase (it);
change = true; change = true;
@ -309,9 +343,8 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter)
} }
// test if new files are created // test if new files are created
std::vector<Glib::ustring> subDirs; auto dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); auto subDirs = listSubDirs (dir, options.fbShowHidden);
safe_build_subdir_list (dir, subDirs, options.fbShowHidden);
for (int i = 0; i < subDirs.size(); i++) { for (int i = 0; i < subDirs.size(); i++) {
bool found = false; bool found = false;
@ -345,7 +378,7 @@ void DirBrowser::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewC
Glib::ustring dname = dirTreeModel->get_iter (path)->get_value (dtColumns.dirname); Glib::ustring dname = dirTreeModel->get_iter (path)->get_value (dtColumns.dirname);
if (safe_file_test (dname, Glib::FILE_TEST_IS_DIR)) if (Glib::file_test (dname, Glib::FILE_TEST_IS_DIR))
dirSelectionSignal (dname, Glib::ustring()); dirSelectionSignal (dname, Glib::ustring());
} }
@ -442,7 +475,7 @@ void DirBrowser::open (const Glib::ustring& dirname, const Glib::ustring& fileNa
void DirBrowser::file_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName) void DirBrowser::file_changed (const Glib::RefPtr<Gio::File>& file, const Glib::RefPtr<Gio::File>& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName)
{ {
if (!file || !safe_file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type == Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) { if (!file || !Glib::file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type == Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) {
return; return;
} }

View File

@ -51,6 +51,24 @@ DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer",
Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b); Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b);
milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.324 rad: 2.5 milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.324 rad: 2.5
Gtk::VBox * cbVBox = Gtk::manage ( new Gtk::VBox());
cbVBox->set_border_width(4);
cbVBox->set_spacing(2);
cdbox = Gtk::manage (new Gtk::HBox ());
labmcd = Gtk::manage (new Gtk::Label (M("TP_CBDL_METHOD") + ":"));
cdbox->pack_start (*labmcd, Gtk::PACK_SHRINK, 1);
cbdlMethod = Gtk::manage (new MyComboBoxText ());
cbdlMethod->append (M("TP_CBDL_BEF"));
cbdlMethod->append (M("TP_CBDL_AFT"));
cbdlMethod->set_active(0);
cbdlMethodConn = cbdlMethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrEqualizer::cbdlMethodChanged) );
cbdlMethod->set_tooltip_markup (M("TP_CBDL_METHOD_TOOLTIP"));
cdbox->pack_start(*cbdlMethod);
cbVBox->pack_start(*cdbox);
pack_start(*cbVBox);
setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP")); setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP"));
Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox(true, 10)); Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox(true, 10));
@ -145,12 +163,17 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited)
{ {
disableListener (); disableListener ();
cbdlMethodConn.block(true);
if (pedited) { if (pedited) {
set_inconsistent (multiImage && !pedited->dirpyrequalizer.enabled); set_inconsistent (multiImage && !pedited->dirpyrequalizer.enabled);
gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab); gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab);
if (!pedited->dirpyrequalizer.cbdlMethod) {
cbdlMethod->set_active_text(M("GENERAL_UNCHANGED"));
}
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited);
} }
@ -186,6 +209,15 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited)
skinprotect->setValue(pp->dirpyrequalizer.skinprotect); skinprotect->setValue(pp->dirpyrequalizer.skinprotect);
hueskin->setValue<int>(pp->dirpyrequalizer.hueskin); hueskin->setValue<int>(pp->dirpyrequalizer.hueskin);
if (pp->dirpyrequalizer.cbdlMethod == "bef") {
cbdlMethod->set_active (0);
} else if (pp->dirpyrequalizer.cbdlMethod == "aft") {
cbdlMethod->set_active (1);
}
cbdlMethodChanged ();
cbdlMethodConn.block(false);
enableListener (); enableListener ();
} }
@ -207,6 +239,7 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited)
pedited->dirpyrequalizer.enabled = !get_inconsistent(); pedited->dirpyrequalizer.enabled = !get_inconsistent();
pedited->dirpyrequalizer.hueskin = hueskin->getEditedState (); pedited->dirpyrequalizer.hueskin = hueskin->getEditedState ();
pedited->dirpyrequalizer.cbdlMethod = cbdlMethod->get_active_text() != M("GENERAL_UNCHANGED");
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState(); pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState();
@ -217,6 +250,13 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited)
// pedited->dirpyrequalizer.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED"); // pedited->dirpyrequalizer.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED");
} }
if (cbdlMethod->get_active_row_number() == 0) {
pp->dirpyrequalizer.cbdlMethod = "bef";
} else if (cbdlMethod->get_active_row_number() == 1) {
pp->dirpyrequalizer.cbdlMethod = "aft";
}
/* if (algo->get_active_row_number()==0) /* if (algo->get_active_row_number()==0)
pp->dirpyrequalizer.algo = "FI"; pp->dirpyrequalizer.algo = "FI";
else if (algo->get_active_row_number()==1) else if (algo->get_active_row_number()==1)
@ -281,6 +321,16 @@ void DirPyrEqualizer::setBatchMode (bool batchMode)
// algo->append (M("GENERAL_UNCHANGED")); // algo->append (M("GENERAL_UNCHANGED"));
} }
void DirPyrEqualizer::cbdlMethodChanged()
{
if (listener) {
listener->panelChanged (EvcbdlMethod, cbdlMethod->get_active_text ());
}
}
void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval)
{ {

View File

@ -45,6 +45,10 @@ protected:
sigc::connection lumaneutralPressedConn; sigc::connection lumaneutralPressedConn;
sigc::connection lumacontrastPlusPressedConn; sigc::connection lumacontrastPlusPressedConn;
sigc::connection lumacontrastMinusPressedConn; sigc::connection lumacontrastMinusPressedConn;
sigc::connection cbdlMethodConn;
Gtk::Label* labmcd;
Gtk::HBox* cdbox;
MyComboBoxText* cbdlMethod;
bool lastgamutlab; bool lastgamutlab;
@ -61,7 +65,7 @@ public:
void trimValues (rtengine::procparams::ProcParams* pp); void trimValues (rtengine::procparams::ProcParams* pp);
void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight); void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight);
// void algoChanged (); // void algoChanged ();
void cbdlMethodChanged();
void adjusterChanged (Adjuster* a, double newval); void adjusterChanged (Adjuster* a, double newval);
void enabledChanged(); void enabledChanged();
void gamutlabToggled (); void gamutlabToggled ();

View File

@ -18,18 +18,20 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "editorpanel.h" #include "editorpanel.h"
#include "options.h"
#include "progressconnector.h" #include <iostream>
#include "rtwindow.h"
#include "guiutils.h"
#include "procparamchangers.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/imagesource.h" #include "../rtengine/imagesource.h"
#include "../rtengine/iccstore.h" #include "../rtengine/iccstore.h"
#include "soundman.h" #include "soundman.h"
#include "rtimage.h" #include "rtimage.h"
#include <iostream> #include "rtwindow.h"
#include "guiutils.h"
#include "popupbutton.h" #include "popupbutton.h"
#include "options.h"
#include "progressconnector.h"
#include "procparamchangers.h"
#include "placesbrowser.h"
using namespace rtengine::procparams; using namespace rtengine::procparams;
@ -516,7 +518,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
show_all (); show_all ();
/* /*
// save as dialog // save as dialog
if (safe_file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR))
saveAsDialog = new SaveAsDialog (options.lastSaveAsPath); saveAsDialog = new SaveAsDialog (options.lastSaveAsPath);
else else
saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir()); saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir());
@ -813,7 +815,7 @@ void EditorPanel::close ()
navigator->previewWindow->setPreviewHandler (NULL); navigator->previewWindow->setPreviewHandler (NULL);
// If the file was deleted somewhere, the openThm.descreaseRef delete the object, but we don't know here // If the file was deleted somewhere, the openThm.descreaseRef delete the object, but we don't know here
if (safe_file_test (fname, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) {
openThm->removeThumbnailListener (this); openThm->removeThumbnailListener (this);
openThm->decreaseRef (); openThm->decreaseRef ();
} }
@ -827,7 +829,7 @@ void EditorPanel::saveProfile ()
} }
// If the file was deleted, do not generate ghost entries // If the file was deleted, do not generate ghost entries
if (safe_file_test (fname, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) {
ProcParams params; ProcParams params;
ipc->getParams (&params); ipc->getParams (&params);
@ -1573,10 +1575,10 @@ void EditorPanel::saveAsPressed ()
SaveAsDialog* saveAsDialog; SaveAsDialog* saveAsDialog;
auto toplevel = static_cast<Gtk::Window*> (get_toplevel ()); auto toplevel = static_cast<Gtk::Window*> (get_toplevel ());
if (safe_file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) {
saveAsDialog = new SaveAsDialog (options.lastSaveAsPath, toplevel); saveAsDialog = new SaveAsDialog (options.lastSaveAsPath, toplevel);
} else { } else {
saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir(), toplevel); saveAsDialog = new SaveAsDialog (PlacesBrowser::userPicturesDir (), toplevel);
} }
saveAsDialog->set_default_size (options.saveAsDialogWidth, options.saveAsDialogHeight); saveAsDialog->set_default_size (options.saveAsDialogWidth, options.saveAsDialogHeight);
@ -1620,7 +1622,7 @@ void EditorPanel::saveAsPressed ()
fnameTemp = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, dstext); fnameTemp = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, dstext);
} }
if (!safe_file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) { if (!Glib::file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) {
fnameOut = fnameTemp; fnameOut = fnameTemp;
fnameOK = true; fnameOK = true;
break; break;
@ -1731,10 +1733,11 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector<rtengine::IImage16*> *pc,
Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format); Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format);
// TODO: Just list all file with a suitable name instead of brute force...
int tries = 1; int tries = 1;
while (safe_file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) { while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) {
fileName = Glib::ustring::compose ("%1-%2.%3", fname, tries, sf.format); fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
tries++; tries++;
} }
@ -1770,99 +1773,21 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImage1
parent->setProgressStr (""); parent->setProgressStr ("");
parent->setProgress (0.); parent->setProgress (0.);
bool success = false; bool success = false;
Glib::ustring cmdLine;
Glib::ustring executable;
// start gimp
if (options.editorToSendTo == 1) { if (options.editorToSendTo == 1) {
#ifdef WIN32 success = ExtProgStore::openInGimp (filename);
executable = Glib::build_filename (Glib::build_filename (options.gimpDir, "bin"), "gimp-win-remote");
cmdLine = Glib::ustring ("\"") + executable + Glib::ustring ("\" gimp-2.4.exe ") + Glib::ustring ("\"") + filename + Glib::ustring ("\"");
if ( safe_file_test (executable, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) {
success = safe_spawn_command_line_async (cmdLine);
}
#elif defined __APPLE__
cmdLine = Glib::ustring ("open -a /Applications/GIMP.app \'") + filename + Glib::ustring ("\'");
success = safe_spawn_command_line_async (cmdLine);
std::cout << cmdLine << std::endl;
#else
cmdLine = Glib::ustring ("gimp \"") + filename + Glib::ustring ("\"");
success = safe_spawn_command_line_async (cmdLine);
std::cout << cmdLine << std::endl;
#endif
if (!success) {
#ifdef WIN32
int ver = 12;
while (!success && ver) {
executable = Glib::build_filename (Glib::build_filename (options.gimpDir, "bin"), Glib::ustring::compose (Glib::ustring ("gimp-2.%1.exe"), ver));
if ( safe_file_test (executable, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) {
cmdLine = Glib::ustring ("\"") + executable + Glib::ustring ("\" \"") + filename + Glib::ustring ("\"");
success = safe_spawn_command_line_async (cmdLine);
}
ver--;
}
#elif defined __APPLE__
cmdLine = Glib::ustring ("open -a /Applications/Gimp.app/Contents/Resources/start \'") + filename + Glib::ustring ("\'");
success = safe_spawn_command_line_async (cmdLine);
std::cout << cmdLine << std::endl;
#else
cmdLine = Glib::ustring ("gimp-remote \"") + filename + Glib::ustring ("\"");
success = safe_spawn_command_line_async (cmdLine);
std::cout << cmdLine << std::endl;
#endif
}
} else if (options.editorToSendTo == 2) { } else if (options.editorToSendTo == 2) {
#ifdef WIN32 success = ExtProgStore::openInPhotoshop (filename);
executable = Glib::build_filename (options.psDir, "Photoshop.exe");
if ( safe_file_test (executable, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) {
cmdLine = Glib::ustring ("\"") + executable + Glib::ustring ("\" \"") + filename + Glib::ustring ("\"");
success = safe_spawn_command_line_async (cmdLine);
}
#else
#ifdef __APPLE__
cmdLine = Glib::ustring ("open -a \'") + Glib::build_filename (options.psDir, "Photoshop.app\' ") + Glib::ustring ("\'") + filename + Glib::ustring ("\'");
#else
cmdLine = Glib::ustring ("\"") + Glib::build_filename (options.psDir, "Photoshop.exe") + Glib::ustring ("\" \"") + filename + Glib::ustring ("\"");
#endif
success = safe_spawn_command_line_async (cmdLine);
std::cout << cmdLine << std::endl;
#endif
} else if (options.editorToSendTo == 3) { } else if (options.editorToSendTo == 3) {
#ifdef WIN32 success = ExtProgStore::openInCustomEditor (filename);
if ( safe_file_test (options.customEditorProg, (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_EXECUTABLE)) ) {
cmdLine = Glib::ustring ("\"") + options.customEditorProg + Glib::ustring ("\" \"") + filename + Glib::ustring ("\"");
success = safe_spawn_command_line_async (cmdLine);
}
#else
#ifdef __APPLE__
cmdLine = options.customEditorProg + Glib::ustring (" \"") + filename + Glib::ustring ("\"");
#else
cmdLine = Glib::ustring ("\"") + options.customEditorProg + Glib::ustring ("\" \"") + filename + Glib::ustring ("\"");
#endif
success = safe_spawn_command_line_async (cmdLine);
std::cout << cmdLine << std::endl;
#endif
} }
if (!success) { if (!success) {
Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); Gtk::MessageDialog msgd (*parent, M("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd->set_secondary_text (M ("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY")); msgd.set_secondary_text (M("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY"));
msgd->set_title (M ("MAIN_BUTTON_SENDTOEDITOR")); msgd.set_title (M("MAIN_BUTTON_SENDTOEDITOR"));
msgd->run (); msgd.run ();
delete msgd;
} }
} }
return false; return false;

View File

@ -17,7 +17,7 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "exifpanel.h" #include "exifpanel.h"
#include "../rtengine/safegtk.h"
#include "guiutils.h" #include "guiutils.h"
#include "rtimage.h" #include "rtimage.h"
@ -46,9 +46,9 @@ ExifPanel::ExifPanel () : idata(NULL)
exifTreeModel = Gtk::TreeStore::create(exifColumns); exifTreeModel = Gtk::TreeStore::create(exifColumns);
exifTree->set_model (exifTreeModel); exifTree->set_model (exifTreeModel);
delicon = safe_create_from_file ("gtk-close.png"); delicon = RTImage::createFromFile ("gtk-close.png");
keepicon = safe_create_from_file ("gtk-apply.png"); keepicon = RTImage::createFromFile ("gtk-apply.png");
editicon = safe_create_from_file ("gtk-add.png"); editicon = RTImage::createFromFile ("gtk-add.png");
Gtk::TreeView::Column *viewcol = Gtk::manage(new Gtk::TreeView::Column ("Field Name")); Gtk::TreeView::Column *viewcol = Gtk::manage(new Gtk::TreeView::Column ("Field Name"));
Gtk::CellRendererPixbuf* render_pb = Gtk::manage(new Gtk::CellRendererPixbuf ()); Gtk::CellRendererPixbuf* render_pb = Gtk::manage(new Gtk::CellRendererPixbuf ());

View File

@ -16,183 +16,317 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <cstring>
#include "extprog.h" #include "extprog.h"
#include "multilangmgr.h"
#include "../rtengine/safegtk.h" #include <cstring>
#include <iostream>
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
// for GCC32
#ifndef _WIN32_IE
#define _WIN32_IE 0x0600
#endif
#include <shlobj.h> #include <shlobj.h>
#endif #endif
using namespace std;
#include "options.h"
#include "multilangmgr.h"
ExtProgAction::ExtProgAction() {} Glib::ustring ExtProgAction::getFullName () const
ExtProgAction::ExtProgAction(const ExtProgAction* other, int target)
: target(target), filePathEXE(other->filePathEXE), preparams(other->preparams), name(other->name) { }
Glib::ustring ExtProgAction::GetFullName()
{ {
return name + " [" + M(Glib::ustring::compose("EXTPROGTARGET_%1", target)) + "]"; return name + " [" + M(Glib::ustring::compose("EXTPROGTARGET_%1", target)) + "]";
} }
bool ExtProgAction::Execute(std::vector<Glib::ustring> fileNames) bool ExtProgAction::execute (const std::vector<Glib::ustring>& fileNames) const
{ {
if (fileNames.empty()) { if (fileNames.empty ()) {
return false; return false;
} }
// Check if they all exists (maybe not precessed yet) // Check if they all exists as they may not be processed yet.
for (int i = 0; i < fileNames.size(); i++) { for (const auto& fileName : fileNames) {
if (!safe_file_test(fileNames[i], Glib::FILE_TEST_EXISTS)) {
Gtk::MessageDialog msgd (M("MAIN_MSG_IMAGEUNPROCESSED"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); if (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS)) {
msgd.run (); continue;
return false;
} }
Gtk::MessageDialog (M("MAIN_MSG_IMAGEUNPROCESSED"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true).run ();
return false;
} }
Glib::ustring cmdLine = "\"" + filePathEXE + "\""; Glib::ustring cmdLine = "\"" + filePathEXE + "\"";
if (preparams.length() > 0) { if (!preparams.empty()) {
cmdLine += " " + preparams; cmdLine += " " + preparams;
} }
for (int i = 0; i < fileNames.size(); i++) { for (const auto& fileName : fileNames) {
cmdLine += " \"" + fileNames[i] + "\""; cmdLine += " \"" + fileName + "\"";
} }
return safe_spawn_command_line_async (cmdLine); return ExtProgStore::spawnCommandAsync (cmdLine);
} }
// Generates as singleton
ExtProgStore* ExtProgStore::getInstance() ExtProgStore* ExtProgStore::getInstance()
{ {
static ExtProgStore instance_; static ExtProgStore instance_;
return &instance_; return &instance_;
} }
ExtProgStore::~ExtProgStore()
{
for (list<ExtProgAction*>::iterator it = lActions.begin(); it != lActions.end(); it++) {
delete *it;
}
}
// Reads all profiles from the given profiles dir // Reads all profiles from the given profiles dir
void ExtProgStore::init () void ExtProgStore::init ()
{ {
MyMutex::MyLock lock(mtx); MyMutex::MyLock lock(mtx);
lActions.clear(); actions.clear ();
#ifdef WIN32 #ifdef WIN32
SearchProg("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true); // Please do not add obscure little tools here, only widely used programs.
SearchProg("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true); // They should also have a proper setup program and therefore a standard path.
SearchProg("Paint.NET", "Paint.NET\\PaintDotNet.exe", "", 0, false, true);
SearchProg("MS Image Composition Editor", "Microsoft Research\\Image Composite Editor\\ICE.exe", "", 0, false, true);
SearchProg("PTGui", "PTGui\\PTGui.exe", "", 0, false, true);
SearchProg("GeoSetter", "GeoSetter\\GeoSetter.exe", "", 0, true, true);
SearchProg("FastStone Image Viewer", "FastStone Image Viewer\\FSViewer.exe", "", 0, true, true);
SearchProg("FastPictureViewer", "FastPictureViewer\\FastPictureViewer.exe", "", 0, true, true);
if (!SearchProg("Autopano Giga 3", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga.exe", 15, true, true)) { searchProgram ("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true);
if ( !SearchProg("Autopano Pro 3", "Kolor\\Autopano Pro 3.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 3.%1\\AutopanoPro.exe", 15, true, true)) { searchProgram ("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true);
if (!SearchProg("Autopano Giga 2", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga.exe", 6, true, true)) { searchProgram ("Paint.NET", "Paint.NET\\PaintDotNet.exe", "", 0, false, true);
SearchProg("Autopano Pro 2", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 6, true, true); searchProgram ("MS Image Composition Editor", "Microsoft Research\\Image Composite Editor\\ICE.exe", "", 0, false, true);
searchProgram ("PTGui", "PTGui\\PTGui.exe", "", 0, false, true);
searchProgram ("GeoSetter", "GeoSetter\\GeoSetter.exe", "", 0, true, true);
searchProgram ("FastStone Image Viewer", "FastStone Image Viewer\\FSViewer.exe", "", 0, true, true);
searchProgram ("FastPictureViewer", "FastPictureViewer\\FastPictureViewer.exe", "", 0, true, true);
if (!searchProgram ("Autopano Giga 3", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga.exe", 15, true, true)) {
if (!searchProgram ("Autopano Pro 3", "Kolor\\Autopano Pro 3.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 3.%1\\AutopanoPro.exe", 15, true, true)) {
if (!searchProgram ("Autopano Giga 2", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga.exe", 6, true, true)) {
searchProgram ("Autopano Pro 2", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 6, true, true);
} }
} }
} }
// DO NOT add obscure little tools here, only widely used programs with proper setup program to have a standard path
#endif #endif
} }
bool ExtProgStore::SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess) bool ExtProgStore::searchProgram (const Glib::ustring& name,
const Glib::ustring& exePath,
const Glib::ustring& exePath86,
int maxVer,
bool allowRaw,
bool allowQueueProcess)
{ {
bool found = false;
#ifdef WIN32 #ifdef WIN32
// get_user_special_dir crashes on some Windows configurations. // get_user_special_dir crashes on some Windows configurations.
// so we use the safe native functions here
static Glib::ustring progFilesDir, progFilesDirx86; static Glib::ustring progFilesDir, progFilesDirx86;
if (progFilesDir.empty()) { if (progFilesDir.empty ()) {
WCHAR pathW[MAX_PATH] = {0}; WCHAR pathW[MAX_PATH];
char pathA[MAX_PATH]; char pathA[MAX_PATH];
// First prio folder (64bit, otherwise 32bit) if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PROGRAM_FILES, false)) {
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PROGRAM_FILES, false)) { if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) {
char pathA[MAX_PATH]; progFilesDir = pathA;
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
progFilesDir = Glib::ustring(pathA);
}
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PROGRAM_FILESX86, false)) {
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
progFilesDirx86 = Glib::ustring(pathA);
} }
} }
if (exePath86.empty()) { if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PROGRAM_FILESX86, false)) {
exePath86 = exePath; if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) {
progFilesDirx86 = pathA;
}
}
} }
ExtProgAction *pAct = new ExtProgAction(); ExtProgAction action;
pAct->name = name; action.name = name;
pAct->target = (allowRaw ? 1 : 2); action.target = (allowRaw ? 1 : 2);
auto& filePath = action.filePathEXE;
if (maxVer > 0) { if (maxVer > 0) {
for (int verNo = maxVer; verNo >= 0; verNo--) {
pAct->filePathEXE = progFilesDir + "\\" + Glib::ustring::compose(exePath, verNo);
if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { for (auto ver = maxVer; ver >= 0; ver--) {
filePath = progFilesDir + "\\" + Glib::ustring::compose(exePath, ver);
if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
break; break;
} }
pAct->filePathEXE = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, verNo); if (!exePath86.empty ()) {
if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { filePath = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, ver);
if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
break; break;
} }
}
pAct->filePathEXE = ""; filePath.clear ();
} }
} else { } else {
pAct->filePathEXE = progFilesDir + "\\" + exePath;
if (!safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { do {
pAct->filePathEXE = progFilesDirx86 + "\\" + exePath86; filePath = progFilesDir + "\\" + exePath;
if (!safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
pAct->filePathEXE = ""; break;
}
}
} }
if (pAct->filePathEXE.length() > 0) { if (!exePath86.empty ()) {
lActions.push_back(pAct);
filePath = progFilesDirx86 + "\\" + exePath86;
if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
break;
}
}
filePath.clear ();
} while (false);
}
if (!action.filePathEXE.empty ()) {
actions.push_back (action);
// Copy for second target
if (allowRaw && allowQueueProcess) { if (allowRaw && allowQueueProcess) {
lActions.push_back(new ExtProgAction(pAct, 2));
action.target = 2;
actions.push_back (action);
} }
found = true; return true;
} else {
delete pAct;
} }
#endif #endif
return found; return false;
}
bool ExtProgStore::spawnCommandAsync (const Glib::ustring& cmd)
{
try {
const auto encodedCmd = Glib::filename_from_utf8 (cmd);
Glib::spawn_command_line_async (encodedCmd.c_str ());
return true;
} catch (const Glib::Exception& exception) {
if (options.rtSettings.verbose) {
std::cerr << "Failed to execute \"" << cmd << "\": " << exception.what() << std::endl;
}
return false;
}
}
bool ExtProgStore::spawnCommandSync (const Glib::ustring& cmd)
{
auto exitStatus = -1;
try {
Glib::spawn_command_line_sync (cmd, NULL, NULL, &exitStatus);
} catch (const Glib::Exception& exception) {
if (options.rtSettings.verbose) {
std::cerr << "Failed to execute \"" << cmd << "\": " << exception.what() << std::endl;
}
}
return exitStatus == 0;
}
bool ExtProgStore::openInGimp (const Glib::ustring& fileName)
{
#if defined WIN32
auto executable = Glib::build_filename (options.gimpDir, "bin", "gimp-win-remote");
auto cmdLine = Glib::ustring::compose ("\"%1\" gimp-2.4.exe \"%2\"", executable, fileName);
auto success = spawnCommandAsync (cmdLine);
#elif defined __APPLE__
auto cmdLine = Glib::ustring("open -a /Applications/GIMP.app \'") + fileName + Glib::ustring("\'");
auto success = spawnCommandAsync (cmdLine);
#else
auto cmdLine = Glib::ustring("gimp \"") + fileName + Glib::ustring("\"");
auto success = spawnCommandAsync (cmdLine);
#endif
if (success) {
return true;
}
#ifdef WIN32
for (auto ver = 12; ver >= 0; --ver) {
executable = Glib::build_filename (options.gimpDir, "bin", Glib::ustring::compose (Glib::ustring("gimp-2.%1.exe"), ver));
cmdLine = Glib::ustring::compose ("\"%1\" \"%2\"", executable, fileName);
success = spawnCommandAsync (cmdLine);
if (success) {
return true;
}
}
#elif defined __APPLE__
cmdLine = Glib::ustring("open -a /Applications/Gimp.app/Contents/Resources/start \'") + fileName + Glib::ustring("\'");
success = ExtProgStore::spawnCommandAsync (cmdLine);
#else
cmdLine = Glib::ustring("gimp-remote \"") + fileName + Glib::ustring("\"");
success = ExtProgStore::spawnCommandAsync (cmdLine);
#endif
return success;
}
bool ExtProgStore::openInPhotoshop (const Glib::ustring& fileName)
{
#if defined WIN32
const auto executable = Glib::build_filename(options.psDir, "Photoshop.exe");
const auto cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" \"") + fileName + Glib::ustring("\"");
#elif defined __APPLE__
const auto cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir, "Photoshop.app\' ") + Glib::ustring("\'") + fileName + Glib::ustring("\'");
#else
const auto cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir, "Photoshop.exe") + Glib::ustring("\" \"") + fileName + Glib::ustring("\"");
#endif
return spawnCommandAsync (cmdLine);
}
bool ExtProgStore::openInCustomEditor (const Glib::ustring& fileName)
{
#if defined WIN32
const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + fileName + Glib::ustring("\"");
#elif defined __APPLE__
const auto cmdLine = options.customEditorProg + Glib::ustring(" \"") + fileName + Glib::ustring("\"");
#else
const auto cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + fileName + Glib::ustring("\"");
#endif
return spawnCommandAsync (cmdLine);
} }

View File

@ -20,42 +20,58 @@
#ifndef _EXTPROG_ #ifndef _EXTPROG_
#define _EXTPROG_ #define _EXTPROG_
#include <glibmm.h> #include <glibmm/ustring.h>
#include <list>
#include <vector>
#include "threadutils.h" #include "threadutils.h"
class ExtProgAction struct ExtProgAction
{ {
public:
ExtProgAction();
ExtProgAction(const ExtProgAction* other, int target);
Glib::ustring filePathEXE; Glib::ustring filePathEXE;
Glib::ustring preparams; // after EXE and before file names Glib::ustring preparams; // after EXE and before file names
Glib::ustring name; // already localized if necessary Glib::ustring name; // already localized if necessary
int target; // 1=RAW files, 2=batch converted files int target; // 1=RAW files, 2=batch converted files
Glib::ustring GetFullName(); // e.g. "Photoshop (RAW)" Glib::ustring getFullName () const; // e.g. "Photoshop (RAW)"
virtual bool Execute(std::vector<Glib::ustring> fileNames); bool execute (const std::vector<Glib::ustring>& fileNames) const;
}; };
// Stores all external programs that could be called by the user // Stores all external programs that could be called by the user
class ExtProgStore class ExtProgStore
{ {
MyMutex mtx; // covers actions MyMutex mtx; // covers actions
std::vector<ExtProgAction> actions;
bool SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess); bool searchProgram (const Glib::ustring& name,
const Glib::ustring& exePath,
const Glib::ustring& exePath86,
int maxVer,
bool allowRaw,
bool allowQueueProcess);
public: public:
~ExtProgStore();
void init(); // searches computer for installed standard programs
static ExtProgStore* getInstance(); static ExtProgStore* getInstance();
std::list<ExtProgAction*> lActions; // searches computer for installed standard programs
void init();
const std::vector<ExtProgAction>& getActions () const;
static bool spawnCommandAsync (const Glib::ustring& cmd);
static bool spawnCommandSync (const Glib::ustring& cmd);
static bool openInGimp (const Glib::ustring& fileName);
static bool openInPhotoshop (const Glib::ustring& fileName);
static bool openInCustomEditor (const Glib::ustring& fileName);
}; };
#define extProgStore ExtProgStore::getInstance() #define extProgStore ExtProgStore::getInstance()
inline const std::vector<ExtProgAction>& ExtProgStore::getActions () const
{
return actions;
}
#endif #endif

View File

@ -224,11 +224,9 @@ FileBrowser::FileBrowser ()
mMenuExtProgs.clear(); mMenuExtProgs.clear();
amiExtProg = NULL; amiExtProg = NULL;
for (std::list<ExtProgAction*>::iterator it = extProgStore->lActions.begin(); it != extProgStore->lActions.end(); it++) { for (const auto& action : extProgStore->getActions ()) {
ExtProgAction* pAct = *it; if (action.target == 1 || action.target == 2) {
mMenuExtProgs[action.getFullName ()] = &action;
if (pAct->target == 1 || pAct->target == 2) {
mMenuExtProgs[pAct->GetFullName()] = pAct;
} }
} }
@ -247,7 +245,7 @@ FileBrowser::FileBrowser ()
p++; p++;
} }
for (std::map<Glib::ustring, ExtProgAction*>::iterator it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) { for (auto it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) {
submenuExtProg->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p + 1); submenuExtProg->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p + 1);
p++; p++;
} }
@ -260,7 +258,7 @@ FileBrowser::FileBrowser ()
p++; p++;
} }
for (std::map<Glib::ustring, ExtProgAction*>::iterator it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) { for (auto it = mMenuExtProgs.begin(); it != mMenuExtProgs.end(); it++, itemNo++) {
pmenu->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p + 1); pmenu->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p + 1);
p++; p++;
} }
@ -736,7 +734,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m)
for (int j = 0; j < mMenuExtProgs.size(); j++) { for (int j = 0; j < mMenuExtProgs.size(); j++) {
if (m == amiExtProg[j]) { if (m == amiExtProg[j]) {
ExtProgAction* pAct = mMenuExtProgs[m->get_label()]; const auto pAct = mMenuExtProgs[m->get_label()];
// Build vector of all file names // Build vector of all file names
std::vector<Glib::ustring> selFileNames; std::vector<Glib::ustring> selFileNames;
@ -752,7 +750,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m)
selFileNames.push_back(fn); selFileNames.push_back(fn);
} }
pAct->Execute(selFileNames); pAct->execute (selFileNames);
return; return;
} }
} }

View File

@ -93,7 +93,7 @@ protected:
Gtk::MenuItem* menuExtProg; Gtk::MenuItem* menuExtProg;
Gtk::MenuItem** amiExtProg; Gtk::MenuItem** amiExtProg;
Gtk::MenuItem* miOpenDefaultViewer; Gtk::MenuItem* miOpenDefaultViewer;
std::map<Glib::ustring, ExtProgAction*> mMenuExtProgs; // key is menuitem label std::map<Glib::ustring, const ExtProgAction*> mMenuExtProgs; // key is menuitem label
Gtk::MenuItem* menuDF; Gtk::MenuItem* menuDF;
Gtk::MenuItem* selectDF; Gtk::MenuItem* selectDF;

View File

@ -17,16 +17,17 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "filebrowserentry.h" #include "filebrowserentry.h"
#include "thumbbrowserbase.h"
#include "cursormanager.h"
#include <iomanip> #include <iomanip>
#include <cstring>
#include "guiutils.h" #include "guiutils.h"
#include "threadutils.h" #include "threadutils.h"
#include "../rtengine/safegtk.h" #include "rtimage.h"
#include "cursormanager.h"
#include "thumbbrowserbase.h"
#include "inspector.h" #include "inspector.h"
#include <cstring>
#define CROPRESIZEBORDER 4 #define CROPRESIZEBORDER 4
//extern Glib::Threads::Thread* mainThread; //extern Glib::Threads::Thread* mainThread;
@ -53,9 +54,9 @@ FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname)
scale = 1; scale = 1;
if (!iconsLoaded) { if (!iconsLoaded) {
editedIcon = safe_create_from_file ("edited.png"); editedIcon = RTImage::createFromFile ("edited.png");
recentlySavedIcon = safe_create_from_file ("recent-save.png"); recentlySavedIcon = RTImage::createFromFile ("recent-save.png");
enqueuedIcon = safe_create_from_file ("processing.png"); enqueuedIcon = RTImage::createFromFile ("processing.png");
iconsLoaded = true; iconsLoaded = true;
} }

View File

@ -17,22 +17,25 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <glib/gstdio.h> #include "filecatalog.h"
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <glib/gstdio.h>
#include "../rtengine/rt_math.h" #include "../rtengine/rt_math.h"
#include "filecatalog.h" #include "guiutils.h"
#include "filepanel.h"
#include "options.h" #include "options.h"
#include "rtimage.h"
#include "cachemanager.h" #include "cachemanager.h"
#include "multilangmgr.h" #include "multilangmgr.h"
#include "guiutils.h" #include "filepanel.h"
#include "renamedlg.h" #include "renamedlg.h"
#include "thumbimageupdater.h" #include "thumbimageupdater.h"
#include "../rtengine/safegtk.h"
#include "batchqueue.h" #include "batchqueue.h"
#include "rtimage.h" #include "placesbrowser.h"
using namespace std; using namespace std;
@ -544,11 +547,44 @@ void FileCatalog::closeDir ()
std::vector<Glib::ustring> FileCatalog::getFileList () std::vector<Glib::ustring> FileCatalog::getFileList ()
{ {
std::vector<Glib::ustring> names; std::vector<Glib::ustring> names;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (selectedDirectory);
safe_build_file_list (dir, names, selectedDirectory, &(options.parsedExtensions)); std::set<Glib::ustring> extensions;
// Issue 2406 std::sort (names.begin(), names.end()); for (const auto& parsedExt : options.parsedExtensions) {
extensions.emplace (parsedExt.lowercase ());
}
try {
auto dir = Gio::File::create_for_path (selectedDirectory);
auto enumerator = dir->enumerate_children ("standard::name");
while (auto file = enumerator->next_file ()) {
const Glib::ustring fname = file->get_name ();
auto lastdot = fname.find_last_of ('.');
if (lastdot >= fname.length () - 1) {
continue;
}
const auto fext = fname.substr (lastdot + 1).lowercase ();
if (extensions.count (fext) == 0) {
continue;
}
names.emplace_back (Glib::build_filename (selectedDirectory, fname));
}
} catch (Glib::Exception& exception) {
if (options.rtSettings.verbose) {
std::cerr << "Failed to list directory \"" << selectedDirectory << "\": " << exception.what() << std::endl;
}
}
return names; return names;
} }
@ -908,35 +944,26 @@ void FileCatalog::deleteRequested (std::vector<FileBrowserEntry*> tbe, bool inc
if (msd.run() == Gtk::RESPONSE_YES) { if (msd.run() == Gtk::RESPONSE_YES) {
for (unsigned int i = 0; i < tbe.size(); i++) { for (unsigned int i = 0; i < tbe.size(); i++) {
Glib::ustring fname = tbe[i]->filename; const auto fname = tbe[i]->filename;
// remove from browser // remove from browser
FileBrowserEntry* t = fileBrowser->delEntry (fname); delete fileBrowser->delEntry (fname);
// t->thumbnail->decreaseRef ();
delete t;
// remove from cache // remove from cache
cacheMgr->deleteEntry (fname); cacheMgr->deleteEntry (fname);
// delete from file system // delete from file system
safe_g_remove (fname); ::g_remove (fname.c_str ());
// delete paramfile if found // delete paramfile if found
safe_g_remove (Glib::ustring(fname + paramFileExtension)); ::g_remove ((fname + paramFileExtension).c_str ());
safe_g_remove (Glib::ustring(removeExtension(fname) + paramFileExtension)); ::g_remove ((removeExtension(fname) + paramFileExtension).c_str ());
// delete .thm file // delete .thm file
safe_g_remove (Glib::ustring(removeExtension(fname) + ".thm")); ::g_remove ((removeExtension(fname) + ".thm").c_str ());
safe_g_remove (Glib::ustring(removeExtension(fname) + ".THM")); ::g_remove ((removeExtension(fname) + ".THM").c_str ());
if (inclBatchProcessed) { if (inclBatchProcessed) {
Glib::ustring procfName = Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format); Glib::ustring procfName = Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format);
::g_remove (procfName.c_str ());
if (safe_file_test (procfName, Glib::FILE_TEST_EXISTS)) {
safe_g_remove (procfName);
}
// delete paramfile if found
Glib::ustring procfNameParamFile = Glib::ustring::compose ("%1.%2.out%3", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format, paramFileExtension); Glib::ustring procfNameParamFile = Glib::ustring::compose ("%1.%2.out%3", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format, paramFileExtension);
::g_remove (procfNameParamFile.c_str ());
if (safe_file_test (procfNameParamFile, Glib::FILE_TEST_EXISTS)) {
safe_g_remove (procfNameParamFile);
}
} }
previewsLoaded--; previewsLoaded--;
@ -1007,7 +1034,7 @@ void FileCatalog::copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool m
while(!filecopymovecomplete) { while(!filecopymovecomplete) {
// check for filename conflicts at destination - prevent overwriting (actually RT will crash on overwriting attempt) // check for filename conflicts at destination - prevent overwriting (actually RT will crash on overwriting attempt)
if (!safe_file_test(dest_fPath, Glib::FILE_TEST_EXISTS) && !safe_file_test(dest_fPath_param, Glib::FILE_TEST_EXISTS)) { if (!Glib::file_test(dest_fPath, Glib::FILE_TEST_EXISTS) && !Glib::file_test(dest_fPath_param, Glib::FILE_TEST_EXISTS)) {
// copy/move file to destination // copy/move file to destination
Glib::RefPtr<Gio::File> dest_file = Gio::File::create_for_path ( dest_fPath ); Glib::RefPtr<Gio::File> dest_file = Gio::File::create_for_path ( dest_fPath );
@ -1028,15 +1055,15 @@ void FileCatalog::copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool m
// attempt to copy/move paramFile only if it exist next to the src // attempt to copy/move paramFile only if it exist next to the src
Glib::RefPtr<Gio::File> scr_param = Gio::File::create_for_path ( src_fPath + paramFileExtension ); Glib::RefPtr<Gio::File> scr_param = Gio::File::create_for_path ( src_fPath + paramFileExtension );
if (safe_file_test( src_fPath + paramFileExtension, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test( src_fPath + paramFileExtension, Glib::FILE_TEST_EXISTS)) {
Glib::RefPtr<Gio::File> dest_param = Gio::File::create_for_path ( dest_fPath_param); Glib::RefPtr<Gio::File> dest_param = Gio::File::create_for_path ( dest_fPath_param);
// copy/move paramFile to destination // copy/move paramFile to destination
if (moveRequested) { if (moveRequested) {
if (safe_file_test( dest_fPath + paramFileExtension, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test( dest_fPath + paramFileExtension, Glib::FILE_TEST_EXISTS)) {
// profile already got copied to destination from cache after cacheMgr->renameEntry // profile already got copied to destination from cache after cacheMgr->renameEntry
// delete source profile as cleanup // delete source profile as cleanup
safe_g_remove (src_fPath + paramFileExtension); ::g_remove ((src_fPath + paramFileExtension).c_str ());
} else { } else {
scr_param->move(dest_param); scr_param->move(dest_param);
} }
@ -1238,16 +1265,16 @@ void FileCatalog::renameRequested (std::vector<FileBrowserEntry*> tbe)
Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); Glib::ustring nfname = Glib::build_filename (dirName, nBaseName);
/* check if filename already exists*/ /* check if filename already exists*/
if (safe_file_test (nfname, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (nfname, Glib::FILE_TEST_EXISTS)) {
Glib::ustring msg_ = Glib::ustring("<b>") + nfname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "</b>"; Glib::ustring msg_ = Glib::ustring("<b>") + nfname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "</b>";
Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd.run (); msgd.run ();
} else { } else {
success = true; success = true;
if (!safe_g_rename (ofname, nfname)) { if (::g_rename (ofname.c_str (), nfname.c_str ()) == 0) {
cacheMgr->renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); cacheMgr->renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname);
safe_g_remove(ofname + paramFileExtension); ::g_remove((ofname + paramFileExtension).c_str ());
reparseDirectory (); reparseDirectory ();
} }
} }
@ -1684,7 +1711,7 @@ void FileCatalog::reparseDirectory ()
return; return;
} }
if (!safe_file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) { if (!Glib::file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) {
closeDir (); closeDir ();
return; return;
} }
@ -1696,7 +1723,7 @@ void FileCatalog::reparseDirectory ()
std::vector<Glib::ustring> fileNamesToDel; std::vector<Glib::ustring> fileNamesToDel;
for (size_t i = 0; i < t.size(); i++) for (size_t i = 0; i < t.size(); i++)
if (!safe_file_test (t[i]->filename, Glib::FILE_TEST_EXISTS)) { if (!Glib::file_test (t[i]->filename, Glib::FILE_TEST_EXISTS)) {
fileNamesToDel.push_back (t[i]->filename); fileNamesToDel.push_back (t[i]->filename);
} }
@ -1761,54 +1788,82 @@ void FileCatalog::on_dir_changed (const Glib::RefPtr<Gio::File>& file, const Gli
void FileCatalog::checkAndAddFile (Glib::RefPtr<Gio::File> file) void FileCatalog::checkAndAddFile (Glib::RefPtr<Gio::File> file)
{ {
if (!file) {
if (!file ) {
return; return;
} }
if( !file->query_exists()) { if (!file->query_exists()) {
return; return;
} }
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info(file); try {
if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { auto info = file->query_info ();
size_t lastdot = info->get_name().find_last_of ('.');
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) { if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
previewLoader->add (selectedDirectoryId, file->get_parse_name(), this); return;
}
if (!options.fbShowHidden && info->is_hidden ()) {
return;
}
Glib::ustring ext;
const auto lastdot = info->get_name ().find_last_of ('.');
if (lastdot != Glib::ustring::npos) {
ext = info->get_name ().substr (lastdot + 1);
}
if (!options.is_extention_enabled (ext)) {
return;
}
previewLoader->add (selectedDirectoryId, file->get_parse_name (), this);
previewsToLoad++; previewsToLoad++;
}
} } catch(Gio::Error&) {}
} }
void FileCatalog::addAndOpenFile (const Glib::ustring& fname) void FileCatalog::addAndOpenFile (const Glib::ustring& fname)
{ {
auto file = Gio::File::create_for_path (fname);
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path (fname);
if (!file ) { if (!file ) {
return; return;
} }
if( !file->query_exists()) { if (!file->query_exists ()) {
return; return;
} }
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info(file); try {
if( !info ) { auto info = file->query_info ();
if (!info) {
return; return;
} }
size_t lastdot = info->get_name().find_last_of ('.'); Glib::ustring ext;
auto lastdot = info->get_name().find_last_of ('.');
if (lastdot != Glib::ustring::npos) {
ext = info->get_name ().substr (lastdot + 1);
}
if (!options.is_extention_enabled(ext)) {
return;
}
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) {
// if supported, load thumbnail first // if supported, load thumbnail first
Thumbnail* tmb = cacheMgr->getEntry (file->get_parse_name()); const auto tmb = cacheMgr->getEntry (file->get_parse_name ());
if (tmb) { if (!tmb) {
FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name()); return;
}
FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name ());
previewReady (selectedDirectoryId, entry); previewReady (selectedDirectoryId, entry);
// open the file // open the file
FCOIParams* params = new FCOIParams; FCOIParams* params = new FCOIParams;
@ -1816,8 +1871,8 @@ void FileCatalog::addAndOpenFile (const Glib::ustring& fname)
params->tmb.push_back (tmb); params->tmb.push_back (tmb);
tmb->increaseRef (); tmb->increaseRef ();
g_idle_add (openRequestedUI, params); g_idle_add (openRequestedUI, params);
}
} } catch(Gio::Error&) {}
} }
void FileCatalog::emptyTrash () void FileCatalog::emptyTrash ()
@ -1989,10 +2044,9 @@ void FileCatalog::buttonBrowsePathPressed ()
FirstChar = BrowsePathValue.substr (0, 1); FirstChar = BrowsePathValue.substr (0, 1);
if (FirstChar == "~") { // home directory if (FirstChar == "~") { // home directory
DecodedPathPrefix = Glib::get_home_dir(); DecodedPathPrefix = PlacesBrowser::userHomeDir ();
} else if (FirstChar == "!") { // user's pictures directory } else if (FirstChar == "!") { // user's pictures directory
//DecodedPathPrefix = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES); DecodedPathPrefix = PlacesBrowser::userPicturesDir ();
DecodedPathPrefix = safe_get_user_picture_dir();
} }
if (!DecodedPathPrefix.empty()) { if (!DecodedPathPrefix.empty()) {
@ -2003,7 +2057,7 @@ void FileCatalog::buttonBrowsePathPressed ()
// handle shortcuts in the BrowsePath -- END // handle shortcuts in the BrowsePath -- END
// validate the path // validate the path
if (safe_file_test(BrowsePathValue, Glib::FILE_TEST_IS_DIR) && selectDir) { if (Glib::file_test(BrowsePathValue, Glib::FILE_TEST_IS_DIR) && selectDir) {
selectDir (BrowsePathValue); selectDir (BrowsePathValue);
} else } else
// error, likely path not found: show red arrow // error, likely path not found: show red arrow

View File

@ -1,4 +1,3 @@
/* /*
* This file is part of RawTherapee. * This file is part of RawTherapee.
* *
@ -18,9 +17,10 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "filepanel.h" #include "filepanel.h"
#include "rtwindow.h" #include "rtwindow.h"
#include "../rtengine/safegtk.h"
#include "inspector.h" #include "inspector.h"
#include "placesbrowser.h"
int FilePanelInitUI (void* data) int FilePanelInitUI (void* data)
{ {
@ -188,19 +188,19 @@ void FilePanel::init ()
dirBrowser->fillDirTree (); dirBrowser->fillDirTree ();
placesBrowser->refreshPlacesList (); placesBrowser->refreshPlacesList ();
if (argv1 != "" && safe_file_test (argv1, Glib::FILE_TEST_IS_DIR)) { if (argv1 != "" && Glib::file_test (argv1, Glib::FILE_TEST_IS_DIR)) {
dirBrowser->open (argv1); dirBrowser->open (argv1);
} else { } else {
if (options.startupDir == STARTUPDIR_HOME) { if (options.startupDir == STARTUPDIR_HOME) {
dirBrowser->open (safe_get_user_picture_dir()); dirBrowser->open (PlacesBrowser::userPicturesDir ());
} else if (options.startupDir == STARTUPDIR_CURRENT) { } else if (options.startupDir == STARTUPDIR_CURRENT) {
dirBrowser->open (argv0); dirBrowser->open (argv0);
} else if (options.startupDir == STARTUPDIR_CUSTOM || options.startupDir == STARTUPDIR_LAST) { } else if (options.startupDir == STARTUPDIR_CUSTOM || options.startupDir == STARTUPDIR_LAST) {
if (options.startupPath.length() && safe_file_test(options.startupPath, Glib::FILE_TEST_EXISTS) && safe_file_test(options.startupPath, Glib::FILE_TEST_IS_DIR)) { if (options.startupPath.length() && Glib::file_test(options.startupPath, Glib::FILE_TEST_EXISTS) && Glib::file_test(options.startupPath, Glib::FILE_TEST_IS_DIR)) {
dirBrowser->open (options.startupPath); dirBrowser->open (options.startupPath);
} else { } else {
// Fallback option if the path is empty or the folder doesn't exist // Fallback option if the path is empty or the folder doesn't exist
dirBrowser->open (safe_get_user_picture_dir()); dirBrowser->open (PlacesBrowser::userPicturesDir ());
} }
} }
} }
@ -333,9 +333,9 @@ void FilePanel::saveOptions ()
void FilePanel::open (const Glib::ustring& d) void FilePanel::open (const Glib::ustring& d)
{ {
if (safe_file_test (d, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (d, Glib::FILE_TEST_IS_DIR)) {
dirBrowser->open (d.c_str()); dirBrowser->open (d.c_str());
} else if (safe_file_test (d, Glib::FILE_TEST_EXISTS)) { } else if (Glib::file_test (d, Glib::FILE_TEST_EXISTS)) {
dirBrowser->open (Glib::path_get_dirname(d), Glib::path_get_basename(d)); dirBrowser->open (Glib::path_get_dirname(d), Glib::path_get_basename(d));
} }
} }

View File

@ -17,8 +17,9 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "filethumbnailbuttonset.h" #include "filethumbnailbuttonset.h"
#include "rtimage.h"
#include "multilangmgr.h" #include "multilangmgr.h"
#include "../rtengine/safegtk.h"
extern Glib::ustring argv0; extern Glib::ustring argv0;
@ -41,19 +42,19 @@ FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry)
{ {
if (!iconsLoaded) { if (!iconsLoaded) {
unRankIcon = safe_create_from_png ("ratednotg.png"); unRankIcon = RTImage::createFromPng ("ratednotg.png");
rankIcon = safe_create_from_png ("rated.png"); rankIcon = RTImage::createFromPng ("rated.png");
gRankIcon = safe_create_from_png ("grayrated.png"); gRankIcon = RTImage::createFromPng ("grayrated.png");
trashIcon = safe_create_from_png ("trash-thumbnail.png"); trashIcon = RTImage::createFromPng ("trash-thumbnail.png");
unTrashIcon = safe_create_from_png ("undelete-thumbnail.png"); unTrashIcon = RTImage::createFromPng ("undelete-thumbnail.png");
processIcon = safe_create_from_png ("processing-thumbnail.png"); processIcon = RTImage::createFromPng ("processing-thumbnail.png");
colorLabelIcon_0 = safe_create_from_png ("cglabel0.png"); //("nocolorlabel.png"); colorLabelIcon_0 = RTImage::createFromPng ("cglabel0.png"); //("nocolorlabel.png");
colorLabelIcon_1 = safe_create_from_png ("clabel1.png"); colorLabelIcon_1 = RTImage::createFromPng ("clabel1.png");
colorLabelIcon_2 = safe_create_from_png ("clabel2.png"); colorLabelIcon_2 = RTImage::createFromPng ("clabel2.png");
colorLabelIcon_3 = safe_create_from_png ("clabel3.png"); colorLabelIcon_3 = RTImage::createFromPng ("clabel3.png");
colorLabelIcon_4 = safe_create_from_png ("clabel4.png"); colorLabelIcon_4 = RTImage::createFromPng ("clabel4.png");
colorLabelIcon_5 = safe_create_from_png ("clabel5.png"); colorLabelIcon_5 = RTImage::createFromPng ("clabel5.png");
iconsLoaded = true; iconsLoaded = true;
} }

View File

@ -4,7 +4,6 @@
#include "options.h" #include "options.h"
#include "../rtengine/clutstore.h" #include "../rtengine/clutstore.h"
#include "../rtengine/safegtk.h"
using namespace rtengine; using namespace rtengine;
using namespace rtengine::procparams; using namespace rtengine::procparams;

View File

@ -19,7 +19,6 @@
#include "flatfield.h" #include "flatfield.h"
#include "options.h" #include "options.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream> #include <sstream>
#include "rtimage.h" #include "rtimage.h"
@ -140,7 +139,7 @@ void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi
} }
} }
if (safe_file_test (pp->raw.ff_file, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (pp->raw.ff_file, Glib::FILE_TEST_EXISTS)) {
flatFieldFile->set_filename (pp->raw.ff_file); flatFieldFile->set_filename (pp->raw.ff_file);
} else { } else {
flatFieldFile_Reset(); flatFieldFile_Reset();
@ -392,28 +391,21 @@ void FlatField::flatFieldAutoSelectChanged()
} }
void FlatField::setShortcutPath(Glib::ustring path) void FlatField::setShortcutPath(const Glib::ustring& path)
{ {
if (path == "") { if (path.empty ()) {
return; return;
} }
#ifdef WIN32
// Dirty workaround, waiting for a clean solution by using exceptions!
if (!safe_is_shortcut_dir(path))
#endif
{
if (lastShortcutPath != "") {
try { try {
flatFieldFile->remove_shortcut_folder(lastShortcutPath);
} catch (Glib::Error &err) {} if (!lastShortcutPath.empty ()) {
flatFieldFile->remove_shortcut_folder (lastShortcutPath);
} }
flatFieldFile->add_shortcut_folder (path);
lastShortcutPath = path; lastShortcutPath = path;
try { } catch (Glib::Error&) {}
flatFieldFile->add_shortcut_folder(path);
} catch (Glib::Error &err) {}
}
} }

View File

@ -75,7 +75,7 @@ public:
void flatFieldFile_Reset (); void flatFieldFile_Reset ();
void flatFieldAutoSelectChanged (); void flatFieldAutoSelectChanged ();
void flatFieldBlurTypeChanged (); void flatFieldBlurTypeChanged ();
void setShortcutPath(Glib::ustring path); void setShortcutPath (const Glib::ustring& path);
void setFFProvider (FFProvider* p) void setFFProvider (FFProvider* p)
{ {
ffp = p; ffp = p;

View File

@ -156,29 +156,24 @@ void Gradient::updateGeometry(const int centerX, const int centerY, const double
} }
} }
PolarCoord polCoord1, polCoord2; const auto decay = feather * rtengine::norm2<double> (imW, imH) / 200.0;
double decay = feather * rtengine::norm2<double>(imW, imH) / 200.; rtengine::Coord origin (imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200);
rtengine::Coord origin(imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200);
Line *currLine;
Circle *currCircle;
const auto updateLine = [&](Geometry* geometry, const float radius, const float begin, const float end) const auto updateLine = [&](Geometry* geometry, const float radius, const float begin, const float end)
{ {
const auto line = static_cast<Line*>(geometry); const auto line = static_cast<Line*>(geometry);
line->begin.setFromPolar(PolarCoord(radius, -degree + begin)); line->begin = PolarCoord(radius, -degree + begin);
line->begin += origin; line->begin += origin;
line->end.setFromPolar(PolarCoord(radius, -degree + end)); line->end = PolarCoord(radius, -degree + end);
line->end += origin; line->end += origin;
}; };
const auto updateLineWithDecay = [&](Geometry* geometry, const float radius, const float offSetAngle) const auto updateLineWithDecay = [&](Geometry* geometry, const float radius, const float offSetAngle)
{ {
const auto line = static_cast<Line*>(geometry); const auto line = static_cast<Line*>(geometry);
line->begin.setFromPolar(PolarCoord(radius, -degree + 180.) + PolarCoord(decay, -degree + offSetAngle)); line->begin = PolarCoord (radius, -degree + 180.) + PolarCoord (decay, -degree + offSetAngle);
line->begin += origin; line->begin += origin;
line->end.setFromPolar(PolarCoord(radius, -degree) + PolarCoord(decay, -degree + offSetAngle)); line->end = PolarCoord (radius, -degree) + PolarCoord (decay, -degree + offSetAngle);
line->end += origin; line->end += origin;
}; };
@ -408,7 +403,7 @@ bool Gradient::button1Pressed(int modifierKey)
p1.y = p2.y; p1.y = p2.y;
p2.y = p; p2.y = p;
pCoord.setFromCartesian(p1, p2); pCoord = p2 - p1;
draggedPointOldAngle = pCoord.angle; draggedPointOldAngle = pCoord.angle;
//printf("\ndraggedPointOldAngle=%.3f\n\n", draggedPointOldAngle); //printf("\ndraggedPointOldAngle=%.3f\n\n", draggedPointOldAngle);
draggedPointAdjusterAngle = degree->getValue(); draggedPointAdjusterAngle = degree->getValue();
@ -427,7 +422,7 @@ bool Gradient::button1Pressed(int modifierKey)
centerPos.y = currPos.y; centerPos.y = currPos.y;
currPos.y = p; currPos.y = p;
draggedPoint.setFromCartesian(centerPos, currPos); draggedPoint = currPos - centerPos;
// compute the projected value of the dragged point // compute the projected value of the dragged point
draggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle - degree->getValue()) / 180.*M_PI); draggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle - degree->getValue()) / 180.*M_PI);
@ -485,7 +480,7 @@ bool Gradient::drag1(int modifierKey)
centerPos.y = currPos.y; centerPos.y = currPos.y;
currPos.y = p; currPos.y = p;
draggedPoint.setFromCartesian(centerPos, currPos); draggedPoint = currPos - centerPos;
double deltaAngle = draggedPoint.angle - draggedPointOldAngle; double deltaAngle = draggedPoint.angle - draggedPointOldAngle;
if (deltaAngle > 180.) { // crossing the boundary (0->360) if (deltaAngle > 180.) { // crossing the boundary (0->360)
@ -530,7 +525,7 @@ bool Gradient::drag1(int modifierKey)
centerPos.y = currPos.y; centerPos.y = currPos.y;
currPos.y = p; currPos.y = p;
draggedPoint.setFromCartesian(centerPos, currPos); draggedPoint = currPos - centerPos;
double currDraggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle - degree->getValue()) / 180.*M_PI); double currDraggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle - degree->getValue()) / 180.*M_PI);
if (lastObject == 2) if (lastObject == 2)

View File

@ -22,7 +22,6 @@
#include "options.h" #include "options.h"
#include "../rtengine/rt_math.h" #include "../rtengine/rt_math.h"
#include "../rtengine/utils.h" #include "../rtengine/utils.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
#include "multilangmgr.h" #include "multilangmgr.h"
@ -202,7 +201,7 @@ bool confirmOverwrite (Gtk::Window& parent, const std::string& filename)
{ {
bool safe = true; bool safe = true;
if (safe_file_test (filename, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (filename, Glib::FILE_TEST_EXISTS)) {
Glib::ustring msg_ = Glib::ustring ("<b>\"") + Glib::path_get_basename (filename) + "\": " Glib::ustring msg_ = Glib::ustring ("<b>\"") + Glib::path_get_basename (filename) + "\": "
+ M("MAIN_MSG_ALREADYEXISTS") + "</b>\n" + M("MAIN_MSG_QOVERWRITE"); + M("MAIN_MSG_ALREADYEXISTS") + "</b>\n" + M("MAIN_MSG_QOVERWRITE");
Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);

View File

@ -20,7 +20,6 @@
#include "icmpanel.h" #include "icmpanel.h"
#include "options.h" #include "options.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/iccstore.h" #include "../rtengine/iccstore.h"
#include "../rtengine/dcp.h" #include "../rtengine/dcp.h"
#include "rtimage.h" #include "rtimage.h"
@ -609,7 +608,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
} else if (icameraICC->get_active ()) { } else if (icameraICC->get_active ()) {
pp->icm.input = "(cameraICC)"; pp->icm.input = "(cameraICC)";
} else { } else {
if (safe_file_test (ipDialog->get_filename (), Glib::FILE_TEST_EXISTS) && !safe_file_test (ipDialog->get_filename (), Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (ipDialog->get_filename (), Glib::FILE_TEST_EXISTS) && !Glib::file_test (ipDialog->get_filename (), Glib::FILE_TEST_IS_DIR)) {
pp->icm.input = "file:" + ipDialog->get_filename (); pp->icm.input = "file:" + ipDialog->get_filename ();
} else { } else {
pp->icm.input = ""; // just a directory pp->icm.input = ""; // just a directory

View File

@ -22,14 +22,13 @@
#include "cursormanager.h" #include "cursormanager.h"
#include "guiutils.h" #include "guiutils.h"
#include "options.h" #include "options.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/previewimage.h" #include "../rtengine/previewimage.h"
extern Options options; extern Options options;
InspectorBuffer::InspectorBuffer(const Glib::ustring &imagePath) : currTransform(0), fromRaw(false) InspectorBuffer::InspectorBuffer(const Glib::ustring &imagePath) : currTransform(0), fromRaw(false)
{ {
if (!imagePath.empty() && safe_file_test(imagePath, Glib::FILE_TEST_EXISTS) && !safe_file_test(imagePath, Glib::FILE_TEST_IS_DIR)) { if (!imagePath.empty() && Glib::file_test(imagePath, Glib::FILE_TEST_EXISTS) && !Glib::file_test(imagePath, Glib::FILE_TEST_IS_DIR)) {
imgPath = imagePath; imgPath = imagePath;
// generate thumbnail image // generate thumbnail image

View File

@ -19,7 +19,6 @@
#include <glibmm.h> #include <glibmm.h>
#include "lensprofile.h" #include "lensprofile.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/lcp.h" #include "../rtengine/lcp.h"
#include <sstream> #include <sstream>
#include "rtimage.h" #include "rtimage.h"

View File

@ -54,8 +54,6 @@
#include "conio.h" #include "conio.h"
#endif #endif
#include "../rtengine/safegtk.h"
extern Options options; extern Options options;
// stores path to data files // stores path to data files
@ -69,6 +67,29 @@ Glib::RefPtr<Gtk::CssProvider> cssForced;
Glib::RefPtr<Gtk::CssProvider> cssRT; Glib::RefPtr<Gtk::CssProvider> cssRT;
//Glib::Threads::Thread* mainThread; //Glib::Threads::Thread* mainThread;
namespace
{
// For an unknown reason, Glib::filename_to_utf8 doesn't work on reliably Windows,
// so we're using Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows.
Glib::ustring fname_to_utf8 (const char* fname)
{
#ifdef WIN32
try {
return Glib::locale_to_utf8 (fname);
} catch (Glib::Error&) {
return Glib::convert_with_fallback (fname, "UTF-8", "ISO-8859-1", "?");
}
#else
return Glib::filename_to_utf8 (fname);
#endif
}
}
// This recursive mutex will be used by gdk_threads_enter/leave instead of a simple mutex // This recursive mutex will be used by gdk_threads_enter/leave instead of a simple mutex
#ifdef WIN32 #ifdef WIN32
@ -177,7 +198,7 @@ int main(int argc, char **argv)
bool consoleOpened = false; bool consoleOpened = false;
if (argc > 1 || options.rtSettings.verbose) { if (argc > 1 || options.rtSettings.verbose) {
if(options.rtSettings.verbose || ( !safe_file_test( safe_filename_to_utf8(argv[1]), Glib::FILE_TEST_EXISTS ) && !safe_file_test( safe_filename_to_utf8(argv[1]), Glib::FILE_TEST_IS_DIR ))) { if (options.rtSettings.verbose || ( !Glib::file_test (fname_to_utf8 (argv[1]), Glib::FILE_TEST_EXISTS ) && !Glib::file_test (fname_to_utf8 (argv[1]), Glib::FILE_TEST_IS_DIR))) {
bool stdoutRedirectedtoFile = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == 0x0001); bool stdoutRedirectedtoFile = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == 0x0001);
bool stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001); bool stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001);
@ -270,8 +291,8 @@ int main(int argc, char **argv)
#ifndef WIN32 #ifndef WIN32
// Move the old path to the new one if the new does not exist // Move the old path to the new one if the new does not exist
if (safe_file_test(Glib::build_filename(options.rtdir, "cache"), Glib::FILE_TEST_IS_DIR) && !safe_file_test(options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test(Glib::build_filename(options.rtdir, "cache"), Glib::FILE_TEST_IS_DIR) && !Glib::file_test(options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) {
safe_g_rename(Glib::build_filename(options.rtdir, "cache"), options.cacheBaseDir); g_rename(Glib::build_filename (options.rtdir, "cache").c_str (), options.cacheBaseDir.c_str ());
} }
#endif #endif
@ -279,7 +300,7 @@ int main(int argc, char **argv)
simpleEditor = false; simpleEditor = false;
if( !argv1.empty() ) if( !argv1.empty() )
if( safe_file_test(argv1, Glib::FILE_TEST_EXISTS) && !safe_file_test(argv1, Glib::FILE_TEST_IS_DIR)) { if( Glib::file_test(argv1, Glib::FILE_TEST_EXISTS) && !Glib::file_test(argv1, Glib::FILE_TEST_IS_DIR)) {
simpleEditor = true; simpleEditor = true;
} }
@ -421,9 +442,9 @@ int processLineParams( int argc, char **argv )
case 'o': // outputfile or dir case 'o': // outputfile or dir
if( iArg + 1 < argc ) { if( iArg + 1 < argc ) {
iArg++; iArg++;
outputPath = safe_filename_to_utf8 (argv[iArg]); outputPath = fname_to_utf8 (argv[iArg]);
if( safe_file_test (outputPath, Glib::FILE_TEST_IS_DIR)) { if( Glib::file_test (outputPath, Glib::FILE_TEST_IS_DIR)) {
outputDirectory = true; outputDirectory = true;
} }
} }
@ -435,7 +456,7 @@ int processLineParams( int argc, char **argv )
// RT stop if any of them can't be loaded for any reason. // RT stop if any of them can't be loaded for any reason.
if( iArg + 1 < argc ) { if( iArg + 1 < argc ) {
iArg++; iArg++;
Glib::ustring fname = safe_filename_to_utf8 ( argv[iArg] ); Glib::ustring fname = fname_to_utf8 (argv[iArg]);
if (fname.at(0) == '-') { if (fname.at(0) == '-') {
std::cerr << "Error: filename missing next to the -p switch" << std::endl; std::cerr << "Error: filename missing next to the -p switch" << std::endl;
@ -523,39 +544,54 @@ int processLineParams( int argc, char **argv )
break; break;
case 'c': // MUST be last option case 'c': // MUST be last option
while( iArg + 1 < argc ) { while (iArg + 1 < argc) {
iArg++; iArg++;
if( !safe_file_test( safe_filename_to_utf8(argv[iArg]), Glib::FILE_TEST_EXISTS )) { const auto argument = fname_to_utf8 (argv[iArg]);
std::cerr << argv[iArg] << " doesn't exist." << std::endl;
if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) {
inputFiles.emplace_back (argument);
continue; continue;
} }
if( safe_file_test( safe_filename_to_utf8(argv[iArg]), Glib::FILE_TEST_IS_DIR )) { if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) {
std::vector<Glib::ustring> names;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path ( argv[iArg] );
safe_build_file_list (dir, names, argv[iArg] );
for(size_t iFile = 0; iFile < names.size(); iFile++ ) { auto dir = Gio::File::create_for_path (argument);
if( !safe_file_test( names[iFile] , Glib::FILE_TEST_IS_DIR)) { if (!dir || !dir->query_exists()) {
// skip files without extension and without sidecar files
Glib::ustring s(names[iFile]);
Glib::ustring::size_type ext = s.find_last_of('.');
if( Glib::ustring::npos == ext ) {
continue; continue;
} }
if( ! s.substr(ext).compare( paramFileExtension )) { try {
auto enumerator = dir->enumerate_children ();
while (auto file = enumerator->next_file ()) {
const auto fileName = Glib::build_filename (argument, file->get_name ());
if (Glib::file_test (fileName, Glib::FILE_TEST_IS_DIR)) {
continue; continue;
} }
inputFiles.push_back( names[iFile] ); // skip files without extension and sidecar files
auto lastdot = fileName.find_last_of('.');
if (lastdot == Glib::ustring::npos) {
continue;
} }
if (fileName.substr (lastdot).compare (paramFileExtension) == 0) {
continue;
} }
} else {
inputFiles.push_back( safe_filename_to_utf8 (argv[iArg]) ); inputFiles.emplace_back (fileName);
} }
} catch (Glib::Exception&) {}
continue;
}
std::cerr << "\"" << argument << "\" is neither a regular file nor a directory." << std::endl;
} }
break; break;
@ -626,7 +662,7 @@ int processLineParams( int argc, char **argv )
} }
} }
} else { } else {
argv1 = safe_filename_to_utf8 ( argv[iArg] ); argv1 = fname_to_utf8 (argv[iArg]);
if( outputDirectory ) { if( outputDirectory ) {
options.savePathFolder = outputPath; options.savePathFolder = outputPath;
@ -727,7 +763,7 @@ int processLineParams( int argc, char **argv )
continue; continue;
} }
if( !overwriteFiles && safe_file_test( outputFile , Glib::FILE_TEST_EXISTS ) ) { if( !overwriteFiles && Glib::file_test( outputFile , Glib::FILE_TEST_EXISTS ) ) {
std::cerr << outputFile << " already exists: use -Y option to overwrite. This image has been skipped." << std::endl; std::cerr << outputFile << " already exists: use -Y option to overwrite. This image has been skipped." << std::endl;
continue; continue;
} }
@ -768,7 +804,7 @@ int processLineParams( int argc, char **argv )
Glib::ustring sideProcessingParams = inputFile + paramFileExtension; Glib::ustring sideProcessingParams = inputFile + paramFileExtension;
// the "load" method don't reset the procparams values anymore, so values found in the procparam file override the one of currentParams // the "load" method don't reset the procparams values anymore, so values found in the procparam file override the one of currentParams
if( !safe_file_test( sideProcessingParams, Glib::FILE_TEST_EXISTS ) || currentParams.load ( sideProcessingParams )) { if( !Glib::file_test( sideProcessingParams, Glib::FILE_TEST_EXISTS ) || currentParams.load ( sideProcessingParams )) {
std::cerr << "Warning: sidecar file requested but not found for: " << sideProcessingParams << std::endl; std::cerr << "Warning: sidecar file requested but not found for: " << sideProcessingParams << std::endl;
} else { } else {
sideCarFound = true; sideCarFound = true;

View File

@ -21,10 +21,8 @@
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <sstream> #include <sstream>
#include "multilangmgr.h" #include "multilangmgr.h"
#include "../rtengine/safekeyfile.h"
#include "addsetids.h" #include "addsetids.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "version.h" #include "version.h"
#ifdef _OPENMP #ifdef _OPENMP
@ -70,13 +68,13 @@ inline bool Options::checkProfilePath(Glib::ustring &path)
Glib::ustring p = getUserProfilePath(); Glib::ustring p = getUserProfilePath();
if (!p.empty() && safe_file_test (path + paramFileExtension, Glib::FILE_TEST_EXISTS)) { if (!p.empty() && Glib::file_test (path + paramFileExtension, Glib::FILE_TEST_EXISTS)) {
return true; return true;
} }
p = getGlobalProfilePath(); p = getGlobalProfilePath();
if (!p.empty() && safe_file_test (path + paramFileExtension, Glib::FILE_TEST_EXISTS)) { if (!p.empty() && Glib::file_test (path + paramFileExtension, Glib::FILE_TEST_EXISTS)) {
return true; return true;
} else { } else {
return false; return false;
@ -85,7 +83,7 @@ inline bool Options::checkProfilePath(Glib::ustring &path)
bool Options::checkDirPath(Glib::ustring &path, Glib::ustring errString) bool Options::checkDirPath(Glib::ustring &path, Glib::ustring errString)
{ {
if (safe_file_test (path, Glib::FILE_TEST_EXISTS) && safe_file_test (path, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (path, Glib::FILE_TEST_EXISTS) && Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
return true; return true;
} else { } else {
if (!errString.empty()) { if (!errString.empty()) {
@ -107,7 +105,7 @@ void Options::updatePaths()
if (Glib::path_is_absolute(profilePath)) { if (Glib::path_is_absolute(profilePath)) {
// absolute path // absolute path
if (!checkDirPath (profilePath, "")) { if (!checkDirPath (profilePath, "")) {
safe_g_mkdir_with_parents (profilePath, 511); g_mkdir_with_parents (profilePath.c_str (), 511);
if (!checkDirPath (profilePath, "")) { // had problems with mkdir_with_parents return value on OS X, just check dir again if (!checkDirPath (profilePath, "")) { // had problems with mkdir_with_parents return value on OS X, just check dir again
printf("Error: user's profiles' directory \"%s\" creation failed\n", profilePath.c_str()); printf("Error: user's profiles' directory \"%s\" creation failed\n", profilePath.c_str());
@ -140,7 +138,7 @@ void Options::updatePaths()
tmpPath = Glib::build_filename(rtdir, profilePath); tmpPath = Glib::build_filename(rtdir, profilePath);
if (!checkDirPath (tmpPath, "")) { if (!checkDirPath (tmpPath, "")) {
safe_g_mkdir_with_parents (tmpPath, 511); g_mkdir_with_parents (tmpPath.c_str (), 511);
if (!checkDirPath (tmpPath, "")) { if (!checkDirPath (tmpPath, "")) {
printf("Error: user's profiles' directory \"%s\" creation failed\n", tmpPath.c_str()); printf("Error: user's profiles' directory \"%s\" creation failed\n", tmpPath.c_str());
@ -170,51 +168,51 @@ void Options::updatePaths()
Glib::ustring preferredPath = getPreferredProfilePath(); Glib::ustring preferredPath = getPreferredProfilePath();
// Paths are updated only if the user or global profile path is set // Paths are updated only if the user or global profile path is set
if (lastRgbCurvesDir.empty() || !safe_file_test (lastRgbCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastRgbCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastRgbCurvesDir.empty() || !Glib::file_test (lastRgbCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastRgbCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastRgbCurvesDir = preferredPath; lastRgbCurvesDir = preferredPath;
} }
if (lastLabCurvesDir.empty() || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastLabCurvesDir.empty() || !Glib::file_test (lastLabCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastLabCurvesDir = preferredPath; lastLabCurvesDir = preferredPath;
} }
if (lastRetinexDir.empty() || !safe_file_test (lastRetinexDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastRetinexDir.empty() || !Glib::file_test (lastRetinexDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastRetinexDir = preferredPath; lastRetinexDir = preferredPath;
} }
if (lastDenoiseCurvesDir.empty() || !safe_file_test (lastDenoiseCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastDenoiseCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastDenoiseCurvesDir.empty() || !Glib::file_test (lastDenoiseCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastDenoiseCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastDenoiseCurvesDir = preferredPath; lastDenoiseCurvesDir = preferredPath;
} }
if (lastWaveletCurvesDir.empty() || !safe_file_test (lastWaveletCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastWaveletCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastWaveletCurvesDir.empty() || !Glib::file_test (lastWaveletCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastWaveletCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastWaveletCurvesDir = preferredPath; lastWaveletCurvesDir = preferredPath;
} }
if (lastPFCurvesDir.empty() || !safe_file_test (lastPFCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastPFCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastPFCurvesDir.empty() || !Glib::file_test (lastPFCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastPFCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastPFCurvesDir = preferredPath; lastPFCurvesDir = preferredPath;
} }
if (lastHsvCurvesDir.empty() || !safe_file_test (lastHsvCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastHsvCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastHsvCurvesDir.empty() || !Glib::file_test (lastHsvCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastHsvCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastHsvCurvesDir = preferredPath; lastHsvCurvesDir = preferredPath;
} }
if (lastToneCurvesDir.empty() || !safe_file_test (lastToneCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastToneCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastToneCurvesDir.empty() || !Glib::file_test (lastToneCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastToneCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastToneCurvesDir = preferredPath; lastToneCurvesDir = preferredPath;
} }
if (lastProfilingReferenceDir.empty() || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR)) { if (lastProfilingReferenceDir.empty() || !Glib::file_test (lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR)) {
lastProfilingReferenceDir = preferredPath; lastProfilingReferenceDir = preferredPath;
} }
if (lastVibranceCurvesDir.empty() || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastVibranceCurvesDir.empty() || !Glib::file_test (lastVibranceCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastVibranceCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastVibranceCurvesDir = preferredPath; lastVibranceCurvesDir = preferredPath;
} }
if (loadSaveProfilePath.empty() || !safe_file_test (loadSaveProfilePath, Glib::FILE_TEST_EXISTS) || !safe_file_test (loadSaveProfilePath, Glib::FILE_TEST_IS_DIR)) { if (loadSaveProfilePath.empty() || !Glib::file_test (loadSaveProfilePath, Glib::FILE_TEST_EXISTS) || !Glib::file_test (loadSaveProfilePath, Glib::FILE_TEST_IS_DIR)) {
loadSaveProfilePath = preferredPath; loadSaveProfilePath = preferredPath;
} }
if (lastBWCurvesDir.empty() || !safe_file_test (lastBWCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastBWCurvesDir, Glib::FILE_TEST_IS_DIR)) { if (lastBWCurvesDir.empty() || !Glib::file_test (lastBWCurvesDir, Glib::FILE_TEST_EXISTS) || !Glib::file_test (lastBWCurvesDir, Glib::FILE_TEST_IS_DIR)) {
lastBWCurvesDir = preferredPath; lastBWCurvesDir = preferredPath;
} }
@ -255,7 +253,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getUserProfilePath(); p = getUserProfilePath();
Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension); Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension);
if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { if (!p.empty() && Glib::file_test (fullPath, Glib::FILE_TEST_EXISTS)) {
return Glib::path_get_dirname(fullPath); return Glib::path_get_dirname(fullPath);
} }
} else if (p == "${G}") { } else if (p == "${G}") {
@ -263,7 +261,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getGlobalProfilePath(); p = getGlobalProfilePath();
Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension); Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension);
if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { if (!p.empty() && Glib::file_test (fullPath, Glib::FILE_TEST_EXISTS)) {
return Glib::path_get_dirname(fullPath); return Glib::path_get_dirname(fullPath);
} }
} else { } else {
@ -271,7 +269,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getUserProfilePath(); p = getUserProfilePath();
Glib::ustring fullPath = Glib::build_filename(p, profName + paramFileExtension); Glib::ustring fullPath = Glib::build_filename(p, profName + paramFileExtension);
if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { if (!p.empty() && Glib::file_test (fullPath, Glib::FILE_TEST_EXISTS)) {
// update the profile path // update the profile path
profName = Glib::build_filename("${U}", profName); profName = Glib::build_filename("${U}", profName);
return Glib::path_get_dirname(fullPath); return Glib::path_get_dirname(fullPath);
@ -280,7 +278,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getGlobalProfilePath(); p = getGlobalProfilePath();
fullPath = Glib::build_filename(p, profName + paramFileExtension); fullPath = Glib::build_filename(p, profName + paramFileExtension);
if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { if (!p.empty() && Glib::file_test (fullPath, Glib::FILE_TEST_EXISTS)) {
profName = Glib::build_filename("${G}", profName); profName = Glib::build_filename("${G}", profName);
return Glib::path_get_dirname(fullPath); return Glib::path_get_dirname(fullPath);
} }
@ -726,9 +724,10 @@ void Options::filterOutParsedExtensions ()
int Options::readFromFile (Glib::ustring fname) int Options::readFromFile (Glib::ustring fname)
{ {
setlocale(LC_NUMERIC, "C"); // to set decimal point to "." setlocale(LC_NUMERIC, "C"); // to set decimal point to "."
rtengine::SafeKeyFile keyFile;
if( !safe_file_test(fname, Glib::FILE_TEST_EXISTS)) { Glib::KeyFile keyFile;
if( !Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) {
return 1; return 1;
} }
@ -1774,33 +1773,43 @@ int Options::readFromFile (Glib::ustring fname)
if (options.rtSettings.verbose) { if (options.rtSettings.verbose) {
printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); printf("Options::readFromFile / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str());
} }
setDefaults ();
} catch (...) { } catch (...) {
if (options.rtSettings.verbose) { if (options.rtSettings.verbose) {
printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
} }
setDefaults ();
} }
return 1; return 1;
} }
bool Options::safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustring& section, bool Options::safeDirGet(const Glib::KeyFile& keyFile, const Glib::ustring& section,
const Glib::ustring& entryName, Glib::ustring& destination) const Glib::ustring& entryName, Glib::ustring& destination)
{ {
if (keyFile.has_key(section, entryName) && !keyFile.get_string(section, entryName).empty()) { try {
destination = keyFile.get_string(section, entryName);
if (keyFile.has_key (section, entryName) && !keyFile.get_string (section, entryName).empty ()) {
destination = keyFile.get_string (section, entryName);
return true; return true;
} }
} catch(Glib::KeyFileError&) {}
return false; return false;
} }
int Options::saveToFile (Glib::ustring fname) int Options::saveToFile (Glib::ustring fname)
{ {
rtengine::SafeKeyFile keyFile; Glib::ustring keyData;
keyFile.set_boolean ("General", "TabbedEditor", tabbedUI);
try {
Glib::KeyFile keyFile;
keyFile.set_boolean ("General", "TabbedEditor", tabbedUI);
keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit); keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit);
if (startupDir == STARTUPDIR_HOME) { if (startupDir == STARTUPDIR_HOME) {
@ -2099,7 +2108,15 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir);
keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir);
FILE *f = safe_g_fopen (fname, "wt"); keyData = keyFile.to_data ();
} catch (Glib::KeyFileError&) {}
if (keyData.empty ()) {
return 1;
}
FILE *f = g_fopen (fname.c_str (), "wt");
if (f == NULL) { if (f == NULL) {
if (options.rtSettings.verbose) { if (options.rtSettings.verbose) {
@ -2108,7 +2125,7 @@ int Options::saveToFile (Glib::ustring fname)
return 1; return 1;
} else { } else {
fprintf (f, "%s", keyFile.to_data().c_str()); fprintf (f, "%s", keyData.c_str ());
fclose (f); fclose (f);
return 0; return 0;
} }
@ -2181,14 +2198,14 @@ bool Options::load ()
int r = options.readFromFile (Glib::build_filename(rtdir, "options")); int r = options.readFromFile (Glib::build_filename(rtdir, "options"));
// If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it // If the local option file does not exist or is broken, and the local cache folder does not exist, recreate it
if (r && !safe_g_mkdir_with_parents (rtdir, 511)) { if (r && !g_mkdir_with_parents (rtdir.c_str (), 511)) {
// Save the option file // Save the option file
options.saveToFile (Glib::build_filename(rtdir, "options")); options.saveToFile (Glib::build_filename(rtdir, "options"));
} }
#ifdef __APPLE__ #ifdef __APPLE__
// make sure .local/share exists on OS X so we don't get problems with recently-used.xbel // make sure .local/share exists on OS X so we don't get problems with recently-used.xbel
safe_g_mkdir_with_parents (g_get_user_data_dir(), 511); g_mkdir_with_parents (g_get_user_data_dir(), 511);
#endif #endif
} }

View File

@ -58,11 +58,6 @@ enum PPLoadLocation {PLL_Cache = 0, PLL_Input = 1};
enum CPBKeyType {CPBKT_TID = 0, CPBKT_NAME = 1, CPBKT_TID_NAME = 2}; enum CPBKeyType {CPBKT_TID = 0, CPBKT_NAME = 1, CPBKT_TID_NAME = 2};
enum prevdemo_t {PD_Sidecar = 1, PD_Fast = 0}; enum prevdemo_t {PD_Sidecar = 1, PD_Fast = 0};
namespace rtengine
{
class SafeKeyFile;
}
class Options class Options
{ {
@ -87,7 +82,7 @@ private:
* @param destination destination variable to store to * @param destination destination variable to store to
* @return @c true if @p destination was changed * @return @c true if @p destination was changed
*/ */
bool safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustring& section, bool safeDirGet(const Glib::KeyFile& keyFile, const Glib::ustring& section,
const Glib::ustring& entryName, Glib::ustring& destination); const Glib::ustring& entryName, Glib::ustring& destination);
public: public:

View File

@ -375,6 +375,7 @@ void ParamsEdited::set (bool v)
raw.xtranssensor.exBlackGreen = v; raw.xtranssensor.exBlackGreen = v;
raw.xtranssensor.exBlackBlue = v; raw.xtranssensor.exBlackBlue = v;
raw.caCorrection = v; raw.caCorrection = v;
raw.caAutoStrength = v;
raw.caBlue = v; raw.caBlue = v;
raw.caRed = v; raw.caRed = v;
raw.hotPixelFilter = v; raw.hotPixelFilter = v;
@ -487,6 +488,8 @@ void ParamsEdited::set (bool v)
dirpyrequalizer.enabled = v; dirpyrequalizer.enabled = v;
dirpyrequalizer.gamutlab = v; dirpyrequalizer.gamutlab = v;
dirpyrequalizer.cbdlMethod = v;
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
dirpyrequalizer.mult[i] = v; dirpyrequalizer.mult[i] = v;
@ -865,6 +868,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
raw.xtranssensor.exBlackGreen = raw.xtranssensor.exBlackGreen && p.raw.xtranssensor.blackgreen == other.raw.xtranssensor.blackgreen; raw.xtranssensor.exBlackGreen = raw.xtranssensor.exBlackGreen && p.raw.xtranssensor.blackgreen == other.raw.xtranssensor.blackgreen;
raw.xtranssensor.exBlackBlue = raw.xtranssensor.exBlackBlue && p.raw.xtranssensor.blackblue == other.raw.xtranssensor.blackblue; raw.xtranssensor.exBlackBlue = raw.xtranssensor.exBlackBlue && p.raw.xtranssensor.blackblue == other.raw.xtranssensor.blackblue;
raw.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect; raw.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect;
raw.caAutoStrength = raw.caAutoStrength && p.raw.caautostrength == other.raw.caautostrength;
raw.caRed = raw.caRed && p.raw.cared == other.raw.cared; raw.caRed = raw.caRed && p.raw.cared == other.raw.cared;
raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue; raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue;
raw.hotPixelFilter = raw.hotPixelFilter && p.raw.hotPixelFilter == other.raw.hotPixelFilter; raw.hotPixelFilter = raw.hotPixelFilter && p.raw.hotPixelFilter == other.raw.hotPixelFilter;
@ -973,6 +977,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled;
dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab; dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab;
dirpyrequalizer.cbdlMethod = dirpyrequalizer.cbdlMethod && p.dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod;
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i]; dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i];
@ -2290,6 +2295,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect;
} }
if (raw.caAutoStrength) {
toEdit.raw.caautostrength = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.caautostrength + mods.raw.caautostrength : mods.raw.caautostrength;
}
if (raw.caRed) { if (raw.caRed) {
toEdit.raw.cared = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cared + mods.raw.cared : mods.raw.cared; toEdit.raw.cared = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.cared + mods.raw.cared : mods.raw.cared;
} }
@ -2700,6 +2709,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab;
} }
if (dirpyrequalizer.cbdlMethod) {
toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod;
}
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
if(dirpyrequalizer.mult[i]) { if(dirpyrequalizer.mult[i]) {
toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i];
@ -2770,7 +2783,7 @@ bool RAWParamsEdited::XTransSensor::isUnchanged() const
bool RAWParamsEdited::isUnchanged() const bool RAWParamsEdited::isUnchanged() const
{ {
return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caRed && caBlue && hotPixelFilter && deadPixelFilter && hotDeadPixelThresh && darkFrame return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caAutoStrength && caRed && caBlue && hotPixelFilter && deadPixelFilter && hotDeadPixelThresh && darkFrame
&& dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && exPreser && ff_AutoClipControl && ff_clipControl; && dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && exPreser && ff_AutoClipControl && ff_clipControl;
} }

View File

@ -646,7 +646,7 @@ public:
bool enabled; bool enabled;
bool gamutlab; bool gamutlab;
bool mult[6]; bool mult[6];
bool cbdlMethod;
bool threshold; bool threshold;
bool skinprotect; bool skinprotect;
bool hueskin; bool hueskin;
@ -712,6 +712,7 @@ public:
XTransSensor xtranssensor; XTransSensor xtranssensor;
bool caCorrection; bool caCorrection;
bool caAutoStrength;
bool caRed; bool caRed;
bool caBlue; bool caBlue;
bool hotPixelFilter; bool hotPixelFilter;

View File

@ -17,11 +17,17 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "placesbrowser.h" #include "placesbrowser.h"
#include "options.h"
#include "toolpanel.h" #ifdef WIN32
#include "../rtengine/safegtk.h" #include <windows.h>
#include <shlobj.h>
#include <Shlwapi.h>
#endif
#include "guiutils.h" #include "guiutils.h"
#include "rtimage.h" #include "rtimage.h"
#include "options.h"
#include "toolpanel.h"
PlacesBrowser::PlacesBrowser () PlacesBrowser::PlacesBrowser ()
{ {
@ -96,17 +102,14 @@ bool compareMountByRoot (Glib::RefPtr<Gio::Mount> a, Glib::RefPtr<Gio::Mount> b)
void PlacesBrowser::refreshPlacesList () void PlacesBrowser::refreshPlacesList ()
{ {
placesModel->clear (); placesModel->clear ();
// append home directory // append home directory
Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (safe_get_user_home_dir()); // Will send back "My documents" on Windows now, which has no restricted access Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (userHomeDir()); // Will send back "My documents" on Windows now, which has no restricted access
if (hfile && hfile->query_exists()) { if (hfile && hfile->query_exists()) {
try { try {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile); if (auto info = hfile->query_info ()) {
if (info) {
Gtk::TreeModel::Row newrow = *(placesModel->append()); Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon (); newrow[placesColumns.icon] = info->get_icon ();
@ -114,19 +117,15 @@ void PlacesBrowser::refreshPlacesList ()
newrow[placesColumns.type] = 4; newrow[placesColumns.type] = 4;
newrow[placesColumns.rowSeparator] = false; newrow[placesColumns.rowSeparator] = false;
} }
} catch (Gio::Error&) { } catch (Gio::Error&) {}
/* This will be thrown if the path doesn't exist */
}
} }
// append pictures directory // append pictures directory
hfile = Gio::File::create_for_path (safe_get_user_picture_dir()); hfile = Gio::File::create_for_path (userPicturesDir());
if (hfile && hfile->query_exists()) { if (hfile && hfile->query_exists()) {
try { try {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile); if (auto info = hfile->query_info ()) {
if (info) {
Gtk::TreeModel::Row newrow = *(placesModel->append()); Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon (); newrow[placesColumns.icon] = info->get_icon ();
@ -134,9 +133,7 @@ void PlacesBrowser::refreshPlacesList ()
newrow[placesColumns.type] = 4; newrow[placesColumns.type] = 4;
newrow[placesColumns.rowSeparator] = false; newrow[placesColumns.rowSeparator] = false;
} }
} catch (Gio::Error&) { } catch (Gio::Error&) {}
/* This will be thrown if the path doesn't exist */
}
} }
if (!placesModel->children().empty()) { if (!placesModel->children().empty()) {
@ -235,9 +232,8 @@ void PlacesBrowser::refreshPlacesList ()
Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (options.favoriteDirs[i]); Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (options.favoriteDirs[i]);
if (hfile && hfile->query_exists()) { if (hfile && hfile->query_exists()) {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile); try {
if (auto info = hfile->query_info ()) {
if (info) {
Gtk::TreeModel::Row newrow = *(placesModel->append()); Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon (); newrow[placesColumns.icon] = info->get_icon ();
@ -245,6 +241,7 @@ void PlacesBrowser::refreshPlacesList ()
newrow[placesColumns.type] = 5; newrow[placesColumns.type] = 5;
newrow[placesColumns.rowSeparator] = false; newrow[placesColumns.rowSeparator] = false;
} }
} catch(Gio::Error&) {}
} }
} }
} }
@ -325,12 +322,12 @@ void PlacesBrowser::addPressed ()
Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (lastSelectedDir); Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (lastSelectedDir);
if (hfile && hfile->query_exists()) { if (hfile && hfile->query_exists()) {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile); try {
if (auto info = hfile->query_info ()) {
if (info) {
options.favoriteDirs.push_back (hfile->get_parse_name ()); options.favoriteDirs.push_back (hfile->get_parse_name ());
refreshPlacesList (); refreshPlacesList ();
} }
} catch(Gio::Error&) {}
} }
} }
@ -352,3 +349,52 @@ void PlacesBrowser::delPressed ()
refreshPlacesList (); refreshPlacesList ();
} }
Glib::ustring PlacesBrowser::userHomeDir ()
{
#ifdef WIN32
// get_home_dir crashes on some Windows configurations,
// so we rather use the safe native functions here.
WCHAR pathW[MAX_PATH];
if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PERSONAL, false)) {
char pathA[MAX_PATH];
if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) {
return Glib::ustring (pathA);
}
}
return Glib::ustring ("C:\\");
#else
return Glib::get_home_dir ();
#endif
}
Glib::ustring PlacesBrowser::userPicturesDir ()
{
#ifdef WIN32
// get_user_special_dir crashes on some Windows configurations,
// so we rather use the safe native functions here.
WCHAR pathW[MAX_PATH];
if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_MYPICTURES, false)) {
char pathA[MAX_PATH];
if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) {
return Glib::ustring (pathA);
}
}
return Glib::ustring ("C:\\");
#else
return Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES);
#endif
}

View File

@ -72,6 +72,12 @@ public:
void selectionChanged (); void selectionChanged ();
void addPressed (); void addPressed ();
void delPressed (); void delPressed ();
public:
static Glib::ustring userHomeDir ();
static Glib::ustring userPicturesDir ();
}; };
inline void PlacesBrowser::setDirSelector (const PlacesBrowser::DirSelectionSlot& selectDir) inline void PlacesBrowser::setDirSelector (const PlacesBrowser::DirSelectionSlot& selectDir)

View File

@ -22,7 +22,6 @@
#include <gtkmm.h> #include <gtkmm.h>
#include "multilangmgr.h" #include "multilangmgr.h"
#include "popupcommon.h" #include "popupcommon.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
#include "guiutils.h" #include "guiutils.h"

View File

@ -25,7 +25,6 @@
#include "../rtengine/dfmanager.h" #include "../rtengine/dfmanager.h"
#include "../rtengine/ffmanager.h" #include "../rtengine/ffmanager.h"
#include <sstream> #include <sstream>
#include "../rtengine/safegtk.h"
#include "rtimage.h" #include "rtimage.h"
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> #include <omp.h>
@ -1352,7 +1351,7 @@ void Preferences::parseDir (Glib::ustring dirname, std::vector<Glib::ustring>& i
Glib::ustring sname = *i; Glib::ustring sname = *i;
// ignore directories // ignore directories
if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= ext.size() && sname.substr (sname.size() - ext.size(), ext.size()).casefold() == ext) { if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= ext.size() && sname.substr (sname.size() - ext.size(), ext.size()).casefold() == ext) {
items.push_back (sname.substr(0, sname.size() - ext.size())); items.push_back (sname.substr(0, sname.size() - ext.size()));
} }
} }
@ -1640,18 +1639,18 @@ void Preferences::fillPreferences ()
#ifdef WIN32 #ifdef WIN32
edPS->set_active (moptions.editorToSendTo == 2); edPS->set_active (moptions.editorToSendTo == 2);
if (safe_file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) {
gimpDir->set_current_folder (moptions.gimpDir); gimpDir->set_current_folder (moptions.gimpDir);
} }
if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) {
psDir->set_current_folder (moptions.psDir); psDir->set_current_folder (moptions.psDir);
} }
#elif defined __APPLE__ #elif defined __APPLE__
edPS->set_active (moptions.editorToSendTo == 2); edPS->set_active (moptions.editorToSendTo == 2);
if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) { if (Glib::file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) {
psDir->set_current_folder (moptions.psDir); psDir->set_current_folder (moptions.psDir);
} }
@ -1940,18 +1939,17 @@ void Preferences::bundledProfilesChanged ()
void Preferences::iccDirChanged () void Preferences::iccDirChanged ()
{ {
const Glib::ustring currentSelection = monProfile->get_active_text (); const auto currentSelection = monProfile->get_active_text ();
const auto profiles = rtengine::ICCStore::getInstance ()->getProfilesFromDir (iccDir->get_filename ());
monProfile->clear(); monProfile->remove_all();
monProfile->append (M("PREFERENCES_PROFILE_NONE")); monProfile->append (M("PREFERENCES_PROFILE_NONE"));
monProfile->set_active (0);
const std::vector<Glib::ustring> profiles = rtengine::ICCStore::getInstance ()->getProfilesFromDir (iccDir->get_filename ()); for (const auto& profile : profiles)
for (std::vector<Glib::ustring>::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) monProfile->append (profile);
monProfile->append (*profile);
monProfile->set_active_text (currentSelection); setActiveTextOrIndex(*monProfile, currentSelection, 0);
} }
void Preferences::storeCurrentValue() void Preferences::storeCurrentValue()

View File

@ -18,7 +18,6 @@
*/ */
#include "preprocess.h" #include "preprocess.h"
#include "guiutils.h" #include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream> #include <sstream>
using namespace rtengine; using namespace rtengine;

Some files were not shown because too many files have changed in this diff Show More