Merge branch 'master' into 'gtk3'
This commit is contained in:
commit
a04c7706db
@ -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
|
||||
|
16
README.md
16
README.md
@ -1,23 +1,21 @@
|
||||

|
||||
|
||||
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.
BIN
rtdata/dcpprofiles/Fujifilm X100T.dcp
Normal file
BIN
rtdata/dcpprofiles/Fujifilm X100T.dcp
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
rtdata/dcpprofiles/Ricoh Pentax K-3.dcp
Normal file
BIN
rtdata/dcpprofiles/Ricoh Pentax K-3.dcp
Normal file
Binary file not shown.
BIN
rtdata/dcpprofiles/Sony ILCE-7M2.dcp
Normal file
BIN
rtdata/dcpprofiles/Sony ILCE-7M2.dcp
Normal file
Binary file not shown.
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
379
rtengine/coord.h
379
rtengine/coord.h
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,11 @@ public:
|
||||
{
|
||||
return height;
|
||||
}
|
||||
int getWidth ()
|
||||
int getWidth () const
|
||||
{
|
||||
return width;
|
||||
}
|
||||
int getHeight ()
|
||||
int getHeight () const
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
@ -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)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -466,7 +466,9 @@ enum ProcEvent {
|
||||
EvmapMethod = 436,
|
||||
EvRetinexmapcurve = 437,
|
||||
EvviewMethod = 438,
|
||||
EvcbdlMethod = 439,
|
||||
NUMOFEVENTS
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include "safegtk.h"
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ();
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
#include "bayerpreprocess.h"
|
||||
#include "guiutils.h"
|
||||
#include "../rtengine/safegtk.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace rtengine;
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
#include "bayerrawexposure.h"
|
||||
#include "guiutils.h"
|
||||
#include "../rtengine/safegtk.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace rtengine;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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 (¶ms);
|
||||
|
||||
@ -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;
|
||||
|
@ -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 ());
|
||||
|
314
rtgui/extprog.cc
314
rtgui/extprog.cc
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "options.h"
|
||||
#include "../rtengine/clutstore.h"
|
||||
#include "../rtengine/safegtk.h"
|
||||
|
||||
using namespace rtengine;
|
||||
using namespace rtengine::procparams;
|
||||
|
@ -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&) {}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
110
rtgui/main.cc
110
rtgui/main.cc
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <gtkmm.h>
|
||||
#include "multilangmgr.h"
|
||||
#include "popupcommon.h"
|
||||
#include "../rtengine/safegtk.h"
|
||||
#include "rtimage.h"
|
||||
#include "guiutils.h"
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user