diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 4a4bd2895..9236b8e51 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -690,7 +690,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip) { + void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, int* outCurve1, int* outCurve2, unsigned int* outBeforeCCurveHistogram, int skip) { double def_mul = pow (2.0, defmul); @@ -735,7 +735,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou float toneslope=(shouldery-toey)/(shoulderx-toex); if (shoulderx<1) {//a>1; positive EC //move shoulder down if there is highlight rolloff - shouldery = shouldery-(0.3)*(hlcompr/100.0); + shouldery = shouldery-(0.2)*(hlcompr/100.0); shoulderx = shoulderx - (1-shouldery)/toneslope; } else {//a<1; negative EC //if (shoulderx>1) { @@ -814,6 +814,11 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou //val = basecurve (val, a, black, D, hlcompr/100.0, shcompr/100.0); val = basecurve->getVal (val); + outCurve1[i] = (int) (65535.0 * CLIPD(val)); + + // change to [0,1] range + val = (double)i / 65535.0; + // gamma correction if (gamma_>0) val = gamma (val, gamma_, start, slope, mul, add); @@ -853,6 +858,7 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou prev+=skip; continue; } + outCurve1[i] = ( outCurve1[prev] * (skip - i%skip) + outCurve1[prev+skip] * (i%skip) ) / skip; dcurve[i] = ( dcurve[prev] * (skip - i%skip) + dcurve[prev+skip] * (i%skip) ) / skip; } @@ -899,12 +905,12 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou double val = contrastcurve->getVal (dcurve[i]); if (igamma && gamma_>0) val = igamma2 (val); - outCurve[i] = (int) (65535.0 * CLIPD(val)); + outCurve2[i] = (int) (65535.0 * CLIPD(val)); } } else for (int i=0; i<=0xffff; i++) - outCurve[i] = (int) (65535.0 * dcurve[i]); + outCurve2[i] = (int) (65535.0 * dcurve[i]); delete [] dcurve; } diff --git a/rtengine/curves.h b/rtengine/curves.h index 8798c735d..fb81f3ce6 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -128,7 +128,7 @@ class CurveFactory { public: // static void updateCurve3 (int* curve, int* ohistogram, const std::vector& cpoints, double defmul, double ecomp, int black, double hlcompr, double shcompr, double br, double contr, double gamma_, bool igamma, int skip=1); - static void complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, int* outCurve, unsigned int* outBeforeCCurveHistogram, int skip=1); + static void complexCurve (double ecomp, double black, double hlcompr, double shcompr, double br, double contr, double defmul, double gamma_, bool igamma, const std::vector& curvePoints, unsigned int* histogram, int* outCurve1, int* outCurve2, unsigned int* outBeforeCCurveHistogram, int skip=1); static void complexsgnCurve (double satclip, double satcompr, double saturation, double colormult, const std::vector& curvePoints, int* outCurve, int skip=1); }; diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 8c9d67a10..65dc125b6 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -158,12 +158,12 @@ void Crop::update (int todo, bool internal) { // shadows & highlights & tone curve & convert to cielab if (todo & M_RGBCURVE) - parent->ipf.rgbProc (baseCrop, laboCrop, parent->tonecurve, cshmap); + parent->ipf.rgbProc (baseCrop, laboCrop, parent->tonecurve1, parent->tonecurve2, cshmap); // apply luminance operations if (todo & (M_LUMINANCE+M_COLOR)) { - parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve, 0, croph); + parent->ipf.luminanceCurve (laboCrop, labnCrop, parent->lumacurve2, 0, croph); parent->ipf.chrominanceCurve (laboCrop, labnCrop, 0, parent->chroma_acurve, 0, croph); parent->ipf.chrominanceCurve (laboCrop, labnCrop, 1, parent->chroma_bcurve, 0, croph); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 2577a455e..19112e12f 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -144,8 +144,8 @@ void ImProcCoordinator::updatePreviewImage (int todo) { progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases); if (todo & M_RGBCURVE) { - CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, vhist16, tonecurve, bcrgbhist, scale==1 ? 1 : 1); - ipf.rgbProc (oprevi, oprevl, tonecurve, shmap); + CurveFactory::complexCurve (params.toneCurve.expcomp, params.toneCurve.black/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, vhist16, tonecurve1, tonecurve2, bcrgbhist, scale==1 ? 1 : 1); + ipf.rgbProc (oprevi, oprevl, tonecurve1, tonecurve2, shmap); // recompute luminance histogram memset (lhist16, 0, 65536*sizeof(int)); @@ -156,7 +156,7 @@ void ImProcCoordinator::updatePreviewImage (int todo) { readyphase++; if (todo & M_LUMACURVE) { - CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, lhist16, lumacurve, bcLhist, scale==1 ? 1 : 16); + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, lhist16, lumacurve1, lumacurve2, bcLhist, scale==1 ? 1 : 16); CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, chroma_acurve, scale==1 ? 1 : 16); CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, chroma_bcurve, scale==1 ? 1 : 16); } @@ -212,7 +212,7 @@ void ImProcCoordinator::updatePreviewImage (int todo) { if (todo & (M_LUMINANCE+M_COLOR) ) { progress ("Applying Luminance Curve...",100*readyphase/numofphases); - ipf.luminanceCurve (oprevl, nprevl, lumacurve, 0, pH); + ipf.luminanceCurve (oprevl, nprevl, lumacurve2, 0, pH); readyphase++; progress ("Applying Color Boost...",100*readyphase/numofphases); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 49ef294d0..9d5112697 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -61,10 +61,13 @@ class ImProcCoordinator : public StagedImageProcessor { void freeAll (); - int tonecurve [65536]; - int lumacurve [65536]; - int chroma_acurve [65536]; - int chroma_bcurve [65536]; + int tonecurve1 [65536]; + int tonecurve2 [65536]; + + int lumacurve1 [65536]; + int lumacurve2 [65536]; + int chroma_acurve [65536]; + int chroma_bcurve [65536]; unsigned int vhist16[65536]; unsigned int lhist16[65536]; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 64988993b..8b6f7c58a 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -245,7 +245,7 @@ void ImProcFunctions::firstAnalysis (Image16* original, const ProcParams* params delete [] hist; } -void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve, SHMap* shmap) { +void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve1, int* tonecurve2, SHMap* shmap) { int h_th, s_th; if (shmap) { @@ -321,10 +321,23 @@ void ImProcFunctions::rgbProc (Image16* working, LabImage* lab, int* tonecurve, b = CLIP((int)(factor*b)); } } - r = tonecurve[r]; + /*r = tonecurve[r]; g = tonecurve[g]; - b = tonecurve[b]; + b = tonecurve[b];*/ + //int Y = (int)(0.299*r + 0.587*g + 0.114*b); + //float tonefactor = (Y>0 ? (float)tonecurve[Y]/Y : 0); + float rtonefactor = (r>0 ? (float)tonecurve1[r]/r : 0); + float gtonefactor = (g>0 ? (float)tonecurve1[g]/g : 0); + float btonefactor = (b>0 ? (float)tonecurve1[b]/b : 0); + float tonefactor = MIN(rtonefactor, MIN(gtonefactor,btonefactor)); + r *= tonefactor; + g *= tonefactor; + b *= tonefactor; + r = tonecurve2[r]; + g = tonecurve2[g]; + b = tonecurve2[b]; + int x = (toxyz[0][0] * r + toxyz[1][0] * g + toxyz[2][0] * b) >> 15; int y = (toxyz[0][1] * r + toxyz[1][1] * g + toxyz[2][1] * b) >> 15; int z = (toxyz[0][2] * r + toxyz[1][2] * g + toxyz[2][2] * b) >> 15; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cdef8b7b2..7de8b703b 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -79,7 +79,7 @@ class ImProcFunctions { bool needsTransform (); void firstAnalysis (Image16* working, const ProcParams* params, unsigned int* vhist16, double gamma); - void rgbProc (Image16* working, LabImage* lab, int* tonecurve, SHMap* shmap); + void rgbProc (Image16* working, LabImage* lab, int* tonecurve1, int* tonecurve2, SHMap* shmap); void luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to); void chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to); void colorCurve (LabImage* lold, LabImage* lnew); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 5d18a31ce..3ee47d5a5 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -311,11 +311,12 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei if (params.toneCurve.autoexp && aeHistogram) ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, br, bl); - int* curve = new int [65536]; - CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, logDefGain, isRaw ? 2.2 : 0, true, params.toneCurve.curve, hist16, curve, NULL, 16); + int* curve1 = new int [65536]; + int* curve2 = new int [65536]; + CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, logDefGain, isRaw ? 2.2 : 0, true, params.toneCurve.curve, hist16, curve1, curve2, NULL, 16); LabImage* labView = new LabImage (baseImg); - ipf.rgbProc (baseImg, labView, curve, shmap); + ipf.rgbProc (baseImg, labView, curve1, curve2, shmap); if (shmap) delete shmap; @@ -327,15 +328,15 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei hist16[labView->L[i][j]]++; // luminance processing - CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve, NULL, 16); - ipf.luminanceCurve (labView, labView, curve, 0, fh); - CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve, 16); - ipf.chrominanceCurve (labView, labView, 0, curve, 0, fh); - CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve, 16); - ipf.chrominanceCurve (labView, labView, 1, curve, 0, fh); + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, NULL, 16); + ipf.luminanceCurve (labView, labView, curve2, 0, fh); + CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 16); + ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh); + CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 16); + ipf.chrominanceCurve (labView, labView, 1, curve1, 0, fh); - - delete [] curve; + delete [] curve1; + delete [] curve2; delete [] hist16; // color processing diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 5e1e81ee5..37f46ebab 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1,239 +1,241 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * 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 -#include -#include -#include -#include - -#include - -#undef THREAD_PRIORITY_NORMAL - -namespace rtengine { - -IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl) { - - errorCode = 0; - - ProcessingJobImpl* job = (ProcessingJobImpl*) pjob; - - if (pl) { - pl->setProgressStr ("Processing..."); - pl->setProgress (0.0); - } - - InitialImage* ii = job->initialImage; - if (!ii) { - ii = InitialImage::load (job->fname, job->isRaw, &errorCode); - if (errorCode) { - ii->decreaseRef (); - delete job; - return NULL; - } - } - procparams::ProcParams& params = job->pparams; - - // aquire image from imagesource - ImageSource* imgsrc = ii->getImageSource (); - ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); - if (params.wb.method=="Camera") - currWB = imgsrc->getWB (); - else if (params.wb.method=="Auto") - currWB = imgsrc->getAutoWB (); - - int tr = TR_NONE; - if (params.coarse.rotate==90) tr |= TR_R90; - if (params.coarse.rotate==180) tr |= TR_R180; - if (params.coarse.rotate==270) tr |= TR_R270; - if (params.coarse.hflip) tr |= TR_HFLIP; - if (params.coarse.vflip) tr |= TR_VFLIP; - - int fw, fh; - imgsrc->getFullSize (fw, fh, tr); - - ImProcFunctions ipf (¶ms, true); - - Image16* baseImg; - PreviewProps pp (0, 0, fw, fh, 1); - if (fabs(params.resize.scale-1.0)<1e-5) { - baseImg = new Image16 (fw, fh); - imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm); - } - else { - Image16* oorig = new Image16 (fw, fh); - imgsrc->getImage (currWB, tr, oorig, pp, params.hlrecovery, params.icm); - fw *= params.resize.scale; - fh *= params.resize.scale; - baseImg = new Image16 (fw, fh); - ipf.resize (oorig, baseImg); - delete oorig; - } - if (pl) - pl->setProgress (0.25); - - // perform first analysis - unsigned int* hist16 = new unsigned int[65536]; - ipf.firstAnalysis (baseImg, ¶ms, hist16, imgsrc->getGamma()); - - // perform transform - if (ipf.needsTransform()) { - Image16* trImg = new Image16 (fw, fh); - ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh); - delete baseImg; - baseImg = trImg; - } - - // update blurmap - int** buffer = new int*[fh]; - for (int i=0; iupdate (baseImg, (unsigned short**)buffer, shradius, ipf.lumimul, params.sh.hq); - } - // RGB processing -//!!!// auto exposure!!! - double br = params.toneCurve.expcomp; - int bl = params.toneCurve.black; - - if (params.toneCurve.autoexp) { - unsigned int aehist[65536]; int aehistcompr; - imgsrc->getAEHistogram (aehist, aehistcompr); - ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, br, bl); - } - - int* curve = new int [65536]; - - CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, hist16, curve, NULL); - - LabImage* labView = new LabImage (baseImg); - ipf.rgbProc (baseImg, labView, curve, shmap); - - if (shmap) - delete shmap; - - if (pl) - pl->setProgress (0.5); - - - // luminance histogram update - memset (hist16, 0, 65536*sizeof(int)); - for (int i=0; iL[i][j]]++; - - // luminance processing - CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve, NULL); - ipf.luminanceCurve (labView, labView, curve, 0, fh); - CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve, 1); - ipf.chrominanceCurve (labView, labView, 0, curve, 0, fh); - CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve, 1); - ipf.chrominanceCurve (labView, labView, 1, curve, 0, fh); - - ipf.impulsedenoise (labView); - ipf.lumadenoise (labView, buffer); - ipf.sharpening (labView, (unsigned short**)buffer); - - delete [] curve; - delete [] hist16; - - // color processing - ipf.colorCurve (labView, labView); - ipf.colordenoise (labView, buffer); - ipf.dirpyrdenoise (labView); - - // wavelet equalizer - ipf.waveletEqualizer (labView, true, true); - - // directional pyramid equalizer - ipf.dirpyrequalizer (labView); - - for (int i=0; isetProgress (0.75); - - // obtain final image - Image16* readyImg; - int cx = 0, cy = 0, cw = labView->W, ch = labView->H; - if (params.crop.enabled) { - cx = params.crop.x; - cy = params.crop.y; - cw = params.crop.w; - ch = params.crop.h; - } - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); - - if (pl) - pl->setProgress (1.0); - - readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); - - ProfileContent pc; - if (params.icm.output.compare (0, 6, "No ICM") && params.icm.output!="") - pc = iccStore.getContent (params.icm.output); - - readyImg->setOutputProfile (pc.data, pc.length); - - delete baseImg; - - if (!job->initialImage) - ii->decreaseRef (); - - delete job; - - if (pl) { - pl->setProgress (1.0); - pl->setProgressStr ("Ready."); - } - - return readyImg; -} - -void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl) { - - ProcessingJob* currentJob = job; - - while (currentJob) { - int errorCode; - IImage16* img = processImage (currentJob, errorCode, bpl); - if (errorCode) - bpl->error ("Can not load input image."); - currentJob = bpl->imageReady (img); - } -} - -void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl) { - - if (bpl) - Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl), 0, true, true, Glib::THREAD_PRIORITY_LOW); - -} - -} +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * 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 +#include +#include +#include +#include + +#include + +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { + +IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl) { + + errorCode = 0; + + ProcessingJobImpl* job = (ProcessingJobImpl*) pjob; + + if (pl) { + pl->setProgressStr ("Processing..."); + pl->setProgress (0.0); + } + + InitialImage* ii = job->initialImage; + if (!ii) { + ii = InitialImage::load (job->fname, job->isRaw, &errorCode); + if (errorCode) { + ii->decreaseRef (); + delete job; + return NULL; + } + } + procparams::ProcParams& params = job->pparams; + + // aquire image from imagesource + ImageSource* imgsrc = ii->getImageSource (); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") + currWB = imgsrc->getAutoWB (); + + int tr = TR_NONE; + if (params.coarse.rotate==90) tr |= TR_R90; + if (params.coarse.rotate==180) tr |= TR_R180; + if (params.coarse.rotate==270) tr |= TR_R270; + if (params.coarse.hflip) tr |= TR_HFLIP; + if (params.coarse.vflip) tr |= TR_VFLIP; + + int fw, fh; + imgsrc->getFullSize (fw, fh, tr); + + ImProcFunctions ipf (¶ms, true); + + Image16* baseImg; + PreviewProps pp (0, 0, fw, fh, 1); + if (fabs(params.resize.scale-1.0)<1e-5) { + baseImg = new Image16 (fw, fh); + imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm); + } + else { + Image16* oorig = new Image16 (fw, fh); + imgsrc->getImage (currWB, tr, oorig, pp, params.hlrecovery, params.icm); + fw *= params.resize.scale; + fh *= params.resize.scale; + baseImg = new Image16 (fw, fh); + ipf.resize (oorig, baseImg); + delete oorig; + } + if (pl) + pl->setProgress (0.25); + + // perform first analysis + unsigned int* hist16 = new unsigned int[65536]; + ipf.firstAnalysis (baseImg, ¶ms, hist16, imgsrc->getGamma()); + + // perform transform + if (ipf.needsTransform()) { + Image16* trImg = new Image16 (fw, fh); + ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh); + delete baseImg; + baseImg = trImg; + } + + // update blurmap + int** buffer = new int*[fh]; + for (int i=0; iupdate (baseImg, (unsigned short**)buffer, shradius, ipf.lumimul, params.sh.hq); + } + // RGB processing +//!!!// auto exposure!!! + double br = params.toneCurve.expcomp; + int bl = params.toneCurve.black; + + if (params.toneCurve.autoexp) { + unsigned int aehist[65536]; int aehistcompr; + imgsrc->getAEHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, br, bl); + } + + int* curve1 = new int [65536]; + int* curve2 = new int [65536]; + + CurveFactory::complexCurve (br, bl/65535.0, params.toneCurve.hlcompr, params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, imgsrc->getDefGain(), imgsrc->getGamma(), true, params.toneCurve.curve, hist16, curve1, curve2, NULL); + + LabImage* labView = new LabImage (baseImg); + ipf.rgbProc (baseImg, labView, curve1, curve2, shmap); + + if (shmap) + delete shmap; + + if (pl) + pl->setProgress (0.5); + + + // luminance histogram update + memset (hist16, 0, 65536*sizeof(int)); + for (int i=0; iL[i][j]]++; + + // luminance processing + CurveFactory::complexCurve (0.0, 0.0, 0.0, 0.0, params.labCurve.brightness, params.labCurve.contrast, 0.0, 0.0, false, params.labCurve.lcurve, hist16, curve1, curve2, NULL); + ipf.luminanceCurve (labView, labView, curve2, 0, fh); + CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.acurve, curve1, 1); + ipf.chrominanceCurve (labView, labView, 0, curve1, 0, fh); + CurveFactory::complexsgnCurve (0.0, 100.0, params.labCurve.saturation, 1.0, params.labCurve.bcurve, curve1, 1); + ipf.chrominanceCurve (labView, labView, 1, curve1, 0, fh); + + ipf.impulsedenoise (labView); + ipf.lumadenoise (labView, buffer); + ipf.sharpening (labView, (unsigned short**)buffer); + + delete [] curve1; + delete [] curve2; + delete [] hist16; + + // color processing + ipf.colorCurve (labView, labView); + ipf.colordenoise (labView, buffer); + ipf.dirpyrdenoise (labView); + + // wavelet equalizer + ipf.waveletEqualizer (labView, true, true); + + // directional pyramid equalizer + ipf.dirpyrequalizer (labView); + + for (int i=0; isetProgress (0.75); + + // obtain final image + Image16* readyImg; + int cx = 0, cy = 0, cw = labView->W, ch = labView->H; + if (params.crop.enabled) { + cx = params.crop.x; + cy = params.crop.y; + cw = params.crop.w; + ch = params.crop.h; + } + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); + + if (pl) + pl->setProgress (1.0); + + readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + + ProfileContent pc; + if (params.icm.output.compare (0, 6, "No ICM") && params.icm.output!="") + pc = iccStore.getContent (params.icm.output); + + readyImg->setOutputProfile (pc.data, pc.length); + + delete baseImg; + + if (!job->initialImage) + ii->decreaseRef (); + + delete job; + + if (pl) { + pl->setProgress (1.0); + pl->setProgressStr ("Ready."); + } + + return readyImg; +} + +void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl) { + + ProcessingJob* currentJob = job; + + while (currentJob) { + int errorCode; + IImage16* img = processImage (currentJob, errorCode, bpl); + if (errorCode) + bpl->error ("Can not load input image."); + currentJob = bpl->imageReady (img); + } +} + +void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl) { + + if (bpl) + Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl), 0, true, true, Glib::THREAD_PRIORITY_LOW); + +} + +}