1 /* -*- C++ -*- 2 * 3 * This file is part of RawTherapee. 4 * 5 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com> 6 * 7 * RawTherapee is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * RawTherapee is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 #pragma once 21 22 #include "rtengine.h" 23 #include "improcfun.h" 24 #include "image8.h" 25 #include "image16.h" 26 #include "imagesource.h" 27 #include "procevents.h" 28 #include "dcrop.h" 29 #include "LUT.h" 30 #include "../rtgui/threadutils.h" 31 32 namespace rtengine { 33 34 using namespace procparams; 35 36 class Crop; 37 38 /** @brief Manages the image processing, espc. of the preview windows 39 * 40 * There is one ImProcCoordinator per edit panel. 41 * 42 * The ImProcCoordinator handle an sized down image representation of the full image, that is used when paning 43 * and in the Navigator object. 44 * 45 * Each ImProcCoordinator handles an rtengine::Crop list, which process images too with their own pipeline, 46 * but using this class' LUT and other precomputed parameters. The main preview area is displaying a non framed Crop object, 47 * while detail windows are framed Crop objects. 48 */ 49 class ImProcCoordinator : public StagedImageProcessor, public HistogramObservable 50 { 51 52 friend class Crop; 53 54 protected: 55 Imagefloat *orig_prev; 56 Imagefloat *oprevi; 57 Imagefloat *spotprev; 58 Imagefloat *bufs_[3]; 59 std::array<bool, 4> pipeline_stop_; 60 61 Imagefloat *drcomp_11_dcrop_cache; // global cache for dynamicRangeCompression used in 1:1 detail windows (except when denoise is active) 62 Image8 *previmg; // displayed image in monitor color space, showing the output profile as well (soft-proofing enabled, which then correspond to workimg) or not 63 Image8 *workimg; // internal image in output color space for analysis 64 65 ImageSource* imgsrc; 66 67 ColorTemp currWB; 68 ColorTemp autoWB; 69 70 double lastAwbEqual; 71 72 ImProcFunctions ipf; 73 DCPProfile::ApplyState dcpApplyState; 74 75 Glib::ustring monitorProfile; 76 RenderingIntent monitorIntent; 77 bool softProof; 78 bool gamutCheck; 79 bool sharpMask; 80 81 int scale; 82 bool highDetailPreprocessComputed; 83 bool highDetailRawComputed; 84 bool allocated; 85 86 void freeAll (); 87 88 // Precomputed values used by DetailedCrop ---------------------------------------------- 89 90 LUTu vhist16; 91 LUTu histRed, histRedRaw; 92 LUTu histGreen, histGreenRaw; 93 LUTu histBlue, histBlueRaw; 94 LUTu histLuma, histToneCurve, histLCurve, histCCurve; 95 LUTu /*histLLCurve,*/ histLCAM, histCCAM, histChroma, histLRETI; 96 97 bool hist_lrgb_dirty; 98 /// Used to simulate a lazy update of the raw histogram. 99 bool hist_raw_dirty; 100 int vectorscopeScale; 101 bool vectorscope_hc_dirty, vectorscope_hs_dirty; 102 array2D<int> vectorscope_hc, vectorscope_hs; 103 /// Waveform's intensity. Same as height of reference image. 104 int waveformScale; 105 bool waveform_dirty; 106 array2D<int> waveformRed, waveformGreen, waveformBlue, waveformLuma; 107 // ------------------------------------------------------------------------------------ 108 109 int fw, fh, tr, fullw, fullh; 110 int pW, pH; 111 112 ProgressListener* plistener; 113 PreviewImageListener* imageListener; 114 AutoExpListener* aeListener; 115 AutoWBListener* awbListener; 116 FlatFieldAutoClipListener *flatFieldAutoClipListener; 117 AutoContrastListener *bayerAutoContrastListener; 118 AutoContrastListener *xtransAutoContrastListener; 119 FrameCountListener *frameCountListener; 120 ImageTypeListener *imageTypeListener; 121 FilmNegListener *filmNegListener; 122 123 AutoChromaListener* adnListener; 124 125 HistogramListener* hListener; 126 std::vector<SizeListener*> sizeListeners; 127 128 AutoLogListener *autoLogListener; 129 AutoDeconvRadiusListener *autoRadiusListener; 130 131 std::vector<Crop*> crops; 132 133 bool resultValid; 134 135 MyMutex minit; // to gain mutually exclusive access to ... to what exactly? 136 void backupParams(); 137 void restoreParams(); 138 139 void progress (Glib::ustring str, int pr); 140 void reallocAll (); 141 void allocCache (Imagefloat* &imgfloat); 142 void setScale (int prevscale); 143 void updatePreviewImage (int todo, bool panningRelatedChange); 144 void updateWB(); 145 146 void notifyHistogramChanged(); 147 /// Updates L, R, G, and B histograms. Returns true unless not updated. 148 bool updateLRGBHistograms(); 149 /// Updates the H-C vectorscope. Returns true unless not updated. 150 bool updateVectorscopeHC(); 151 /// Updates the H-S vectorscope. Returns true unless not updated. 152 bool updateVectorscopeHS(); 153 /// Updates all waveforms. Returns true unless not updated. 154 bool updateWaveforms(); 155 156 MyMutex mProcessing; 157 ProcParams params; 158 ProcParams paramsBackup; 159 TweakOperator* tweakOperator; 160 161 // for optimization purpose, the output profile, output rendering intent and 162 // output BPC will trigger a regeneration of the profile on parameter change only 163 // and automatically 164 Glib::ustring lastOutputProfile; 165 RenderingIntent lastOutputIntent; 166 bool lastOutputBPC; 167 168 // members of the updater: 169 Glib::Thread* thread; 170 MyMutex updaterThreadStart; 171 MyMutex paramsUpdateMutex; 172 int changeSinceLast; 173 bool updaterRunning; 174 ProcParams nextParams; 175 bool destroying; 176 void startProcessing (); 177 void process (); 178 bool highQualityComputed; 179 cmsHTRANSFORM customTransformIn; 180 cmsHTRANSFORM customTransformOut; 181 public: 182 183 ImProcCoordinator (); 184 ~ImProcCoordinator () override; 185 void assign (ImageSource* imgsrc); 186 getParams(procparams::ProcParams * dst)187 void getParams (procparams::ProcParams* dst) override 188 { 189 *dst = params; 190 } 191 192 void startProcessing (int changeCode) override; 193 ProcParams* beginUpdateParams () override; 194 void endUpdateParams (ProcEvent change) override; // must be called after beginUpdateParams, triggers update 195 void endUpdateParams (int changeFlags) override; 196 void stopProcessing () override; 197 198 setPreviewScale(int scale)199 void setPreviewScale (int scale) override 200 { 201 setScale (scale); 202 } getPreviewScale()203 int getPreviewScale () override 204 { 205 return scale; 206 } 207 208 //void fullUpdatePreviewImage (); 209 getFullWidth()210 int getFullWidth () override 211 { 212 return fullw; 213 } getFullHeight()214 int getFullHeight () override 215 { 216 return fullh; 217 } 218 getPreviewWidth()219 int getPreviewWidth () override 220 { 221 return pW; 222 } getPreviewHeight()223 int getPreviewHeight () override 224 { 225 return pH; 226 } 227 228 DetailedCrop* createCrop (::EditDataProvider *editDataProvider, bool isDetailWindow) override; 229 void setTweakOperator (TweakOperator *tOperator) override; 230 void unsetTweakOperator (TweakOperator *tOperator) override; 231 232 bool getAutoWB (double& temp, double& green, double equal) override; 233 void getCamWB (double& temp, double& green) override; 234 void getSpotWB (int x, int y, int rectSize, double& temp, double& green) override; 235 void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) override; 236 bool getFilmNegativeExponents(int xA, int yA, int xB, int yB, std::array<float, 3>& newExps) override; 237 bool getImageSpotValues(int x, int y, int spotSize, std::array<float, 3>& rawValues) override; 238 bool getHighQualComputed() override; 239 void setHighQualComputed() override; 240 void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent) override; 241 void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const override; 242 void setSoftProofing (bool softProof, bool gamutCheck) override; 243 void getSoftProofing (bool &softProof, bool &gamutCheck) override; 244 void setSharpMask (bool sharpMask) override; updateTryLock()245 bool updateTryLock () override 246 { 247 return updaterThreadStart.trylock(); 248 } updateUnLock()249 void updateUnLock () override 250 { 251 updaterThreadStart.unlock(); 252 } 253 setProgressListener(ProgressListener * pl)254 void setProgressListener (ProgressListener* pl) override 255 { 256 plistener = pl; 257 } setPreviewImageListener(PreviewImageListener * il)258 void setPreviewImageListener (PreviewImageListener* il) override 259 { 260 imageListener = il; 261 } setSizeListener(SizeListener * il)262 void setSizeListener (SizeListener* il) override 263 { 264 sizeListeners.push_back (il); 265 } delSizeListener(SizeListener * il)266 void delSizeListener (SizeListener* il) override 267 { 268 std::vector<SizeListener*>::iterator it = std::find (sizeListeners.begin(), sizeListeners.end(), il); 269 270 if (it != sizeListeners.end()) { 271 sizeListeners.erase (it); 272 } 273 } setAutoExpListener(AutoExpListener * ael)274 void setAutoExpListener (AutoExpListener* ael) override 275 { 276 aeListener = ael; 277 } setHistogramListener(HistogramListener * h)278 void setHistogramListener (HistogramListener *h) override 279 { 280 if (hListener) { 281 hListener->setObservable(nullptr); 282 } 283 hListener = h; 284 if (h) { 285 h->setObservable(this); 286 } 287 } setAutoWBListener(AutoWBListener * awb)288 void setAutoWBListener (AutoWBListener* awb) override 289 { 290 awbListener = awb; 291 } setAutoChromaListener(AutoChromaListener * adn)292 void setAutoChromaListener (AutoChromaListener* adn) override 293 { 294 adnListener = adn; 295 } 296 setFrameCountListener(FrameCountListener * fcl)297 void setFrameCountListener (FrameCountListener* fcl) override 298 { 299 frameCountListener = fcl; 300 } 301 setFlatFieldAutoClipListener(FlatFieldAutoClipListener * ffacl)302 void setFlatFieldAutoClipListener (FlatFieldAutoClipListener* ffacl) override 303 { 304 flatFieldAutoClipListener = ffacl; 305 } setBayerAutoContrastListener(AutoContrastListener * acl)306 void setBayerAutoContrastListener (AutoContrastListener* acl) override 307 { 308 bayerAutoContrastListener = acl; 309 } 310 setXtransAutoContrastListener(AutoContrastListener * acl)311 void setXtransAutoContrastListener (AutoContrastListener* acl) override 312 { 313 xtransAutoContrastListener = acl; 314 } 315 setImageTypeListener(ImageTypeListener * itl)316 void setImageTypeListener (ImageTypeListener* itl) override 317 { 318 imageTypeListener = itl; 319 } 320 setFilmNegListener(FilmNegListener * fnl)321 void setFilmNegListener(FilmNegListener* fnl) override 322 { 323 filmNegListener = fnl; 324 } 325 setAutoLogListener(AutoLogListener * l)326 void setAutoLogListener(AutoLogListener *l) override 327 { 328 autoLogListener = l; 329 } 330 setAutoDeconvRadiusListener(AutoDeconvRadiusListener * l)331 void setAutoDeconvRadiusListener(AutoDeconvRadiusListener *l) override 332 { 333 autoRadiusListener = l; 334 } 335 336 void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) override; 337 getInitialImage()338 InitialImage* getInitialImage () override 339 { 340 return imgsrc; 341 } 342 getCustomTransformIn()343 cmsHTRANSFORM& getCustomTransformIn () 344 { 345 return customTransformIn; 346 } 347 getCustomTransformOut()348 cmsHTRANSFORM& getCustomTransformOut () 349 { 350 return customTransformOut; 351 } 352 353 bool getDeltaELCH(EditUniqueID id, int x, int y, float &L, float &C, float &H) override; 354 355 ImProcFunctions::DenoiseInfoStore denoiseInfoStore; 356 357 void requestUpdateHistogram() override; 358 void requestUpdateHistogramRaw() override; 359 void requestUpdateVectorscopeHC() override; 360 void requestUpdateVectorscopeHS() override; 361 void requestUpdateWaveform() override; 362 }; 363 364 } // namespace rtengine 365