diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index e32cf101e..8082403aa 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -7,7 +7,7 @@ link_directories (${CMAKE_CURRENT_SOURCE_DIR}/../rtexif ${EXTRA_LIBDIR} ${GTHREA ${GOBJECT_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS}) -set (RTENGINESOURCEFILES colortemp.cc curves.cc flatcurves.cc diagonalcurves.cc dcraw.cc iccstore.cc +set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagonalcurves.cc dcraw.cc iccstore.cc dfmanager.cc rawimage.cc image8.cc image16.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 798313354..01cef1082 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -24,6 +24,7 @@ #endif #include #include +#include #include namespace rtengine { @@ -144,7 +145,7 @@ cmsHPROFILE ICCStore::getProfile (Glib::ustring name) { if (r!=fileProfiles.end()) return r->second; else { - if (!name.compare (0, 5, "file:") && Glib::file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !Glib::file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { + if (!name.compare (0, 5, "file:") && safe_file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !safe_file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { ProfileContent pc (name.substr(5)); if (pc.data) { cmsHPROFILE profile = pc.toProfile (); @@ -178,7 +179,7 @@ std::vector ICCStore::parseDir (Glib::ustring pdir) { Glib::ustring dirname = pdir; Glib::Dir* dir = NULL; try { - if (!Glib::file_test (dirname, Glib::FILE_TEST_IS_DIR)) + if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) return result; dir = new Glib::Dir (dirname); } @@ -190,7 +191,7 @@ std::vector ICCStore::parseDir (Glib::ustring pdir) { Glib::ustring fname = dirname + *i; Glib::ustring sname = *i; // ignore directories - if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) { + if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { int lastdot = sname.find_last_of ('.'); if (lastdot!=Glib::ustring::npos && lastdot<=(int)sname.size()-4 && (!sname.casefold().compare (lastdot, 4, ".icm") || !sname.casefold().compare (lastdot, 4, ".icc"))) { if( options.rtSettings.verbose ) @@ -216,7 +217,7 @@ std::vector ICCStore::parseDir (Glib::ustring pdir) { ProfileContent::ProfileContent (Glib::ustring fileName) { data = NULL; - FILE* f = g_fopen (fileName.c_str(), "rb"); + FILE* f = safe_g_fopen (fileName, "rb"); if (!f) return; fseek (f, 0, SEEK_END); diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 96bbebf5b..645e5e6d9 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -45,7 +45,7 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { #ifdef RAWZOR_SUPPORT // RAWZOR support begin if (dotposexifBase>=0 || ri->ciffBase>=0)) { - FILE* f = g_fopen (fname.c_str (), "rb"); + FILE* f = safe_g_fopen (fname, "rb"); if (f) { fseek (f, 0, SEEK_END); int rzwSize = ftell (f); @@ -66,7 +66,7 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { else if (ri->ciffBase>=0) root = rtexif::ExifManager::parseCIFF (tf, ri->ciffBase, ri->ciffLength); fclose (tf); - ::g_remove (tfname.c_str()); + safe_g_remove (tfname); extractInfo (); } delete [] rawData; @@ -79,7 +79,7 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { else #endif if (ri && (ri->exifBase>=0 || ri->ciffBase>=0)) { - FILE* f = g_fopen (fname.c_str(), "rb"); + FILE* f = safe_g_fopen (fname, "rb"); if (f) { if (ri->exifBase>=0) { root = rtexif::ExifManager::parse (f, ri->exifBase); @@ -96,18 +96,18 @@ ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { } } else if (dotpos<(int)fname.size()-3 && !fname.casefold().compare (dotpos, 4, ".jpg")) { - FILE* f = g_fopen (fname.c_str (), "rb"); + FILE* f = safe_g_fopen (fname, "rb"); if (f) { root = rtexif::ExifManager::parseJPEG (f); extractInfo (); fclose (f); - FILE* ff = g_fopen (fname.c_str (), "rb"); + FILE* ff = safe_g_fopen (fname, "rb"); iptc = iptc_data_new_from_jpeg_file (ff); fclose (ff); } } else if ((dotpos<(int)fname.size()-3 && !fname.casefold().compare (dotpos, 4, ".tif")) || (dotpossetProgressStr ("Ready."); pl->setProgress (1.0); @@ -592,11 +585,7 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality) { cinfo.err = jpeg_std_error (&jerr); jpeg_create_compress (&cinfo); - // create a temporary file name that is opened in parallel by e.g. image viewers whilte RT is still writing - Glib::ustring tmpFname=fname; - tmpFname.append(".tmp"); - - FILE *file = g_fopen (safe_locale_from_utf8(tmpFname).c_str (), "wb"); + FILE *file = safe_g_fopen_WriteBinLock (fname); if (!file) return IMIO_CANNOTREADFILE; @@ -688,9 +677,6 @@ int ImageIO::saveJPEG (Glib::ustring fname, int quality) { fclose (file); - // Rename temporary filename, practically atomic - g_rename(safe_locale_from_utf8(tmpFname).c_str (),safe_locale_from_utf8(fname).c_str ()); - if (pl) { pl->setProgressStr ("Ready."); pl->setProgress (1.0); @@ -711,7 +697,7 @@ int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) { unsigned char* linebuffer = new unsigned char[lineWidth]; // TODO the following needs to be looked into - do we really need two ways to write a Tiff file ? if (exifRoot && uncompressed) { - FILE *file = g_fopen (safe_locale_from_utf8(fname).c_str (), "wb"); + FILE *file = safe_g_fopen_WriteBinLock (fname); if (!file) return IMIO_CANNOTREADFILE; @@ -884,7 +870,8 @@ void png_flush(png_structp png_ptr) { int ImageIO::load (Glib::ustring fname) { int lastdot = fname.find_last_of ('.'); - + if( Glib::ustring::npos == lastdot ) + return IMIO_FILETYPENOTSUPPORTED; if (!fname.casefold().compare (lastdot, 4, ".png")) return loadPNG (fname); else if (!fname.casefold().compare (lastdot, 4, ".jpg")) @@ -897,7 +884,8 @@ int ImageIO::load (Glib::ustring fname) { int ImageIO::save (Glib::ustring fname) { int lastdot = fname.find_last_of ('.'); - + if( Glib::ustring::npos == lastdot ) + return IMIO_FILETYPENOTSUPPORTED; if (!fname.casefold().compare (lastdot, 4, ".png")) return savePNG (fname); else if (!fname.casefold().compare (lastdot, 4, ".jpg")) diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc index 0c791dc7e..041f9a264 100644 --- a/rtengine/myfile.cc +++ b/rtengine/myfile.cc @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef RAWZOR_SUPPORT #include #endif @@ -65,19 +66,7 @@ int munmap(void *start, size_t length) IMFILE* fopen (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 - + int fd = safe_open_ReadOnly(fname); if ( fd < 0 ) return 0; @@ -116,7 +105,7 @@ IMFILE* gfopen (const char* fname) IMFILE* fopen (const char* fname) { - FILE* f = fopen (fname, "rb"); + FILE* f = g_fopen (fname, "rb"); if (!f) return NULL; IMFILE* mf = new IMFILE; @@ -148,8 +137,7 @@ IMFILE* fopen (const char* fname) { } // RAWZOR support end #endif - - return mf; + return mf; } IMFILE* gfopen (const char* fname) { diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index fb4b3c83a..18b4de0d7 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include @@ -58,7 +58,7 @@ void ProcParams::setDefaults () { toneCurve.expcomp = 0; toneCurve.brightness = 0; toneCurve.contrast = 0; - toneCurve.saturation = 0; + toneCurve.saturation = 0; toneCurve.black = 0; toneCurve.hlcompr = 70; toneCurve.hlcomprthresh = 0; @@ -68,13 +68,13 @@ void ProcParams::setDefaults () { labCurve.brightness = 0; labCurve.contrast = 0; - labCurve.saturation = 0; - labCurve.avoidclip = false; + labCurve.saturation = 0; + labCurve.avoidclip = false; labCurve.enable_saturationlimiter = false; - labCurve.saturationlimit = 40; + labCurve.saturationlimit = 50; labCurve.lcurve.clear (); labCurve.lcurve.push_back(DCT_Linear); - labCurve.acurve.clear (); + labCurve.acurve.clear (); labCurve.acurve.push_back(DCT_Linear); labCurve.bcurve.clear (); labCurve.bcurve.push_back(DCT_Linear); @@ -115,17 +115,17 @@ void ProcParams::setDefaults () { colorDenoise.radius = 1.9; colorDenoise.edgetolerance = 2000; - impulseDenoise.enabled = false; - impulseDenoise.thresh = 50; + impulseDenoise.enabled = false; + impulseDenoise.thresh = 50; - defringe.enabled = false; - defringe.radius = 2.0; - defringe.threshold = 25; + defringe.enabled = false; + defringe.radius = 2.0; + defringe.threshold = 25; - dirpyrDenoise.enabled = false; + dirpyrDenoise.enabled = false; dirpyrDenoise.luma = 10; - dirpyrDenoise.chroma = 10; - dirpyrDenoise.gamma = 2.0; + dirpyrDenoise.chroma = 10; + dirpyrDenoise.gamma = 2.0; sh.enabled = false; sh.hq = false; @@ -205,16 +205,16 @@ void ProcParams::setDefaults () { { dirpyrequalizer.mult[i] = 1.0; } - dirpyrequalizer.mult[4] = 0.0; - hsvequalizer.hcurve.clear (); - hsvequalizer.hcurve.push_back (FCT_Linear); - hsvequalizer.scurve.clear (); - hsvequalizer.scurve.push_back (FCT_Linear); - hsvequalizer.vcurve.clear (); - hsvequalizer.vcurve.push_back (FCT_Linear); + dirpyrequalizer.mult[4] = 0.0; + hsvequalizer.hcurve.clear (); + hsvequalizer.hcurve.push_back (FCT_Linear); + hsvequalizer.scurve.clear (); + hsvequalizer.scurve.push_back (FCT_Linear); + hsvequalizer.vcurve.clear (); + hsvequalizer.vcurve.push_back (FCT_Linear); raw.df_autoselect = false; raw.cared = 0; - raw.cablue = 0; + raw.cablue = 0; raw.ca_autocorrect = false; raw.hotdeadpix_filt = false; raw.linenoise = 0; @@ -223,11 +223,11 @@ void ProcParams::setDefaults () { raw.dmethod = RAWParams::methodstring[RAWParams::hphd];; raw.dcb_iterations=2; raw.dcb_enhance=false; - //exposition + // exposure before interpolation raw.expos=1.0; raw.preser=0.0; - //raw.expos_correc=false; - // expos + + exif.clear (); iptc.clear (); @@ -436,7 +436,7 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame ); keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); - keyFile.set_double ("RAW", "CARed", raw.cared ); + keyFile.set_double ("RAW", "CARed", raw.cared ); keyFile.set_double ("RAW", "CABlue", raw.cablue ); keyFile.set_boolean ("RAW", "HotDeadPixels", raw.hotdeadpix_filt ); keyFile.set_integer ("RAW", "LineDenoise", raw.linenoise); @@ -445,7 +445,6 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_string ("RAW", "Method", raw.dmethod ); keyFile.set_integer ("RAW", "DCBIterations", raw.dcb_iterations ); keyFile.set_boolean ("RAW", "DCBEnhance", raw.dcb_enhance ); - //exposure keyFile.set_double ("RAW", "PreExposure", raw.expos ); keyFile.set_double ("RAW", "PrePreserv", raw.preser ); @@ -461,7 +460,7 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_string_list ("IPTC", iptc[i].field, values); } - FILE *f = g_fopen (safe_locale_from_utf8(fname).c_str(), "wt"); + FILE *f = safe_g_fopen (fname, "wt"); if (f==NULL) return 1; @@ -478,7 +477,7 @@ int ProcParams::load (Glib::ustring fname) { try { setDefaults (); - FILE* f = g_fopen (fname.c_str(), "rt"); + FILE* f = safe_g_fopen (fname, "rt"); if (!f) return 1; char* buffer = new char[1024]; @@ -536,7 +535,6 @@ if (keyFile.has_group ("Luminance Curve")) { if (keyFile.has_key ("Luminance Curve", "AvoidColorClipping")) labCurve.avoidclip = keyFile.get_boolean ("Luminance Curve", "AvoidColorClipping"); if (keyFile.has_key ("Luminance Curve", "SaturationLimiter")) labCurve.enable_saturationlimiter= keyFile.get_boolean ("Luminance Curve", "SaturationLimiter"); if (keyFile.has_key ("Luminance Curve", "SaturationLimit")) labCurve.saturationlimit = keyFile.get_double ("Luminance Curve", "SaturationLimit"); - if (ppVersion>200) if (keyFile.has_key ("Luminance Curve", "LCurve")) labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); if (keyFile.has_key ("Luminance Curve", "aCurve")) labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); if (keyFile.has_key ("Luminance Curve", "bCurve")) labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); @@ -750,8 +748,8 @@ if (keyFile.has_group ("RAW")) { if (keyFile.has_key ("RAW", "DarkFrame")) raw.dark_frame = keyFile.get_string ("RAW", "DarkFrame" ); if (keyFile.has_key ("RAW", "DarkFrameAuto")) raw.df_autoselect = keyFile.get_boolean ("RAW", "DarkFrameAuto" ); if (keyFile.has_key ("RAW", "CA")) raw.ca_autocorrect = keyFile.get_boolean ("RAW", "CA" ); - if (keyFile.has_key ("RAW", "CARed")) raw.cared = keyFile.get_double ("RAW", "CARed" ); - if (keyFile.has_key ("RAW", "CABlue")) raw.cablue = keyFile.get_double ("RAW", "CABlue" ); + if (keyFile.has_key ("RAW", "CARed")) raw.cared = keyFile.get_double ("RAW", "CARed" ); + if (keyFile.has_key ("RAW", "CABlue")) raw.cablue = keyFile.get_double ("RAW", "CABlue" ); if (keyFile.has_key ("RAW", "HotDeadPixels")) raw.hotdeadpix_filt = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (keyFile.has_key ("RAW", "LineDenoise")) raw.linenoise = keyFile.get_integer ("RAW", "LineDenoise" ); if (keyFile.has_key ("RAW", "GreenEqThreshold")) raw.greenthresh= keyFile.get_integer ("RAW", "GreenEqThreshold"); @@ -761,8 +759,6 @@ if (keyFile.has_group ("RAW")) { if (keyFile.has_key ("RAW", "DCBEnhance")) raw.dcb_enhance =keyFile.get_boolean("RAW", "DCBEnhance"); if (keyFile.has_key ("RAW", "PreExposure")) raw.expos =keyFile.get_double("RAW", "PreExposure"); if (keyFile.has_key ("RAW", "PrePreserv")) raw.preser =keyFile.get_double("RAW", "PrePreserv"); - - } // load exif change settings @@ -831,136 +827,136 @@ bool operator==(const IPTCPair& a, const IPTCPair& b) { } bool ProcParams::operator== (const ProcParams& other) { - return - toneCurve.curve == other.toneCurve.curve - && toneCurve.brightness == other.toneCurve.brightness - && toneCurve.black == other.toneCurve.black - && toneCurve.contrast == other.toneCurve.contrast + return + toneCurve.curve == other.toneCurve.curve + && toneCurve.brightness == other.toneCurve.brightness + && toneCurve.black == other.toneCurve.black + && toneCurve.contrast == other.toneCurve.contrast && toneCurve.saturation == other.toneCurve.saturation - && toneCurve.shcompr == other.toneCurve.shcompr - && toneCurve.hlcompr == other.toneCurve.hlcompr - && toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh - && toneCurve.autoexp == other.toneCurve.autoexp - && toneCurve.clip == other.toneCurve.clip - && toneCurve.expcomp == other.toneCurve.expcomp - && labCurve.lcurve == other.labCurve.lcurve - && labCurve.acurve == other.labCurve.acurve - && labCurve.bcurve == other.labCurve.bcurve - && labCurve.brightness == other.labCurve.brightness - && labCurve.contrast == other.labCurve.contrast + && toneCurve.shcompr == other.toneCurve.shcompr + && toneCurve.hlcompr == other.toneCurve.hlcompr + && toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh + && toneCurve.autoexp == other.toneCurve.autoexp + && toneCurve.clip == other.toneCurve.clip + && toneCurve.expcomp == other.toneCurve.expcomp + && labCurve.lcurve == other.labCurve.lcurve + && labCurve.acurve == other.labCurve.acurve + && labCurve.bcurve == other.labCurve.bcurve + && labCurve.brightness == other.labCurve.brightness + && labCurve.contrast == other.labCurve.contrast && labCurve.saturation == other.labCurve.saturation && labCurve.avoidclip == other.labCurve.avoidclip && labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter - && labCurve.saturationlimit == other.labCurve.saturationlimit - && sharpening.enabled == other.sharpening.enabled - && sharpening.radius == other.sharpening.radius - && sharpening.amount == other.sharpening.amount - && sharpening.threshold == other.sharpening.threshold - && sharpening.edgesonly == other.sharpening.edgesonly - && sharpening.edges_radius == other.sharpening.edges_radius - && sharpening.edges_tolerance == other.sharpening.edges_tolerance - && sharpening.halocontrol == other.sharpening.halocontrol - && sharpening.halocontrol_amount== other.sharpening.halocontrol_amount - && sharpening.method == other.sharpening.method - && sharpening.deconvamount == other.sharpening.deconvamount - && sharpening.deconvradius == other.sharpening.deconvradius - && sharpening.deconviter == other.sharpening.deconviter - && sharpening.deconvdamping == other.sharpening.deconvdamping - && colorBoost.amount == other.colorBoost.amount - && colorBoost.avoidclip == other.colorBoost.avoidclip - && colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter - && colorBoost.saturationlimit == other.colorBoost.saturationlimit - && wb.method == other.wb.method - && wb.green == other.wb.green - && wb.temperature == other.wb.temperature - && colorShift.a == other.colorShift.a - && colorShift.b == other.colorShift.b - && impulseDenoise.enabled == other.impulseDenoise.enabled - && impulseDenoise.thresh == other.impulseDenoise.thresh - && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled - && dirpyrDenoise.luma == other.dirpyrDenoise.luma - && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma - && dirpyrDenoise.gamma == other.dirpyrDenoise.gamma - && defringe.enabled == other.defringe.enabled - && defringe.radius == other.defringe.radius - && defringe.threshold == other.defringe.threshold - && lumaDenoise.enabled == other.lumaDenoise.enabled - && lumaDenoise.radius == other.lumaDenoise.radius - && lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance - && colorDenoise.enabled == other.colorDenoise.enabled - && colorDenoise.radius == other.colorDenoise.radius - && colorDenoise.edgetolerance == other.colorDenoise.edgetolerance - && colorDenoise.edgesensitive == other.colorDenoise.edgesensitive - && sh.enabled == other.sh.enabled - && sh.hq == other.sh.hq - && sh.highlights == other.sh.highlights - && sh.htonalwidth == other.sh.htonalwidth - && sh.shadows == other.sh.shadows - && sh.stonalwidth == other.sh.stonalwidth - && sh.localcontrast == other.sh.localcontrast - && sh.radius == other.sh.radius - && crop.enabled == other.crop.enabled - && crop.x == other.crop.x - && crop.y == other.crop.y - && crop.w == other.crop.w - && crop.h == other.crop.h - && crop.fixratio == other.crop.fixratio - && crop.ratio == other.crop.ratio - && crop.orientation == other.crop.orientation - && crop.guide == other.crop.guide - && coarse.rotate == other.coarse.rotate - && coarse.hflip == other.coarse.hflip - && coarse.vflip == other.coarse.vflip - && rotate.degree == other.rotate.degree - && commonTrans.autofill == other.commonTrans.autofill - && distortion.uselensfun == other.distortion.uselensfun - && distortion.amount == other.distortion.amount - && perspective.horizontal == other.perspective.horizontal - && perspective.vertical == other.perspective.vertical - && cacorrection.red == other.cacorrection.red - && cacorrection.blue == other.cacorrection.blue - && vignetting.amount == other.vignetting.amount - && vignetting.radius == other.vignetting.radius - && vignetting.strength == other.vignetting.strength - && vignetting.centerX == other.vignetting.centerX - && vignetting.centerY == other.vignetting.centerY - && !memcmp (&chmixer.red, &other.chmixer.red, 3*sizeof(int)) - && !memcmp (&chmixer.green, &other.chmixer.green, 3*sizeof(int)) - && !memcmp (&chmixer.blue, &other.chmixer.blue, 3*sizeof(int)) - && hlrecovery.enabled == other.hlrecovery.enabled - && hlrecovery.method == other.hlrecovery.method - && resize.scale == other.resize.scale - && resize.appliesTo == other.resize.appliesTo - && resize.method == other.resize.method - && resize.dataspec == other.resize.dataspec - && resize.width == other.resize.width - && resize.height == other.resize.height - && raw.dark_frame == other.raw.dark_frame - && raw.df_autoselect == other.raw.df_autoselect - && raw.dcb_enhance == other.raw.dcb_enhance - && raw.dcb_iterations == other.raw.dcb_iterations - && raw.ccSteps == other.raw.ccSteps - && raw.ca_autocorrect == other.raw.ca_autocorrect - && raw.cared == other.raw.cared - && raw.cablue == other.raw.cablue - && raw.hotdeadpix_filt == other.raw.hotdeadpix_filt - && raw.dmethod == other.raw.dmethod - && raw.greenthresh == other.raw.greenthresh - && raw.linenoise == other.raw.linenoise - && icm.input == other.icm.input - && icm.gammaOnInput == other.icm.gammaOnInput - && icm.working == other.icm.working - && icm.output == other.icm.output - && equalizer == other.equalizer - && dirpyrequalizer == other.dirpyrequalizer - && hsvequalizer.hcurve == other.hsvequalizer.hcurve - && hsvequalizer.scurve == other.hsvequalizer.scurve - && hsvequalizer.vcurve == other.hsvequalizer.vcurve - && exif==other.exif - && iptc==other.iptc - && raw.expos==other.raw.expos // exposi - && raw.preser==other.raw.preser; -} + && labCurve.saturationlimit == other.labCurve.saturationlimit + && sharpening.enabled == other.sharpening.enabled + && sharpening.radius == other.sharpening.radius + && sharpening.amount == other.sharpening.amount + && sharpening.threshold == other.sharpening.threshold + && sharpening.edgesonly == other.sharpening.edgesonly + && sharpening.edges_radius == other.sharpening.edges_radius + && sharpening.edges_tolerance == other.sharpening.edges_tolerance + && sharpening.halocontrol == other.sharpening.halocontrol + && sharpening.halocontrol_amount== other.sharpening.halocontrol_amount + && sharpening.method == other.sharpening.method + && sharpening.deconvamount == other.sharpening.deconvamount + && sharpening.deconvradius == other.sharpening.deconvradius + && sharpening.deconviter == other.sharpening.deconviter + && sharpening.deconvdamping == other.sharpening.deconvdamping + && colorBoost.amount == other.colorBoost.amount + && colorBoost.avoidclip == other.colorBoost.avoidclip + && colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter + && colorBoost.saturationlimit == other.colorBoost.saturationlimit + && wb.method == other.wb.method + && wb.green == other.wb.green + && wb.temperature == other.wb.temperature + && colorShift.a == other.colorShift.a + && colorShift.b == other.colorShift.b + && impulseDenoise.enabled == other.impulseDenoise.enabled + && impulseDenoise.thresh == other.impulseDenoise.thresh + && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled + && dirpyrDenoise.luma == other.dirpyrDenoise.luma + && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma + && dirpyrDenoise.gamma == other.dirpyrDenoise.gamma + && defringe.enabled == other.defringe.enabled + && defringe.radius == other.defringe.radius + && defringe.threshold == other.defringe.threshold + && lumaDenoise.enabled == other.lumaDenoise.enabled + && lumaDenoise.radius == other.lumaDenoise.radius + && lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance + && colorDenoise.enabled == other.colorDenoise.enabled + && colorDenoise.radius == other.colorDenoise.radius + && colorDenoise.edgetolerance == other.colorDenoise.edgetolerance + && colorDenoise.edgesensitive == other.colorDenoise.edgesensitive + && sh.enabled == other.sh.enabled + && sh.hq == other.sh.hq + && sh.highlights == other.sh.highlights + && sh.htonalwidth == other.sh.htonalwidth + && sh.shadows == other.sh.shadows + && sh.stonalwidth == other.sh.stonalwidth + && sh.localcontrast == other.sh.localcontrast + && sh.radius == other.sh.radius + && crop.enabled == other.crop.enabled + && crop.x == other.crop.x + && crop.y == other.crop.y + && crop.w == other.crop.w + && crop.h == other.crop.h + && crop.fixratio == other.crop.fixratio + && crop.ratio == other.crop.ratio + && crop.orientation == other.crop.orientation + && crop.guide == other.crop.guide + && coarse.rotate == other.coarse.rotate + && coarse.hflip == other.coarse.hflip + && coarse.vflip == other.coarse.vflip + && rotate.degree == other.rotate.degree + && commonTrans.autofill == other.commonTrans.autofill + && distortion.uselensfun == other.distortion.uselensfun + && distortion.amount == other.distortion.amount + && perspective.horizontal == other.perspective.horizontal + && perspective.vertical == other.perspective.vertical + && cacorrection.red == other.cacorrection.red + && cacorrection.blue == other.cacorrection.blue + && vignetting.amount == other.vignetting.amount + && vignetting.radius == other.vignetting.radius + && vignetting.strength == other.vignetting.strength + && vignetting.centerX == other.vignetting.centerX + && vignetting.centerY == other.vignetting.centerY + && !memcmp (&chmixer.red, &other.chmixer.red, 3*sizeof(int)) + && !memcmp (&chmixer.green, &other.chmixer.green, 3*sizeof(int)) + && !memcmp (&chmixer.blue, &other.chmixer.blue, 3*sizeof(int)) + && hlrecovery.enabled == other.hlrecovery.enabled + && hlrecovery.method == other.hlrecovery.method + && resize.scale == other.resize.scale + && resize.appliesTo == other.resize.appliesTo + && resize.method == other.resize.method + && resize.dataspec == other.resize.dataspec + && resize.width == other.resize.width + && resize.height == other.resize.height + && raw.dark_frame == other.raw.dark_frame + && raw.df_autoselect == other.raw.df_autoselect + && raw.dcb_enhance == other.raw.dcb_enhance + && raw.dcb_iterations == other.raw.dcb_iterations + && raw.ccSteps == other.raw.ccSteps + && raw.ca_autocorrect == other.raw.ca_autocorrect + && raw.cared == other.raw.cared + && raw.cablue == other.raw.cablue + && raw.hotdeadpix_filt == other.raw.hotdeadpix_filt + && raw.dmethod == other.raw.dmethod + && raw.greenthresh == other.raw.greenthresh + && raw.linenoise == other.raw.linenoise + && icm.input == other.icm.input + && icm.gammaOnInput == other.icm.gammaOnInput + && icm.working == other.icm.working + && icm.output == other.icm.output + && equalizer == other.equalizer + && dirpyrequalizer == other.dirpyrequalizer + && hsvequalizer.hcurve == other.hsvequalizer.hcurve + && hsvequalizer.scurve == other.hsvequalizer.scurve + && hsvequalizer.vcurve == other.hsvequalizer.vcurve + && exif==other.exif + && iptc==other.iptc + && raw.expos==other.raw.expos + && raw.preser==other.raw.preser; + } bool ProcParams::operator!= (const ProcParams& other) { diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 3c8561f60..8bcf548a0 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -13,7 +13,7 @@ #else #include #endif - +#include namespace rtengine{ @@ -133,9 +133,8 @@ int RawImage::loadRaw (bool loadData, bool closeFile) verbose = settings->verbose; oprof = NULL; - ifp = gfopen (filename.c_str()); - if (!ifp) - return 3; + ifp = gfopen (ifname); // Maps to either file map or direct fopen + if (!ifp) return 3; thumb_length = 0; thumb_offset = 0; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1e12b6d73..c07d30211 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "jpeg.h" @@ -91,6 +92,7 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, } // bilinear interpolation + if (tpp->thumbImg) delete tpp->thumbImg; tpp->thumbImg = img->resize (w, h, TI_Bilinear); // histogram computation @@ -203,6 +205,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL tpp->scale = (double)img->width / w; } + if (tpp->thumbImg) delete tpp->thumbImg; tpp->thumbImg = img->resize (w, h, TI_Nearest); delete img; @@ -377,6 +380,7 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati else h = tmph * w / tmpw; + if (tpp->thumbImg) delete tpp->thumbImg; tpp->thumbImg = tmpImg->resize(w, h, TI_Bilinear); delete tmpImg; @@ -559,11 +563,13 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int return img8; } +// Full thumbnail processing, second stage if complete profile exists IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, double& myscale) { // compute WB multipliers ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); if (params.wb.method=="Camera") { + //recall colorMatrix is rgb_cam double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue; double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue; @@ -573,6 +579,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei currWB = ColorTemp (autowbTemp, autowbGreen); double r, g, b; currWB.getMultipliers (r, g, b); + //iColorMatrix is cam_rgb double rm = iColorMatrix[0][0]*r + iColorMatrix[0][1]*g + iColorMatrix[0][2]*b; double gm = iColorMatrix[1][0]*r + iColorMatrix[1][1]*g + iColorMatrix[1][2]*b; double bm = iColorMatrix[2][0]*r + iColorMatrix[2][1]*g + iColorMatrix[2][2]*b; @@ -760,6 +767,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei } int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight) { + if (thumbImg==NULL) return 0; // Can happen if thumb is just building and GUI comes in with resize wishes int rwidth; if (params.coarse.rotate==90 || params.coarse.rotate==270) @@ -975,7 +983,7 @@ bool Thumbnail::writeImage (const Glib::ustring& fname, int format) { } if (format==1) { - FILE* f = g_fopen (fname.c_str(), "wb"); + FILE* f = safe_g_fopen (fname, "wb"); if (!f) { delete [] tmpdata; return false; @@ -986,7 +994,7 @@ bool Thumbnail::writeImage (const Glib::ustring& fname, int format) { fclose (f); } else if (format==3) { - FILE* f = g_fopen (fname.c_str(), "wb"); + FILE* f = safe_g_fopen (fname, "wb"); if (!f) { delete [] tmpdata; return false; @@ -1031,7 +1039,7 @@ bool Thumbnail::writeImage (const Glib::ustring& fname, int format) { return true; } else if (format==2) { - FILE* f = g_fopen (fname.c_str(), "wb"); + FILE* f = safe_g_fopen (fname, "wb"); if (!f) return false; fwrite (&thumbImg->width, 1, sizeof (int), f); @@ -1055,17 +1063,17 @@ bool Thumbnail::readImage (const Glib::ustring& fname) { thumbImg = NULL; int imgType = 0; - if (Glib::file_test (fname+".cust16", Glib::FILE_TEST_EXISTS)) + if (safe_file_test (fname+".cust16", Glib::FILE_TEST_EXISTS)) imgType = 2; - if (Glib::file_test (fname+".cust", Glib::FILE_TEST_EXISTS)) + if (safe_file_test (fname+".cust", Glib::FILE_TEST_EXISTS)) imgType = 1; - else if (Glib::file_test (fname+".jpg", Glib::FILE_TEST_EXISTS)) + else if (safe_file_test (fname+".jpg", Glib::FILE_TEST_EXISTS)) imgType = 3; if (!imgType) return false; else if (imgType==1) { - FILE* f = g_fopen ((fname+".cust").c_str(), "rb"); + FILE* f = safe_g_fopen (fname+".cust", "rb"); if (!f) return false; int width, height; @@ -1098,7 +1106,7 @@ bool Thumbnail::readImage (const Glib::ustring& fname) { return true; } else if (imgType==2) { - FILE* f = g_fopen ((fname+".cust16").c_str(), "rb"); + FILE* f = safe_g_fopen (fname+".cust16", "rb"); if (!f) return false; int width, height; @@ -1115,7 +1123,7 @@ bool Thumbnail::readImage (const Glib::ustring& fname) { return true; } else if (imgType==3) { - FILE* f = g_fopen ((fname+".jpg").c_str(), "rb"); + FILE* f = safe_g_fopen (fname+".jpg", "rb"); if (!f) return false; struct jpeg_decompress_struct cinfo; @@ -1213,7 +1221,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname) { SafeKeyFile keyFile; try { - if( Glib::file_test(fname,Glib::FILE_TEST_EXISTS) ) + if( safe_file_test(fname,Glib::FILE_TEST_EXISTS) ) keyFile.load_from_file (fname); } catch (...) {} @@ -1233,7 +1241,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname) { Glib::ArrayHandle cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE); keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm); - FILE *f = g_fopen (fname.c_str(), "wt"); + FILE *f = safe_g_fopen (fname, "wt"); if (!f) return false; else { @@ -1245,7 +1253,7 @@ bool Thumbnail::writeData (const Glib::ustring& fname) { bool Thumbnail::readEmbProfile (const Glib::ustring& fname) { - FILE* f = fopen (fname.c_str(), "rb"); + FILE* f = safe_g_fopen (fname, "rb"); if (!f) { embProfileData = NULL; embProfile = NULL; @@ -1267,7 +1275,7 @@ bool Thumbnail::readEmbProfile (const Glib::ustring& fname) { bool Thumbnail::writeEmbProfile (const Glib::ustring& fname) { if (embProfileData) { - FILE* f = fopen (fname.c_str(), "wb"); + FILE* f = safe_g_fopen(fname, "wb"); if (f) { fwrite (embProfileData, 1, embProfileLength, f); fclose (f); @@ -1279,7 +1287,7 @@ bool Thumbnail::writeEmbProfile (const Glib::ustring& fname) { bool Thumbnail::readAEHistogram (const Glib::ustring& fname) { - FILE* f = fopen (fname.c_str(), "rb"); + FILE* f = safe_g_fopen (fname, "rb"); if (!f) aeHistogram = NULL; else { @@ -1294,7 +1302,7 @@ bool Thumbnail::readAEHistogram (const Glib::ustring& fname) { bool Thumbnail::writeAEHistogram (const Glib::ustring& fname) { if (aeHistogram) { - FILE* f = fopen (fname.c_str(), "wb"); + FILE* f = safe_g_fopen (fname, "wb"); if (f) { fwrite (aeHistogram, 1, (65536>>aeHistCompression)*sizeof(int), f); fclose (f); diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc new file mode 100644 index 000000000..6ba18662e --- /dev/null +++ b/rtengine/safegtk.cc @@ -0,0 +1,289 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2010 Sasha Vasko + * Copyright (c) 2010 Oliver Duis + * + * 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 . + */ + +#include +#include +#include +#include +#ifdef WIN32 +#include +#else +#include +#endif + + +Glib::RefPtr safe_create_from_file(const std::string& filename) +{ + Glib::RefPtr res; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + res = Gdk::Pixbuf::create_from_file (filename); + } + catch (Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); + } +#else + std::auto_ptr error; + res = Gdk::Pixbuf::create_from_file (filename, error); + if (error.get()) + printf ("%s\n", error->what().c_str()); +#endif + + return res; +} + +Cairo::RefPtr safe_create_from_png(const std::string& filename) +{ + Cairo::RefPtr res; + + if (!safe_file_test (filename, Glib::FILE_TEST_EXISTS)) { + printf ("ERROR: File \"%s\" not found.\n", filename.c_str()); + } else { + try { + res = Cairo::ImageSurface::create_from_png (filename); + } catch (...) {} + } + + return res; +} + +Glib::RefPtr safe_query_file_info (Glib::RefPtr &file) +{ + Glib::RefPtr info; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { info = file->query_info(); }catch (...) { } +#else + std::auto_ptr error; + info = file->query_info("*", Gio::FILE_QUERY_INFO_NONE, error); +#endif + return info; +} + +#ifdef GLIBMM_EXCEPTIONS_ENABLED +# define SAFE_ENUMERATOR_CODE_START \ + do{try { if ((dirList = dir->enumerate_children ())) \ + for (Glib::RefPtr info = dirList->next_file(); info; info = dirList->next_file()) { + +# define SAFE_ENUMERATOR_CODE_END \ + }} catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }}while(0) +#else +# define SAFE_ENUMERATOR_CODE_START \ + do{std::auto_ptr error; Glib::RefPtr cancellable; \ + if ((dirList = dir->enumerate_children (cancellable, "*", Gio::FILE_QUERY_INFO_NONE, error))) \ + for (Glib::RefPtr info = dirList->next_file(cancellable, error); !error.get() && info; info = dirList->next_file(cancellable, error)) { + +# define SAFE_ENUMERATOR_CODE_END } if (error.get()) printf ("%s\n", error->what().c_str());}while (0) +#endif + +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist) +{ + Glib::RefPtr dirList; + if (dir) { + SAFE_ENUMERATOR_CODE_START + flist.push_back (FileMTimeInfo (removeExtension(info->get_name()), info->modification_time())); + SAFE_ENUMERATOR_CODE_END; + } +} + +void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory) +{ + Glib::RefPtr dirList; + if (dir) { + SAFE_ENUMERATOR_CODE_START + names.push_back (Glib::build_filename (directory, info->get_name())); + SAFE_ENUMERATOR_CODE_END; + } +} + + +void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden) +{ + Glib::RefPtr 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 + if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || add_hidden)) + subDirs.push_back (info->get_name()); + SAFE_ENUMERATOR_CODE_END; + } +} + +Glib::ustring safe_locale_to_utf8 (const std::string& src) +{ + Glib::ustring utf8_str; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + utf8_str = Glib::locale_to_utf8(src); + } + catch (const Glib::ConvertError& e) { + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?"); + } +#else + { + std::auto_ptr error; + utf8_str = locale_to_utf8(src, error); + if (error.get()) + utf8_str = Glib::convert_with_fallback(src, "UTF8", "LATIN1","?", error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + return utf8_str; +} + +std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str) +{ + std::string str; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + str = Glib::locale_from_utf8(utf8_str); + } + catch (const Glib::ConvertError& e) { + //str = Glib::convert_with_fallback(utf8_str, "LATIN1", "UTF8", "?"); + } +#else + { + std::auto_ptr error; + str = Glib::locale_from_utf8(utf8_str, error); + /*if (error.get()) + {str = Glib::convert_with_fallback(utf8_str, "LATIN1", "UTF8", "?", error);}*/ + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + return str; +} + +bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8) +{ + std::string cmd; + bool success = false; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + 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()); + } +#else + std::auto_ptr error; + cmd = Glib::filename_from_utf8(cmd_utf8, error); + if (!error.get()) { + printf ("command line: %s\n", cmd.c_str()); + Glib::spawn_command_line_async (cmd, error); + } + if (error.get()) + printf ("%s\n", error->what().c_str()); + else + success = true; +#endif + return success; +} + +bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8) +{ + std::string cmd; + std::string stdOut; + std::string stdErr; + + bool success = false; + + 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); +} \ No newline at end of file diff --git a/rtgui/safegtk.h b/rtengine/safegtk.h similarity index 69% rename from rtgui/safegtk.h rename to rtengine/safegtk.h index b9b597aaa..ae8c597f4 100644 --- a/rtgui/safegtk.h +++ b/rtengine/safegtk.h @@ -1,34 +1,41 @@ -#ifndef SAFE_GTK_H_INCLUDED -#define SAFE_GTK_H_INCLUDED - -#include -#include -#include - -Glib::RefPtr safe_create_from_file(const std::string& filename); -Cairo::RefPtr safe_create_from_png(const std::string& filename); - -class FileMTimeInfo { - - public: - Glib::ustring fname; - Glib::TimeVal mtime; - - FileMTimeInfo (Glib::ustring name, Glib::TimeVal mtime) : fname(name), mtime(mtime) {} - bool operator<(const FileMTimeInfo& other) const { return mtime safe_query_file_info (Glib::RefPtr &file); -void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist); -void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = ""); -void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &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_locale_to_utf8 (const std::string& src); // from rtengine -std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str); - - - -#endif +#ifndef SAFE_GTK_H_INCLUDED +#define SAFE_GTK_H_INCLUDED + +#include +#include +#include + +Glib::RefPtr safe_create_from_file(const std::string& filename); +Cairo::RefPtr safe_create_from_png(const std::string& filename); + +class FileMTimeInfo { + + public: + Glib::ustring fname; + Glib::TimeVal mtime; + + FileMTimeInfo (Glib::ustring name, Glib::TimeVal mtime) : fname(name), mtime(mtime) {} + bool operator<(const FileMTimeInfo& other) const { return mtime safe_query_file_info (Glib::RefPtr &file); +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist); +void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = ""); +void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &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_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); +#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 7d703eacc..defcc90eb 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -19,7 +19,7 @@ set (BASESOURCEFILES histogrampanel.cc history.cc imagearea.cc imageareapanel.cc iptcpanel.cc labcurve.cc lumadenoise.cc main.cc multilangmgr.cc mycurve.cc myflatcurve.cc mydiagonalcurve.cc options.cc - preferences.cc profilepanel.cc safegtk.cc saveasdlg.cc + preferences.cc profilepanel.cc saveasdlg.cc saveformatpanel.cc splash.cc thumbnail.cc tonecurve.cc toolbar.cc guiutils.cc zoompanel.cc toolpanelcoord.cc diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index b724981bb..f70f9e0f7 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -91,7 +91,7 @@ bool BatchQueue::saveBatchQueue( ) { Glib::ustring savedQueueFile; savedQueueFile = options.rtdir+"/batch/queue"; - FILE *f = g_fopen (safe_locale_from_utf8(savedQueueFile).c_str(), "wt"); + FILE *f = safe_g_fopen (savedQueueFile, "wt"); if (f==NULL) return false; @@ -108,7 +108,7 @@ bool BatchQueue::loadBatchQueue( ) { Glib::ustring savedQueueFile; savedQueueFile = options.rtdir+"/batch/queue"; - FILE *f = g_fopen (safe_locale_from_utf8(savedQueueFile).c_str(), "rt"); + FILE *f = safe_g_fopen (savedQueueFile, "rt"); if (f==NULL) return false; @@ -173,7 +173,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/"; - g_mkdir_with_parents (savedParamPath.c_str(), 0755); + safe_g_mkdir_with_parents (savedParamPath, 0755); savedParamPath += Glib::path_get_basename (filename); savedParamPath += stringTimestamp; savedParamPath += paramFileExtension; @@ -182,7 +182,7 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename int deleteitem (void* data) { - ::remove( safe_locale_from_utf8( ((BatchQueueEntry*)data)->savedParamsFile).c_str () ); + safe_g_remove( ((BatchQueueEntry*)data)->savedParamsFile ); gdk_threads_enter (); delete (BatchQueueEntry*)data; gdk_threads_leave (); @@ -358,7 +358,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) { next->removeButtonSet (); } if( saveBatchQueue( ) ){ - ::remove( safe_locale_from_utf8(processedParams).c_str () ); + safe_g_remove( processedParams ); // Delete all files in directory \batch when finished, just to be sure to remove zombies if( fd.size()==0 ){ std::vector names; @@ -366,7 +366,7 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) { Glib::RefPtr dir = Gio::File::create_for_path (batchdir); safe_build_file_list (dir, names, batchdir); for(std::vector::iterator iter=names.begin(); iter != names.end();iter++ ) - ::remove( safe_locale_from_utf8(*iter).c_str () ); + safe_g_remove( *iter ); } } redraw (); @@ -461,7 +461,7 @@ Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, c Glib::ustring dstfname = Glib::path_get_basename (fileName); // create directory, if does not exist - if (g_mkdir_with_parents (dstdir.c_str(), 0755) ) + if (safe_g_mkdir_with_parents (dstdir, 0755) ) return ""; // In overwrite mode we TRY to delete the old file first. @@ -475,11 +475,10 @@ Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, c else fname = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, format); - int fileExists=Glib::file_test (fname, Glib::FILE_TEST_EXISTS); + int fileExists=safe_file_test (fname, Glib::FILE_TEST_EXISTS); if (inOverwriteMode && fileExists) { - // do NOT use g_remove as it has compiler problems on Unix and OSX (GTK namespace problem) - if (::remove(safe_locale_from_utf8(fname).c_str ()) == -1) + if (safe_g_remove(fname) == -1) inOverwriteMode = false; // failed to delete- revert to old naming scheme else fileExists = false; // deleted now diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index b72b7f3ce..71ba56393 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -21,6 +21,7 @@ #include #include #include +#include BatchQueuePanel::BatchQueuePanel () { @@ -77,7 +78,7 @@ BatchQueuePanel::BatchQueuePanel () { saveFormatPanel->init (options.saveFormat); outdirTemplate->set_text (options.savePathTemplate); - if (Glib::file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) outdirFolder->set_current_folder (options.savePathFolder); useTemplate->set_active (options.saveUsePathTemplate); useFolder->set_active (!options.saveUsePathTemplate); @@ -279,7 +280,7 @@ void BatchQueuePanel::saveOptions () { options.procQueueEnabled = autoStart->get_active (); } -// We only want to save the following when it changes, \ +// We only want to save the following when it changes, // since these settings are shared with editorpanel : void BatchQueuePanel::pathFolderChanged () { diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index de14bb7fe..12b658a25 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -20,6 +20,7 @@ #include #include #include +#include CacheImageData::CacheImageData () : md5(""), supported(false), format(FT_Invalid), rank(0), inTrash(false), recentlySaved(false), @@ -96,7 +97,7 @@ int CacheImageData::save (const Glib::ustring& fname) { rtengine::SafeKeyFile keyFile; - if (::g_file_test(fname.c_str(),G_FILE_TEST_EXISTS)) keyFile.load_from_file (fname); + if (safe_file_test(fname,Glib::FILE_TEST_EXISTS)) keyFile.load_from_file (fname); keyFile.set_string ("General", "MD5", md5); keyFile.set_string ("General", "Version", options.version); @@ -132,7 +133,7 @@ int CacheImageData::save (const Glib::ustring& fname) { keyFile.set_integer ("ExtraRawInfo", "ThumbImageOffset", thumbOffset); } - FILE *f = g_fopen (fname.c_str(), "wt"); + FILE *f = safe_g_fopen (fname, "wt"); if (!f) return 1; else { diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc index 30c9d1102..b0e07d89a 100644 --- a/rtgui/cachemanager.cc +++ b/rtgui/cachemanager.cc @@ -47,18 +47,18 @@ void CacheManager::init () { openEntries.clear (); baseDir = options.cacheBaseDir; - if (!Glib::file_test (baseDir, Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (baseDir.c_str(), 511); - if (!Glib::file_test (Glib::build_filename (baseDir, "profiles"), Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "profiles")).c_str(), 511); - if (!Glib::file_test (Glib::build_filename (baseDir, "images"), Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "images")).c_str(), 511); - if (!Glib::file_test (Glib::build_filename (baseDir, "aehistograms"), Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "aehistograms")).c_str(), 511); - if (!Glib::file_test (Glib::build_filename (baseDir, "embprofiles"), Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "embprofiles")).c_str(), 511); - if (!Glib::file_test (Glib::build_filename (baseDir, "data"), Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "data")).c_str(), 511); + if (!safe_file_test (baseDir, Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (baseDir, 511); + if (!safe_file_test (Glib::build_filename (baseDir, "profiles"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "profiles")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "images"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "images")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "aehistograms"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "aehistograms")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "embprofiles"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "embprofiles")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "data"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "data")), 511); } Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) { @@ -87,7 +87,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) { Glib::ustring cfname = getCacheFileName ("data", fname, md5) + ".txt"; // let's see if we have it in the cache - if (Glib::file_test (cfname, Glib::FILE_TEST_EXISTS)) { + if (safe_file_test (cfname, Glib::FILE_TEST_EXISTS)) { CacheImageData* cfs = new CacheImageData (); int e = cfs->load (cfname); if (!e && cfs->supported==true) @@ -150,23 +150,25 @@ void CacheManager::deleteEntry (const Glib::ustring& fname) { // if in the editor, the thumbnail still exists. If not, delete it: r = openEntries.find (fname); if (r==openEntries.end() && md5!="") { - ::g_remove ((getCacheFileName ("data", fname, md5) + ".txt").c_str()); - ::g_remove ((getCacheFileName ("profiles", fname, md5) + paramFileExtension).c_str()); - ::g_remove ((getCacheFileName ("images", fname, md5) + ".cust").c_str()); - ::g_remove ((getCacheFileName ("images", fname, md5) + ".jpg").c_str()); - ::g_remove ((getCacheFileName ("aehistograms", fname, md5)).c_str()); - ::g_remove ((getCacheFileName ("embprofiles", fname, md5) + ".icc").c_str()); + safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); + safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); + safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); + safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); } } else { std::string md5 = getMD5 (fname); if (md5!="") { - ::g_remove ((getCacheFileName ("data", fname, md5) + ".txt").c_str()); - ::g_remove ((getCacheFileName ("profiles", fname, md5) + paramFileExtension).c_str()); - ::g_remove ((getCacheFileName ("images", fname, md5) + ".cust").c_str()); - ::g_remove ((getCacheFileName ("images", fname, md5) + ".jpg").c_str()); - ::g_remove ((getCacheFileName ("aehistograms", fname, md5)).c_str()); - ::g_remove ((getCacheFileName ("embprofiles", fname, md5) + ".icc").c_str()); + safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); + safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); + safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); + safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); } } } @@ -178,12 +180,13 @@ void CacheManager::renameEntry (const std::string& oldfilename, const std::strin std::string newmd5 = getMD5 (newfilename); - ::g_rename ((getCacheFileName ("profiles", oldfilename, oldmd5) + paramFileExtension).c_str(), (getCacheFileName ("profiles", newfilename, newmd5) + paramFileExtension).c_str()); - ::g_rename ((getCacheFileName ("images", oldfilename, oldmd5) + ".cust").c_str(), (getCacheFileName ("images", newfilename, newmd5) + ".cust").c_str()); - ::g_rename ((getCacheFileName ("images", oldfilename, oldmd5) + ".jpg").c_str(), (getCacheFileName ("images", newfilename, newmd5) + ".jpg").c_str()); - ::g_rename ((getCacheFileName ("aehistograms", oldfilename, oldmd5)).c_str(), (getCacheFileName ("aehistograms", newfilename, newmd5)).c_str()); - ::g_rename ((getCacheFileName ("embprofiles", oldfilename, oldmd5) + ".icc").c_str(), (getCacheFileName ("embprofiles", newfilename, newmd5) + ".icc").c_str()); - ::g_rename ((getCacheFileName ("data", oldfilename, oldmd5) + ".txt").c_str(), (getCacheFileName ("data", newfilename, newmd5) + ".txt").c_str()); + safe_g_rename (getCacheFileName ("profiles", oldfilename, oldmd5) + paramFileExtension, (getCacheFileName ("profiles", newfilename, newmd5) + paramFileExtension).c_str()); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".cust16", getCacheFileName ("images", newfilename, newmd5) + ".cust16"); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".cust", getCacheFileName ("images", newfilename, newmd5) + ".cust"); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".jpg", getCacheFileName ("images", newfilename, newmd5) + ".jpg"); + safe_g_rename (getCacheFileName ("aehistograms", oldfilename, oldmd5), getCacheFileName ("aehistograms", newfilename, newmd5)); + safe_g_rename (getCacheFileName ("embprofiles", oldfilename, oldmd5) + ".icc", getCacheFileName ("embprofiles", newfilename, newmd5) + ".icc"); + safe_g_rename (getCacheFileName ("data", oldfilename, oldmd5) + ".txt", getCacheFileName ("data", newfilename, newmd5) + ".txt"); // check if it is opened string_thumb_map::iterator r = openEntries.find (oldfilename); @@ -254,7 +257,7 @@ void CacheManager::deleteDir (const Glib::ustring& dirName) { try { Glib::Dir* dir = new Glib::Dir (Glib::build_filename (baseDir, dirName)); for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) - ::g_remove (Glib::build_filename (Glib::build_filename (baseDir, dirName), *i).c_str()); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, dirName), *i)); delete dir; } catch (const Glib::FileError& fe) { @@ -290,12 +293,13 @@ void CacheManager::applyCacheSizeLimitation () { if (flist.size() > options.maxCacheEntries) { std::sort (flist.begin(), flist.end()); while (flist.size() > options.maxCacheEntries) { - ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "data"), flist.front().fname) + ".txt").c_str()); - ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust").c_str()); - ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".jpg").c_str()); - ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "aehistograms"), flist.front().fname)).c_str()); - ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "embprofiles"), flist.front().fname) + ".icc").c_str()); - // ::g_remove ((Glib::build_filename (Glib::build_filename (baseDir, "profiles"), flist.front().fname) + paramFileExtension).c_str()); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "data"), flist.front().fname) + ".txt"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust16"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".jpg"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "aehistograms"), flist.front().fname)); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "embprofiles"), flist.front().fname) + ".icc"); + // safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "profiles"), flist.front().fname) + paramFileExtension); flist.erase (flist.begin()); } } diff --git a/rtgui/crophandler.h b/rtgui/crophandler.h index 0b6e8d5f2..77d09c361 100644 --- a/rtgui/crophandler.h +++ b/rtgui/crophandler.h @@ -57,10 +57,11 @@ class CropHandler : public rtengine::DetailedCropListener, public rtengine::Size CropHandlerListener* listener; CropHandlerIdleHelper* chi; - void update (); void compDim (); public: + void update (); + rtengine::procparams::CropParams cropParams; Glib::RefPtr cropPixbuf; Glib::Mutex cimg; diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 3661d5a87..59624d251 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -24,6 +24,7 @@ #include #include #include +#include extern Glib::ustring argv0; @@ -326,7 +327,7 @@ Glib::ustring CurveEditorSubGroup::outputFile () { if (getExtension (fname)!="rtc") fname = fname + ".rtc"; - if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { + if (safe_file_test (fname, Glib::FILE_TEST_EXISTS)) { Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + ""; Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); int response = msgd.run (); diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index ff6b0af18..24b349ac6 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include using namespace rtengine; @@ -52,7 +53,7 @@ void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi if(pedited ){ dfAuto->set_inconsistent(!pedited->raw.dfAuto ); } - if (Glib::file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) + if (safe_file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) darkFrameFile->set_filename (pp->raw.dark_frame); else if( !options.rtSettings.darkFramesPath.empty() ) darkFrameFile->set_current_folder( options.rtSettings.darkFramesPath ); diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 5e0bfe14e..804ddf21b 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -235,8 +235,8 @@ void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) { while (change) { change = false; for (Gtk::TreeModel::iterator it=iter->children().begin(); it!=iter->children().end(); it++) - 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)) { + 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)) { dirTreeModel->erase (it); change = true; break; @@ -272,7 +272,7 @@ void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustri void DirBrowser::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) { Glib::ustring dname = dirTreeModel->get_iter (path)->get_value (dtColumns.dirname); - if (Glib::file_test (dname, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (dname, Glib::FILE_TEST_IS_DIR)) for (int i=0; idirSelected (dname); } @@ -352,7 +352,7 @@ void DirBrowser::open (const Glib::ustring& dirname, const Glib::ustring& fileNa void DirBrowser::file_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName) { - if (!file || !Glib::file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type==Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) + if (!file || !safe_file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type==Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) return; gdk_threads_enter(); diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index cb5734718..1fb7e5a16 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -209,7 +209,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) : beforePreviewHandler(NULL), be show_all (); // save as dialog - if (Glib::file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) saveAsDialog = new SaveAsDialog (options.lastSaveAsPath); else saveAsDialog = new SaveAsDialog (Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES)); @@ -348,14 +348,17 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) { const CacheImageData* cfs=openThm->getCacheImageData(); if (!options.customProfileBuilder.empty() && !openThm->hasProcParams() && cfs && cfs->exifValid) { + // For the filename etc. do NOT use streams, since they are not UTF8 safe + Glib::ustring cmdLine=Glib::ustring("\"") + options.customProfileBuilder + Glib::ustring("\" \"") + fname + Glib::ustring("\" \"") + + options.rtdir + Glib::ustring("/") + options.profilePath + Glib::ustring("/") + defProf + Glib::ustring(".pp3") + Glib::ustring("\" "); + + // ustring doesn't know int etc formatting, so take these via (unsafe) stream std::ostringstream strm; - strm << Glib::ustring("\"") << options.customProfileBuilder << Glib::ustring("\" \"") << openThm->getFileName() << Glib::ustring("\" \""); - strm << options.rtdir << Glib::ustring("/") << options.profilePath << Glib::ustring("/") << defProf << Glib::ustring(".pp3"); - strm << Glib::ustring("\" ") << cfs->fnumber << Glib::ustring(" ") << cfs->shutter << Glib::ustring(" "); + strm << cfs->fnumber << Glib::ustring(" ") << cfs->shutter << Glib::ustring(" "); strm << cfs->focalLen << Glib::ustring(" ") << cfs->iso << Glib::ustring(" \""); strm << cfs->lens << Glib::ustring("\" \"") << cfs->camera << Glib::ustring("\""); - bool success = safe_spawn_command_line_sync (strm.str()); + bool success = safe_spawn_command_line_sync (cmdLine + strm.str()); // Now they SHOULD be there, so try to load them if (success) openThm->loadProcParams(); @@ -386,6 +389,10 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) { { iarea->imageArea->mainCropWindow->cropHandler.newImage(ipc); iarea->imageArea->mainCropWindow->initialImageArrived(); + + // In single tab mode, the image is not always updated between switches + // normal redraw don't work, so this is the hard way + if (!options.tabbedUI) iarea->imageArea->mainCropWindow->cropHandler.update(); } else { Gtk::Allocation alloc; iarea->imageArea->on_resized(alloc); @@ -393,15 +400,15 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) { } void EditorPanel::close () { - if (ipc) { saveProfile (); // close image processor and the current thumbnail tpc->closeImage (); // this call stops image processing tpc->writeOptions (); - rtengine::ImageSource* is=isrc->getImageSource(); - is->setProgressListener( NULL ); + rtengine::ImageSource* is=isrc->getImageSource(); + is->setProgressListener( NULL ); + if (ipc) ipc->setPreviewImageListener (NULL); @@ -419,17 +426,20 @@ void EditorPanel::close () { rtengine::StagedImageProcessor::destroy (ipc); ipc = NULL; navigator->previewWindow->setPreviewHandler (NULL); - // navigator->previewWindow->setImageArea (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)) { openThm->removeThumbnailListener (this); openThm->decreaseRef (); - + } } } void EditorPanel::saveProfile () { if (!ipc || !openThm) return; + // If the file was deleted, do not generate ghost entries + if (safe_file_test(fname, Glib::FILE_TEST_EXISTS)) { ProcParams params; ipc->getParams (¶ms); @@ -438,6 +448,7 @@ void EditorPanel::saveProfile () { if (options.saveParamsCache) openThm->setProcParams (params, EDITOR); } +} Glib::ustring EditorPanel::getShortName () { @@ -761,7 +772,7 @@ int EditorPanel::saveImage (rtengine::IImage16* img, Glib::ustring& fname, SaveF Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format); if (findNewNameIfNeeded) { int tries = 1; - while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) { + while (safe_file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) { fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format); tries++; } @@ -843,7 +854,7 @@ void EditorPanel::saveAsPressed () { else fnameTemp = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, sf.format); - if (!Glib::file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) { + if (!safe_file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) { fname = fnameTemp; fnameOK = true; break; @@ -853,7 +864,7 @@ void EditorPanel::saveAsPressed () { // check if it exists if (!fnameOK) { fname = Glib::ustring::compose ("%1.%2", Glib::build_filename (dstdir, dstfname), sf.format); - if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { + if (safe_file_test (fname, Glib::FILE_TEST_EXISTS)) { Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + ""; Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); int response = msgd.run (); @@ -926,7 +937,7 @@ bool EditorPanel::idle_sendToGimp( ProgressConnector *pc){ Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format); int tries = 1; - while (Glib::file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) { + while (safe_file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) { fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format); tries++; } @@ -966,7 +977,7 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* #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 ( Glib::file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { success = safe_spawn_command_line_async (cmdLine); } #else @@ -978,7 +989,7 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* 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 ( Glib::file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + 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); } @@ -996,7 +1007,7 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* else if (options.editorToSendTo==2) { #ifdef _WIN32 executable = Glib::build_filename(options.psDir,"Photoshop.exe"); - if ( Glib::file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + 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); } @@ -1011,7 +1022,7 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* } else if (options.editorToSendTo==3) { #ifdef _WIN32 - if ( Glib::file_test(options.customEditorProg, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + 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); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index bf6156962..0f3e972c5 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -86,7 +86,9 @@ class EditorPanel : public Gtk::VBox, FilePanel* fPanel; - Thumbnail* openThm; + Thumbnail* openThm; // may get invalid on external delete event + Glib::ustring fname; // must be safed seperately + rtengine::InitialImage* isrc; rtengine::StagedImageProcessor* ipc; rtengine::StagedImageProcessor* beforeIpc; // for the before-after view diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 402c1da28..19f7ec005 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -477,13 +477,13 @@ void FileCatalog::deleteRequested (std::vector tbe) { // remove from cache cacheMgr->deleteEntry (fname); // delete from file system - ::g_remove (fname.c_str()); + safe_g_remove (fname); // delete paramfile if found - ::g_remove (Glib::ustring(fname+paramFileExtension).c_str()); - ::g_remove (Glib::ustring(removeExtension(fname)+paramFileExtension).c_str()); + safe_g_remove (Glib::ustring(fname+paramFileExtension)); + safe_g_remove (Glib::ustring(removeExtension(fname)+paramFileExtension)); // delete .thm file - ::g_remove (Glib::ustring(removeExtension(fname)+".thm").c_str()); - ::g_remove (Glib::ustring(removeExtension(fname)+".THM").c_str()); + safe_g_remove (Glib::ustring(removeExtension(fname)+".thm")); + safe_g_remove (Glib::ustring(removeExtension(fname)+".THM")); } redrawAll (); } @@ -543,14 +543,14 @@ void FileCatalog::renameRequested (std::vector tbe) { Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); /* check if filename already exists*/ - if (Glib::file_test (nfname, Glib::FILE_TEST_EXISTS)) { + if (safe_file_test (nfname, Glib::FILE_TEST_EXISTS)) { Glib::ustring msg_ = Glib::ustring("") + nfname + ": " + M("MAIN_MSG_ALREADYEXISTS") + ""; Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msgd.run (); } else { success = true; - if (!::g_rename (ofname.c_str(), nfname.c_str())) { + if (!safe_g_rename (ofname, nfname)) { cacheMgr->renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); reparseDirectory (); } @@ -600,7 +600,7 @@ void FileCatalog::renameRequested (std::vector tbe) { nBaseName += "." + (lastdot!=Glib::ustring::npos ? baseName.substr (lastdot+1) : ""); } Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); - if (!::g_rename (ofname.c_str(), nfname.c_str())) { + if (!safe_g_rename (ofname, nfname)) { cacheMgr->renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); // the remaining part (removing old and adding new entry) is done by the directory monitor reparseDirectory (); @@ -751,7 +751,7 @@ int FileCatalog::reparseDirectory () { if (selectedDirectory=="") return 0; - if (!Glib::file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) { + if (!safe_file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) { closeDir (); return 0; } @@ -762,7 +762,7 @@ int FileCatalog::reparseDirectory () { const std::vector& t = fileBrowser->getEntries (); std::vector fileNamesToDel; for (size_t i=0; ifilename, Glib::FILE_TEST_EXISTS)) + if (!safe_file_test (t[i]->filename, Glib::FILE_TEST_EXISTS)) fileNamesToDel.push_back (t[i]->filename); for (size_t i=0; idelEntry (fileNamesToDel[i]); diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index c22ee9fa3..f62c6f0e7 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -19,6 +19,7 @@ */ #include #include +#include int fbinit (void* data) { @@ -130,7 +131,7 @@ void FilePanel::init () { dirBrowser->fillDirTree (); placesBrowser->refreshPlacesList (); - if (argv1!="" && Glib::file_test (argv1, Glib::FILE_TEST_IS_DIR)) + if (argv1!="" && safe_file_test (argv1, Glib::FILE_TEST_IS_DIR)) dirBrowser->open (argv1); else { if (options.startupDir==STARTUPDIR_HOME) @@ -200,9 +201,9 @@ void FilePanel::saveOptions () { void FilePanel::open (const Glib::ustring& d) { - if (Glib::file_test (d, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (d, Glib::FILE_TEST_IS_DIR)) dirBrowser->open (d.c_str()); - else if (Glib::file_test (d, Glib::FILE_TEST_EXISTS)) + else if (safe_file_test (d, Glib::FILE_TEST_EXISTS)) dirBrowser->open (Glib::path_get_dirname(d), Glib::path_get_basename(d)); } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index f507c40d2..88492be57 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -19,6 +19,7 @@ #include #include #include +#include using namespace rtengine; using namespace rtengine::procparams; @@ -118,7 +119,7 @@ ICMPanel::ICMPanel () : Gtk::VBox(), FoldableToolPanel(this), iunchanged(NULL), opDialog->add_filter (filter_icc); opDialog->add_filter (filter_any); - if (Glib::file_test (options.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) { + if (safe_file_test (options.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) { ipDialog->set_current_folder (options.rtSettings.iccDirectory); opDialog->set_current_folder (options.rtSettings.iccDirectory); } diff --git a/rtgui/main.cc b/rtgui/main.cc index 9a817d9f9..dfcd3c202 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -43,10 +43,6 @@ extern Options options; -//#ifdef WIN32 -//#include // included for WinMain -//#endif - // stores path to data files Glib::ustring argv0; Glib::ustring argv1; @@ -103,8 +99,8 @@ int main(int argc, char **argv) #ifndef _WIN32 // Move the old path to the new one if the new does not exist - 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()); + 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); #endif // Gtk::RC::add_default_file (argv0+"/themes/"+options.theme); @@ -118,7 +114,7 @@ int main(int argc, char **argv) Gtk::RC::set_default_files (rcfiles); } Gtk::Main m(&argc, &argv); -// MainWindow *MainWindow = new class MainWindow(); + RTWindow *rtWindow = new class RTWindow(); gdk_threads_enter (); m.run(*rtWindow); diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index 02fdd0707..15cf4b489 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -26,7 +26,7 @@ MultiLangMgr langMgr; Glib::ustring M (std::string key) { return langMgr.getStr (key); } bool MultiLangMgr::load (Glib::ustring fname, MultiLangMgr* fb) { - FILE *f = g_fopen (fname.c_str(), "rt"); + FILE *f = safe_g_fopen (fname, "rt"); fallBack = fb; @@ -72,7 +72,7 @@ bool MultiLangMgr::load (Glib::ustring fname, MultiLangMgr* fb) { bool MultiLangMgr::save (Glib::ustring fname) { - FILE *f = g_fopen (fname.c_str(), "wt"); + FILE *f = safe_g_fopen (fname, "wt"); if (f==NULL) return false; diff --git a/rtgui/options.cc b/rtgui/options.cc index c6062bfe0..eee40e4bd 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include Options options; @@ -135,7 +136,11 @@ void Options::setDefaults () { rtSettings.dualThreadEnabled = true; rtSettings.darkFramesPath = ""; #ifdef WIN32 - rtSettings.iccDirectory = "C:/WINDOWS/System32/spool/drivers/color"; + const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" + if (sysRoot!=NULL) + rtSettings.iccDirectory = Glib::ustring(sysRoot) + Glib::ustring("\\System32\\spool\\drivers\\color"); + else + rtSettings.iccDirectory = "C:\\WINDOWS\\System32\\spool\\drivers\\color"; #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif @@ -155,7 +160,7 @@ int Options::readFromFile (Glib::ustring fname) { rtengine::SafeKeyFile keyFile; try { - if( !Glib::file_test(fname,Glib::FILE_TEST_EXISTS)) + if( !safe_file_test(fname,Glib::FILE_TEST_EXISTS)) return 1; if (!keyFile.load_from_file (fname)) return 1; @@ -434,7 +439,8 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); - FILE *f = g_fopen (fname.c_str(), "wt"); + + FILE *f = safe_g_fopen (fname, "wt"); if (f==NULL) return 1; else { @@ -454,9 +460,9 @@ void Options::load () { cacheBaseDir = argv0 + "/cache"; if (options.multiUser) { int r = options.readFromFile (rtdir + "/options"); - if (r && !g_mkdir_with_parents (rtdir.c_str(), 511)) { + if (r && !safe_g_mkdir_with_parents (rtdir, 511)) { Glib::ustring profdir = rtdir + "/profiles"; - g_mkdir_with_parents (profdir.c_str(), 511); + safe_g_mkdir_with_parents (profdir, 511); options.saveToFile (rtdir + "/options"); } #ifdef _WIN32 diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index ee6cf6d2c..ce85f7c75 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -69,7 +69,7 @@ PopUpCommon::type_signal_changed PopUpCommon::signal_changed() { bool PopUpCommon::addEntry (Glib::ustring imagePath, Glib::ustring label) { bool added = false; - if ( Glib::file_test(safe_locale_from_utf8(imagePath), Glib::FILE_TEST_EXISTS) && label.size() ) { + if ( safe_file_test(imagePath, Glib::FILE_TEST_EXISTS) && label.size() ) { imagePaths.push_back(imagePath); sItems.push_back(label); // Create the image diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4d5674e0c..f0b4f7266 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -24,6 +24,7 @@ #include #include #include +#include extern Options options; extern Glib::ustring argv0; @@ -719,7 +720,7 @@ void Preferences::parseDir (Glib::ustring dirname, std::vector& i Glib::ustring fname = dirname + *i; Glib::ustring sname = *i; // ignore directories - if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= ext.size() && sname.substr (sname.size()-ext.size(), ext.size()).casefold() == ext) + if (!safe_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())); } delete dir; @@ -827,7 +828,7 @@ void Preferences::fillPreferences () { rprofiles->set_active_text (moptions.defProfRaw); iprofiles->set_active_text (moptions.defProfImg); dateformat->set_text (moptions.dateFormat); - if (Glib::file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) + if (safe_file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) monProfile->set_filename (moptions.rtSettings.monitorProfile); if (moptions.rtSettings.monitorProfile.empty()) monProfile->set_current_folder (moptions.rtSettings.iccDirectory); @@ -855,13 +856,13 @@ void Preferences::fillPreferences () { edOther->set_active (moptions.editorToSendTo==3); #ifdef _WIN32 edPS->set_active (moptions.editorToSendTo==2); - if (Glib::file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) gimpDir->set_filename (moptions.gimpDir); - if (Glib::file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) psDir->set_filename (moptions.psDir); #elif defined __APPLE__ edPS->set_active (moptions.editorToSendTo==2); - if (Glib::file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) psDir->set_filename (moptions.psDir); #endif editorToSendTo->set_text (moptions.customEditorProg); diff --git a/rtgui/previewloader.cc b/rtgui/previewloader.cc index 288ce79e0..70f2f1003 100644 --- a/rtgui/previewloader.cc +++ b/rtgui/previewloader.cc @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef _OPENMP #include @@ -104,7 +105,7 @@ public: // if something got Thumbnail* tmb = 0; { - if (Glib::file_test(j.dir_entry_, Glib::FILE_TEST_EXISTS)) + if (safe_file_test(j.dir_entry_, Glib::FILE_TEST_EXISTS)) { tmb = cacheMgr->getEntry(j.dir_entry_); } diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index e684f98de..3d7a63afd 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -21,6 +21,7 @@ #include #include #include +#include using namespace rtengine; using namespace rtengine::procparams; @@ -158,7 +159,7 @@ void ProfilePanel::save_clicked () { if (!hasext) fname = fname + paramFileExtension; - if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) { + if (safe_file_test (fname, Glib::FILE_TEST_EXISTS)) { Glib::ustring msg_ = Glib::ustring("") + fname + ": " + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE") + ""; Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); int response = msgd.run (); diff --git a/rtgui/profilestore.cc b/rtgui/profilestore.cc index b112e4d6a..a1455bd6f 100644 --- a/rtgui/profilestore.cc +++ b/rtgui/profilestore.cc @@ -19,6 +19,7 @@ #include #include #include +#include ProfileStore profileStore; @@ -36,8 +37,8 @@ void ProfileStore::parseProfiles () { if (options.multiUser) { Glib::ustring userPD = options.rtdir + "/" + options.profilePath; - if (!Glib::file_test (userPD, Glib::FILE_TEST_IS_DIR)) - g_mkdir_with_parents (userPD.c_str(), 511); + if (!safe_file_test (userPD, Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (userPD, 511); parseDir (userPD); } parseDir (argv0 + "/" + options.profilePath); @@ -61,7 +62,7 @@ void ProfileStore::parseDir (const Glib::ustring& pdir) { Glib::ustring fname = dirname + *i; Glib::ustring sname = *i; // ignore directories - if (!Glib::file_test (fname, Glib::FILE_TEST_IS_DIR)) { + if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { int lastdot = sname.find_last_of ('.'); if (lastdot!=Glib::ustring::npos && lastdot<=sname.size()-4 && !sname.casefold().compare (lastdot, 4, paramFileExtension)) { if( options.rtSettings.verbose ) diff --git a/rtgui/splash.cc b/rtgui/splash.cc index 2a7b3e4fb..5f6df525a 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -91,8 +91,8 @@ Splash::Splash () { #else std::string buildFileName = Glib::build_filename (CREDITS_SEARCH_PATH, "AboutThisBuild.txt"); #endif - if ( Glib::file_test(buildFileName, (Glib::FILE_TEST_EXISTS)) ) { - FILE *f = g_fopen (buildFileName.c_str(), "rt"); + if ( safe_file_test(buildFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (buildFileName, "rt"); if (f != NULL) { char* buffer = new char[1024]; std::ostringstream ostr; @@ -118,8 +118,8 @@ Splash::Splash () { #else std::string creditsFileName = Glib::build_filename (CREDITS_SEARCH_PATH, "AUTHORS.txt"); #endif - if ( Glib::file_test(creditsFileName, (Glib::FILE_TEST_EXISTS)) ) { - FILE *f = g_fopen (creditsFileName.c_str(), "rt"); + if ( safe_file_test(creditsFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (creditsFileName, "rt"); if (f != NULL) { char* buffer = new char[1024]; std::ostringstream ostr; @@ -145,8 +145,8 @@ Splash::Splash () { #else std::string licenseFileName = Glib::build_filename (LICENCE_SEARCH_PATH, "LICENSE.txt"); #endif - if ( Glib::file_test(licenseFileName, (Glib::FILE_TEST_EXISTS)) ) { - FILE *f = g_fopen (licenseFileName.c_str(), "rt"); + if ( safe_file_test(licenseFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (licenseFileName, "rt"); if (f != NULL) { char* buffer = new char[1024]; std::ostringstream ostr; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 013f83d6f..0ee858662 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -29,6 +29,7 @@ #include #include #include +#include using namespace rtengine::procparams; @@ -180,16 +181,16 @@ void Thumbnail::clearProcParams (int whoClearedIt) { needsReProcessing = true; // remove param file from cache Glib::ustring fname_ = getCacheFileName ("profiles")+paramFileExtension; - if (Glib::file_test (fname_, Glib::FILE_TEST_EXISTS)) - ::g_remove (fname_.c_str()); + if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); // remove param file located next to the file // fname_ = removeExtension(fname) + paramFileExtension; fname_ = fname + paramFileExtension; - if (Glib::file_test (fname_, Glib::FILE_TEST_EXISTS)) - ::g_remove (fname_.c_str()); + if (safe_file_test(fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); fname_ = removeExtension(fname) + paramFileExtension; - if (Glib::file_test (fname_, Glib::FILE_TEST_EXISTS)) - ::g_remove (fname_.c_str()); + if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); for (int i=0; iprocParamsChanged (this, whoClearedIt); @@ -437,9 +438,9 @@ void Thumbnail::_saveThumbnail () { if (!tpp) return; - ::g_remove ((getCacheFileName ("images")+".cust").c_str()); - ::g_remove ((getCacheFileName ("images")+".cust16").c_str()); - ::g_remove ((getCacheFileName ("images")+".jpg").c_str()); + safe_g_remove (getCacheFileName ("images")+".cust"); + safe_g_remove (getCacheFileName ("images")+".cust16"); + safe_g_remove (getCacheFileName ("images")+".jpg"); // save thumbnail image if (options.thumbnailFormat == FT_Custom) @@ -520,8 +521,10 @@ bool Thumbnail::openDefaultViewer(int destination) { if (destination==1) { openFName = Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fname), options.saveFormat.format); - if (Glib::file_test (openFName, Glib::FILE_TEST_EXISTS)) { - ShellExecute(NULL, "open", openFName.c_str(), NULL, NULL, SW_SHOWMAXIMIZED ); + if (safe_file_test (openFName, Glib::FILE_TEST_EXISTS)) { + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (openFName.c_str(), -1, NULL, NULL, NULL); + ShellExecuteW(NULL, L"open", wfilename, NULL, NULL, SW_SHOWMAXIMIZED ); + g_free(wfilename); } else { printf("File not found\n"); return false; @@ -532,25 +535,28 @@ bool Thumbnail::openDefaultViewer(int destination) { printf("Opening %s\n", openFName.c_str()); - if (Glib::file_test (openFName, Glib::FILE_TEST_EXISTS)) { + if (safe_file_test (openFName, Glib::FILE_TEST_EXISTS)) { // Output file exists, so open explorer and select output file - const char* org=Glib::ustring::compose("/select,\"%1\"", openFName).c_str(); - char* par=new char[strlen(org)+1]; - strcpy(par, org); + wchar_t* org=(wchar_t*)g_utf8_to_utf16 (Glib::ustring::compose("/select,\"%1\"", openFName).c_str(), -1, NULL, NULL, NULL); + wchar_t* par=new wchar_t[wcslen(org)+1]; + wcscpy(par, org); // In this case the / disturbs - char* p = par+1; // skip the first backslash + wchar_t* p = par+1; // skip the first backslash while (*p!=0) { - if (*p=='/') *p='\\'; + if (*p==L'/') *p=L'\\'; p++; } - ShellExecute(NULL, "open", "explorer.exe", par, NULL, SW_SHOWNORMAL ); + ShellExecuteW(NULL, L"open", L"explorer.exe", par, NULL, SW_SHOWNORMAL ); delete[] par; - } else if (Glib::file_test (Glib::path_get_dirname(openFName), Glib::FILE_TEST_EXISTS)) { + g_free(org); + } else if (safe_file_test (Glib::path_get_dirname(openFName), Glib::FILE_TEST_EXISTS)) { // Out file does not exist, but directory - ShellExecute(NULL, "explore", Glib::path_get_dirname(openFName).c_str(), NULL, NULL, SW_SHOWNORMAL ); + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (Glib::path_get_dirname(openFName).c_str(), -1, NULL, NULL, NULL); + ShellExecuteW(NULL, L"explore", wfilename, NULL, NULL, SW_SHOWNORMAL ); + g_free(wfilename); } else { printf("File and dir not found\n"); return false;