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 (FFTW3F REQUIRED fftw3f)
pkg_check_modules (IPTCDATA REQUIRED libiptcdata)
pkg_check_modules(FFTW3 fftw3)
find_package (JPEG REQUIRED)
find_package (PNG REQUIRED)
find_package (TIFF REQUIRED)
@ -311,7 +310,7 @@ set(OOSB_FILES "${PROJECT_SOURCE_DIR}/rtdata/rawtherapee.desktop" "${PROJECT_SOU
if (OUT_OF_SOURCE_BUILD)
foreach(f ${OOSB_FILES})
file (REMOVE "${f}")
endforeach(f)
endforeach(f)
endif ()
# check for generated files in the source tree which should not be there when
@ -322,7 +321,7 @@ if (OUT_OF_SOURCE_BUILD)
if (EXISTS "${f}")
message (SEND_ERROR "Generated \"${f}\" found inside the source tree. Please remove it as it is a relic of the old build system and prevents valid compilation now.")
endif ()
endforeach(f)
endforeach(f)
endif ()
## BEGIN: Generating AboutThisBuild.txt

View File

@ -1,23 +1,21 @@
![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.
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
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.
## Links
Website:
http://rawtherapee.com/
Features:
http://rawpedia.rawtherapee.com/Features
Official documentation:
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_438;Retinex - M - Equalizer
HISTORY_MSG_439;Retinex - Preview
HISTORY_MSG_440;CbDL - method
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOT;Snapshot
@ -1208,6 +1209,10 @@ TP_BWMIX_VAL;L
TP_CACORRECTION_BLUE;Blue
TP_CACORRECTION_LABEL;Chromatic Aberration Correction
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_GREEN;Green channel
TP_CHMIXER_LABEL;Channel Mixer
@ -1613,6 +1618,7 @@ TP_PREPROCESS_NO_FOUND;None found
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_RAWCACORR_AUTO;Auto-correction
TP_RAWCACORR_CASTR;Strength
TP_RAWCACORR_CABLUE;Blue
TP_RAWCACORR_CARED;Red
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 (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
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

View File

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

View File

@ -3,7 +3,6 @@
*/
#include "camconst.h"
#include "settings.h"
#include "safegtk.h"
#include "rt_math.h"
#include <cstdio>
#include <cstring>
@ -689,7 +688,7 @@ void CameraConstantsStore::init(Glib::ustring baseDir, Glib::ustring userSetting
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);
}
}

View File

@ -328,7 +328,7 @@ double Ciecam02::calculate_fl_from_la_ciecam02( double la )
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 )
@ -340,7 +340,7 @@ float Ciecam02::calculate_fl_from_la_ciecam02float( float la )
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 )

View File

@ -1,7 +1,6 @@
#include "clutstore.h"
#include "rt_math.h"
#include "stdimagesource.h"
#include "safegtk.h"
#include "../rtgui/options.h"
rtengine::CLUTStore clutStore;
@ -154,7 +153,7 @@ Imagefloat* HaldCLUT::loadFile( Glib::ustring filename, Glib::ustring workingCol
Imagefloat *result = 0;
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;
}

View File

@ -36,6 +36,7 @@ LUTf Color::cachef;
LUTf Color::gamma2curve;
LUTf Color::gammatab;
LUTuc Color::gammatabThumb;
LUTf Color::igammatab_srgb;
LUTf Color::gammatab_srgb;
// LUTf Color::igammatab_709;
@ -133,129 +134,204 @@ void MunsellDebugInfo::reinitValues()
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);
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);
constexpr auto maxindex = 65536;
igammatab_26_11(65536, 0);
gammatab_26_11(65536, 0);
igammatab_24_17(65536, 0);
gammatab_24_17a(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW);
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);
cachef(maxindex, LUT_CLIP_BELOW);
gamma2curve(maxindex, LUT_CLIP_BELOW | LUT_CLIP_ABOVE);
gammatab(maxindex, 0);
gammatabThumb(maxindex, 0);
for (int i = 0; i < 65536; i++) {
gammatab_srgb[i] = (65535.0 * gamma2 (i / 65535.0));
igammatab_srgb(maxindex, 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(; i < maxindex; i++)
{
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
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_srgb[i] = 65535.0 * igamma2 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
{
double rsRGBGamma = 1.0 / sRGBGamma;
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);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_55[i] = 65535.0 * igamma55 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_4[i] = 65535.0 * gamma4 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_4[i] = 65535.0 * igamma4 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_13_2[i] = 65535.0 * gamma13_2 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_13_2[i] = 65535.0 * igamma13_2 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_115_2[i] = 65535.0 * gamma115_2 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_115_2[i] = 65535.0 * igamma115_2 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_145_3[i] = 65535.0 * gamma145_3 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_145_3[i] = 65535.0 * igamma145_3 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_26_11[i] = 65535.0 * gamma26_11 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_26_11[i] = 65535.0 * igamma26_11 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
gammatab_24_17a[i] = gamma24_17(i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < maxindex; i++) {
igammatab_24_17[i] = 65535.0 * igamma24_17 (i / 65535.0);
}
#ifdef _OPENMP
#pragma omp section
#endif
initMunsell();
#ifdef _OPENMP
#pragma omp section
#endif
linearGammaTRC = cmsBuildGamma(NULL, 1.0);
}
for (int i = 0; i < 65536; i++) {
igammatab_srgb[i] = (65535.0 * igamma2 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
gammatab[i] = (65535.0 * pow (i / 65535.0, 0.454545));
}
/* for (int i=0; i<65536; i++)
gammatab_709[i] = (65535.0 * gamma709 (i/65535.0));
for (int i=0; i<65536; i++)
igammatab_709[i] = (65535.0 * igamma709 (i/65535.0));
*/
for (int i = 0; i < 65536; i++) {
gammatab_55[i] = (65535.0 * gamma55 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
igammatab_55[i] = (65535.0 * igamma55 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
gammatab_4[i] = (65535.0 * gamma4 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
igammatab_4[i] = (65535.0 * igamma4 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
gammatab_13_2[i] = (65535.0 * gamma13_2 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
igammatab_13_2[i] = (65535.0 * igamma13_2 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
gammatab_115_2[i] = (65535.0 * gamma115_2 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
igammatab_115_2[i] = (65535.0 * igamma115_2 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
gammatab_145_3[i] = (65535.0 * gamma145_3 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
igammatab_145_3[i] = (65535.0 * igamma145_3 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
gammatab_26_11[i] = (65535.0 * gamma26_11 (i / 65535.0));
}
//gammatab_145_3
for (int i = 0; i < 65536; i++) {
igammatab_26_11[i] = (65535.0 * igamma26_11 (i / 65535.0));
}
for (int i = 0; i < 65536; i++) {
float j = (float)i / 65535.0f;
gammatab_24_17a[i] = gamma24_17(j);
}
for (int i = 0; i < 65536; i++) {
igammatab_24_17[i] = (65535.0 * igamma24_17 (i / 65535.0));
}
/*FILE* f = fopen ("c.txt", "wt");
for (int i=0; i<256; i++)
fprintf (f, "%g %g\n", i/255.0, clower (i/255.0, 2.0, 1.0));
fclose (f);*/
initMunsell();
linearGammaTRC = cmsBuildGamma(NULL, 1.0);
}
void Color::cleanup ()
@ -808,6 +884,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
float somm;
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 !
//presets
if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") {
@ -869,6 +954,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
bbm = 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;
mixerGreen = mixerGreen / somm;
mixerBlue = mixerBlue / somm;
@ -1084,6 +1178,10 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u
mixerGreen = mixerGreen * filgreen;
mixerBlue = mixerBlue * filblue;
if(mixerRed + mixerGreen + mixerBlue == 0) {
mixerRed += 1.f;
}
mixerRed = filcor * mixerRed / (mixerRed + mixerGreen + mixerBlue);
mixerGreen = filcor * mixerGreen / (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") {
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") {
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);
float fx = (X <= 65535.0 ? cachef[X] : (327.68 * exp(log(X / MAXVALF) / 3.0 )));
float fy = (Y <= 65535.0 ? cachef[Y] : (327.68 * exp(log(Y / MAXVALF) / 3.0 )));
float fz = (Z <= 65535.0 ? cachef[Z] : (327.68 * exp(log(Z / 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 * std::cbrt(Y / MAXVALF)));
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;
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;
if (Y > float(eps)) {
L = 116.f * pow(Y, 1.f / 3.f) - 16.f;
L = 116.f * std::cbrt(Y) - 16.f;
} else {
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())
static LUTf igammatab_srgb;
static LUTf gammatab_srgb;
// static LUTf igammatab_709;
// static LUTf gammatab_709;
static LUTf igammatab_55;
static LUTf gammatab_55;
static LUTf igammatab_4;
@ -150,6 +148,7 @@ public:
// look-up tables for the simple exponential gamma
static LUTf gammatab;
static LUTuc gammatabThumb; // for thumbnails
static void init ();

View File

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

View File

@ -19,21 +19,49 @@
#include "coord.h"
#include "rt_math.h"
namespace rtengine
{
void Coord::setFromPolar(PolarCoord polar)
Coord& Coord::operator= (const PolarCoord& other)
{
while (polar.angle < 0.f) {
polar.angle += 360.f;
}
const auto radius = other.radius;
const auto angle = other.angle / 180.0 * M_PI;
while (polar.angle > 360.f) {
polar.angle -= 360.f;
}
x = radius * std::cos (angle);
y = radius * std::sin (angle);
x = polar.radius * cos(polar.angle / 180.f * M_PI);
y = polar.radius * sin(polar.angle / 180.f * M_PI);
return *this;
}
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
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __COORD__
#define __COORD__
#include "rt_math.h"
namespace rtengine
{
class PolarCoord;
struct Coord;
struct PolarCoord;
// Do not confuse with rtengine::Coord2D, this one is for the GUI
class Coord
// Do not confuse with Coord2D, this one is used by the UI.
struct Coord
{
public:
int x;
int y;
int x = 0;
int y = 0;
Coord() : x(-1), y(-1) {}
Coord(int x, int y) : x(x), y(y) {}
Coord () = default;
Coord (const int x, const int y);
Coord (const Coord& other) = default;
Coord (const PolarCoord& other);
void set (int x, int y)
{
this->x = x;
this->y = y;
}
Coord& operator= (const Coord& other) = default;
Coord& operator= (const PolarCoord& other);
void setFromPolar(PolarCoord polar);
void get (int& x, int& y) const;
void set (const int x, const int y);
/// @brief Clip the coord to stay in the width x height bounds
/// @return true if the x or y coordinate has changed
bool clip(int width, int height)
{
int trimmedX = rtengine::LIM<int>(x, 0, width);
int trimmedY = rtengine::LIM<int>(y, 0, height);
bool retval = trimmedX != x || trimmedY != y;
x = trimmedX;
y = trimmedY;
return retval;
}
bool clip (const int width, const int height);
bool operator== (const Coord& other) const
{
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;
y *= scale;
}
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
{
public:
double radius;
double angle; // degree
PolarCoord() : radius(1.), angle(0.) {}
PolarCoord(double radius, double angle) : radius(radius), angle(angle) {}
PolarCoord(Coord start, Coord end) : radius(1.), angle(0.)
{
setFromCartesian(start, end);
}
PolarCoord(Coord delta) : radius(1.), angle(0.)
{
setFromCartesian(delta);
}
void set (double radius, double angle)
{
this->radius = radius;
this->angle = angle;
}
void setFromCartesian(Coord start, Coord end)
{
Coord delta(end.x - start.x, end.y - start.y);
setFromCartesian(delta);
}
void setFromCartesian(Coord delta)
{
if (!delta.x && !delta.y) {
// null vector, we set to a default value
radius = 1.;
angle = 0.;
return;
}
double x_ = double(delta.x);
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;
}
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;
}
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->y = y;
}
inline Coord& Coord::operator+= (const Coord& other)
{
x += other.x;
y += other.y;
return *this;
}
inline Coord& Coord::operator-= (const Coord& other)
{
x -= other.x;
y -= other.y;
return *this;
}
inline Coord& Coord::operator*= (const double scale)
{
x *= scale;
y *= scale;
return *this;
}
inline bool operator== (const Coord& lhs, const Coord& rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
}
inline bool operator!= (const Coord& lhs, const Coord& rhs)
{
return !(lhs == rhs);
}
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->angle = angle;
}
inline PolarCoord& PolarCoord::operator+= (const PolarCoord& other)
{
*this = Coord (*this) + Coord (other);
return *this;
}
inline PolarCoord &PolarCoord::operator-= (const PolarCoord &other)
{
*this = Coord (*this) - Coord (other);
return *this;
}
inline PolarCoord &PolarCoord::operator*= (const double scale)
{
radius *= scale;
return *this;
}
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 "opthelper.h"
#include "ciecam02.h"
#include "color.h"
#undef CLIPD
#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
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.0 + state.debug.p2 / 100.0f;
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[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::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[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

View File

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

View File

@ -19,7 +19,6 @@
#include <cstring>
#include "dcp.h"
#include "safegtk.h"
#include "iccmatrices.h"
#include "iccstore.h"
#include "rawimagesource.h"
@ -828,7 +827,7 @@ DCPProfile::DCPProfile(Glib::ustring fname)
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);
@ -1717,7 +1716,7 @@ void DCPStore::init (Glib::ustring rtProfileDir)
Glib::Dir* dir = NULL;
try {
if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) {
if (!Glib::file_test (dirname, Glib::FILE_TEST_IS_DIR)) {
return;
}
@ -1733,7 +1732,7 @@ void DCPStore::init (Glib::ustring rtProfileDir)
Glib::ustring sname = *i;
// 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 ('.');
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
{
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;
}

View File

@ -705,6 +705,17 @@ void Crop::update (int todo)
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
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;
@ -725,6 +736,7 @@ void Crop::update (int todo)
}
}
// shadows & highlights & tone curve & convert to cielab
/*int xref,yref;
xref=000;yref=000;
@ -831,12 +843,13 @@ void Crop::update (int todo)
// if (skip==1) {
WaveletParams WaveParams = params.wavelet;
if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
parent->ipf.dirpyrequalizer (labnCrop, skip);
// parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip);
if(params.dirpyrequalizer.cbdlMethod == "aft") {
if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) {
parent->ipf.dirpyrequalizer (labnCrop, skip);
// parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip);
}
}
int kall = 0;
int minwin = min(labnCrop->W, labnCrop->H);
int maxlevelcrop = 10;

View File

@ -90,17 +90,17 @@ void RawImageSource::eahd_demosaic ()
threshold = (int)(0.008856 * MAXVALD);
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
const JaggedArray<float>
rh (W, 3), gh (W, 4), bh (W, 3),
rv (W, 3), gv (W, 4), bv (W, 3),
lLh (W, 3), lah (W, 3), lbh (W, 3),
lLv (W, 3), lav (W, 3), lbv (W, 3),
homh (W, 3), homv (W, 3);
rh (W, 3), gh (W, 4), bh (W, 3),
rv (W, 3), gv (W, 4), bv (W, 3),
lLh (W, 3), lah (W, 3), lbh (W, 3),
lLv (W, 3), lav (W, 3), lbv (W, 3),
homh (W, 3), homv (W, 3);
// interpolate first two lines
interpolate_row_g (gh[0], gv[0], 0);
@ -2703,7 +2703,7 @@ void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh)
for (i = 0; i < 0x10000; i++) {
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++)

View File

@ -20,7 +20,6 @@
#include "../rtgui/options.h"
#include <giomm.h>
#include "../rtgui/guiutils.h"
#include "safegtk.h"
#include "rawimage.h"
#include <sstream>
#include <iostream>
@ -263,13 +262,21 @@ void dfInfo::updateBadPixelList( RawImage *df )
void DFManager::init( Glib::ustring pathname )
{
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;
}
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();
bpList.clear();
@ -320,65 +327,84 @@ void DFManager::init( Glib::ustring pathname )
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;
}
if( !file->query_exists()) {
if (!file->query_exists ()) {
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)) {
size_t lastdot = info->get_name().find_last_of ('.');
auto info = file->query_info ();
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) {
RawImage ri(filename);
int res = ri.loadRaw(false); // Read informations about shot
if (!info && info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
return 0;
}
if( !res ) {
dfList_t::iterator iter;
if (!options.fbShowHidden && info->is_hidden ()) {
return 0;
}
if(!pool) {
dfInfo n(filename, "", "", 0, 0, 0);
iter = dfList.insert(std::pair< std::string, dfInfo>( "", n ) );
return &(iter->second);
}
Glib::ustring ext;
RawMetaDataLocation rml;
rml.exifBase = ri.get_exifBase();
rml.ciffBase = ri.get_ciffBase();
rml.ciffLength = ri.get_ciffLen();
ImageData idata(filename, &rml);
/* Files are added in the map, divided by same maker/model,ISO and shutter*/
std::string key( dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed()) );
iter = dfList.find( key );
auto lastdot = info->get_name ().find_last_of ('.');
if (lastdot != Glib::ustring::npos) {
ext = info->get_name ().substr (lastdot + 1);
}
if( iter == dfList.end() ) {
dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS() );
iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) );
} else {
while( iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6 ) { // 6 hour difference
iter++;
}
if (!options.is_extention_enabled (ext)) {
return 0;
}
if( iter != dfList.end() ) {
iter->second.pathNames.push_back( filename );
} else {
dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS());
iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) );
}
}
RawImage ri (filename);
int res = ri.loadRaw (false); // Read informations about shot
return &(iter->second);
if (res != 0) {
return 0;
}
dfList_t::iterator iter;
if(!pool) {
dfInfo n(filename, "", "", 0, 0, 0);
iter = dfList.insert(std::pair< std::string, dfInfo>( "", n ) );
return &(iter->second);
}
RawMetaDataLocation rml;
rml.exifBase = ri.get_exifBase();
rml.ciffBase = ri.get_ciffBase();
rml.ciffLength = ri.get_ciffLen();
ImageData idata(filename, &rml);
/* Files are added in the map, divided by same maker/model,ISO and shutter*/
std::string key( dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed()) );
iter = dfList.find( key );
if( iter == dfList.end() ) {
dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS() );
iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) );
} else {
while( iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6 ) { // 6 hour difference
iter++;
}
if( iter != dfList.end() ) {
iter->second.pathNames.push_back( filename );
} else {
dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS());
iter = dfList.insert(std::pair< std::string, dfInfo>( key, n ) );
}
}
}
return &(iter->second);
} catch(Gio::Error&) {}
return 0;
}

View File

@ -19,7 +19,6 @@
#include "ffmanager.h"
#include "../rtgui/options.h"
#include <giomm.h>
#include "safegtk.h"
#include "rawimage.h"
#include <sstream>
#include <cstdio>
@ -209,13 +208,21 @@ void ffInfo::updateRawImage()
void FFManager::init( Glib::ustring pathname )
{
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;
}
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();
@ -253,65 +260,85 @@ void FFManager::init( Glib::ustring pathname )
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 ) {
return 0;
}
if( !file->query_exists()) {
if (!file->query_exists ()) {
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)) {
size_t lastdot = info->get_name().find_last_of ('.');
auto info = file->query_info ();
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) {
RawImage ri(filename);
int res = ri.loadRaw(false); // Read informations about shot
if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
return 0;
}
if( !res ) {
ffList_t::iterator iter;
if (!options.fbShowHidden && info->is_hidden ()) {
return 0;
}
if(!pool) {
ffInfo n(filename, "", "", "", 0, 0, 0);
iter = ffList.insert(std::pair< std::string, ffInfo>( "", n ) );
return &(iter->second);
}
Glib::ustring ext;
RawMetaDataLocation rml;
rml.exifBase = ri.get_exifBase();
rml.ciffBase = ri.get_ciffBase();
rml.ciffLength = ri.get_ciffLen();
ImageData idata(filename, &rml);
/* Files are added in the map, divided by same maker/model,lens and aperture*/
std::string key( ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber()) );
iter = ffList.find( key );
auto lastdot = info->get_name ().find_last_of ('.');
if (lastdot != Glib::ustring::npos) {
ext = info->get_name ().substr (lastdot + 1);
}
if( iter == ffList.end() ) {
ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS());
iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) );
} else {
while( iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6 ) { // 6 hour difference
iter++;
}
if (!options.is_extention_enabled (ext)) {
return 0;
}
if( iter != ffList.end() ) {
iter->second.pathNames.push_back( filename );
} else {
ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS());
iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) );
}
}
return &(iter->second);
RawImage ri (filename);
int res = ri.loadRaw (false); // Read informations about shot
if (res != 0) {
return 0;
}
ffList_t::iterator iter;
if(!pool) {
ffInfo n(filename, "", "", "", 0, 0, 0);
iter = ffList.insert(std::pair< std::string, ffInfo>( "", n ) );
return &(iter->second);
}
RawMetaDataLocation rml;
rml.exifBase = ri.get_exifBase();
rml.ciffBase = ri.get_ciffBase();
rml.ciffLength = ri.get_ciffLen();
ImageData idata(filename, &rml);
/* Files are added in the map, divided by same maker/model,lens and aperture*/
std::string key( ffInfo::key(idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber()) );
iter = ffList.find( key );
if( iter == ffList.end() ) {
ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS());
iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) );
} else {
while( iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) > 60 * 60 * 6 ) { // 6 hour difference
iter++;
}
if( iter != ffList.end() ) {
iter->second.pathNames.push_back( filename );
} else {
ffInfo n(filename, idata.getMake(), idata.getModel(), idata.getLens(), idata.getFocalLen(), idata.getFNumber(), idata.getDateTimeAsTS());
iter = ffList.insert(std::pair< std::string, ffInfo>( key, n ) );
}
}
}
return &(iter->second);
} catch (Gio::Error&) {}
return 0;
}

View File

@ -16,18 +16,21 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "iccstore.h"
#include <cstring>
#ifdef WIN32
#include <winsock2.h>
#else
#include <netinet/in.h>
#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
{
@ -59,7 +62,7 @@ void loadProfiles (const Glib::ustring& dirName,
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;
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);
if (r != fileProfiles.end ())
if (r != fileProfiles.end ()) {
return r->second;
}
if (name.compare (0, 5, "file:") == 0) {
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
@ -418,7 +422,6 @@ ProfileContent ICCStore::getContent (const Glib::ustring& name) const
std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const
{
MyMutex::MyLock lock (mutex_);
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
{
MyMutex::MyLock lock (mutex_);
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
{
MyMutex::MyLock lock (mutex_);
return getSupportedIntents (profile, LCMS_USED_AS_PROOF);
@ -503,7 +504,7 @@ void ICCStore::findDefaultMonitorProfile ()
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) {
return;

View File

@ -19,12 +19,25 @@
#include "imagedata.h"
#include "iptcpairs.h"
#include <glib/gstdio.h>
#include "safegtk.h"
using namespace rtengine;
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)
{
@ -39,7 +52,7 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri)
iptc = NULL;
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 (ri->exifBase >= 0) {
@ -60,18 +73,18 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri)
extractInfo ();
}
} 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) {
root = rtexif::ExifManager::parseJPEG (f);
extractInfo ();
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);
fclose (ff);
}
} 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) {
root = rtexif::ExifManager::parseTIFF (f);
@ -271,176 +284,183 @@ void ImageData::extractInfo ()
} else if(!make.compare (0, 4, "SONY")) {
if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* isoTag = exif->getTag ("RecommendedExposureIndex");
if(isoTag)
if(isoTag) {
iso_speed = isoTag->toDouble();
}
}
}
else if (root->findTag("MakerNote")) {
rtexif::TagDirectory* mnote = root->findTag("MakerNote")->getDirectory();
if (mnote && !make.compare (0, 5, "NIKON")) {
// ISO at max value supported, check manufacturer specific
if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* isoTag = mnote->getTagP("ISOInfo/ISO");
if (lens == "Unknown") {
rtexif::Tag* mnoteTag = root->findTag("MakerNote");
if (isoTag) {
iso_speed = isoTag->toInt();
if (mnoteTag) {
rtexif::TagDirectory* mnote = mnoteTag->getDirectory();
if (mnote && !make.compare (0, 5, "NIKON")) {
// ISO at max value supported, check manufacturer specific
if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* isoTag = mnote->getTagP("ISOInfo/ISO");
if (isoTag) {
iso_speed = isoTag->toInt();
}
}
}
bool lensOk = false;
bool lensOk = false;
if (mnote->getTag ("LensData")) {
std::string ldata = mnote->getTag ("LensData")->valueToString ();
int pos;
if (mnote->getTag ("LensData")) {
std::string ldata = mnote->getTag ("LensData")->valueToString ();
int pos;
if (ldata.size() > 10 && (pos = ldata.find ("Lens = ")) != Glib::ustring::npos) {
lens = ldata.substr (pos + 7);
if (ldata.size() > 10 && (pos = ldata.find ("Lens = ")) != Glib::ustring::npos) {
lens = ldata.substr (pos + 7);
if (lens.compare (0, 7, "Unknown")) {
lensOk = true;
} else {
int pos = lens.find("$FL$"); // is there a placeholder for focallength?
if (lens.compare (0, 7, "Unknown")) {
lensOk = true;
} else {
int pos = lens.find("$FL$"); // is there a placeholder for focallength?
if(pos != Glib::ustring::npos) { // then fill in focallength
lens = lens.replace(pos, 4, exif->getTag ("FocalLength")->valueToString ());
if(pos != Glib::ustring::npos) { // then fill in focallength
lens = lens.replace(pos, 4, exif->getTag ("FocalLength")->valueToString ());
if(mnote->getTag ("LensType")) {
std::string ltype = mnote->getTag ("LensType")->valueToString ();
if(mnote->getTag ("LensType")) {
std::string ltype = mnote->getTag ("LensType")->valueToString ();
if(ltype.find("MF = Yes") != Glib::ustring::npos) { // check, whether it's a MF lens, should be always
lens = lens.replace(0, 7, "MF");
if(ltype.find("MF = Yes") != Glib::ustring::npos) { // check, whether it's a MF lens, should be always
lens = lens.replace(0, 7, "MF");
}
lensOk = true;
}
lensOk = true;
}
}
}
}
}
if (!lensOk && mnote->getTag ("Lens")) {
std::string ldata = mnote->getTag ("Lens")->valueToString ();
size_t i = 0, j = 0;
double n[4];
if (!lensOk && mnote->getTag ("Lens")) {
std::string ldata = mnote->getTag ("Lens")->valueToString ();
size_t i = 0, j = 0;
double n[4];
for (int m = 0; m < 4; m++) {
while (i < ldata.size() && ldata[i] != '/') {
for (int m = 0; m < 4; m++) {
while (i < ldata.size() && ldata[i] != '/') {
i++;
}
int nom = atoi(ldata.substr(j, i).c_str());
j = i + 1;
i++;
while (i < ldata.size() && ldata[i] != ',') {
i++;
}
int den = atoi(ldata.substr(j, i).c_str());
j = i + 2;
i += 2;
n[m] = (double) nom / den;
}
int nom = atoi(ldata.substr(j, i).c_str());
j = i + 1;
i++;
std::ostringstream str;
while (i < ldata.size() && ldata[i] != ',') {
i++;
}
int den = atoi(ldata.substr(j, i).c_str());
j = i + 2;
i += 2;
n[m] = (double) nom / den;
}
std::ostringstream str;
if (n[0] == n[1]) {
str << "Unknown " << n[0] << "mm F/" << n[2];
} else if (n[2] == n[3]) {
str << "Unknown " << n[0] << "-" << n[1] << "mm F/" << n[2];
} else {
str << "Unknown " << n[0] << "-" << n[1] << "mm F/" << n[2] << "-" << n[3];
}
lens = str.str();
// Look whether it's MF or AF
if(mnote->getTag ("LensType")) {
std::string ltype = mnote->getTag ("LensType")->valueToString ();
if(ltype.find("MF = Yes") != Glib::ustring::npos) { // check, whether it's a MF lens
lens = lens.replace(0, 7, "MF"); // replace 'Unknwon' with 'MF'
if (n[0] == n[1]) {
str << "Unknown " << n[0] << "mm F/" << n[2];
} else if (n[2] == n[3]) {
str << "Unknown " << n[0] << "-" << n[1] << "mm F/" << n[2];
} else {
lens = lens.replace(0, 7, "AF"); // replace 'Unknwon' with 'AF'
str << "Unknown " << n[0] << "-" << n[1] << "mm F/" << n[2] << "-" << n[3];
}
lens = str.str();
// Look whether it's MF or AF
if(mnote->getTag ("LensType")) {
std::string ltype = mnote->getTag ("LensType")->valueToString ();
if(ltype.find("MF = Yes") != Glib::ustring::npos) { // check, whether it's a MF lens
lens = lens.replace(0, 7, "MF"); // replace 'Unknwon' with 'MF'
} else {
lens = lens.replace(0, 7, "AF"); // replace 'Unknwon' with 'AF'
}
}
}
}
} else if (mnote && !make.compare (0, 5, "Canon")) {
// ISO at max value supported, check manufacturer specific
if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* baseIsoTag = mnote->getTagP("CanonShotInfo/BaseISO");
} else if (mnote && !make.compare (0, 5, "Canon")) {
// ISO at max value supported, check manufacturer specific
if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* baseIsoTag = mnote->getTagP("CanonShotInfo/BaseISO");
if (baseIsoTag) {
iso_speed = baseIsoTag->toInt();
if (baseIsoTag) {
iso_speed = baseIsoTag->toInt();
}
}
}
int found = false;
// canon EXIF have a string for lens model
rtexif::Tag *lt = mnote->getTag("LensType");
if ( lt ) {
std::string ldata = lt->valueToString ();
if (ldata.size() > 1) {
found = true;
lens = "Canon " + ldata;
}
}
if( !found || lens.substr(lens.find(' ')).length() < 7 ) {
lt = mnote->findTag("LensID");
int found = false;
// canon EXIF have a string for lens model
rtexif::Tag *lt = mnote->getTag("LensType");
if ( lt ) {
std::string ldata = lt->valueToString ();
if (ldata.size() > 1) {
lens = ldata;
found = true;
lens = "Canon " + ldata;
}
}
if( !found || lens.substr(lens.find(' ')).length() < 7 ) {
lt = mnote->findTag("LensID");
if ( lt ) {
std::string ldata = lt->valueToString ();
if (ldata.size() > 1) {
lens = ldata;
}
}
}
} else if (mnote && (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) {
if (mnote->getTag ("LensType")) {
lens = mnote->getTag ("LensType")->valueToString ();
}
// Try to get the FocalLength from the LensInfo structure, where length below 10mm will be correctly set
rtexif::Tag* flt = mnote->getTagP ("LensInfo/FocalLength");
if (flt) {
// Don't replace Exif focal_len if Makernotes focal_len is 0
if (flt->toDouble() > 0) {
focal_len = flt->toDouble ();
}
} else if ((flt = mnote->getTagP ("FocalLength"))) {
rtexif::Tag* flt = mnote->getTag ("FocalLength");
focal_len = flt->toDouble ();
}
if (mnote->getTag ("FocalLengthIn35mmFilm")) {
focal_len35mm = mnote->getTag ("FocalLengthIn35mmFilm")->toDouble ();
}
} else if (mnote && (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA"))) {
if (mnote->getTag ("LensID")) {
lens = mnote->getTag ("LensID")->valueToString ();
}
} else if (mnote && !make.compare (0, 7, "OLYMPUS")) {
if (mnote->getTag ("Equipment")) {
rtexif::TagDirectory* eq = mnote->getTag ("Equipment")->getDirectory ();
if (eq->getTag ("LensType")) {
lens = eq->getTag ("LensType")->valueToString ();
}
}
}
} else if (mnote && (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) {
if (mnote->getTag ("LensType")) {
lens = mnote->getTag ("LensType")->valueToString ();
}
// Try to get the FocalLength from the LensInfo structure, where length below 10mm will be correctly set
rtexif::Tag* flt = mnote->getTagP ("LensInfo/FocalLength");
if (flt) {
// Don't replace Exif focal_len if Makernotes focal_len is 0
if (flt->toDouble() > 0) {
focal_len = flt->toDouble ();
}
} else if ((flt = mnote->getTagP ("FocalLength"))) {
rtexif::Tag* flt = mnote->getTag ("FocalLength");
focal_len = flt->toDouble ();
}
if (mnote->getTag ("FocalLengthIn35mmFilm")) {
focal_len35mm = mnote->getTag ("FocalLengthIn35mmFilm")->toDouble ();
}
} else if (mnote && (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA"))) {
if (mnote->getTag ("LensID")) {
lens = mnote->getTag ("LensID")->valueToString ();
}
} else if (mnote && !make.compare (0, 7, "OLYMPUS")) {
if (mnote->getTag ("Equipment")) {
rtexif::TagDirectory* eq = mnote->getTag ("Equipment")->getDirectory ();
if (eq->getTag ("LensType")) {
lens = eq->getTag ("LensType")->valueToString ();
}
}
} else if (exif->getTag ("DNGLensInfo")) {
lens = exif->getTag ("DNGLensInfo")->valueToString ();
} else if (exif->getTag ("LensModel")) {
lens = exif->getTag ("LensModel")->valueToString ();
} else if (exif->getTag ("LensInfo")) {
lens = exif->getTag ("LensInfo")->valueToString ();
}
} else if (exif->getTag ("DNGLensInfo")) {
lens = exif->getTag ("DNGLensInfo")->valueToString ();
} else if (exif->getTag ("LensModel")) {
lens = exif->getTag ("LensModel")->valueToString ();
} else if (exif->getTag ("LensInfo")) {
lens = exif->getTag ("LensInfo")->valueToString ();
}
}
}
@ -472,7 +492,7 @@ const procparams::IPTCPairs ImageData::getIPTCData () const
if (ds) {
iptc_dataset_get_data (ds, buffer, 2100);
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;
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))) {
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;
@ -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))) {
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);
}

View File

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

View File

@ -36,7 +36,6 @@
#endif
#include "imageio.h"
#include "safegtk.h"
#include "iptcpairs.h"
#include "iccjpeg.h"
#include "color.h"
@ -47,9 +46,46 @@ using namespace std;
using namespace rtengine;
using namespace rtengine::procparams;
Glib::ustring safe_locale_to_utf8 (const std::string& src);
Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.", "Error while reading header.", "File reading error", "Image format not supported."};
namespace
{
// 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
void ImageIO::setMetadata (const rtexif::TagDirectory* eroot)
@ -77,12 +113,6 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr
// store exif info
exifChange.clear();
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) {
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++) {
IptcDataSet * ds = iptc_dataset_new ();
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_data_add_dataset (iptc, 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++) {
IptcDataSet * ds = iptc_dataset_new ();
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_data_add_dataset (iptc, 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())) {
IptcDataSet * ds = iptc_dataset_new ();
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_data_add_dataset (iptc, 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)
{
FILE *file = safe_g_fopen (fname, "rb");
FILE *file = g_fopen (fname.c_str (), "rb");
if (!file) {
return IMIO_CANNOTREADFILE;
@ -251,7 +281,7 @@ int ImageIO::getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat,
int ImageIO::loadPNG (Glib::ustring fname)
{
FILE *file = safe_g_fopen (fname, "rb");
FILE *file = g_fopen (fname.c_str (), "rb");
if (!file) {
return IMIO_CANNOTREADFILE;
@ -500,7 +530,7 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
int ImageIO::loadJPEG (Glib::ustring fname)
{
FILE *file = safe_g_fopen(fname, "rb");
FILE *file = g_fopen(fname.c_str (), "rb");
if (!file) {
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)
{
FILE *file = safe_g_fopen_WriteBinLock (fname);
FILE *file = g_fopen_withBinaryAndLock (fname);
if (!file) {
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)
{
FILE *file = safe_g_fopen_WriteBinLock (fname);
FILE *file = g_fopen_withBinaryAndLock (fname);
if (!file) {
return IMIO_CANNOTWRITEFILE;
@ -1011,7 +1041,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
*/
jpeg_destroy_compress(&cinfo);
fclose(file);
safe_g_remove(fname);
g_remove (fname.c_str());
return IMIO_CANNOTWRITEFILE;
}
@ -1130,7 +1160,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
delete [] row;
jpeg_destroy_compress(&cinfo);
fclose(file);
safe_g_remove(fname);
g_remove (fname.c_str());
return IMIO_CANNOTWRITEFILE;
}
@ -1142,7 +1172,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp)
jpeg_destroy_compress (&cinfo);
delete [] row;
fclose (file);
safe_g_remove(fname);
g_remove (fname.c_str());
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 ?
if (exifRoot && uncompressed) {
FILE *file = safe_g_fopen_WriteBinLock (fname);
FILE *file = g_fopen_withBinaryAndLock (fname);
if (!file) {
delete [] linebuffer;
@ -1370,7 +1400,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed)
if(writeOk) {
return IMIO_SUCCESS;
} else {
safe_g_remove(fname);
g_remove (fname.c_str());
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 mapcontlutili = 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(),
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);
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);
}
readyphase++;
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.bcurve, bCurve, scale == 1 ? 1 : 1);
TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working);
double wp[3][3] = {
{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.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
progress ("Pyramid wavelet...", 100 * readyphase / numofphases);
ipf.dirpyrequalizer (nprevl, scale);
//ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale);
readyphase++;
if(params.dirpyrequalizer.cbdlMethod == "aft") {
if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ) {
progress ("Pyramid wavelet...", 100 * readyphase / numofphases);
ipf.dirpyrequalizer (nprevl, scale);
//ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale);
readyphase++;
}
}
//}
wavcontlutili = false;
//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
if (todo & M_MONITOR) {
ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent);

View File

@ -52,45 +52,7 @@ namespace rtengine
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;
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 ()
{
@ -3421,10 +3383,22 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
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);
}
int W = working->width;
int H = working->height;
#define TS 112
#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;
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 ))));
fy = (y < 65535.0f ? cachef[std::max(y, 0.f)] : (327.68f * float(exp(log(y / MAXVALF) / 3.0f ))));
fz = (z < 65535.0f ? cachef[std::max(z, 0.f)] : (327.68f * float(exp(log(z / MAXVALF) / 3.0f ))));
fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
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;
a_1 = (500.0f * (fx - fy) );
@ -3836,7 +3810,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
// Luminosity after
// only Luminance in Lab
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);
//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
if(blackwhite) {
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) {
// ready, fill lab
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;
fx = (x < 65535.0f ? cachef[std::max(x, 0.f)] : (327.68f * float(exp(log(x / MAXVALF) / 3.0f ))));
fy = (y < 65535.0f ? cachef[std::max(y, 0.f)] : (327.68f * float(exp(log(y / MAXVALF) / 3.0f ))));
fz = (z < 65535.0f ? cachef[std::max(z, 0.f)] : (327.68f * float(exp(log(z / MAXVALF) / 3.0f ))));
fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
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->a[i][j] = (500.0f * (fx - fy) );
@ -4879,9 +4855,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
float fx, fy, fz;
fx = (x < 65535.0f ? cachef[std::max(x, 0.f)] : (327.68f * float(exp(log(x / MAXVALF) / 3.0f ))));
fy = (y < 65535.0f ? cachef[std::max(y, 0.f)] : (327.68f * float(exp(log(y / MAXVALF) / 3.0f ))));
fz = (z < 65535.0f ? cachef[std::max(z, 0.f)] : (327.68f * float(exp(log(z / MAXVALF) / 3.0f ))));
fx = (x < 65535.0f ? Color::cachef[std::max(x, 0.f)] : 327.68f * std::cbrt(x / MAXVALF));
fy = (y < 65535.0f ? Color::cachef[std::max(y, 0.f)] : 327.68f * std::cbrt(y / MAXVALF));
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->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)
{
if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) {
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;
@ -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
{
static LUTf gamma2curve;
cmsHTRANSFORM monitorTransform;
cmsHTRANSFORM lab2outputTransform;
@ -201,7 +200,6 @@ class ImProcFunctions
public:
static LUTf cachef;
double lumimul[3];
// float chau;
// float chred;
@ -221,8 +219,6 @@ public:
// float maxblueresid;//used by noise_residual
// int comptlevel;
static void initCache ();
static void cleanupCache ();
ImProcFunctions (const ProcParams* iparams, bool imultiThread = true)
: 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 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);
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);
@ -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 double getAutoDistor (const Glib::ustring& fname, int thumb_size);
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

View File

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

View File

@ -117,9 +117,9 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image)
/* copy RGB */
//int R1=((int)gamma2curve[(R)])
data[ix++] = ((int)gamma2curve[CLIP(R)]) >> 8;
data[ix++] = ((int)gamma2curve[CLIP(G)]) >> 8;
data[ix++] = ((int)gamma2curve[CLIP(B)]) >> 8;
data[ix++] = ((int)Color::gamma2curve[CLIP(R)]) >> 8;
data[ix++] = ((int)Color::gamma2curve[CLIP(G)]) >> 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);
image->data[ix++] = (int)gamma2curve[CLIP(R)] >> 8;
image->data[ix++] = (int)gamma2curve[CLIP(G)] >> 8;
image->data[ix++] = (int)gamma2curve[CLIP(B)] >> 8;
image->data[ix++] = (int)Color::gamma2curve[CLIP(R)] >> 8;
image->data[ix++] = (int)Color::gamma2curve[CLIP(G)] >> 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);
image->r(i - cy, j - cx) = (int)gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)gamma2curve[CLIP(G)];
image->b(i - cy, j - cx) = (int)gamma2curve[CLIP(B)];
image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
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);
image->r(i - cy, j - cx) = (int)gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)gamma2curve[CLIP(G)];
image->b(i - cy, j - cx) = (int)gamma2curve[CLIP(B)];
image->r(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(R)];
image->g(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(G)];
image->b(i - cy, j - cx) = (int)Color::gamma2curve[CLIP(B)];
}
}
}

View File

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

View File

@ -19,7 +19,6 @@
#include <cstring>
#include "lcp.h"
#include "safegtk.h"
#include "iccmatrices.h"
#include "iccstore.h"
#include "rawimagesource.h"
@ -303,7 +302,7 @@ LCPProfile::LCPProfile(Glib::ustring fname)
persModelCount = 0;
*inInvalidTag = 0;
FILE *pFile = safe_g_fopen(fname, "rb");
FILE *pFile = g_fopen(fname.c_str (), "rb");
bool done;
@ -807,7 +806,7 @@ LCPProfile* LCPStore::getProfile (Glib::ustring filename)
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;
}
@ -828,7 +827,7 @@ Glib::ustring LCPStore::getDefaultCommonDirectory() const
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 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;
}
}

View File

@ -19,7 +19,6 @@
#include "myfile.h"
#include <cstdarg>
#include <glibmm.h>
#include "safegtk.h"
#ifdef BZIP_SUPPORT
#include <bzlib.h>
#endif
@ -58,6 +57,7 @@ int munmap(void *start, size_t length)
#else // WIN32
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
@ -68,7 +68,25 @@ int munmap(void *start, size_t length)
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 ) {
return 0;
@ -78,7 +96,7 @@ IMFILE* fopen (const char* fname)
if ( fstat(fd, &stat_buffer) < 0 ) {
printf("no stat\n");
close(fd);
close (fd);
return 0;
}

View File

@ -23,8 +23,6 @@
#include "iimage.h"
#include "rtthumbnail.h"
#include "rawimagesource.h"
#include "StopWatch.h"
#include "utils.h"
using namespace rtengine;
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);
output = new Image8(fw, fh);
rawImage.convertColorSpace(image, params.icm, wb);
StopWatch Stop1("inspector loop");
#pragma omp parallel for schedule(dynamic, 10)
for (int i = 0; i < fh; ++i)
for (int j = 0; j < fw; ++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)];
}
Stop1.stop();
image->resizeImgTo<Image8>(fw, fh, TI_Nearest, output);
data = output->getData();

View File

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

View File

@ -16,11 +16,9 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
//#include <glib/gstdio.h>
#include <glib/gstdio.h>
#include "procparams.h"
#include "rt_math.h"
#include "safegtk.h"
#include "safekeyfile.h"
#include "dcp.h"
#include "../rtgui/multilangmgr.h"
#include "../rtgui/version.h"
@ -890,6 +888,7 @@ void RAWParams::setDefaults()
ff_clipControl = 0;
cared = 0;
cablue = 0;
caautostrength = 6;
ca_autocorrect = false;
hotPixelFilter = false;
deadPixelFilter = false;
@ -1219,6 +1218,8 @@ void ProcParams::setDefaults ()
dirpyrequalizer.enabled = false;
dirpyrequalizer.gamutlab = false;
dirpyrequalizer.cbdlMethod = "bef";
for(int i = 0; i < 6; i ++) {
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)
{
if (!fname.length() && !fname2.length()) {
if (fname.empty () && fname2.empty ()) {
return 0;
}
SafeKeyFile keyFile;
Glib::ustring sPParams;
try {
Glib::KeyFile keyFile;
keyFile.set_string ("Version", "AppVersion", APPVERSION);
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);
}
if (!pedited || pedited->dirpyrequalizer.cbdlMethod) {
keyFile.set_string ("Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod);
}
for(int i = 0; i < 6; i++) {
std::stringstream ss;
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 );
}
if (!pedited || pedited->raw.caAutoStrength) {
keyFile.set_double ("RAW", "CAAutoStrength", raw.caautostrength );
}
if (!pedited || pedited->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;
error1 = write (fname , sPParams);
error1 = write (fname, sPParams);
if (fname2.length()) {
if (!fname2.empty ()) {
error2 = write (fname2, sPParams);
// 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()) {
FILE *f;
f = safe_g_fopen (fname, "wt");
f = g_fopen (fname.c_str (), "wt");
if (f == NULL) {
error = 1;
@ -3406,15 +3425,15 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
return 1;
}
SafeKeyFile keyFile;
Glib::KeyFile keyFile;
try {
//setDefaults ();
if (pedited) {
pedited->set(false);
}
FILE* f = safe_g_fopen (fname, "rt");
FILE* f = g_fopen (fname.c_str (), "rt");
if (!f) {
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_key ("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", "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")) {
raw.cared = keyFile.get_double ("RAW", "CARed" );
@ -7427,9 +7462,11 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited)
return 0;
} catch (const Glib::Error& e) {
printf ("-->%s\n", e.what().c_str());
setDefaults ();
return 1;
} catch (...) {
printf ("-->unknown exception!\n");
setDefaults ();
return 1;
}
@ -7777,6 +7814,7 @@ bool ProcParams::operator== (const ProcParams& other)
&& raw.expos == other.raw.expos
&& raw.preser == other.raw.preser
&& raw.ca_autocorrect == other.raw.ca_autocorrect
&& raw.caautostrength == other.raw.caautostrength
&& raw.cared == other.raw.cared
&& raw.cablue == other.raw.cablue
&& raw.hotPixelFilter == other.raw.hotPixelFilter
@ -7880,6 +7918,7 @@ bool ProcParams::operator== (const ProcParams& other)
// && dirpyrequalizer.algo == other.dirpyrequalizer.algo
&& dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin
&& dirpyrequalizer.threshold == other.dirpyrequalizer.threshold
&& dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod
&& dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect
&& hsvequalizer.hcurve == other.hsvequalizer.hcurve
&& hsvequalizer.scurve == other.hsvequalizer.scurve

View File

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

View File

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

View File

@ -1422,6 +1422,7 @@ SSEFUNCTION int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thres
}
#else
// 25 fabs function calls and 25 float additions without SSE
for (int mm = rr - 2; mm <= rr + 2; mm++) {
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);
}
CA_correct_RT(raw.cared, raw.cablue);
CA_correct_RT(raw.cared, raw.cablue, 10.0 - raw.caautostrength);
}
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 bo = min(b, maxval);
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)
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 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 )));
y = (y < 65535.0 ? ImProcFunctions::cachef[y] / 327.68 : (exp(log(y / MAXVALD) / 3.0 )));
z = (z < 65535.0 ? ImProcFunctions::cachef[z] / 327.68 : (exp(log(z / MAXVALD) / 3.0 )));
x = (x < 65535.0 ? Color::cachef[x] / 327.68 : std::cbrt(x / MAXVALD));
y = (y < 65535.0 ? Color::cachef[y] / 327.68 : std::cbrt(y / MAXVALD));
z = (z < 65535.0 ? Color::cachef[z] / 327.68 : std::cbrt(z / MAXVALD));
// convert back to rgb
double fz = fy - y + z;
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_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 (double cared, double cablue);
void CA_correct_RT (const double cared, const double cablue, const double caautostrength);
void ddct8x8s(int isgn, float a[8][8]);
void processRawWhitepoint (float expos, float preser); // exposure before interpolation

View File

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

View File

@ -33,8 +33,6 @@
#include "stdimagesource.h"
#include <glib/gstdio.h>
#include <csetjmp>
#include "safekeyfile.h"
#include "safegtk.h"
#include "rawimage.h"
#include "jpeg.h"
#include "../rtgui/ppversion.h"
@ -720,30 +718,6 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
#undef FISGREEN
#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 ()
{
@ -1456,9 +1430,9 @@ unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width)
image->convertTo(image->r(i, j), r_);
image->convertTo(image->g(i, j), g_);
image->convertTo(image->b(i, j), b_);
int r = gammatab[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = gammatab[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int b = gammatab[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int r = Color::gammatabThumb[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = Color::gammatabThumb[min(g_, 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;
}
} 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->g(i, j), g_);
image->convertTo(image->b(i, j), b_);
int r = gammatab[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = gammatab[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int b = gammatab[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int r = Color::gammatabThumb[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = Color::gammatabThumb[min(g_, 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;
}
} 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->g(i, j), g_);
image->convertTo(image->b(i, j), b_);
int r = gammatab[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = gammatab[min(g_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int b = gammatab[min(b_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int r = Color::gammatabThumb[min(r_, static_cast<unsigned short>(max_)) * scaleForSave >> 13];
int g = Color::gammatabThumb[min(g_, 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;
}
}
@ -1653,7 +1627,7 @@ bool Thumbnail::writeImage (const Glib::ustring& fname, int format)
Glib::ustring fullFName = fname + ".rtti";
FILE* f = safe_g_fopen (fullFName, "wb");
FILE* f = g_fopen (fullFName.c_str (), "wb");
if (!f) {
return false;
@ -1692,11 +1666,11 @@ bool Thumbnail::readImage (const Glib::ustring& fname)
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;
}
FILE* f = safe_g_fopen (fullFName, "rb");
FILE* f = g_fopen (fullFName.c_str (), "rb");
if (!f) {
return false;
@ -1738,12 +1712,14 @@ bool Thumbnail::readImage (const Glib::ustring& fname)
bool Thumbnail::readData (const Glib::ustring& fname)
{
setlocale(LC_NUMERIC, "C"); // to set decimal point to "."
SafeKeyFile keyFile;
Glib::KeyFile keyFile;
try {
MyMutex::MyLock thmbLock(thumbMutex);
if (!keyFile.load_from_file (fname)) {
try {
keyFile.load_from_file (fname);
} catch (Glib::Error&) {
return false;
}
@ -1831,16 +1807,38 @@ bool Thumbnail::readData (const Glib::ustring& fname)
bool Thumbnail::writeData (const Glib::ustring& fname)
{
SafeKeyFile keyFile;
MyMutex::MyLock thmbLock(thumbMutex);
Glib::ustring keyData;
try {
if( safe_file_test(fname, Glib::FILE_TEST_EXISTS) ) {
Glib::KeyFile keyFile;
try {
keyFile.load_from_file (fname);
}
} catch (Glib::Error &err) {
} catch (Glib::Error&) {}
keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed);
keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen);
keyFile.set_double ("LiveThumbData", "CamWBBlue", camwbBlue);
keyFile.set_double ("LiveThumbData", "RedAWBMul", redAWBMul);
keyFile.set_double ("LiveThumbData", "GreenAWBMul", greenAWBMul);
keyFile.set_double ("LiveThumbData", "BlueAWBMul", blueAWBMul);
keyFile.set_integer ("LiveThumbData", "AEHistCompression", aeHistCompression);
keyFile.set_double ("LiveThumbData", "RedMultiplier", redMultiplier);
keyFile.set_double ("LiveThumbData", "GreenMultiplier", greenMultiplier);
keyFile.set_double ("LiveThumbData", "BlueMultiplier", blueMultiplier);
keyFile.set_double ("LiveThumbData", "Scale", scale);
keyFile.set_double ("LiveThumbData", "DefaultGain", defGain);
keyFile.set_integer ("LiveThumbData", "ScaleForSave", scaleForSave);
keyFile.set_boolean ("LiveThumbData", "GammaCorrected", gammaCorrected);
Glib::ArrayHandle<double> cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm);
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());
}
@ -1850,24 +1848,11 @@ bool Thumbnail::writeData (const Glib::ustring& fname)
}
}
keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed);
keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen);
keyFile.set_double ("LiveThumbData", "CamWBBlue", camwbBlue);
keyFile.set_double ("LiveThumbData", "RedAWBMul", redAWBMul);
keyFile.set_double ("LiveThumbData", "GreenAWBMul", greenAWBMul);
keyFile.set_double ("LiveThumbData", "BlueAWBMul", blueAWBMul);
keyFile.set_integer ("LiveThumbData", "AEHistCompression", aeHistCompression);
keyFile.set_double ("LiveThumbData", "RedMultiplier", redMultiplier);
keyFile.set_double ("LiveThumbData", "GreenMultiplier", greenMultiplier);
keyFile.set_double ("LiveThumbData", "BlueMultiplier", blueMultiplier);
keyFile.set_double ("LiveThumbData", "Scale", scale);
keyFile.set_double ("LiveThumbData", "DefaultGain", defGain);
keyFile.set_integer ("LiveThumbData", "ScaleForSave", scaleForSave);
keyFile.set_boolean ("LiveThumbData", "GammaCorrected", gammaCorrected);
Glib::ArrayHandle<double> cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE);
keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm);
if (keyData.empty ()) {
return false;
}
FILE *f = safe_g_fopen (fname, "wt");
FILE *f = g_fopen (fname.c_str (), "wt");
if (!f) {
if (options.rtSettings.verbose) {
@ -1876,7 +1861,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname)
return false;
} else {
fprintf (f, "%s", keyFile.to_data().c_str());
fprintf (f, "%s", keyData.c_str ());
fclose (f);
}
@ -1886,7 +1871,7 @@ bool Thumbnail::writeData (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) {
embProfileData = NULL;
@ -1910,7 +1895,7 @@ bool Thumbnail::writeEmbProfile (const Glib::ustring& fname)
{
if (embProfileData) {
FILE* f = safe_g_fopen(fname, "wb");
FILE* f = g_fopen(fname.c_str (), "wb");
if (f) {
fwrite (embProfileData, 1, embProfileLength, f);
@ -1925,7 +1910,7 @@ bool Thumbnail::writeEmbProfile (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) {
aeHistogram(0);
@ -1943,7 +1928,7 @@ bool Thumbnail::writeAEHistogram (const Glib::ustring& fname)
{
if (aeHistogram) {
FILE* f = safe_g_fopen (fname, "wb");
FILE* f = g_fopen (fname.c_str (), "wb");
if (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);
static unsigned short *igammatab;
static unsigned char *gammatab;
ImageIO* thumbImg;
double camwbRed;
double camwbGreen;
@ -72,8 +69,6 @@ public:
~Thumbnail ();
Thumbnail ();
static void initGamma ();
static void cleanupGamma ();
void init ();
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;
}
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
SHMap* shmap = NULL;
@ -982,9 +992,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL );
// directional pyramid wavelet
if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) {
ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one
if(params.dirpyrequalizer.cbdlMethod == "aft") {
if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) {
ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one
}
}
int kall = 2;

View File

@ -25,9 +25,11 @@
#include <sstream>
#include <stdint.h>
#include "../rtgui/cacheimagedata.h"
#include <glib/gstdio.h>
#include "rtexif.h"
#include "../rtengine/safegtk.h"
#include "../rtgui/cacheimagedata.h"
#include "../rtgui/version.h"
#include "../rtgui/ppversion.h"
@ -247,17 +249,10 @@ void TagDirectory::printAll (unsigned int level) const
*
* @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,
rtengine::SafeKeyFile *keyFile, Glib::ustring tagDirName) const
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, Glib::KeyFile *keyFile, Glib::ustring tagDirName) const
{
rtengine::SafeKeyFile *kf;
if (!keyFile) {
kf = new rtengine::SafeKeyFile();
} else {
kf = keyFile;
}
const auto kf = keyFile ? keyFile : new Glib::KeyFile;
if (!kf) {
return false;
@ -274,7 +269,7 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
if (!keyFile) {
// open the file in write mode
f = safe_g_fopen (commFName, "wt");
f = g_fopen (commFName.c_str (), "wt");
if (f == NULL) {
printf("TagDirectory::keyFileDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str());
@ -282,21 +277,25 @@ bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring
return false;
}
kf->set_string ("RT General", "CachePath", options.cacheBaseDir);
kf->set_string ("RT General", "AppVersion", VERSION);
kf->set_integer("RT General", "ProcParamsVersion", PPVERSION);
kf->set_string ("RT General", "ImageFileName", imageFName);
kf->set_string ("RT General", "OutputProfileFileName", profileFName);
kf->set_string ("RT General", "DefaultProcParams", defaultPParams);
kf->set_boolean("RT General", "FlaggingMode", flagMode);
try {
kf->set_double ("Common Data", "FNumber", cfs->fnumber);
kf->set_double ("Common Data", "Shutter", cfs->shutter);
kf->set_double ("Common Data", "FocalLength", cfs->focalLen);
kf->set_integer("Common Data", "ISO", cfs->iso);
kf->set_string ("Common Data", "Lens", cfs->lens);
kf->set_string ("Common Data", "Make", cfs->camMake);
kf->set_string ("Common Data", "Model", cfs->camModel);
kf->set_string ("RT General", "CachePath", options.cacheBaseDir);
kf->set_string ("RT General", "AppVersion", VERSION);
kf->set_integer("RT General", "ProcParamsVersion", PPVERSION);
kf->set_string ("RT General", "ImageFileName", imageFName);
kf->set_string ("RT General", "OutputProfileFileName", profileFName);
kf->set_string ("RT General", "DefaultProcParams", defaultPParams);
kf->set_boolean("RT General", "FlaggingMode", flagMode);
kf->set_double ("Common Data", "FNumber", cfs->fnumber);
kf->set_double ("Common Data", "Shutter", cfs->shutter);
kf->set_double ("Common Data", "FocalLength", cfs->focalLen);
kf->set_integer("Common Data", "ISO", cfs->iso);
kf->set_string ("Common Data", "Lens", cfs->lens);
kf->set_string ("Common Data", "Make", cfs->camMake);
kf->set_string ("Common Data", "Model", cfs->camModel);
} catch (Glib::KeyFileError&) {}
}
// 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
tagDirPaths.push_back( Glib::ustring( tagDirName + "/" + getDumpKey(tags[i]->getID(), tagName) ) );
tagDirList.push_back(tags[i]->getDirectory(j));
kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), "$subdir");
try {
kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), "$subdir");
} catch (Glib::KeyFileError&) {}
}
else {
kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), tags[i]->valueToString());
try {
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) {
fprintf (f, "%s", kf->to_data().c_str());
try {
fprintf (f, "%s", kf->to_data().c_str());
} catch (Glib::KeyFileError&) {}
fclose (f);
delete kf;
}

View File

@ -29,7 +29,6 @@
#include <cmath>
#include <glibmm.h>
#include "../rtengine/procparams.h"
#include "../rtengine/safekeyfile.h"
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 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 ();
};

View File

@ -32,7 +32,6 @@
#include "filecatalog.h"
#include "batchqueuebuttonset.h"
#include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h"
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);
Glib::ustring savedParamPath;
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 += stringTimestamp;
savedParamPath += paramFileExtension;
@ -381,8 +380,11 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename
int cancelItemUI (void* data)
{
safe_g_remove( (static_cast<BatchQueueEntry*>(data))->savedParamsFile );
delete static_cast<BatchQueueEntry*>(data);
const auto bqe = static_cast<BatchQueueEntry*>(data);
g_remove (bqe->savedParamsFile.c_str ());
delete bqe;
return 0;
}
@ -667,24 +669,31 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img)
processing->removeButtonSet ();
}
if (saveBatchQueue( )) {
safe_g_remove( processedParams );
// Delete all files in directory \batch when finished, just to be sure to remove zombies
if (saveBatchQueue ()) {
::g_remove (processedParams.c_str ());
// Not sure that locking is necessary, but it should be safer
MYREADERLOCK(l, entryRW);
// Delete all files in directory batch when finished, just to be sure to remove zombies
auto isEmpty = false;
if( fd.empty() ) {
MYREADERLOCK_RELEASE(l);
{
MYREADERLOCK(l, entryRW);
isEmpty = fd.empty();
}
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);
if (isEmpty) {
for(std::vector<Glib::ustring>::iterator iter = names.begin(); iter != names.end(); iter++ ) {
safe_g_remove( *iter );
}
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;
// create directory, if does not exist
if (safe_g_mkdir_with_parents (dstdir, 0755) ) {
return "";
if (g_mkdir_with_parents (dstdir.c_str (), 0755)) {
return Glib::ustring ();
}
// 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);
}
int fileExists = safe_file_test (fname, Glib::FILE_TEST_EXISTS);
int fileExists = Glib::file_test (fname, Glib::FILE_TEST_EXISTS);
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
} else {
fileExists = false; // deleted now

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -65,7 +65,6 @@ public:
// additional info on raw images
int rotate;
int thumbImgType;
int thumbOffset;
enum {
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
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cropwindow.h"
#include <iomanip>
#include "cropwindow.h"
#include "options.h"
#include "guiutils.h"
#include "threadutils.h"
#include "../rtengine/mytime.h"
#include "imagearea.h"
#include "cursormanager.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/rt_math.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;
struct ZoomStep {
@ -84,11 +86,11 @@ CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_,
titleHeight = ih;
bZoomOut = new LWButton (safe_create_from_png ("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");
bZoom100 = new LWButton (safe_create_from_png ("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");
bClose = new LWButton (safe_create_from_png ("gtk-close-small.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close");
bZoomOut = new LWButton (RTImage::createFromPng ("gtk-zoom-out-small.png"), 0, NULL, LWButton::Left, LWButton::Center, "Zoom Out");
bZoomIn = new LWButton (RTImage::createFromPng ("gtk-zoom-in-small.png"), 1, NULL, LWButton::Left, LWButton::Center, "Zoom In");
bZoom100 = new LWButton (RTImage::createFromPng ("gtk-zoom-100-small.png"), 2, NULL, LWButton::Left, LWButton::Center, "Zoom 100/%");
//bZoomFit = new LWButton (RTImage::createFromPng ("gtk-zoom-fit.png"), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit");
bClose = new LWButton (RTImage::createFromPng ("gtk-close-small.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close");
buttonSet.add (bZoomOut);
buttonSet.add (bZoomIn);

View File

@ -17,8 +17,8 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cursormanager.h"
#include "options.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h"
CursorManager mainWindowCursorManager;
@ -51,14 +51,14 @@ void CursorManager::init (Glib::RefPtr<Gdk::Window> mainWindow)
cAdd = Gdk::Cursor::create (display, Gdk::PLUS);
cWait = Gdk::Cursor::create (display, Gdk::CLOCK);
Glib::RefPtr<Gdk::Pixbuf> hand = safe_create_from_file("cross.png");
Glib::RefPtr<Gdk::Pixbuf> close_hand = safe_create_from_file("closedhand.png");
Glib::RefPtr<Gdk::Pixbuf> wbpick = safe_create_from_file("gtk-color-picker-small.png");
Glib::RefPtr<Gdk::Pixbuf> empty = safe_create_from_file("empty.png");
Glib::RefPtr<Gdk::Pixbuf> move2D = safe_create_from_file("move-2D.png");
Glib::RefPtr<Gdk::Pixbuf> move1DH = safe_create_from_file("move-1D-h.png");
Glib::RefPtr<Gdk::Pixbuf> move1DV = safe_create_from_file("move-1D-v.png");
Glib::RefPtr<Gdk::Pixbuf> moveRotate = safe_create_from_file("move-rotate.png");
Glib::RefPtr<Gdk::Pixbuf> hand = RTImage::createFromFile ("cross.png");
Glib::RefPtr<Gdk::Pixbuf> close_hand = RTImage::createFromFile ("closedhand.png");
Glib::RefPtr<Gdk::Pixbuf> wbpick = RTImage::createFromFile ("gtk-color-picker-small.png");
Glib::RefPtr<Gdk::Pixbuf> empty = RTImage::createFromFile ("empty.png");
Glib::RefPtr<Gdk::Pixbuf> move2D = RTImage::createFromFile ("move-2D.png");
Glib::RefPtr<Gdk::Pixbuf> move1DH = RTImage::createFromFile ("move-1D-h.png");
Glib::RefPtr<Gdk::Pixbuf> move1DV = RTImage::createFromFile ("move-1D-v.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);
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 "flatcurveeditorsubgroup.h"
#include "multilangmgr.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h"
CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), curve_reset(NULL),

View File

@ -19,7 +19,6 @@
#include "darkframe.h"
#include "options.h"
#include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream>
#include "rtimage.h"
@ -81,7 +80,7 @@ void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi
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);
} else {
darkFrameReset();

View File

@ -17,27 +17,57 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dirbrowser.h"
#include <cstring>
#ifdef WIN32
#define _WIN32_WINNT 0x0600
#include <windows.h>
#endif
#include "options.h"
#include "multilangmgr.h"
#include "../rtengine/safegtk.h"
#include <cstring>
#include "guiutils.h"
#include "rtimage.h"
#include "multilangmgr.h"
#include "options.h"
#define CHECKTIME 5000
namespace
{
std::vector<Glib::ustring> listSubDirs (const Glib::RefPtr<Gio::File>& dir, bool addHidden)
{
std::vector<Glib::ustring> subDirs;
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;
}
struct DirNameComparator {
template<class T>
bool operator()(T const &firstDir, T const &secondDir) const
{
return options.dirBrowserSortType == Gtk::SORT_ASCENDING ? firstDir < secondDir : firstDir > secondDir;
}
};
return subDirs;
}
}
DirBrowser::DirBrowser () : dirTreeModel(),
dtColumns(),
@ -71,13 +101,13 @@ DirBrowser::DirBrowser () : dirTreeModel(),
void DirBrowser::fillDirTree ()
{
openfolder = safe_create_from_file ("gtk-open.png");
closedfolder = safe_create_from_file ("folder.png");
icdrom = safe_create_from_file ("drive-optical.png");
ifloppy = safe_create_from_file ("drive-removable-media.png");
ihdd = safe_create_from_file ("drive-harddisk.png");
iremovable = safe_create_from_file ("media-usb.png");
inetwork = safe_create_from_file ("network.png");
openfolder = RTImage::createFromFile ("gtk-open.png");
closedfolder = RTImage::createFromFile ("folder.png");
icdrom = RTImage::createFromFile ("drive-optical.png");
ifloppy = RTImage::createFromFile ("drive-removable-media.png");
ihdd = RTImage::createFromFile ("drive-harddisk.png");
iremovable = RTImage::createFromFile ("media-usb.png");
inetwork = RTImage::createFromFile ("network.png");
//Create the Tree model:
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
g_timeout_add (CHECKTIME, updateVolumesUI, this);
g_timeout_add (5000, updateVolumesUI, this);
#else
Gtk::TreeModel::Row rootRow = *(dirTreeModel->append());
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
// in list tree dramatically. Therefore will do:
// 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)
int prevSortColumn;
Gtk::SortType prevSortType;
dirTreeModel->get_sort_column_id(prevSortColumn, prevSortType);
dirTreeModel->set_sort_column(Gtk::TreeSortable::DEFAULT_UNSORTED_COLUMN_ID, Gtk::SORT_ASCENDING);
typedef std::vector<Glib::ustring> DirPathType;
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);
auto dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
auto subDirs = listSubDirs (dir, options.fbShowHidden);
if (subDirs.empty()) {
dirtree->collapse_row(path);
@ -263,14 +289,22 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::
Gtk::TreeNodeChildren children = iter->children();
std::list<Gtk::TreeIter> forErase(children.begin(), children.end());
DirNameComparator comparator;
sort(subDirs.begin(), subDirs.end(), comparator);
std::sort (subDirs.begin (), subDirs.end (), [] (const Glib::ustring& firstDir, const Glib::ustring& secondDir)
{
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);
}
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);
}
@ -299,8 +333,8 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter)
change = false;
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)
|| !safe_file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) {
if (!Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS)
|| !Glib::file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) {
GThreadLock lock;
dirTreeModel->erase (it);
change = true;
@ -309,9 +343,8 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter)
}
// test if new files are created
std::vector<Glib::ustring> subDirs;
Glib::RefPtr<Gio::File> dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
safe_build_subdir_list (dir, subDirs, options.fbShowHidden);
auto dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname));
auto subDirs = listSubDirs (dir, options.fbShowHidden);
for (int i = 0; i < subDirs.size(); i++) {
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);
if (safe_file_test (dname, Glib::FILE_TEST_IS_DIR))
if (Glib::file_test (dname, Glib::FILE_TEST_IS_DIR))
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)
{
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;
}

View File

@ -51,6 +51,24 @@ DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer",
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
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"));
Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox(true, 10));
@ -145,12 +163,17 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited)
{
disableListener ();
cbdlMethodConn.block(true);
if (pedited) {
set_inconsistent (multiImage && !pedited->dirpyrequalizer.enabled);
gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab);
if (!pedited->dirpyrequalizer.cbdlMethod) {
cbdlMethod->set_active_text(M("GENERAL_UNCHANGED"));
}
for(int i = 0; i < 6; i++) {
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);
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 ();
}
@ -207,6 +239,7 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited)
pedited->dirpyrequalizer.enabled = !get_inconsistent();
pedited->dirpyrequalizer.hueskin = hueskin->getEditedState ();
pedited->dirpyrequalizer.cbdlMethod = cbdlMethod->get_active_text() != M("GENERAL_UNCHANGED");
for(int i = 0; i < 6; i++) {
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");
}
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)
pp->dirpyrequalizer.algo = "FI";
else if (algo->get_active_row_number()==1)
@ -281,6 +321,16 @@ void DirPyrEqualizer::setBatchMode (bool batchMode)
// algo->append (M("GENERAL_UNCHANGED"));
}
void DirPyrEqualizer::cbdlMethodChanged()
{
if (listener) {
listener->panelChanged (EvcbdlMethod, cbdlMethod->get_active_text ());
}
}
void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval)
{

View File

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

View File

@ -18,18 +18,20 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "editorpanel.h"
#include "options.h"
#include "progressconnector.h"
#include "rtwindow.h"
#include "guiutils.h"
#include "procparamchangers.h"
#include "../rtengine/safegtk.h"
#include <iostream>
#include "../rtengine/imagesource.h"
#include "../rtengine/iccstore.h"
#include "soundman.h"
#include "rtimage.h"
#include <iostream>
#include "rtwindow.h"
#include "guiutils.h"
#include "popupbutton.h"
#include "options.h"
#include "progressconnector.h"
#include "procparamchangers.h"
#include "placesbrowser.h"
using namespace rtengine::procparams;
@ -516,7 +518,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
show_all ();
/*
// 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);
else
saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir());
@ -813,7 +815,7 @@ void EditorPanel::close ()
navigator->previewWindow->setPreviewHandler (NULL);
// 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->decreaseRef ();
}
@ -827,7 +829,7 @@ void EditorPanel::saveProfile ()
}
// 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;
ipc->getParams (&params);
@ -1573,10 +1575,10 @@ void EditorPanel::saveAsPressed ()
SaveAsDialog* saveAsDialog;
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);
} else {
saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir(), toplevel);
saveAsDialog = new SaveAsDialog (PlacesBrowser::userPicturesDir (), toplevel);
}
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);
}
if (!safe_file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) {
if (!Glib::file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) {
fnameOut = fnameTemp;
fnameOK = true;
break;
@ -1731,10 +1733,11 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector<rtengine::IImage16*> *pc,
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;
while (safe_file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) {
fileName = Glib::ustring::compose ("%1-%2.%3", fname, tries, sf.format);
while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries < 1000) {
fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format);
tries++;
}
@ -1770,99 +1773,21 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImage1
parent->setProgressStr ("");
parent->setProgress (0.);
bool success = false;
Glib::ustring cmdLine;
Glib::ustring executable;
// start gimp
if (options.editorToSendTo == 1) {
#ifdef WIN32
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
}
success = ExtProgStore::openInGimp (filename);
} else if (options.editorToSendTo == 2) {
#ifdef WIN32
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
success = ExtProgStore::openInPhotoshop (filename);
} else if (options.editorToSendTo == 3) {
#ifdef WIN32
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
success = ExtProgStore::openInCustomEditor (filename);
}
if (!success) {
Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd->set_secondary_text (M ("MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY"));
msgd->set_title (M ("MAIN_BUTTON_SENDTOEDITOR"));
msgd->run ();
delete msgd;
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_title (M("MAIN_BUTTON_SENDTOEDITOR"));
msgd.run ();
}
}
return false;

View File

@ -17,7 +17,7 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "exifpanel.h"
#include "../rtengine/safegtk.h"
#include "guiutils.h"
#include "rtimage.h"
@ -46,9 +46,9 @@ ExifPanel::ExifPanel () : idata(NULL)
exifTreeModel = Gtk::TreeStore::create(exifColumns);
exifTree->set_model (exifTreeModel);
delicon = safe_create_from_file ("gtk-close.png");
keepicon = safe_create_from_file ("gtk-apply.png");
editicon = safe_create_from_file ("gtk-add.png");
delicon = RTImage::createFromFile ("gtk-close.png");
keepicon = RTImage::createFromFile ("gtk-apply.png");
editicon = RTImage::createFromFile ("gtk-add.png");
Gtk::TreeView::Column *viewcol = Gtk::manage(new Gtk::TreeView::Column ("Field Name"));
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
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstring>
#include "extprog.h"
#include "multilangmgr.h"
#include "../rtengine/safegtk.h"
#include <cstring>
#include <iostream>
#ifdef WIN32
#include <windows.h>
// for GCC32
#ifndef _WIN32_IE
#define _WIN32_IE 0x0600
#endif
#include <shlobj.h>
#endif
using namespace std;
#include "options.h"
#include "multilangmgr.h"
ExtProgAction::ExtProgAction() {}
ExtProgAction::ExtProgAction(const ExtProgAction* other, int target)
: target(target), filePathEXE(other->filePathEXE), preparams(other->preparams), name(other->name) { }
Glib::ustring ExtProgAction::GetFullName()
Glib::ustring ExtProgAction::getFullName () const
{
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;
}
// Check if they all exists (maybe not precessed yet)
for (int i = 0; i < fileNames.size(); i++) {
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);
msgd.run ();
return false;
// Check if they all exists as they may not be processed yet.
for (const auto& fileName : fileNames) {
if (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS)) {
continue;
}
Gtk::MessageDialog (M("MAIN_MSG_IMAGEUNPROCESSED"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true).run ();
return false;
}
Glib::ustring cmdLine = "\"" + filePathEXE + "\"";
if (preparams.length() > 0) {
if (!preparams.empty()) {
cmdLine += " " + preparams;
}
for (int i = 0; i < fileNames.size(); i++) {
cmdLine += " \"" + fileNames[i] + "\"";
for (const auto& fileName : fileNames) {
cmdLine += " \"" + fileName + "\"";
}
return safe_spawn_command_line_async (cmdLine);
return ExtProgStore::spawnCommandAsync (cmdLine);
}
// Generates as singleton
ExtProgStore* ExtProgStore::getInstance()
{
static ExtProgStore 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
void ExtProgStore::init ()
{
MyMutex::MyLock lock(mtx);
lActions.clear();
actions.clear ();
#ifdef WIN32
SearchProg("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true);
SearchProg("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true);
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);
// Please do not add obscure little tools here, only widely used programs.
// They should also have a proper setup program and therefore a standard path.
if (!SearchProg("Autopano Giga 3", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga.exe", 15, true, true)) {
if ( !SearchProg("Autopano Pro 3", "Kolor\\Autopano Pro 3.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 3.%1\\AutopanoPro.exe", 15, 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)) {
SearchProg("Autopano Pro 2", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 6, true, true);
searchProgram ("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true);
searchProgram ("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true);
searchProgram ("Paint.NET", "Paint.NET\\PaintDotNet.exe", "", 0, false, 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
}
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
// get_user_special_dir crashes on some Windows configurations.
// so we use the safe native functions here
static Glib::ustring progFilesDir, progFilesDirx86;
if (progFilesDir.empty()) {
WCHAR pathW[MAX_PATH] = {0};
if (progFilesDir.empty ()) {
WCHAR pathW[MAX_PATH];
char pathA[MAX_PATH];
// First prio folder (64bit, otherwise 32bit)
if (SHGetSpecialFolderPathW(NULL, pathW, CSIDL_PROGRAM_FILES, false)) {
char pathA[MAX_PATH];
WideCharToMultiByte(CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0);
progFilesDir = Glib::ustring(pathA);
if (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PROGRAM_FILES, false)) {
if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) {
progFilesDir = 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 (SHGetSpecialFolderPathW (NULL, pathW, CSIDL_PROGRAM_FILESX86, false)) {
if (WideCharToMultiByte (CP_UTF8, 0, pathW, -1, pathA, MAX_PATH, 0, 0)) {
progFilesDirx86 = pathA;
}
}
}
if (exePath86.empty()) {
exePath86 = exePath;
}
ExtProgAction action;
action.name = name;
action.target = (allowRaw ? 1 : 2);
ExtProgAction *pAct = new ExtProgAction();
pAct->name = name;
pAct->target = (allowRaw ? 1 : 2);
auto& filePath = action.filePathEXE;
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;
}
pAct->filePathEXE = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, verNo);
if (!exePath86.empty ()) {
if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) {
break;
filePath = progFilesDirx86 + "\\" + Glib::ustring::compose(exePath86, ver);
if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
break;
}
}
pAct->filePathEXE = "";
filePath.clear ();
}
} 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)) {
pAct->filePathEXE = "";
if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
break;
}
}
if (!exePath86.empty ()) {
filePath = progFilesDirx86 + "\\" + exePath86;
if (Glib::file_test (filePath, Glib::FILE_TEST_EXISTS)) {
break;
}
}
filePath.clear ();
} while (false);
}
if (pAct->filePathEXE.length() > 0) {
lActions.push_back(pAct);
if (!action.filePathEXE.empty ()) {
actions.push_back (action);
// Copy for second target
if (allowRaw && allowQueueProcess) {
lActions.push_back(new ExtProgAction(pAct, 2));
action.target = 2;
actions.push_back (action);
}
found = true;
} else {
delete pAct;
return true;
}
#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_
#define _EXTPROG_
#include <glibmm.h>
#include <list>
#include <glibmm/ustring.h>
#include <vector>
#include "threadutils.h"
class ExtProgAction
struct ExtProgAction
{
public:
ExtProgAction();
ExtProgAction(const ExtProgAction* other, int target);
Glib::ustring filePathEXE;
Glib::ustring preparams; // after EXE and before file names
Glib::ustring name; // already localized if necessary
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
class ExtProgStore
{
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:
~ExtProgStore();
void init(); // searches computer for installed standard programs
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()
inline const std::vector<ExtProgAction>& ExtProgStore::getActions () const
{
return actions;
}
#endif

View File

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

View File

@ -93,7 +93,7 @@ protected:
Gtk::MenuItem* menuExtProg;
Gtk::MenuItem** amiExtProg;
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* selectDF;

View File

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

View File

@ -17,22 +17,25 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib/gstdio.h>
#include "filecatalog.h"
#include <iostream>
#include <iomanip>
#include <glib/gstdio.h>
#include "../rtengine/rt_math.h"
#include "filecatalog.h"
#include "filepanel.h"
#include "guiutils.h"
#include "options.h"
#include "rtimage.h"
#include "cachemanager.h"
#include "multilangmgr.h"
#include "guiutils.h"
#include "filepanel.h"
#include "renamedlg.h"
#include "thumbimageupdater.h"
#include "../rtengine/safegtk.h"
#include "batchqueue.h"
#include "rtimage.h"
#include "placesbrowser.h"
using namespace std;
@ -544,11 +547,44 @@ void FileCatalog::closeDir ()
std::vector<Glib::ustring> FileCatalog::getFileList ()
{
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));
// Issue 2406 std::sort (names.begin(), names.end());
std::set<Glib::ustring> extensions;
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;
}
@ -908,35 +944,26 @@ void FileCatalog::deleteRequested (std::vector<FileBrowserEntry*> tbe, bool inc
if (msd.run() == Gtk::RESPONSE_YES) {
for (unsigned int i = 0; i < tbe.size(); i++) {
Glib::ustring fname = tbe[i]->filename;
const auto fname = tbe[i]->filename;
// remove from browser
FileBrowserEntry* t = fileBrowser->delEntry (fname);
// t->thumbnail->decreaseRef ();
delete t;
delete fileBrowser->delEntry (fname);
// remove from cache
cacheMgr->deleteEntry (fname);
// delete from file system
safe_g_remove (fname);
::g_remove (fname.c_str ());
// delete paramfile if found
safe_g_remove (Glib::ustring(fname + paramFileExtension));
safe_g_remove (Glib::ustring(removeExtension(fname) + paramFileExtension));
::g_remove ((fname + paramFileExtension).c_str ());
::g_remove ((removeExtension(fname) + paramFileExtension).c_str ());
// delete .thm file
safe_g_remove (Glib::ustring(removeExtension(fname) + ".thm"));
safe_g_remove (Glib::ustring(removeExtension(fname) + ".THM"));
::g_remove ((removeExtension(fname) + ".thm").c_str ());
::g_remove ((removeExtension(fname) + ".THM").c_str ());
if (inclBatchProcessed) {
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);
if (safe_file_test (procfNameParamFile, Glib::FILE_TEST_EXISTS)) {
safe_g_remove (procfNameParamFile);
}
::g_remove (procfNameParamFile.c_str ());
}
previewsLoaded--;
@ -1007,7 +1034,7 @@ void FileCatalog::copyMoveRequested (std::vector<FileBrowserEntry*> tbe, bool m
while(!filecopymovecomplete) {
// 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
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
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);
// copy/move paramFile to destination
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
// delete source profile as cleanup
safe_g_remove (src_fPath + paramFileExtension);
::g_remove ((src_fPath + paramFileExtension).c_str ());
} else {
scr_param->move(dest_param);
}
@ -1238,16 +1265,16 @@ void FileCatalog::renameRequested (std::vector<FileBrowserEntry*> tbe)
Glib::ustring nfname = Glib::build_filename (dirName, nBaseName);
/* 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>";
Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
msgd.run ();
} else {
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);
safe_g_remove(ofname + paramFileExtension);
::g_remove((ofname + paramFileExtension).c_str ());
reparseDirectory ();
}
}
@ -1684,7 +1711,7 @@ void FileCatalog::reparseDirectory ()
return;
}
if (!safe_file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) {
if (!Glib::file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) {
closeDir ();
return;
}
@ -1696,7 +1723,7 @@ void FileCatalog::reparseDirectory ()
std::vector<Glib::ustring> fileNamesToDel;
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);
}
@ -1761,63 +1788,91 @@ void FileCatalog::on_dir_changed (const Glib::RefPtr<Gio::File>& file, const Gli
void FileCatalog::checkAndAddFile (Glib::RefPtr<Gio::File> file)
{
if (!file ) {
if (!file) {
return;
}
if( !file->query_exists()) {
if (!file->query_exists()) {
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)) {
size_t lastdot = info->get_name().find_last_of ('.');
auto info = file->query_info ();
if (options.is_extention_enabled(lastdot != Glib::ustring::npos ? info->get_name().substr (lastdot + 1) : "")) {
previewLoader->add (selectedDirectoryId, file->get_parse_name(), this);
previewsToLoad++;
if (!info || info->get_file_type () == Gio::FILE_TYPE_DIRECTORY) {
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++;
} catch(Gio::Error&) {}
}
void FileCatalog::addAndOpenFile (const Glib::ustring& fname)
{
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path (fname);
auto file = Gio::File::create_for_path (fname);
if (!file ) {
return;
}
if( !file->query_exists()) {
if (!file->query_exists ()) {
return;
}
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info(file);
try {
if( !info ) {
return;
}
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 supported, load thumbnail first
Thumbnail* tmb = cacheMgr->getEntry (file->get_parse_name());
if (tmb) {
FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name());
previewReady (selectedDirectoryId, entry);
// open the file
FCOIParams* params = new FCOIParams;
params->catalog = this;
params->tmb.push_back (tmb);
tmb->increaseRef ();
g_idle_add (openRequestedUI, params);
if (!info) {
return;
}
}
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 supported, load thumbnail first
const auto tmb = cacheMgr->getEntry (file->get_parse_name ());
if (!tmb) {
return;
}
FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name ());
previewReady (selectedDirectoryId, entry);
// open the file
FCOIParams* params = new FCOIParams;
params->catalog = this;
params->tmb.push_back (tmb);
tmb->increaseRef ();
g_idle_add (openRequestedUI, params);
} catch(Gio::Error&) {}
}
void FileCatalog::emptyTrash ()
@ -1989,10 +2044,9 @@ void FileCatalog::buttonBrowsePathPressed ()
FirstChar = BrowsePathValue.substr (0, 1);
if (FirstChar == "~") { // home directory
DecodedPathPrefix = Glib::get_home_dir();
DecodedPathPrefix = PlacesBrowser::userHomeDir ();
} else if (FirstChar == "!") { // user's pictures directory
//DecodedPathPrefix = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES);
DecodedPathPrefix = safe_get_user_picture_dir();
DecodedPathPrefix = PlacesBrowser::userPicturesDir ();
}
if (!DecodedPathPrefix.empty()) {
@ -2003,7 +2057,7 @@ void FileCatalog::buttonBrowsePathPressed ()
// handle shortcuts in the BrowsePath -- END
// 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);
} else
// error, likely path not found: show red arrow

View File

@ -1,4 +1,3 @@
/*
* This file is part of RawTherapee.
*
@ -18,9 +17,10 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "filepanel.h"
#include "rtwindow.h"
#include "../rtengine/safegtk.h"
#include "inspector.h"
#include "placesbrowser.h"
int FilePanelInitUI (void* data)
{
@ -188,19 +188,19 @@ void FilePanel::init ()
dirBrowser->fillDirTree ();
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);
} else {
if (options.startupDir == STARTUPDIR_HOME) {
dirBrowser->open (safe_get_user_picture_dir());
dirBrowser->open (PlacesBrowser::userPicturesDir ());
} else if (options.startupDir == STARTUPDIR_CURRENT) {
dirBrowser->open (argv0);
} 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);
} else {
// 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)
{
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());
} 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));
}
}

View File

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

View File

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

View File

@ -19,7 +19,6 @@
#include "flatfield.h"
#include "options.h"
#include "guiutils.h"
#include "../rtengine/safegtk.h"
#include <sstream>
#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);
} else {
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;
}
#ifdef WIN32
try {
// Dirty workaround, waiting for a clean solution by using exceptions!
if (!safe_is_shortcut_dir(path))
#endif
{
if (lastShortcutPath != "") {
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;
try {
flatFieldFile->add_shortcut_folder(path);
} catch (Glib::Error &err) {}
}
} catch (Glib::Error&) {}
}

View File

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

View File

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

View File

@ -22,7 +22,6 @@
#include "options.h"
#include "../rtengine/rt_math.h"
#include "../rtengine/utils.h"
#include "../rtengine/safegtk.h"
#include "rtimage.h"
#include "multilangmgr.h"
@ -202,7 +201,7 @@ bool confirmOverwrite (Gtk::Window& parent, const std::string& filename)
{
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) + "\": "
+ M("MAIN_MSG_ALREADYEXISTS") + "</b>\n" + M("MAIN_MSG_QOVERWRITE");
Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);

View File

@ -20,7 +20,6 @@
#include "icmpanel.h"
#include "options.h"
#include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/iccstore.h"
#include "../rtengine/dcp.h"
#include "rtimage.h"
@ -609,7 +608,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited)
} else if (icameraICC->get_active ()) {
pp->icm.input = "(cameraICC)";
} 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 ();
} else {
pp->icm.input = ""; // just a directory

View File

@ -22,14 +22,13 @@
#include "cursormanager.h"
#include "guiutils.h"
#include "options.h"
#include "../rtengine/safegtk.h"
#include "../rtengine/previewimage.h"
extern Options options;
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;
// generate thumbnail image

View File

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

View File

@ -54,8 +54,6 @@
#include "conio.h"
#endif
#include "../rtengine/safegtk.h"
extern Options options;
// stores path to data files
@ -69,6 +67,29 @@ Glib::RefPtr<Gtk::CssProvider> cssForced;
Glib::RefPtr<Gtk::CssProvider> cssRT;
//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
#ifdef WIN32
@ -177,7 +198,7 @@ int main(int argc, char **argv)
bool consoleOpened = false;
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 stderrRedirectedtoFile = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == 0x0001);
@ -270,8 +291,8 @@ int main(int argc, char **argv)
#ifndef WIN32
// 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)) {
safe_g_rename(Glib::build_filename(options.rtdir, "cache"), options.cacheBaseDir);
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)) {
g_rename(Glib::build_filename (options.rtdir, "cache").c_str (), options.cacheBaseDir.c_str ());
}
#endif
@ -279,7 +300,7 @@ int main(int argc, char **argv)
simpleEditor = false;
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;
}
@ -421,9 +442,9 @@ int processLineParams( int argc, char **argv )
case 'o': // outputfile or dir
if( iArg + 1 < argc ) {
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;
}
}
@ -435,7 +456,7 @@ int processLineParams( int argc, char **argv )
// RT stop if any of them can't be loaded for any reason.
if( iArg + 1 < argc ) {
iArg++;
Glib::ustring fname = safe_filename_to_utf8 ( argv[iArg] );
Glib::ustring fname = fname_to_utf8 (argv[iArg]);
if (fname.at(0) == '-') {
std::cerr << "Error: filename missing next to the -p switch" << std::endl;
@ -523,39 +544,54 @@ int processLineParams( int argc, char **argv )
break;
case 'c': // MUST be last option
while( iArg + 1 < argc ) {
while (iArg + 1 < argc) {
iArg++;
if( !safe_file_test( safe_filename_to_utf8(argv[iArg]), Glib::FILE_TEST_EXISTS )) {
std::cerr << argv[iArg] << " doesn't exist." << std::endl;
const auto argument = fname_to_utf8 (argv[iArg]);
if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) {
inputFiles.emplace_back (argument);
continue;
}
if( safe_file_test( safe_filename_to_utf8(argv[iArg]), 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] );
if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) {
for(size_t iFile = 0; iFile < names.size(); iFile++ ) {
if( !safe_file_test( names[iFile] , Glib::FILE_TEST_IS_DIR)) {
// 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;
}
if( ! s.substr(ext).compare( paramFileExtension )) {
continue;
}
inputFiles.push_back( names[iFile] );
}
auto dir = Gio::File::create_for_path (argument);
if (!dir || !dir->query_exists()) {
continue;
}
} else {
inputFiles.push_back( safe_filename_to_utf8 (argv[iArg]) );
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;
}
// 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;
}
inputFiles.emplace_back (fileName);
}
} catch (Glib::Exception&) {}
continue;
}
std::cerr << "\"" << argument << "\" is neither a regular file nor a directory." << std::endl;
}
break;
@ -626,7 +662,7 @@ int processLineParams( int argc, char **argv )
}
}
} else {
argv1 = safe_filename_to_utf8 ( argv[iArg] );
argv1 = fname_to_utf8 (argv[iArg]);
if( outputDirectory ) {
options.savePathFolder = outputPath;
@ -727,7 +763,7 @@ int processLineParams( int argc, char **argv )
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;
continue;
}
@ -768,7 +804,7 @@ int processLineParams( int argc, char **argv )
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
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;
} else {
sideCarFound = true;

View File

@ -21,10 +21,8 @@
#include <glib/gstdio.h>
#include <sstream>
#include "multilangmgr.h"
#include "../rtengine/safekeyfile.h"
#include "addsetids.h"
#include "guiutils.h"
#include "../rtengine/safegtk.h"
#include "version.h"
#ifdef _OPENMP
@ -70,13 +68,13 @@ inline bool Options::checkProfilePath(Glib::ustring &path)
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;
}
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;
} else {
return false;
@ -85,7 +83,7 @@ inline bool Options::checkProfilePath(Glib::ustring &path)
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;
} else {
if (!errString.empty()) {
@ -107,7 +105,7 @@ void Options::updatePaths()
if (Glib::path_is_absolute(profilePath)) {
// absolute path
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
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);
if (!checkDirPath (tmpPath, "")) {
safe_g_mkdir_with_parents (tmpPath, 511);
g_mkdir_with_parents (tmpPath.c_str (), 511);
if (!checkDirPath (tmpPath, "")) {
printf("Error: user's profiles' directory \"%s\" creation failed\n", tmpPath.c_str());
@ -170,51 +168,51 @@ void Options::updatePaths()
Glib::ustring preferredPath = getPreferredProfilePath();
// 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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
@ -255,7 +253,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getUserProfilePath();
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);
}
} else if (p == "${G}") {
@ -263,7 +261,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getGlobalProfilePath();
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);
}
} else {
@ -271,7 +269,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getUserProfilePath();
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
profName = Glib::build_filename("${U}", profName);
return Glib::path_get_dirname(fullPath);
@ -280,7 +278,7 @@ Glib::ustring Options::findProfilePath(Glib::ustring &profName)
p = getGlobalProfilePath();
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);
return Glib::path_get_dirname(fullPath);
}
@ -726,9 +724,10 @@ void Options::filterOutParsedExtensions ()
int Options::readFromFile (Glib::ustring fname)
{
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;
}
@ -1774,23 +1773,29 @@ int Options::readFromFile (Glib::ustring fname)
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());
}
setDefaults ();
} catch (...) {
if (options.rtSettings.verbose) {
printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str());
}
setDefaults ();
}
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)
{
if (keyFile.has_key(section, entryName) && !keyFile.get_string(section, entryName).empty()) {
destination = keyFile.get_string(section, entryName);
return true;
}
try {
if (keyFile.has_key (section, entryName) && !keyFile.get_string (section, entryName).empty ()) {
destination = keyFile.get_string (section, entryName);
return true;
}
} catch(Glib::KeyFileError&) {}
return false;
}
@ -1798,9 +1803,13 @@ bool Options::safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustri
int Options::saveToFile (Glib::ustring fname)
{
rtengine::SafeKeyFile keyFile;
keyFile.set_boolean ("General", "TabbedEditor", tabbedUI);
Glib::ustring keyData;
try {
Glib::KeyFile keyFile;
keyFile.set_boolean ("General", "TabbedEditor", tabbedUI);
keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit);
if (startupDir == STARTUPDIR_HOME) {
@ -2099,7 +2108,15 @@ int Options::saveToFile (Glib::ustring fname)
keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir);
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 (options.rtSettings.verbose) {
@ -2108,7 +2125,7 @@ int Options::saveToFile (Glib::ustring fname)
return 1;
} else {
fprintf (f, "%s", keyFile.to_data().c_str());
fprintf (f, "%s", keyData.c_str ());
fclose (f);
return 0;
}
@ -2181,14 +2198,14 @@ bool Options::load ()
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 (r && !safe_g_mkdir_with_parents (rtdir, 511)) {
if (r && !g_mkdir_with_parents (rtdir.c_str (), 511)) {
// Save the option file
options.saveToFile (Glib::build_filename(rtdir, "options"));
}
#ifdef __APPLE__
// 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
}

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 prevdemo_t {PD_Sidecar = 1, PD_Fast = 0};
namespace rtengine
{
class SafeKeyFile;
}
class Options
{
@ -87,7 +82,7 @@ private:
* @param destination destination variable to store to
* @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);
public:

View File

@ -375,6 +375,7 @@ void ParamsEdited::set (bool v)
raw.xtranssensor.exBlackGreen = v;
raw.xtranssensor.exBlackBlue = v;
raw.caCorrection = v;
raw.caAutoStrength = v;
raw.caBlue = v;
raw.caRed = v;
raw.hotPixelFilter = v;
@ -487,6 +488,8 @@ void ParamsEdited::set (bool v)
dirpyrequalizer.enabled = v;
dirpyrequalizer.gamutlab = v;
dirpyrequalizer.cbdlMethod = v;
for(int i = 0; i < 6; i++) {
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.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.caAutoStrength = raw.caAutoStrength && p.raw.caautostrength == other.raw.caautostrength;
raw.caRed = raw.caRed && p.raw.cared == other.raw.cared;
raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue;
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.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++) {
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;
}
if (raw.caAutoStrength) {
toEdit.raw.caautostrength = dontforceSet && options.baBehav[ADDSET_RAWCACORR] ? toEdit.raw.caautostrength + mods.raw.caautostrength : mods.raw.caautostrength;
}
if (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;
}
if (dirpyrequalizer.cbdlMethod) {
toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod;
}
for(int i = 0; i < 6; 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];
@ -2770,7 +2783,7 @@ bool RAWParamsEdited::XTransSensor::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;
}

View File

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

View File

@ -17,11 +17,17 @@
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "placesbrowser.h"
#include "options.h"
#include "toolpanel.h"
#include "../rtengine/safegtk.h"
#ifdef WIN32
#include <windows.h>
#include <shlobj.h>
#include <Shlwapi.h>
#endif
#include "guiutils.h"
#include "rtimage.h"
#include "options.h"
#include "toolpanel.h"
PlacesBrowser::PlacesBrowser ()
{
@ -96,17 +102,14 @@ bool compareMountByRoot (Glib::RefPtr<Gio::Mount> a, Glib::RefPtr<Gio::Mount> b)
void PlacesBrowser::refreshPlacesList ()
{
placesModel->clear ();
// 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()) {
try {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile);
if (info) {
if (auto info = hfile->query_info ()) {
Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon ();
@ -114,19 +117,15 @@ void PlacesBrowser::refreshPlacesList ()
newrow[placesColumns.type] = 4;
newrow[placesColumns.rowSeparator] = false;
}
} catch (Gio::Error&) {
/* This will be thrown if the path doesn't exist */
}
} catch (Gio::Error&) {}
}
// 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()) {
try {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile);
if (info) {
if (auto info = hfile->query_info ()) {
Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon ();
@ -134,9 +133,7 @@ void PlacesBrowser::refreshPlacesList ()
newrow[placesColumns.type] = 4;
newrow[placesColumns.rowSeparator] = false;
}
} catch (Gio::Error&) {
/* This will be thrown if the path doesn't exist */
}
} catch (Gio::Error&) {}
}
if (!placesModel->children().empty()) {
@ -235,16 +232,16 @@ void PlacesBrowser::refreshPlacesList ()
Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (options.favoriteDirs[i]);
if (hfile && hfile->query_exists()) {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile);
if (info) {
Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon ();
newrow[placesColumns.root] = hfile->get_parse_name ();
newrow[placesColumns.type] = 5;
newrow[placesColumns.rowSeparator] = false;
}
try {
if (auto info = hfile->query_info ()) {
Gtk::TreeModel::Row newrow = *(placesModel->append());
newrow[placesColumns.label] = info->get_display_name ();
newrow[placesColumns.icon] = info->get_icon ();
newrow[placesColumns.root] = hfile->get_parse_name ();
newrow[placesColumns.type] = 5;
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);
if (hfile && hfile->query_exists()) {
Glib::RefPtr<Gio::FileInfo> info = safe_query_file_info (hfile);
if (info) {
options.favoriteDirs.push_back (hfile->get_parse_name ());
refreshPlacesList ();
}
try {
if (auto info = hfile->query_info ()) {
options.favoriteDirs.push_back (hfile->get_parse_name ());
refreshPlacesList ();
}
} catch(Gio::Error&) {}
}
}
@ -352,3 +349,52 @@ void PlacesBrowser::delPressed ()
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 addPressed ();
void delPressed ();
public:
static Glib::ustring userHomeDir ();
static Glib::ustring userPicturesDir ();
};
inline void PlacesBrowser::setDirSelector (const PlacesBrowser::DirSelectionSlot& selectDir)

View File

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

View File

@ -25,7 +25,6 @@
#include "../rtengine/dfmanager.h"
#include "../rtengine/ffmanager.h"
#include <sstream>
#include "../rtengine/safegtk.h"
#include "rtimage.h"
#ifdef _OPENMP
#include <omp.h>
@ -1352,7 +1351,7 @@ void Preferences::parseDir (Glib::ustring dirname, std::vector<Glib::ustring>& i
Glib::ustring sname = *i;
// 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()));
}
}
@ -1640,18 +1639,18 @@ void Preferences::fillPreferences ()
#ifdef WIN32
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);
}
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);
}
#elif defined __APPLE__
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);
}
@ -1940,18 +1939,17 @@ void Preferences::bundledProfilesChanged ()
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->set_active (0);
const std::vector<Glib::ustring> profiles = rtengine::ICCStore::getInstance ()->getProfilesFromDir (iccDir->get_filename ());
for (std::vector<Glib::ustring>::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile)
monProfile->append (*profile);
for (const auto& profile : profiles)
monProfile->append (profile);
monProfile->set_active_text (currentSelection);
setActiveTextOrIndex(*monProfile, currentSelection, 0);
}
void Preferences::storeCurrentValue()

View File

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

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