From 8883f45b7e59f41e346249f1c80c012af2d5b8ef Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 22 Mar 2018 18:31:37 +0100 Subject: [PATCH 1/8] pixelshift: bugfix for transitions and improvement for monochrome motion mask. fixes #4456 --- rtengine/pixelshift.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 511e4c95d..3d2ba39d5 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -382,11 +382,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA constexpr float greenWeight = 2.f; const bool blurMap = bayerParams.pixelShiftBlur; const float sigma = bayerParams.pixelShiftSigma; - constexpr float threshold = 3.f + 9.f; + constexpr float noMotion = 0.99f; + constexpr float threshold = 3.f + 9 * noMotion; const bool holeFill = bayerParams.pixelShiftHoleFill; const bool equalBrightness = bayerParams.pixelShiftEqualBright; const bool equalChannel = bayerParams.pixelShiftEqualBrightChannel; - const bool smoothTransitions = blurMap && bayerParams.pixelShiftSmoothFactor > 0. && !showOnlyMask; + const bool smoothTransitions = blurMap && bayerParams.pixelShiftSmoothFactor > 0.; const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; static const float nReadK3II[] = { 3.4f, // ISO 100 @@ -775,7 +776,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA unsigned int offset = FC(i, winx + border - offsX) & 1; for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { - psMask[i][j] = 1.f; + psMask[i][j] = noMotion; if(checkGreen) { if(greenDiff((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset], (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset], stddevFactorGreen, eperIsoGreen, nRead, prnu) > 0.f) { @@ -912,10 +913,14 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA unsigned int offset = FC(i, winx + border - offsX) & 1; for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { - if(mask[i][j] == 255) { + if(showOnlyMask) { + if(smoothTransitions) { // we want only motion mask => paint areas according to their motion (dark = no motion, bright = motion) + redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = psMask[i][j] * 32768.f; + } else { + redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = mask[i][j] == 255 ? 65535.f : 0.f; + } + } else if(mask[i][j] == 255) { paintMotionMask(j + offsX, showMotion, showOnlyMask, greenDest, redDest, blueDest); - } else if(showOnlyMask) { // we want only motion mask => paint areas without motion in pure black - redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = 0.f; } else { if(smoothTransitions) { #ifdef __SSE2__ From 15794cc1baab45a40c2f32453389849fceab349c Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 5 Apr 2018 14:41:02 +0200 Subject: [PATCH 2/8] First steps to extend dynamic profiles for Pixel Shift and HDR images --- rtdata/languages/default | 1 + rtengine/dynamicprofile.cc | 5 ++++- rtengine/dynamicprofile.h | 1 + rtengine/imagedata.cc | 9 +++++++++ rtengine/imagedata.h | 2 ++ rtengine/rtengine.h | 3 +++ rtgui/cacheimagedata.h | 1 + rtgui/dynamicprofilepanel.cc | 7 +++++++ rtgui/dynamicprofilepanel.h | 3 +++ 9 files changed, 31 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3621596f3..3c6313305 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -60,6 +60,7 @@ EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Lens EXIFFILTER_METADATAFILTER;Enable metadata filters EXIFFILTER_SHUTTER;Shutter +EXIFFILTER_RAWTYPE;Raw type EXIFPANEL_ADDEDIT;Add/Edit EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 1afc04446..fc8b952e4 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -80,7 +80,8 @@ bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const && shutterspeed (im->getShutterSpeed()) && expcomp (im->getExpComp()) && camera (im->getCamera()) - && lens (im->getLens())); + && lens (im->getLens()) + && rawType(im->getRawType(0))); } namespace @@ -208,6 +209,7 @@ bool DynamicProfileRules::loadRules() get_double_range (rule.expcomp, kf, group, "expcomp"); get_optional (rule.camera, kf, group, "camera"); get_optional (rule.lens, kf, group, "lens"); + get_optional (rule.rawType, kf, group, "rawtype"); try { rule.profilepath = kf.get_string (group, "profilepath"); @@ -240,6 +242,7 @@ bool DynamicProfileRules::storeRules() set_double_range (kf, group, "expcomp", rule.expcomp); set_optional (kf, group, "camera", rule.camera); set_optional (kf, group, "lens", rule.lens); + set_optional (kf, group, "rawtype", rule.rawType); kf.set_string (group, "profilepath", rule.profilepath); } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index 4e6bbbba9..2de3f422f 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -59,6 +59,7 @@ public: Range expcomp; Optional camera; Optional lens; + Optional rawType; Glib::ustring profilepath; }; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index eb213a8ea..78a762f2b 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -692,6 +692,10 @@ bool FrameData::getHDR () const { return isHDR; } +std::string FrameData::getRawType () const +{ + return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; +} IIOSampleFormat FrameData::getSampleFormat () const { return sampleFormat; @@ -808,6 +812,11 @@ bool FramesData::getHDR (unsigned int frame) const return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getHDR (); } +std::string FramesData::getRawType (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? "STD" : frames.at(0)->getRawType(); +} + IIOSampleFormat FramesData::getSampleFormat (unsigned int frame) const { return frames.empty() || frame >= frames.size() ? IIOSF_UNKNOWN : frames.at(frame)->getSampleFormat (); diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index b9f955611..3c8d3b657 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -63,6 +63,7 @@ public: bool getPixelShift () const; bool getHDR () const; + std::string getRawType () const; IIOSampleFormat getSampleFormat () const; rtexif::TagDirectory* getExifData () const; procparams::IPTCPairs getIPTCData () const; @@ -104,6 +105,7 @@ public: FrameData *getFrameData (unsigned int frame) const; bool getPixelShift (unsigned int frame = 0) const; bool getHDR (unsigned int frame = 0) const; + std::string getRawType (unsigned int frame) const; IIOSampleFormat getSampleFormat (unsigned int frame = 0) const; rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const; rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 687836c49..b86a2f98a 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -123,6 +123,9 @@ public: virtual bool getPixelShift (unsigned int frame = 0) const = 0; /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ virtual bool getHDR (unsigned int frame = 0) const = 0; + + /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ + virtual std::string getRawType (unsigned int frame) const = 0; /** @return the sample format based on MetaData */ virtual IIOSampleFormat getSampleFormat (unsigned int frame = 0) const = 0; diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 71541cdb8..9d177a05e 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -110,6 +110,7 @@ public: std::string getOrientation (unsigned int frame = 0) const { return ""; } // TODO bool getPixelShift (unsigned int frame = 0) const { return isPixelShift; } bool getHDR (unsigned int frame = 0) const { return isHDR; } + std::string getRawType (unsigned int frame) const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat (unsigned int frame = 0) const { return sampleFormat; } }; #endif diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index c8a8a1644..7f0ed5db7 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -41,6 +41,7 @@ DynamicProfilePanel::EditDialog::EditDialog (const Glib::ustring &title, Gtk::Wi add_optional (M ("EXIFFILTER_CAMERA"), has_camera_, camera_); add_optional (M ("EXIFFILTER_LENS"), has_lens_, lens_); + add_optional (M ("EXIFFILTER_RAWTYPE"), has_rawtype_, rawtype_); add_range (M ("EXIFFILTER_ISO"), iso_min_, iso_max_); add_range (M ("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_); @@ -81,6 +82,9 @@ void DynamicProfilePanel::EditDialog::set_rule ( has_lens_->set_active (rule.lens.enabled); lens_->set_text (rule.lens.value); + has_rawtype_->set_active (rule.rawType.enabled); + rawtype_->set_text (rule.rawType.value); + profilepath_->updateProfileList(); if (!profilepath_->setActiveRowFromFullPath (rule.profilepath)) { @@ -112,6 +116,9 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() ret.lens.enabled = has_lens_->get_active(); ret.lens.value = lens_->get_text(); + ret.rawType.enabled = has_rawtype_->get_active(); + ret.rawType.value = rawtype_->get_text(); + ret.profilepath = profilepath_->getFullPathFromActiveRow(); return ret; diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index dca62f1e6..26e816cb0 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -109,6 +109,9 @@ private: Gtk::CheckButton *has_lens_; Gtk::Entry *lens_; + Gtk::CheckButton *has_rawtype_; + Gtk::Entry *rawtype_; + ProfileStoreComboBox *profilepath_; }; From 4a1a10aab07916f8fe26d6930302f81d49acb3f8 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 14 Apr 2018 01:11:01 +0200 Subject: [PATCH 3/8] Pixel Shift: Improve motion mask and further changes --- rtdata/languages/default | 4 +- rtengine/LUT.h | 18 +- rtengine/dcrop.cc | 11 +- rtengine/dynamicprofile.cc | 6 +- rtengine/dynamicprofile.h | 2 +- rtengine/imagedata.cc | 20 +- rtengine/imagedata.h | 6 +- rtengine/improcfun.cc | 1348 +--------------------------------- rtengine/pixelshift.cc | 239 +++--- rtengine/procevents.h | 6 +- rtengine/procparams.cc | 31 +- rtengine/procparams.h | 2 +- rtengine/refreshmap.cc | 3 +- rtengine/rtengine.h | 4 +- rtengine/simpleprocess.cc | 19 +- rtexif/pentaxattribs.cc | 1 + rtgui/bayerprocess.cc | 377 ---------- rtgui/bayerprocess.h | 22 - rtgui/cacheimagedata.h | 4 +- rtgui/dynamicprofilepanel.cc | 28 +- rtgui/dynamicprofilepanel.h | 7 +- rtgui/paramsedited.cc | 8 +- rtgui/paramsedited.h | 1 - 23 files changed, 227 insertions(+), 1940 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3c6313305..10ac79acb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -56,11 +56,11 @@ EXIFFILTER_CAMERA;Camera EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) EXIFFILTER_FILETYPE;File type EXIFFILTER_FOCALLEN;Focal length +EXIFFILTER_IMAGETYPE;Image type EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Lens EXIFFILTER_METADATAFILTER;Enable metadata filters EXIFFILTER_SHUTTER;Shutter -EXIFFILTER_RAWTYPE;Raw type EXIFPANEL_ADDEDIT;Add/Edit EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value @@ -1816,8 +1816,6 @@ TP_RAW_PIXELSHIFTNONGREENCROSS2;Check green AMaZE TP_RAW_PIXELSHIFTNONGREENHORIZONTAL;Check red/blue horizontal TP_RAW_PIXELSHIFTNONGREENVERTICAL;Check red/blue vertical TP_RAW_PIXELSHIFTNREADISO;nRead -TP_RAW_PIXELSHIFTONEGREEN;Use one green instead of average -TP_RAW_PIXELSHIFTONEGREEN_TOOLTIP;Use one green instead of averaging two greens for regions without motion. TP_RAW_PIXELSHIFTPRNU;PRNU (%) TP_RAW_PIXELSHIFTREDBLUEWEIGHT;Red&Blue weight TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask diff --git a/rtengine/LUT.h b/rtengine/LUT.h index c0a63037a..15ae988e3 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -74,8 +74,9 @@ // Bit representations of flags enum { - LUT_CLIP_BELOW = 1 << 0, - LUT_CLIP_ABOVE = 1 << 1 + LUT_CLIP_OFF, // LUT does not clip input values + LUT_CLIP_BELOW, // LUT clips input values at lower bound + LUT_CLIP_ABOVE // LUT clips input values at upper bound }; template @@ -111,7 +112,7 @@ public: /// The user have to handle it itself, even if some method can (re)initialize it bool dirty; - LUT(int s, int flags = 0xfffffff) + LUT(int s, int flags = LUT_CLIP_BELOW | LUT_CLIP_ABOVE, bool initZero = false) { #ifndef NDEBUG @@ -137,8 +138,11 @@ public: sizeiv = _mm_set1_epi32( (int)(size - 1) ); sizev = F2V( size - 1 ); #endif + if (initZero) { + clear(); + } } - void operator ()(int s, int flags = 0xfffffff) + void operator ()(int s, int flags = LUT_CLIP_BELOW | LUT_CLIP_ABOVE, bool initZero = false) { #ifndef NDEBUG @@ -167,6 +171,10 @@ public: sizeiv = _mm_set1_epi32( (int)(size - 1) ); sizev = F2V( size - 1 ); #endif + if (initZero) { + clear(); + } + } LUT() @@ -616,7 +624,7 @@ public: } // share the buffer with another LUT, handy for same data but different clip flags - void share(const LUT &source, int flags = 0xfffffff) + void share(const LUT &source, int flags = LUT_CLIP_BELOW | LUT_CLIP_ABOVE) { if (owner && data) { delete[] data; diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 482b64a55..079a5de16 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1026,16 +1026,9 @@ void Crop::update (int todo) cieCrop = new CieImage (cropw, croph); } - if (settings->ciecamfloat) { - float d, dj, yb; // not used after this block - parent->ipf.ciecam_02float (cieCrop, float (adap), 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, + float d, dj, yb; // not used after this block + parent->ipf.ciecam_02float (cieCrop, float (adap), 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, skip, execsharp, d, dj, yb, 1); - } else { - double dd, dj; // not used after this block - - parent->ipf.ciecam_02 (cieCrop, adap, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, - dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, skip, execsharp, dd, dj, 1); - } } else { // CIECAM is disabled, we free up its image buffer to save some space if (cieCrop) { diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index fc8b952e4..7b7f2a517 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -81,7 +81,7 @@ bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const && expcomp (im->getExpComp()) && camera (im->getCamera()) && lens (im->getLens()) - && rawType(im->getRawType(0))); + && imagetype(im->getImageType(0))); } namespace @@ -209,7 +209,7 @@ bool DynamicProfileRules::loadRules() get_double_range (rule.expcomp, kf, group, "expcomp"); get_optional (rule.camera, kf, group, "camera"); get_optional (rule.lens, kf, group, "lens"); - get_optional (rule.rawType, kf, group, "rawtype"); + get_optional (rule.imagetype, kf, group, "imagetype"); try { rule.profilepath = kf.get_string (group, "profilepath"); @@ -242,7 +242,7 @@ bool DynamicProfileRules::storeRules() set_double_range (kf, group, "expcomp", rule.expcomp); set_optional (kf, group, "camera", rule.camera); set_optional (kf, group, "lens", rule.lens); - set_optional (kf, group, "rawtype", rule.rawType); + set_optional (kf, group, "imagetype", rule.imagetype); kf.set_string (group, "profilepath", rule.profilepath); } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index 2de3f422f..fc5c85e4c 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -59,7 +59,7 @@ public: Range expcomp; Optional camera; Optional lens; - Optional rawType; + Optional imagetype; Glib::ustring profilepath; }; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 78a762f2b..3920b3d90 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -506,7 +506,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* if (!isHDR) { const rtexif::Tag* const q = mnote->findTag("Quality"); - if (q && q->toInt() == 7) { + if (q && (q->toInt() == 7 || q->toInt() == 8)) { isPixelShift = true; #if PRINT_HDR_PS_DETECTION printf("PixelShift detected ! -> \"Quality\" = 7\n"); @@ -692,7 +692,7 @@ bool FrameData::getHDR () const { return isHDR; } -std::string FrameData::getRawType () const +std::string FrameData::getImageType () const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } @@ -791,30 +791,28 @@ FrameData *FramesData::getFrameData (unsigned int frame) const return frames.empty() || frame >= frames.size() ? nullptr : frames.at(frame); } -bool FramesData::getPixelShift (unsigned int frame) const +bool FramesData::getPixelShift () const { - // So far only Pentax and Sony provide multi-frame HDR file. - // Only the first frame contains the HDR tag + // So far only Pentax and Sony provide multi-frame Pixel Shift files. + // Only the first frame contains the Pixel Shift tag // If more brand have to be supported, this rule may need // to evolve - //return frames.at(frame)->getPixelShift (); - return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getPixelShift (); + return frames.empty() ? false : frames.at(0)->getPixelShift (); } bool FramesData::getHDR (unsigned int frame) const { - // So far only Pentax provide multi-frame HDR file. + // So far only Pentax provides multi-frame HDR file. // Only the first frame contains the HDR tag // If more brand have to be supported, this rule may need // to evolve - //return frames.at(frame)->getHDR (); return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getHDR (); } -std::string FramesData::getRawType (unsigned int frame) const +std::string FramesData::getImageType (unsigned int frame) const { - return frames.empty() || frame >= frames.size() ? "STD" : frames.at(0)->getRawType(); + return frames.empty() || frame >= frames.size() ? "STD" : frames.at(0)->getImageType(); } IIOSampleFormat FramesData::getSampleFormat (unsigned int frame) const diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 3c8d3b657..0427ee519 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -63,7 +63,7 @@ public: bool getPixelShift () const; bool getHDR () const; - std::string getRawType () const; + std::string getImageType () const; IIOSampleFormat getSampleFormat () const; rtexif::TagDirectory* getExifData () const; procparams::IPTCPairs getIPTCData () const; @@ -103,9 +103,9 @@ public: unsigned int getRootCount () const; unsigned int getFrameCount () const; FrameData *getFrameData (unsigned int frame) const; - bool getPixelShift (unsigned int frame = 0) const; + bool getPixelShift () const; bool getHDR (unsigned int frame = 0) const; - std::string getRawType (unsigned int frame) const; + std::string getImageType (unsigned int frame) const; IIOSampleFormat getSampleFormat (unsigned int frame = 0) const; rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const; rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index a49d00bdd..08fe8db0e 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -459,1294 +459,6 @@ void ImProcFunctions::firstAnalysis (const Imagefloat* const original, const Pro } } -// Copyright (c) 2012 Jacques Desmis -void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int pW, int pwb, LabImage* lab, const ProcParams* params, - const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2, const ColorAppearance & customColCurve3, - LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, double &d, double &dj, int rtt) -{ - if (params->colorappearance.enabled) { -//int lastskip; -//if(rtt==1) {lastskip=scale;} //not for Rtthumbnail - -#ifdef _DEBUG - MyTime t1e, t2e; - t1e.set(); -#endif - LUTf dLcurve; - LUTu hist16JCAM; - bool jp = false; - - //preparate for histograms CIECAM - if (pW != 1) { //only with improccoordinator - dLcurve (65536, 0); - dLcurve.clear(); - hist16JCAM (65536, 0); - hist16JCAM.clear(); - - for (int i = 0; i < 32768; i++) { //# 32768*1.414 approximation maxi for chroma - float val = (double)i / 32767.0; - dLcurve[i] = CLIPD (val); - } - } - - LUTf dCcurve; - LUTu hist16_CCAM; - bool chropC = false; - - if (pW != 1) { //only with improccoordinator - dCcurve (65536, 0); - hist16_CCAM (65536); - hist16_CCAM.clear(); - - for (int i = 0; i < 48000; i++) { //# 32768*1.414 approximation maxi for chroma - float valc = (double)i / 47999.0; - dCcurve[i] = CLIPD (valc); - } - } - - //end preparate histogram - int width = lab->W, height = lab->H; - float minQ = 10000.f; - float maxQ = -1000.f; - float a_w; - float c_; - float f_l; - double Yw; - Yw = 1.0; - double Xw, Zw; - double Xwout, Zwout; - double Xwsc, Zwsc; - - double f = 0., c = 0., nc = 0., yb = 0., la, xw, yw, zw, f2 = 0., c2 = 0., nc2 = 0., yb2 = 0., la2; - double fl, n, nbb, ncb, aw; - double xwd = 0., ywd, zwd = 0.; - double xws, yws, zws; - int alg = 0; - bool algepd = false; - float sum = 0.f; - - bool ciedata = params->colorappearance.datacie; - - ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB - ColorTemp::temp2mulxyz (params->colorappearance.tempout, "Custom", Xwout, Zwout); - ColorTemp::temp2mulxyz (params->colorappearance.tempsc, "Custom", Xwsc, Zwsc); - - //viewing condition for surrsrc - if (params->colorappearance.surrsrc == "Average") { - f = 1.00; - c = 0.69; - nc = 1.00; - } else if (params->colorappearance.surrsrc == "Dim") { - f = 0.9; - c = 0.59; - nc = 0.9; - } else if (params->colorappearance.surrsrc == "Dark") { - f = 0.8; - c = 0.525; - nc = 0.8; - } else if (params->colorappearance.surrsrc == "ExtremelyDark") { - f = 0.8; - c = 0.41; - nc = 0.8; - } - - - //viewing condition for surround - if (params->colorappearance.surround == "Average") { - f2 = 1.0, c2 = 0.69, nc2 = 1.0; - } else if (params->colorappearance.surround == "Dim") { - f2 = 0.9; - c2 = 0.59; - nc2 = 0.9; - } else if (params->colorappearance.surround == "Dark") { - f2 = 0.8; - c2 = 0.525; - nc2 = 0.8; - } else if (params->colorappearance.surround == "ExtremelyDark") { - f2 = 0.8; - c2 = 0.41; - nc2 = 0.8; - } - - /* - //scene condition for surround - if (params->colorappearance.surrsource) { - f = 0.85; // if user => source image has surround very dark - c = 0.55; - nc = 0.85; - } - */ - //with which algorithme - if (params->colorappearance.algo == "JC") { - alg = 0; - } else if (params->colorappearance.algo == "JS") { - alg = 1; - } else if (params->colorappearance.algo == "QM") { - alg = 2; - algepd = true; - } else if (params->colorappearance.algo == "ALL") { - alg = 3; - algepd = true; - } - - bool needJ = (alg == 0 || alg == 1 || alg == 3); - bool needQ = (alg == 2 || alg == 3); - /* - //settings white point of output device - or illuminant viewing - if (settings->viewingdevice == 0) { - xwd = 96.42; //5000K - ywd = 100.0; - zwd = 82.52; - } else if (settings->viewingdevice == 1) { - xwd = 95.68; //5500 - ywd = 100.0; - zwd = 92.15; - } else if (settings->viewingdevice == 2) { - xwd = 95.24; //6000 - ywd = 100.0; - zwd = 100.81; - } else if (settings->viewingdevice == 3) { - xwd = 95.04; //6500 - ywd = 100.0; - zwd = 108.88; - } else if (settings->viewingdevice == 4) { - xwd = 109.85; //tungsten - ywd = 100.0; - zwd = 35.58; - } else if (settings->viewingdevice == 5) { - xwd = 99.18; //fluo F2 - ywd = 100.0; - zwd = 67.39; - } else if (settings->viewingdevice == 6) { - xwd = 95.04; //fluo F7 - ywd = 100.0; - zwd = 108.75; - } else if (settings->viewingdevice == 7) { - xwd = 100.96; //fluo F11 - ywd = 100.0; - zwd = 64.35; - } - */ - - xwd = 100. * Xwout; - zwd = 100. * Zwout; - ywd = 100. / params->colorappearance.greenout;//approximation to simplify - - xws = 100. * Xwsc; - zws = 100. * Zwsc; - yws = 100. / params->colorappearance.greensc;//approximation to simplify - - /* - //settings mean Luminance Y of output device or viewing - if (settings->viewingdevicegrey == 0) { - yb2 = 5.0; - } else if (settings->viewingdevicegrey == 1) { - yb2 = 10.0; - } else if (settings->viewingdevicegrey == 2) { - yb2 = 15.0; - } else if (settings->viewingdevicegrey == 3) { - yb2 = 18.0; - } else if (settings->viewingdevicegrey == 4) { - yb2 = 23.0; - } else if (settings->viewingdevicegrey == 5) { - yb2 = 30.0; - } else if (settings->viewingdevicegrey == 6) { - yb2 = 40.0; - } - */ - yb2 = params->colorappearance.ybout; - - //La and la2 = ambiant luminosity scene and viewing - la = double (params->colorappearance.adapscen); - - if (pwb == 2) { - if (params->colorappearance.autoadapscen) { - la = adap; - } - } - - la2 = double (params->colorappearance.adaplum); - - // level of adaptation - double deg = (params->colorappearance.degree) / 100.0; - double pilot = params->colorappearance.autodegree ? 2.0 : deg; - - - const float degout = (params->colorappearance.degreeout) / 100.0; - const float pilotout = params->colorappearance.autodegreeout ? 2.0 : degout; - - //algoritm's params - float jli = params->colorappearance.jlight; - float chr = params->colorappearance.chroma; - float contra = params->colorappearance.contrast; - float qbri = params->colorappearance.qbright; - float schr = params->colorappearance.schroma; - float mchr = params->colorappearance.mchroma; - float qcontra = params->colorappearance.qcontrast; - float hue = params->colorappearance.colorh; - double rstprotection = 100. - params->colorappearance.rstprotection; - - if (schr > 0.0) { - schr = schr / 2.0f; //divide sensibility for saturation - } - - // extracting datas from 'params' to avoid cache flush (to be confirmed) - ColorAppearanceParams::TcMode curveMode = params->colorappearance.curveMode; - ColorAppearanceParams::TcMode curveMode2 = params->colorappearance.curveMode2; - bool hasColCurve1 = bool (customColCurve1); - bool hasColCurve2 = bool (customColCurve2); - ColorAppearanceParams::CtcMode curveMode3 = params->colorappearance.curveMode3; - bool hasColCurve3 = bool (customColCurve3); - - - if (CAMBrightCurveJ.dirty || CAMBrightCurveQ.dirty) { - LUTu hist16J; - LUTu hist16Q; - - if (needJ) { - hist16J (65536); - hist16J.clear(); - } - - if (needQ) { - hist16Q (65536); - hist16Q.clear(); - } - - float koef = 1.0f; //rough correspondence between L and J - - for (int i = 0; i < height; i++) - - // for (int i=begh; iL[i][j] / 327.68f; - - if (currL > 95.) { - koef = 1.f; - } else if (currL > 85.) { - koef = 0.97f; - } else if (currL > 80.) { - koef = 0.93f; - } else if (currL > 70.) { - koef = 0.87f; - } else if (currL > 60.) { - koef = 0.85f; - } else if (currL > 50.) { - koef = 0.8f; - } else if (currL > 40.) { - koef = 0.75f; - } else if (currL > 30.) { - koef = 0.7f; - } else if (currL > 20.) { - koef = 0.7f; - } else if (currL > 10.) { - koef = 0.9f; - } else if (currL > 0.) { - koef = 1.0f; - } - - if (needJ) { - hist16J[CLIP ((int) ((koef * lab->L[i][j])))]++; //evaluate histogram luminance L # J - } - - if (needQ) { - hist16Q[CLIP ((int) (32768.f * sqrt ((koef * (lab->L[i][j])) / 32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L - } - - sum += koef * lab->L[i][j]; //evaluate mean J to calculate Yb - } - - //mean=(sum/((endh-begh)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone - mean = (sum / ((height) * width)) / 327.68f; //for Yb for all image...if one day "pipette" we can adapt Yb for each zone - - //evaluate lightness, contrast - if (needJ) { - if (!CAMBrightCurveJ) { - CAMBrightCurveJ (65536, 0); - CAMBrightCurveJ.dirty = false; - } - - Ciecam02::curveJ (jli, contra, 1, CAMBrightCurveJ, hist16J);//lightness and contrast J - } - - if (needQ) { - if (!CAMBrightCurveQ) { - CAMBrightCurveQ (65536, 0); - CAMBrightCurveQ.dirty = false; - } - - Ciecam02::curveJ (qbri, qcontra, 1, CAMBrightCurveQ, hist16Q);//brightness and contrast Q - } - } - - // if (settings->viewinggreySc == 0) { //auto - if (params->colorappearance.autoybscen && pwb == 2) {//auto - - if (mean < 15.f) { - yb = 3.0; - } else if (mean < 30.f) { - yb = 5.0; - } else if (mean < 40.f) { - yb = 10.0; - } else if (mean < 45.f) { - yb = 15.0; - } else if (mean < 50.f) { - yb = 18.0; - } else if (mean < 55.f) { - yb = 23.0; - } else if (mean < 60.f) { - yb = 30.0; - } else if (mean < 70.f) { - yb = 40.0; - } else if (mean < 80.f) { - yb = 60.0; - } else if (mean < 90.f) { - yb = 80.0; - } else { - yb = 90.0; - } - } else { - yb = params->colorappearance.ybscen; - } - - if (settings->viewinggreySc == 1) { - yb = 18.0; - } - - int gamu = 0; - bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated - - if (params->colorappearance.gamut) { - gamu = 1; //enabled gamut control - } - - xw = 100.0 * Xw; - yw = 100.0 * Yw; - zw = 100.0 * Zw; - double xw1 = 0., yw1 = 0., zw1 = 0., xw2 = 0., yw2 = 0., zw2 = 0.; - - // settings of WB: scene and viewing - if (params->colorappearance.wbmodel == "RawT") { - xw1 = 96.46; //use RT WB; CAT 02 is used for output device (see prefreneces) - yw1 = 100.0; - zw1 = 82.445; - xw2 = xwd; - yw2 = ywd; - zw2 = zwd; - } else if (params->colorappearance.wbmodel == "RawTCAT02") { - xw1 = xw; // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences - yw1 = yw; - zw1 = zw; - xw2 = xwd; - yw2 = ywd; - zw2 = zwd; - } else if (params->colorappearance.wbmodel == "free") { - xw1 = xws; // free temp and green - yw1 = yws; - zw1 = zws; - xw2 = xwd; - yw2 = ywd; - zw2 = zwd; - } - - double cz, wh, pfl; - Ciecam02::initcam1 (gamu, yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c); - double nj, nbbj, ncbj, czj, awj, flj; - Ciecam02::initcam2 (gamu, yb2, pilotout, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj, czj, awj, flj); - - - - -#ifndef _DEBUG - #pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,nc2,f2,c2, alg,algepd, gamu, highlight, rstprotection, pW, scale) -#endif - { - //matrix for current working space - TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.working); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; - -#ifndef _DEBUG - #pragma omp for schedule(dynamic, 10) -#endif - - for (int i = 0; i < height; i++) - -// for (int i=begh; iL[i][j]; - float a = lab->a[i][j]; - float b = lab->b[i][j]; - float x1, y1, z1; - double x, y, z; - double epsil = 0.0001; - //convert Lab => XYZ - Color::Lab2XYZ (L, a, b, x1, y1, z1); - // double J, C, h, Q, M, s, aw, fl, wh; - double J, C, h, Q, M, s; - - double Jpro, Cpro, hpro, Qpro, Mpro, spro; - bool t1L = false; - bool t1B = false; - bool t2B = false; - int c1s = 0; - int c1co = 0; - //double n,nbb,ncb,pfl,cz,d; - x = (double)x1 / 655.35; - y = (double)y1 / 655.35; - z = (double)z1 / 655.35; - //process source==> normal - Ciecam02::xyz2jchqms_ciecam02 ( J, C, h, - Q, M, s, aw, fl, wh, - x, y, z, - xw1, yw1, zw1, - c, nc, gamu, n, nbb, ncb, pfl, cz, d ); - Jpro = J; - Cpro = C; - hpro = h; - Qpro = Q; - Mpro = M; - spro = s; - a_w = aw; - c_ = c; - f_l = fl; - - // we cannot have all algorithms with all chroma curves - if (alg == 1) { - // Lightness saturation - if (Jpro > 99.9f) { - Jpro = 99.9f; - } - - Jpro = (CAMBrightCurveJ[ (float) (Jpro * 327.68)]) / 327.68; //ligthness CIECAM02 + contrast - double sres; - double Sp = spro / 100.0; - double parsat = 1.5; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) - - if (schr == -100.0) { - schr = -99.8; - } - - Ciecam02::curvecolor (schr, Sp, sres, parsat); - double coe = pow (fl, 0.25); - float dred = 100.f; // in C mode - float protect_red = 80.0f; // in C mode - dred = 100.0 * sqrt ((dred * coe) / Qpro); - protect_red = 100.0 * sqrt ((protect_red * coe) / Qpro); - int sk = 0; - float ko = 100.f; - Color::skinred (Jpro, hpro, sres, Sp, dred, protect_red, sk, rstprotection, ko, spro); - Qpro = ( 4.0 / c ) * sqrt ( Jpro / 100.0 ) * ( aw + 4.0 ) ; - Cpro = (spro * spro * Qpro) / (10000.0); - } else if (alg == 3 || alg == 0 || alg == 2) { - double coef = 32760. / wh; - - if (alg == 3 || alg == 2) { - if (Qpro * coef > 32767.0f) { - Qpro = (CAMBrightCurveQ[ (float)32767.0f]) / coef; //brightness and contrast - } else { - Qpro = (CAMBrightCurveQ[ (float) (Qpro * coef)]) / coef; //brightness and contrast - } - } - - double Mp, sres; - double coe = pow (fl, 0.25); - Mp = Mpro / 100.0; - double parsat = 2.5; - - if (mchr == -100.0) { - mchr = -99.8 ; - } - - if (mchr == 100.0) { - mchr = 99.9; - } - - if (alg == 3 || alg == 2) { - Ciecam02::curvecolor (mchr, Mp, sres, parsat); - } else { - Ciecam02::curvecolor (0.0, Mp, sres, parsat); //colorfullness - } - - float dred = 100.f; //in C mode - float protect_red = 80.0f; // in C mode - dred *= coe; //in M mode - protect_red *= coe; //M mode - int sk = 0; - float ko = 100.f; - Color::skinred (Jpro, hpro, sres, Mp, dred, protect_red, sk, rstprotection, ko, Mpro); - Jpro = (100.0 * Qpro * Qpro) / (wh * wh); - Cpro = Mpro / coe; - spro = 100.0 * sqrt ( Mpro / Qpro ); - - if (alg != 2) { - if (Jpro > 99.9f) { - Jpro = 99.9f; - } - - Jpro = (CAMBrightCurveJ[ (float) (Jpro * 327.68f)]) / 327.68f; //ligthness CIECAM02 + contrast - } - - double Cp; - double Sp = spro / 100.0; - parsat = 1.5; - - if (schr == -100.0) { - schr = -99.; - } - - if (schr == 100.0) { - schr = 98.; - } - - if (alg == 3) { - Ciecam02::curvecolor (schr, Sp, sres, parsat); - } else { - Ciecam02::curvecolor (0.0, Sp, sres, parsat); //saturation - } - - dred = 100.f; // in C mode - protect_red = 80.0f; // in C mode - dred = 100.0 * sqrt ((dred * coe) / Q); - protect_red = 100.0 * sqrt ((protect_red * coe) / Q); - sk = 0; - Color::skinred (Jpro, hpro, sres, Sp, dred, protect_red, sk, rstprotection, ko, spro); - //double Q1; - Qpro = ( 4.0 / c ) * sqrt ( Jpro / 100.0 ) * ( aw + 4.0 ) ; - Cpro = (spro * spro * Qpro) / (10000.0); - Cp = Cpro / 100.0; - parsat = 1.8; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation : for not) - - if (chr == -100.0) { - chr = -99.8; - } - - if (alg != 2) { - Ciecam02::curvecolor (chr, Cp, sres, parsat); - } else { - Ciecam02::curvecolor (0.0, Cp, sres, parsat); //chroma - } - - dred = 55.f; - protect_red = 30.0f; - sk = 1; - Color::skinred (Jpro, hpro, sres, Cp, dred, protect_red, sk, rstprotection, ko, Cpro); - - if (Jpro < 1. && Cpro > 12.) { - Cpro = 12.; //reduce artifacts by "pseudo gamut control CIECAM" - } else if (Jpro < 2. && Cpro > 15.) { - Cpro = 15.; - } else if (Jpro < 4. && Cpro > 30.) { - Cpro = 30.; - } else if (Jpro < 7. && Cpro > 50.) { - Cpro = 50.; - } - - hpro = hpro + hue; - - if ( hpro < 0.0 ) { - hpro += 360.0; //hue - } - } - - if (hasColCurve1) {//curve 1 with Lightness and Brightness - if (curveMode == ColorAppearanceParams::TcMode::LIGHT) { - /* float Jj=(float) Jpro*327.68; - float Jold=Jj; - const Lightcurve& userColCurve = static_cast(customColCurve1); - userColCurve.Apply(Jj); - Jj=0.7f*(Jj-Jold)+Jold;//divide sensibility - */ - float Jj = (float) Jpro * 327.68f; - float Jold = Jj; - float Jold100 = (float) Jpro; - float redu = 25.f; - float reduc = 1.f; - const Lightcurve& userColCurveJ1 = static_cast (customColCurve1); - userColCurveJ1.Apply (Jj); - - if (Jj > Jold) { - if (Jj < 65535.f) { - if (Jold < 327.68f * redu) { - Jj = 0.3f * (Jj - Jold) + Jold; //divide sensibility - } else { - reduc = LIM ((100.f - Jold100) / (100.f - redu), 0.f, 1.f); - Jj = 0.3f * reduc * (Jj - Jold) + Jold; //reduct sensibility in highlights - } - } - } else if (Jj > 10.f) { - Jj = 0.8f * (Jj - Jold) + Jold; - } else if (Jj >= 0.f) { - Jj = 0.90f * (Jj - Jold) + Jold; // not zero ==>artifacts - } - - - Jpro = (double) (Jj / 327.68f); - - if (Jpro < 1.) { - Jpro = 1.; - } - - t1L = true; - } else if (curveMode == ColorAppearanceParams::TcMode::BRIGHT) { - //attention! Brightness curves are open - unlike Lightness or Lab or RGB==> rendering and algorithms will be different - float coef = ((aw + 4.f) * (4.f / c)) / 100.f; - float Qanc = Qpro; - float Qq = (float) Qpro * 327.68f * (1.f / coef); - float Qold100 = (float) Qpro / coef; - - float Qold = Qq; - float redu = 20.f; - float reduc = 1.f; - - const Brightcurve& userColCurveB1 = static_cast (customColCurve1); - userColCurveB1.Apply (Qq); - - if (Qq > Qold) { - if (Qq < 65535.f) { - if (Qold < 327.68f * redu) { - Qq = 0.25f * (Qq - Qold) + Qold; //divide sensibility - } else { - reduc = LIM ((100.f - Qold100) / (100.f - redu), 0.f, 1.f); - Qq = 0.25f * reduc * (Qq - Qold) + Qold; //reduct sensibility in highlights - } - } - } else if (Qq > 10.f) { - Qq = 0.5f * (Qq - Qold) + Qold; - } else if (Qq >= 0.f) { - Qq = 0.7f * (Qq - Qold) + Qold; // not zero ==>artifacts - } - - if (Qold == 0.f) { - Qold = 0.001f; - } - - Qpro = Qanc * (Qq / Qold); - Jpro = Jpro * SQR (Qq / Qold); - -// Qpro = (double) (Qq * (coef) / 327.68f); -// Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); - t1B = true; - - if (Jpro < 1.) { - Jpro = 1.; - } - - } - } - - if (hasColCurve2) {//curve 2 with Lightness and Brightness - if (curveMode2 == ColorAppearanceParams::TcMode::LIGHT) { - float Jj = (float) Jpro * 327.68; - float Jold = Jj; - /* - const Lightcurve& userColCurve = static_cast(customColCurve2); - userColCurve.Apply(Jj); - Jj=0.7f*(Jj-Jold)+Jold;//divide sensibility - */ - float Jold100 = (float) Jpro; - float redu = 25.f; - float reduc = 1.f; - const Lightcurve& userColCurveJ2 = static_cast (customColCurve2); - userColCurveJ2.Apply (Jj); - - if (Jj > Jold) { - if (Jj < 65535.f) { - if (Jold < 327.68f * redu) { - Jj = 0.3f * (Jj - Jold) + Jold; //divide sensibility - } else { - reduc = LIM ((100.f - Jold100) / (100.f - redu), 0.f, 1.f); - Jj = 0.3f * reduc * (Jj - Jold) + Jold; //reduct sensibility in highlights - } - } - } else if (Jj > 10.f) { - if (!t1L) { - Jj = 0.8f * (Jj - Jold) + Jold; - } else { - Jj = 0.4f * (Jj - Jold) + Jold; - } - } else if (Jj >= 0.f) { - if (!t1L) { - Jj = 0.90f * (Jj - Jold) + Jold; // not zero ==>artifacts - } else { - Jj = 0.5f * (Jj - Jold) + Jold; - } - } - - Jpro = (double) (Jj / 327.68f); - - if (Jpro < 1.) { - Jpro = 1.; - } - - } else if (curveMode2 == ColorAppearanceParams::TcMode::BRIGHT) { // - float Qanc = Qpro; - float coef = ((aw + 4.f) * (4.f / c)) / 100.f; - float Qq = (float) Qpro * 327.68f * (1.f / coef); - float Qold100 = (float) Qpro / coef; - - float Qold = Qq; - float redu = 20.f; - float reduc = 1.f; - - const Brightcurve& userColCurveB2 = static_cast (customColCurve2); - userColCurveB2.Apply (Qq); - - if (Qq > Qold) { - if (Qq < 65535.f) { - if (Qold < 327.68f * redu) { - Qq = 0.25f * (Qq - Qold) + Qold; //divide sensibility - } else { - reduc = LIM ((100.f - Qold100) / (100.f - redu), 0.f, 1.f); - Qq = 0.25f * reduc * (Qq - Qold) + Qold; //reduct sensibility in highlights - } - } - } else if (Qq > 10.f) { - Qq = 0.5f * (Qq - Qold) + Qold; - } else if (Qq >= 0.f) { - Qq = 0.7f * (Qq - Qold) + Qold; // not zero ==>artifacts - } - - if (Qold == 0.f) { - Qold = 0.001f; - } - - // Qpro = (float) (Qq * (coef) / 327.68f); - Qpro = Qanc * (Qq / Qold); - Jpro = Jpro * SQR (Qq / Qold); - - // Qpro = (double) (Qq * (coef) / 327.68f); - // Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); - t2B = true; - - if (t1L) { //to workaround the problem if we modify curve1-lightnees after curve2 brightness(the cat that bites its own tail!) in fact it's another type of curve only for this case - coef = 2.f; //adapt Q to J approximation - Qq = (float) Qpro * coef; - Qold = Qq; - const Lightcurve& userColCurveJ1 = static_cast (customColCurve1); - userColCurveJ1.Apply (Qq); - Qq = 0.1f * (Qq - Qold) + Qold; //approximative adaptation - Qpro = (double) (Qq / coef); - Jpro = 100.* (Qpro * Qpro) / ((4.0 / c) * (4.0 / c) * (aw + 4.0) * (aw + 4.0)); - } - - if (Jpro < 1.) { - Jpro = 1.; - } - } - } - - if (hasColCurve3) {//curve 3 with chroma saturation colorfullness - if (curveMode3 == ColorAppearanceParams::CtcMode::CHROMA) { - double parsat = 0.8; //0.68; - double coef = 327.68 / parsat; - float Cc = (float) Cpro * coef; - float Ccold = Cc; - const Chromacurve& userColCurve = static_cast (customColCurve3); - userColCurve.Apply (Cc); - float dred = 55.f; - float protect_red = 30.0f; - float sk = 1; - float ko = 1.f / coef; - Color::skinred (Jpro, hpro, Cc, Ccold, dred, protect_red, sk, rstprotection, ko, Cpro); - - if (Jpro < 1. && Cpro > 12.) { - Cpro = 12.; //reduce artifacts by "pseudo gamut control CIECAM" - } else if (Jpro < 2. && Cpro > 15.) { - Cpro = 15.; - } else if (Jpro < 4. && Cpro > 30.) { - Cpro = 30.; - } else if (Jpro < 7. && Cpro > 50.) { - Cpro = 50.; - } - - // Cpro=Cc/coef; - } else if (curveMode3 == ColorAppearanceParams::CtcMode::SATUR) { // - double parsat = 0.8; //0.6 - double coef = 327.68 / parsat; - float Ss = (float) spro * coef; - float Sold = Ss; - const Saturcurve& userColCurve = static_cast (customColCurve3); - userColCurve.Apply (Ss); - Ss = 0.6f * (Ss - Sold) + Sold; //divide sensibility saturation - double coe = pow (fl, 0.25); - float dred = 100.f; // in C mode - float protect_red = 80.0f; // in C mode - dred = 100.0 * sqrt ((dred * coe) / Qpro); - protect_red = 100.0 * sqrt ((protect_red * coe) / Qpro); - int sk = 0; - float ko = 1.f / coef; - Color::skinred (Jpro, hpro, Ss, Sold, dred, protect_red, sk, rstprotection, ko, spro); - Qpro = ( 4.0 / c ) * sqrt ( Jpro / 100.0 ) * ( aw + 4.0 ) ; - Cpro = (spro * spro * Qpro) / (10000.0); - c1s = 1; - - } else if (curveMode3 == ColorAppearanceParams::CtcMode::COLORF) { // - double parsat = 0.8; //0.68; - double coef = 327.68 / parsat; - float Mm = (float) Mpro * coef; - float Mold = Mm; - const Colorfcurve& userColCurve = static_cast (customColCurve3); - userColCurve.Apply (Mm); - double coe = pow (fl, 0.25); - float dred = 100.f; //in C mode - float protect_red = 80.0f; // in C mode - dred *= coe; //in M mode - protect_red *= coe; - int sk = 0; - float ko = 1.f / coef; - Color::skinred (Jpro, hpro, Mm, Mold, dred, protect_red, sk, rstprotection, ko, Mpro); - Cpro = Mpro / coe; - - if (Jpro < 1. && Mpro > 12.*coe) { - Mpro = 12.*coe; //reduce artifacts by "pseudo gamut control CIECAM" - } else if (Jpro < 2. && Mpro > 15.*coe) { - Mpro = 15.*coe; - } else if (Jpro < 4. && Mpro > 30.*coe) { - Mpro = 30.*coe; - } else if (Jpro < 7. && Mpro > 50.*coe) { - Mpro = 50.*coe; - } - - - c1co = 1; - } - } - - //to retrieve the correct values of variables - if (t2B && t1B) { - Jpro = (100.0 * Qpro * Qpro) / (wh * wh); // for brightness curve - } - - if (c1s == 1) { - Qpro = ( 4.0 / c ) * sqrt ( Jpro / 100.0 ) * ( aw + 4.0 ) ; //for saturation curve - Cpro = (spro * spro * Qpro) / (10000.0); - } - - if (c1co == 1) { - double coe = pow (fl, 0.25); // for colorfullness curve - Cpro = Mpro / coe; - } - - //retrieve values C,J...s - C = Cpro; - J = Jpro; - Q = Qpro; - M = Mpro; - h = hpro; - s = spro; - - if (params->colorappearance.tonecie || settings->autocielab) { //use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail - // if(params->colorappearance.tonecie || params->colorappearance.sharpcie){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail - float Qred = ( 4.0 / c) * ( aw + 4.0 ); //estimate Q max if J=100.0 - ncie->Q_p[i][j] = (float)Q + epsil; //epsil to avoid Q=0 - ncie->M_p[i][j] = (float)M + epsil; - ncie->J_p[i][j] = (float)J + epsil; - ncie->h_p[i][j] = (float)h; - ncie->C_p[i][j] = (float)C + epsil; - // ncie->s_p[i][j]=(float)s; - ncie->sh_p[i][j] = (float) 32768.* (( 4.0 / c ) * sqrt ( J / 100.0 ) * ( aw + 4.0 )) / Qred ; - - // ncie->ch_p[i][j]=(float) 327.68*C; - if (ncie->Q_p[i][j] < minQ) { - minQ = ncie->Q_p[i][j]; //minima - } - - if (ncie->Q_p[i][j] > maxQ) { - maxQ = ncie->Q_p[i][j]; //maxima - } - } - - if (!params->colorappearance.tonecie || !settings->autocielab || !params->epd.enabled ) { - -// if(!params->epd.enabled || !params->colorappearance.tonecie || !settings->autocielab){ - // if(!params->epd.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){ - double brli = 327.; - double chsacol = 327.; - int libr = 0; - int colch = 0; - - if (curveMode == ColorAppearanceParams::TcMode::BRIGHT) { - brli = 70.0; - libr = 1; - } else if (curveMode == ColorAppearanceParams::TcMode::LIGHT) { - brli = 327.; - libr = 0; - } - - if (curveMode3 == ColorAppearanceParams::CtcMode::CHROMA) { - chsacol = 400.;//327.; - colch = 0; - } else if (curveMode3 == ColorAppearanceParams::CtcMode::SATUR) { - chsacol = 450.0; - colch = 1; - } else if (curveMode3 == ColorAppearanceParams::CtcMode::COLORF) { - chsacol = 400.;//327.0; - colch = 2; - } - - if (ciedata) { - // Data for J Q M s and C histograms - //update histogram - jp = true; - - if (pW != 1) { //only with improccoordinator - int posl; - - if (libr == 1) { - posl = CLIP ((int) (Q * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J - } else { /*if(libr == 0)*/ - posl = CLIP ((int) (J * brli)); //327 for J - } - - hist16JCAM[posl]++; - } - - chropC = true; - - if (pW != 1) { //only with improccoordinator - int posc; - - if (colch == 0) { - posc = CLIP ((int) (C * chsacol)); //450.0 approximative factor for s 320 for M - } else if (colch == 1) { - posc = CLIP ((int) (s * chsacol)); - } else { /*if(colch == 2)*/ - posc = CLIP ((int) (M * chsacol)); - } - - hist16_CCAM[posc]++; - } - } - - double xx, yy, zz; - //double nj, nbbj, ncbj, flj, czj, dj, awj; - //process normal==> viewing - Ciecam02::jch2xyz_ciecam02 ( xx, yy, zz, - J, C, h, - xw2, yw2, zw2, - c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj); - x = (float)xx * 655.35; - y = (float)yy * 655.35; - z = (float)zz * 655.35; - float Ll, aa, bb; - //convert xyz=>lab - Color::XYZ2Lab (x, y, z, Ll, aa, bb); - lab->L[i][j] = Ll; - lab->a[i][j] = aa; - lab->b[i][j] = bb; - - // gamut control in Lab mode; I must study how to do with cIECAM only - if (gamu == 1) { - float R, G, B; - float HH, Lprov1, Chprov1; - Lprov1 = lab->L[i][j] / 327.68f; - Chprov1 = sqrt (SQR (lab->a[i][j] / 327.68f) + SQR (lab->b[i][j] / 327.68f)); - HH = atan2 (lab->b[i][j], lab->a[i][j]); - -#ifdef _DEBUG - bool neg = false; - bool more_rgb = false; - //gamut control : Lab values are in gamut - Color::gamutLchonly (HH, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); -#else - //gamut control : Lab values are in gamut - Color::gamutLchonly (HH, Lprov1, Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); -#endif - - lab->L[i][j] = Lprov1 * 327.68f; - lab->a[i][j] = 327.68f * Chprov1 * cos (HH); - lab->b[i][j] = 327.68f * Chprov1 * sin (HH); - - } - } - } - } - - // End of parallelization - if (!params->epd.enabled || !params->colorappearance.tonecie || !settings->autocielab) { //normal -//if(!params->epd.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){//normal - - if (ciedata) { - //update histogram J - if (pW != 1) { //only with improccoordinator - for (int i = 0; i < 32768; i++) { // - if (jp) { - float hval = dLcurve[i]; - int hi = (int) (255.0 * CLIPD (hval)); // - histLCAM[hi] += hist16JCAM[i] ; - } - } - } - - if (pW != 1) { //only with improccoordinator - for (int i = 0; i < 48000; i++) { // - if (chropC) { - float hvalc = dCcurve[i]; - int hic = (int) (255.0 * CLIPD (hvalc)); // - histCCAM[hic] += hist16_CCAM[i] ; - } - } - } - } - } - -#ifdef _DEBUG - - if (settings->verbose) { - t2e.set(); - printf ("CIECAM02 performed in %d usec:\n", t2e.etime (t1e)); - // printf("minc=%f maxc=%f minj=%f maxj=%f\n",minc,maxc,minj,maxj); - } - -#endif - - if (settings->autocielab) { -//if(params->colorappearance.sharpcie) { - -//all this treatments reduce artifacts, but can lead to slightly different results - if (params->defringe.enabled) if (execsharp) { - ImProcFunctions::defringecam (ncie); // - } - -//if(params->dirpyrequalizer.enabled) if(execsharp) { - if (params->dirpyrequalizer.enabled && params->dirpyrequalizer.gamutlab && rtt) { //remove artifacts by gaussian blur - skin control, but not for thumbs - constexpr float artifact = 4.f; - constexpr float chrom = 50.f; - const bool hotbad = params->dirpyrequalizer.skinprotect != 0.0; - ImProcFunctions::badpixcam (ncie, artifact / scale, 5, 2, chrom, hotbad); //enabled remove artifacts for cbDL - } - - if (params->colorappearance.badpixsl > 0 && execsharp) { - int mode = params->colorappearance.badpixsl; - ImProcFunctions::badpixcam (ncie, 3.4, 5, mode, 0, true);//for bad pixels CIECAM - } - - if (params->sharpenMicro.enabled)if (execsharp) { - ImProcFunctions::MLmicrocontrastcam (ncie); - } - - if (params->sharpening.enabled) - if (execsharp) { - float **buffer = lab->L; // We can use the L-buffer from lab as buffer to save some memory - ImProcFunctions::sharpeningcam (ncie, buffer); // sharpening adapted to CIECAM - } - -//if(params->dirpyrequalizer.enabled) if(execsharp) { - if (params->dirpyrequalizer.enabled /*&& (execsharp)*/) { - -// if (params->dirpyrequalizer.algo=="FI") choice=0; -// else if(params->dirpyrequalizer.algo=="LA") choice=1; - if (rtt == 1) { - float b_l = static_cast (params->dirpyrequalizer.hueskin.getBottomLeft()) / 100.0f; - float t_l = static_cast (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f; - float t_r = static_cast (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f; - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM - } - } - - float Qredi = ( 4.0 / c_) * ( a_w + 4.0 ); - float co_e = (pow (f_l, 0.25f)); - -#ifndef _DEBUG - #pragma omp parallel default(shared) firstprivate(height,width, Qredi,a_w,c_) -#endif - { -#ifndef _DEBUG - #pragma omp for schedule(dynamic, 10) -#endif - - for (int i = 0; i < height; i++) // update CieImages with new values after sharpening, defringe, contrast by detail level - for (int j = 0; j < width; j++) { - float interm = Qredi * ncie->sh_p[i][j] / (32768.f); - ncie->J_p[i][j] = 100.0 * interm * interm / ((a_w + 4.) * (a_w + 4.) * (4. / c_) * (4. / c_)); - ncie->Q_p[i][j] = ( 4.0 / c_) * ( a_w + 4.0 ) * sqrt (ncie->J_p[i][j] / 100.f); - ncie->M_p[i][j] = ncie->C_p[i][j] * co_e; - } - } - } - - if ((params->colorappearance.tonecie || (params->colorappearance.tonecie && params->epd.enabled)) || (params->sharpening.enabled && settings->autocielab) - || (params->dirpyrequalizer.enabled && settings->autocielab) || (params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) - || (params->colorappearance.badpixsl > 0 && settings->autocielab)) { - - if (params->epd.enabled && params->colorappearance.tonecie && algepd) { - ImProcFunctions::EPDToneMapCIE (ncie, a_w, c_, width, height, minQ, maxQ, Iterates, scale ); - } - - //EPDToneMapCIE adapted to CIECAM - - -#ifndef _DEBUG - #pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width, nc2,f2,c2, gamu, highlight,pW) -#endif - { - TMatrix wiprofa = ICCStore::getInstance()->workingSpaceInverseMatrix (params->icm.working); - double wipa[3][3] = { - {wiprofa[0][0], wiprofa[0][1], wiprofa[0][2]}, - {wiprofa[1][0], wiprofa[1][1], wiprofa[1][2]}, - {wiprofa[2][0], wiprofa[2][1], wiprofa[2][2]} - }; - - -#ifndef _DEBUG - #pragma omp for schedule(dynamic, 10) -#endif - - for (int i = 0; i < height; i++) // update CIECAM with new values after tone-mapping - - // for (int i=begh; iepd.enabled) ncie->J_p[i][j]=(100.0* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h); - if (params->epd.enabled) { - ncie->J_p[i][j] = (100.0 * ncie->Q_p[i][j] * ncie->Q_p[i][j]) / SQR ((4. / c) * (aw + 4.)); - } - - ncie->C_p[i][j] = (ncie->M_p[i][j]) / co_e; - //show histogram in CIECAM mode (Q,J, M,s,C) - double brli = 327.; - double chsacol = 327.; - int libr = 0; - int colch = 0; - - if (curveMode == ColorAppearanceParams::TcMode::BRIGHT) { - brli = 70.0; - libr = 1; - } else if (curveMode == ColorAppearanceParams::TcMode::LIGHT) { - brli = 327.; - libr = 0; - } - - if (curveMode3 == ColorAppearanceParams::CtcMode::CHROMA) { - chsacol = 400.;//327.; - colch = 0; - } else if (curveMode3 == ColorAppearanceParams::CtcMode::SATUR) { - chsacol = 450.0; - colch = 1; - } else if (curveMode3 == ColorAppearanceParams::CtcMode::COLORF) { - chsacol = 400.;//327.0; - colch = 2; - } - - if (ciedata) { - // Data for J Q M s and C histograms - //update histogram - jp = true; - - if (pW != 1) { //only with improccoordinator - int posl; - - if (libr == 1) { - posl = CLIP ((int) (ncie->Q_p[i][j] * brli)); //40.0 to 100.0 approximative factor for Q - 327 for J - } else { /*if(libr == 0)*/ - posl = CLIP ((int) (ncie->J_p[i][j] * brli)); //327 for J - } - - hist16JCAM[posl]++; - } - - chropC = true; - - if (pW != 1) { //only with improccoordinator - int posc; - - if (colch == 0) { - posc = CLIP ((int) (ncie->C_p[i][j] * chsacol)); //450.0 approximative factor for s 320 for M - } else if (colch == 1) { - float sa_t = 100.f * sqrt (ncie->C_p[i][j] / ncie->Q_p[i][j]); //Q_p always > 0 - posc = CLIP ((int) (sa_t * chsacol)); - } else { /*if(colch == 2)*/ - posc = CLIP ((int) (ncie->M_p[i][j] * chsacol)); - } - - hist16_CCAM[posc]++; - } - } - - //end histograms - // double nd, nbbd, ncbd, fld, czd, dd, awd; - Ciecam02::jch2xyz_ciecam02 ( xx, yy, zz, - ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j], - xw2, yw2, zw2, - c2, nc2, gamu, nj, nbbj, ncbj, flj, czj, dj, awj); - x = (float)xx * 655.35; - y = (float)yy * 655.35; - z = (float)zz * 655.35; - float Ll, aa, bb; - //convert xyz=>lab - Color::XYZ2Lab (x, y, z, Ll, aa, bb); - lab->L[i][j] = Ll; - lab->a[i][j] = aa; - lab->b[i][j] = bb; - - if (gamu == 1) { - float R, G, B; - float HH, Lprov1, Chprov1; - Lprov1 = lab->L[i][j] / 327.68f; - Chprov1 = sqrt (SQR (lab->a[i][j] / 327.68f) + SQR (lab->b[i][j] / 327.68f)); - HH = atan2 (lab->b[i][j], lab->a[i][j]); - -#ifdef _DEBUG - bool neg = false; - bool more_rgb = false; - //gamut control : Lab values are in gamut - Color::gamutLchonly (HH, Lprov1, Chprov1, R, G, B, wipa, highlight, 0.15f, 0.96f, neg, more_rgb); -#else - //gamut control : Lab values are in gamut - Color::gamutLchonly (HH, Lprov1, Chprov1, R, G, B, wipa, highlight, 0.15f, 0.96f); -#endif - - lab->L[i][j] = Lprov1 * 327.68f; - lab->a[i][j] = 327.68f * Chprov1 * cos (HH); - lab->b[i][j] = 327.68f * Chprov1 * sin (HH); - } - } - - - } - - //end parallelization - //show CIECAM histograms - if (ciedata) { - //update histogram J and Q - if (pW != 1) { //only with improccoordinator - for (int i = 0; i < 32768; i++) { // - if (jp) { - float hval = dLcurve[i]; - int hi = (int) (255.0 * CLIPD (hval)); // - histLCAM[hi] += hist16JCAM[i] ; - } - } - } - - //update color histogram M,s,C - if (pW != 1) { //only with improccoordinator - for (int i = 0; i < 48000; i++) { // - if (chropC) { - float hvalc = dCcurve[i]; - int hic = (int) (255.0 * CLIPD (hvalc)); // - histCCAM[hic] += hist16_CCAM[i] ; - } - } - } - } - - } - - } -} -//end CIECAM - - // Copyright (c) 2012 Jacques Desmis void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2, const ColorAppearance & customColCurve3, @@ -3750,22 +2462,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } } - for (int i = istart, ti = 0; i < tH; i++, ti++) { - for (int j = jstart, tj = 0; j < tW; j++, tj++) { - // clip out of gamut colors, without distorting colour too bad - float r = std::max(rtemp[ti * TS + tj], 0.f); - float g = std::max(gtemp[ti * TS + tj], 0.f); - float b = std::max(btemp[ti * TS + tj], 0.f); - - if (OOG(r) || OOG(g) || OOG(b)) { - filmlike_clip (&r, &g, &b); - } - rtemp[ti * TS + tj] = r; - gtemp[ti * TS + tj] = g; - btemp[ti * TS + tj] = b; - } - } - highlightToneCurve(hltonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS, exp_scale, comp, hlrange); shadowToneCurve(shtonecurve, rtemp, gtemp, btemp, istart, tH, jstart, tW, TS); @@ -3773,21 +2469,37 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer dcpProf->step2ApplyTile (rtemp, gtemp, btemp, tW - jstart, tH - istart, TS, asIn); } - // for (int i = istart, ti = 0; i < tH; i++, ti++) { - // for (int j = jstart, tj = 0; j < tW; j++, tj++) { - // // clip out of gamut colors, without distorting colour too bad - // float r = std::max(rtemp[ti * TS + tj], 0.f); - // float g = std::max(gtemp[ti * TS + tj], 0.f); - // float b = std::max(btemp[ti * TS + tj], 0.f); + if (params->toneCurve.clampOOG) { + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + // clip out of gamut colors, without distorting colour too bad + float r = std::max(rtemp[ti * TS + tj], 0.f); + float g = std::max(gtemp[ti * TS + tj], 0.f); + float b = std::max(btemp[ti * TS + tj], 0.f); - // if (OOG(r) || OOG(g) || OOG(b)) { - // filmlike_clip (&r, &g, &b); - // } - // rtemp[ti * TS + tj] = r; - // gtemp[ti * TS + tj] = g; - // btemp[ti * TS + tj] = b; - // } - // } + if (OOG(r) || OOG(g) || OOG(b)) { + filmlike_clip(&r, &g, &b); + } + rtemp[ti * TS + tj] = r; + gtemp[ti * TS + tj] = g; + btemp[ti * TS + tj] = b; + } + } + } else { + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + // clip out of gamut colors, without distorting colour too bad + float r = std::max(rtemp[ti * TS + tj], 0.f); + float g = std::max(gtemp[ti * TS + tj], 0.f); + float b = std::max(btemp[ti * TS + tj], 0.f); + + if (OOG(max(r, g, b)) && !OOG(min(r, g, b))) { + filmlike_clip(&r, &g, &b); + } + setUnlessOOG(rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], r, g, b); + } + } + } if (histToneCurveThr) { for (int i = istart, ti = 0; i < tH; i++, ti++) { diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 3d2ba39d5..9b13597a0 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -2,7 +2,7 @@ // // Algorithm for Pentax/Sony Pixel Shift raw files with motion detection // -// Copyright (C) 2016 - 2017 Ingo Weyrich +// Copyright (C) 2016 - 2018 Ingo Weyrich // // // pixelshift.cc is free software: you can redistribute it and/or modify @@ -26,7 +26,8 @@ #include "procparams.h" #include "gauss.h" #include "median.h" - +#define BENCHMARK +#include "StopWatch.h" namespace { @@ -63,16 +64,12 @@ float nonGreenDiffCross(float right, float left, float top, float bottom, float return std::min(hDiff, vDiff) - stddev; } -void paintMotionMask(int index, bool showMotion, bool showOnlyMask, float *maskDest, float *nonMaskDest0, float *nonMaskDest1) +void paintMotionMask(int index, bool showMotion, float *maskDest, float *nonMaskDest0, float *nonMaskDest1) { if(showMotion) { - if(!showOnlyMask) { - // if showMotion is enabled colourize the pixel - maskDest[index] = 13500.f; - nonMaskDest1[index] = nonMaskDest0[index] = 0.f; - } else { - maskDest[index] = nonMaskDest0[index] = nonMaskDest1[index] = 65535.f; - } + // if showMotion is enabled colourize the pixel + maskDest[index] = 13500.f; + nonMaskDest1[index] = nonMaskDest0[index] = 0.f; } } @@ -271,7 +268,7 @@ void floodFill4(int xStart, int xEnd, int yStart, int yEnd, array2D &ma } } -void calcFrameBrightnessFactor(unsigned int frame, uint32_t datalen, LUT *histo[4], float brightnessFactor[4]) +void calcFrameBrightnessFactor(unsigned int frame, uint32_t datalen, LUTu *histo[4], float brightnessFactor[4]) { float medians[4]; @@ -300,7 +297,7 @@ using namespace std; using namespace rtengine; void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RAWParams::BayerSensor &bayerParamsIn, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection) { - +BENCHFUN if(numFrames != 4) { // fallback for non pixelshift files amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue); return; @@ -321,10 +318,11 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA const bool showMotion = bayerParams.pixelShiftShowMotion; const bool showOnlyMask = bayerParams.pixelShiftShowMotionMaskOnly && showMotion; + const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; if(bayerParams.pixelShiftAutomatic) { if(!showOnlyMask) { - if(bayerParams.pixelShiftMedian) { // We need the amaze demosaiced frames for motion correction + if(bayerParams.pixelShiftMedian) { // We need the demosaiced frames for motion correction if(bayerParams.pixelShiftLmmse) { lmmse_interpolate_omp(winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.lmmse_iterations); } else { @@ -370,7 +368,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } } - const bool adaptive = bayerParams.pixelShiftAutomatic; + const bool automatic = bayerParams.pixelShiftAutomatic; constexpr float stddevFactorGreen = 25.f; constexpr float stddevFactorRed = 25.f; constexpr float stddevFactorBlue = 25.f; @@ -388,7 +386,6 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA const bool equalBrightness = bayerParams.pixelShiftEqualBright; const bool equalChannel = bayerParams.pixelShiftEqualBrightChannel; const bool smoothTransitions = blurMap && bayerParams.pixelShiftSmoothFactor > 0.; - const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; static const float nReadK3II[] = { 3.4f, // ISO 100 3.1f, // ISO 125 @@ -422,6 +419,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA static const float ePerIsoK3II = 0.35f; + // currently we use the same values for K-1 and K-1 Mark II, though for the K-1 Mark II the values seem a bit aggressive static const float nReadK1[] = { 3.45f, // ISO 100 3.15f, // ISO 125 3.45f, // ISO 160 @@ -455,15 +453,21 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA 2.4f, // ISO 102400 2.4f, // ISO 128000 2.4f, // ISO 160000 - 2.4f // ISO 204800 + 2.4f, // ISO 204800 + 2.4f, // ISO 256000 // these are for K-1 Mark II to avoid crashes when using high-ISO files + 2.4f, // ISO 320000 + 2.4f, // ISO 409600 + 2.4f, // ISO 512000 + 2.4f, // ISO 640000 + 2.4f // ISO 819200 }; static const float ePerIsoK1 = 0.75f; // currently nReadK70 is used for K-70 and KP - static const float nReadK70[] = { 4.0f, // ISO 100 - 4.0f, // ISO 125 - 4.0f, // ISO 160 + static const float nReadK70[] = { 4.0f, // ISO 100 + 4.0f, // ISO 125 + 4.0f, // ISO 160 4.0f, // ISO 200 4.0f, // ISO 250 4.0f, // ISO 320 @@ -505,40 +509,41 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA static const float ePerIsoK70 = 0.5f; - // preliminary ILCE-7RM3 data, good fidelity except from A) small innaccuracy at places - // due to integer scaling quantization, B) much different noise behavior of PDAF pixels + // preliminary ILCE-7RM3 data, good fidelity except from A) small inaccuracy at places + // due to integer scaling quantization, B) much different noise behaviour of PDAF pixels static const float nReadILCE7RM3[] = { 4.2f, // ISO 100 - 3.9f, // ISO 125 - 3.6f, // ISO 160 - 3.55f, // ISO 200 - 3.5f, // ISO 250 - 3.45f, // ISO 320 - 3.35f, // ISO 400 - 3.3f, // ISO 500 - 1.3f, // ISO 640 - 1.2f, // ISO 800 - 1.2f, // ISO 1000 - 1.2f, // ISO 1250 - 1.15f, // ISO 1600 - 1.2f, // ISO 2000 - 1.15f, // ISO 2500 - 1.15f, // ISO 3200 - 1.1f, // ISO 4000 - 1.1f, // ISO 5000 - 1.05f, // ISO 6400 - 1.05f, // ISO 8000 - 1.05f, // ISO 10000 - 1.0f, // ISO 12800 - 1.0f, // ISO 16000 - 1.0f, // ISO 20000 - 1.0f, // ISO 25600 - 1.0f, // ISO 32000 - 1.0f, // ISO 40000 - 1.0f, // ISO 51200 - 1.1f, // ISO 64000 - 1.1f, // ISO 80000 - 1.1f, // ISO 102400 - }; + 3.9f, // ISO 125 + 3.6f, // ISO 160 + 3.55f, // ISO 200 + 3.5f, // ISO 250 + 3.45f, // ISO 320 + 3.35f, // ISO 400 + 3.3f, // ISO 500 + 1.3f, // ISO 640 + 1.2f, // ISO 800 + 1.2f, // ISO 1000 + 1.2f, // ISO 1250 + 1.15f, // ISO 1600 + 1.2f, // ISO 2000 + 1.15f, // ISO 2500 + 1.15f, // ISO 3200 + 1.1f, // ISO 4000 + 1.1f, // ISO 5000 + 1.05f, // ISO 6400 + 1.05f, // ISO 8000 + 1.05f, // ISO 10000 + 1.0f, // ISO 12800 + 1.0f, // ISO 16000 + 1.0f, // ISO 20000 + 1.0f, // ISO 25600 + 1.0f, // ISO 32000 + 1.0f, // ISO 40000 + 1.0f, // ISO 51200 + 1.1f, // ISO 64000 + 1.1f, // ISO 80000 + 1.1f, // ISO 102400 + }; + static const float ePerIsoILCE7RM3 = 0.8f; if(plistener) { @@ -546,7 +551,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA plistener->setProgress(0.0); } - if(adaptive && blurMap && smoothFactor == 0.f && !showMotion) { + if(automatic && blurMap && smoothFactor == 0.f && !showMotion) { if(plistener) { plistener->setProgress(1.0); } @@ -554,8 +559,6 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA return; } - const float scaleGreen = 1.f / scale_mul[1]; - float nRead; float eperIsoModel; @@ -564,7 +567,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA if(model.find("K-3") != string::npos) { nRead = nReadK3II[nReadIndex]; eperIsoModel = ePerIsoK3II; - } else if(model.find("K-1") != string::npos) { + } else if(model.find("K-1") != string::npos) { // this also matches K-1 Mark II nRead = nReadK1[nReadIndex]; eperIsoModel = ePerIsoK1; } else if(model.find("ILCE-7RM3") != string::npos) { @@ -580,7 +583,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA eperIso = eperIsoModel * (100.f / (rawWpCorrection * idata->getISOSpeed())); const float eperIsoRed = (eperIso / scale_mul[0]) * (65535.f / (c_white[0] - c_black[0])); - const float eperIsoGreen = (eperIso * scaleGreen) * (65535.f / (c_white[1] - c_black[1])); + const float eperIsoGreen = (eperIso / scale_mul[1]) * (65535.f / (c_white[1] - c_black[1])); const float eperIsoBlue = (eperIso / scale_mul[2]) * (65535.f / (c_white[2] - c_black[2])); const float clippedRed = 65535.f / scale_mul[0]; @@ -588,41 +591,35 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA nRead *= nRead; - // calculate average green brightness for each frame + // calculate channel median brightness for each frame float greenBrightness[4] = {1.f, 1.f, 1.f, 1.f}; float redBrightness[4] = {1.f, 1.f, 1.f, 1.f}; float blueBrightness[4] = {1.f, 1.f, 1.f, 1.f}; if(equalBrightness) { if(rawDirty) { - LUT *histogreen[4]; - LUT *histored[4]; - LUT *histoblue[4]; + LUTu *histogreen[4]; + LUTu *histored[4]; + LUTu *histoblue[4]; for(int i = 0; i < 4; ++i) { - histogreen[i] = new LUT(65536); - histogreen[i]->clear(); - histored[i] = new LUT(65536); - histored[i]->clear(); - histoblue[i] = new LUT(65536); - histoblue[i]->clear(); + histogreen[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + histored[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + histoblue[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); } #ifdef _OPENMP #pragma omp parallel #endif { - LUT *histogreenThr[4]; - LUT *historedThr[4]; - LUT *histoblueThr[4]; + LUTu *histogreenThr[4]; + LUTu *historedThr[4]; + LUTu *histoblueThr[4]; for(int i = 0; i < 4; ++i) { - histogreenThr[i] = new LUT(65536); - histogreenThr[i]->clear(); - historedThr[i] = new LUT(65536); - historedThr[i]->clear(); - histoblueThr[i] = new LUT(65536); - histoblueThr[i]->clear(); + histogreenThr[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + historedThr[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + histoblueThr[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); } #ifdef _OPENMP @@ -699,7 +696,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } - if(adaptive) { + if(automatic) { // fill channels psRed and psBlue array2D psRed(winw + 32, winh); // increase width to avoid cache conflicts array2D psBlue(winw + 32, winh); @@ -712,8 +709,8 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA float *nonGreenDest0 = psRed[i]; float *nonGreenDest1 = psBlue[i]; float ngbright[2][4] = {{redBrightness[0], redBrightness[1], redBrightness[2], redBrightness[3]}, - {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} - }; + {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} + }; int ng = 0; int j = winx + 1; int c = FC(i, j); @@ -788,12 +785,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA if(checkNonGreenCross) { // check red cross - float redTop = psRed[i - 1][ j ]; - float redLeft = psRed[ i ][j - 1]; - float redCentre = psRed[ i ][ j ]; - float redRight = psRed[ i ][j + 1]; - float redBottom = psRed[i + 1][ j ]; - float redDiff = nonGreenDiffCross(redRight, redLeft, redTop, redBottom, redCentre, clippedRed, stddevFactorRed, eperIsoRed, nRead, prnu); + float redTop = psRed[i - 1][j]; + float redLeft = psRed[i][j - 1]; + float redCentre = psRed[i][j]; + float redRight = psRed[i][j + 1]; + float redBottom = psRed[i + 1][j]; + float redDiff = nonGreenDiffCross(redRight, redLeft, redTop, redBottom, redCentre, clippedRed, stddevFactorRed, eperIsoRed, nRead, prnu); if(redDiff > 0.f) { psMask[i][j] = redBlueWeight; @@ -801,12 +798,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } // check blue cross - float blueTop = psBlue[i - 1][ j ]; - float blueLeft = psBlue[ i ][j - 1]; - float blueCentre = psBlue[ i ][ j ]; - float blueRight = psBlue[ i ][j + 1]; - float blueBottom = psBlue[i + 1][ j ]; - float blueDiff = nonGreenDiffCross(blueRight, blueLeft, blueTop, blueBottom, blueCentre, clippedBlue, stddevFactorBlue, eperIsoBlue, nRead, prnu); + float blueTop = psBlue[i - 1][j]; + float blueLeft = psBlue[i][j - 1]; + float blueCentre = psBlue[i][j]; + float blueRight = psBlue[i][j + 1]; + float blueBottom = psBlue[i + 1][j]; + float blueDiff = nonGreenDiffCross(blueRight, blueLeft, blueTop, blueBottom, blueCentre, clippedBlue, stddevFactorBlue, eperIsoBlue, nRead, prnu); if(blueDiff > 0.f) { psMask[i][j] = redBlueWeight; @@ -830,7 +827,6 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA if(plistener) { plistener->setProgress(0.6); } - } array2D mask(winw, winh, ARRAY2D_CLEAR_DATA); @@ -886,7 +882,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA for(int i = winy + border - offsY; i < winh - (border + offsY); ++i) { #ifdef __SSE2__ - // pow() is expensive => precalculate blend factor using SSE + // pow() is expensive => pre calculate blend factor using SSE if(smoothTransitions) { // vfloat onev = F2V(1.f); vfloat smoothv = F2V(smoothFactor); @@ -915,40 +911,32 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { if(showOnlyMask) { if(smoothTransitions) { // we want only motion mask => paint areas according to their motion (dark = no motion, bright = motion) - redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = psMask[i][j] * 32768.f; - } else { - redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = mask[i][j] == 255 ? 65535.f : 0.f; - } - } else if(mask[i][j] == 255) { - paintMotionMask(j + offsX, showMotion, showOnlyMask, greenDest, redDest, blueDest); - } else { - if(smoothTransitions) { #ifdef __SSE2__ - // use precalculated blend factor + // use pre calculated blend factor const float blend = psMask[i][j]; #else const float blend = smoothFactor == 0.f ? 1.f : pow_F(std::max(psMask[i][j] - 1.f, 0.f), smoothFactor); #endif - redDest[j + offsX] = intp(blend, redDest[j + offsX], psRed[i][j] ); - if(bayerParams.pixelShiftOneGreen) { - int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset; - int greenJ = (1 - offset != 0) ? j : j + 1; - int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset; - greenDest[j + offsX] = intp(blend, greenDest[j + offsX], (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]); - } else { - greenDest[j + offsX] = intp(blend, greenDest[j + offsX], ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f); - } - blueDest[j + offsX] = intp(blend, blueDest[j + offsX], psBlue[i][j]); + redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = blend * 32768.f; + } else { + redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = mask[i][j] == 255 ? 65535.f : 0.f; + } + } else if(mask[i][j] == 255) { + paintMotionMask(j + offsX, showMotion, greenDest, redDest, blueDest); + } else { + if(smoothTransitions) { +#ifdef __SSE2__ + // use pre calculated blend factor + const float blend = psMask[i][j]; +#else + const float blend = smoothFactor == 0.f ? 1.f : pow_F(std::max(psMask[i][j] - 1.f, 0.f), smoothFactor); +#endif + redDest[j + offsX] = intp(blend, showMotion ? 0.f : redDest[j + offsX], psRed[i][j] ); + greenDest[j + offsX] = intp(blend, showMotion ? 13500.f : greenDest[j + offsX], ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f); + blueDest[j + offsX] = intp(blend, showMotion ? 0.f : blueDest[j + offsX], psBlue[i][j]); } else { redDest[j + offsX] = psRed[i][j]; - if(bayerParams.pixelShiftOneGreen) { - int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset; - int greenJ = (1 - offset != 0) ? j : j + 1; - int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset; - greenDest[j + offsX] = (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]; - } else { - greenDest[j + offsX] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; - } + greenDest[j + offsX] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; blueDest[j + offsX] = psBlue[i][j]; } } @@ -957,7 +945,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } else { // motion detection off => combine the 4 raw frames float ngbright[2][4] = {{redBrightness[0], redBrightness[1], redBrightness[2], redBrightness[3]}, - {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} + {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} }; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -981,14 +969,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA for(; j < winw - 1; ++j) { // set red, green and blue values - if(bayerParams.pixelShiftOneGreen) { - int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset; - int greenJ = (1 - offset != 0) ? j : j + 1; - int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset; - green[i][j] = (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]; - } else { - green[i][j] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; - } + green[i][j] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; nonGreenDest0[j] = (*rawDataFrames[(offset << 1) + offset])[i][j + offset] * ngbright[ng][(offset << 1) + offset]; nonGreenDest1[j] = (*rawDataFrames[2 - offset])[i + 1][j - offset + 1] * ngbright[ng ^ 1][2 - offset]; offset ^= 1; // 0 => 1 or 1 => 0 diff --git a/rtengine/procevents.h b/rtengine/procevents.h index f5751c7d0..dd43a9abe 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -481,8 +481,8 @@ enum ProcEventCode { EvPixelshiftShowMotion = 451, EvPixelshiftShowMotionMaskOnly = 452, EvPixelShiftAutomatic = 453, - EvPixelShiftNonGreenHorizontal = 454, - EvPixelShiftNonGreenVertical = 455, +// EvPixelShiftNonGreenHorizontal = 454, +// EvPixelShiftNonGreenVertical = 455, EvPixelShiftNonGreenCross = 456, EvPixelShiftStddevFactorRed = 457, EvPixelShiftStddevFactorBlue = 458, @@ -520,7 +520,7 @@ enum ProcEventCode { EvWBEnabled = 490, EvRGBEnabled = 491, EvLEnabled = 492, - EvPixelShiftOneGreen = 493, +// EvPixelShiftOneGreen = 493, can be reused NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 0a87d9614..a96c61697 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -328,7 +328,8 @@ ToneCurveParams::ToneCurveParams() : shcompr(50), hlcompr(0), hlcomprthresh(33), - histmatching(false) + histmatching(false), + clampOOG(true) { } @@ -351,7 +352,8 @@ bool ToneCurveParams::operator ==(const ToneCurveParams& other) const && shcompr == other.shcompr && hlcompr == other.hlcompr && hlcomprthresh == other.hlcomprthresh - && histmatching == other.histmatching; + && histmatching == other.histmatching + && clampOOG == other.clampOOG; } bool ToneCurveParams::operator !=(const ToneCurveParams& other) const @@ -2368,8 +2370,8 @@ RAWParams::BayerSensor::BayerSensor() : pixelShiftShowMotion(false), pixelShiftShowMotionMaskOnly(false), pixelShiftAutomatic(true), - pixelShiftNonGreenHorizontal(false), - pixelShiftNonGreenVertical(false), +// pixelShiftNonGreenHorizontal(false), +// pixelShiftNonGreenVertical(false), pixelShiftHoleFill(true), pixelShiftMedian(false), pixelShiftMedian3(false), @@ -2378,7 +2380,6 @@ RAWParams::BayerSensor::BayerSensor() : pixelShiftSmoothFactor(0.7), pixelShiftExp0(false), pixelShiftLmmse(false), - pixelShiftOneGreen(false), pixelShiftEqualBright(false), pixelShiftEqualBrightChannel(false), pixelShiftNonGreenCross(true), @@ -2420,8 +2421,8 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const && pixelShiftShowMotion == other.pixelShiftShowMotion && pixelShiftShowMotionMaskOnly == other.pixelShiftShowMotionMaskOnly && pixelShiftAutomatic == other.pixelShiftAutomatic - && pixelShiftNonGreenHorizontal == other.pixelShiftNonGreenHorizontal - && pixelShiftNonGreenVertical == other.pixelShiftNonGreenVertical +// && pixelShiftNonGreenHorizontal == other.pixelShiftNonGreenHorizontal +// && pixelShiftNonGreenVertical == other.pixelShiftNonGreenVertical && pixelShiftHoleFill == other.pixelShiftHoleFill && pixelShiftMedian == other.pixelShiftMedian && pixelShiftMedian3 == other.pixelShiftMedian3 @@ -2430,7 +2431,6 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const && pixelShiftSmoothFactor == other.pixelShiftSmoothFactor && pixelShiftExp0 == other.pixelShiftExp0 && pixelShiftLmmse == other.pixelShiftLmmse - && pixelShiftOneGreen == other.pixelShiftOneGreen && pixelShiftEqualBright == other.pixelShiftEqualBright && pixelShiftEqualBrightChannel == other.pixelShiftEqualBrightChannel && pixelShiftNonGreenCross == other.pixelShiftNonGreenCross @@ -2460,8 +2460,8 @@ void RAWParams::BayerSensor::setPixelShiftDefaults() pixelShiftSum = 3.0; pixelShiftRedBlueWeight = 0.7; pixelShiftAutomatic = true; - pixelShiftNonGreenHorizontal = false; - pixelShiftNonGreenVertical = false; +// pixelShiftNonGreenHorizontal = false; +// pixelShiftNonGreenVertical = false; pixelShiftHoleFill = true; pixelShiftMedian = false; pixelShiftMedian3 = false; @@ -2470,7 +2470,6 @@ void RAWParams::BayerSensor::setPixelShiftDefaults() pixelShiftSmoothFactor = 0.7; pixelShiftExp0 = false; pixelShiftLmmse = false; - pixelShiftOneGreen = false; pixelShiftEqualBright = false; pixelShiftEqualBrightChannel = false; pixelShiftNonGreenCross = true; @@ -3390,8 +3389,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotion, "RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelShiftShowMotion, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly, "RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelShiftShowMotionMaskOnly, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftAutomatic, "RAW Bayer", "pixelShiftAutomatic", raw.bayersensor.pixelShiftAutomatic, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenHorizontal, "RAW Bayer", "pixelShiftNonGreenHorizontal", raw.bayersensor.pixelShiftNonGreenHorizontal, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenVertical, "RAW Bayer", "pixelShiftNonGreenVertical", raw.bayersensor.pixelShiftNonGreenVertical, keyFile); +// saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenHorizontal, "RAW Bayer", "pixelShiftNonGreenHorizontal", raw.bayersensor.pixelShiftNonGreenHorizontal, keyFile); +// saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenVertical, "RAW Bayer", "pixelShiftNonGreenVertical", raw.bayersensor.pixelShiftNonGreenVertical, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftHoleFill, "RAW Bayer", "pixelShiftHoleFill", raw.bayersensor.pixelShiftHoleFill, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian, "RAW Bayer", "pixelShiftMedian", raw.bayersensor.pixelShiftMedian, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian3, "RAW Bayer", "pixelShiftMedian3", raw.bayersensor.pixelShiftMedian3, keyFile); @@ -3400,7 +3399,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSmooth, "RAW Bayer", "pixelShiftSmoothFactor", raw.bayersensor.pixelShiftSmoothFactor, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftExp0, "RAW Bayer", "pixelShiftExp0", raw.bayersensor.pixelShiftExp0, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftLmmse, "RAW Bayer", "pixelShiftLmmse", raw.bayersensor.pixelShiftLmmse, keyFile); -// saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftOneGreen, "RAW Bayer", "pixelShiftOneGreen", raw.bayersensor.pixelShiftOneGreen, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBright, "RAW Bayer", "pixelShiftEqualBright", raw.bayersensor.pixelShiftEqualBright, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBrightChannel, "RAW Bayer", "pixelShiftEqualBrightChannel", raw.bayersensor.pixelShiftEqualBrightChannel, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross, "RAW Bayer", "pixelShiftNonGreenCross", raw.bayersensor.pixelShiftNonGreenCross, keyFile); @@ -4730,8 +4728,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", pedited, raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", pedited, raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftAutomatic", pedited, raw.bayersensor.pixelShiftAutomatic, pedited->raw.bayersensor.pixelShiftAutomatic); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenHorizontal", pedited, raw.bayersensor.pixelShiftNonGreenHorizontal, pedited->raw.bayersensor.pixelShiftNonGreenHorizontal); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenVertical", pedited, raw.bayersensor.pixelShiftNonGreenVertical, pedited->raw.bayersensor.pixelShiftNonGreenVertical); +// assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenHorizontal", pedited, raw.bayersensor.pixelShiftNonGreenHorizontal, pedited->raw.bayersensor.pixelShiftNonGreenHorizontal); +// assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenVertical", pedited, raw.bayersensor.pixelShiftNonGreenVertical, pedited->raw.bayersensor.pixelShiftNonGreenVertical); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftHoleFill", pedited, raw.bayersensor.pixelShiftHoleFill, pedited->raw.bayersensor.pixelShiftHoleFill); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian", pedited, raw.bayersensor.pixelShiftMedian, pedited->raw.bayersensor.pixelShiftMedian); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian3", pedited, raw.bayersensor.pixelShiftMedian3, pedited->raw.bayersensor.pixelShiftMedian3); @@ -4740,7 +4738,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", pedited, raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftExp0", pedited, raw.bayersensor.pixelShiftExp0, pedited->raw.bayersensor.pixelShiftExp0); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftLmmse", pedited, raw.bayersensor.pixelShiftLmmse, pedited->raw.bayersensor.pixelShiftLmmse); -// assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftOneGreen", pedited, raw.bayersensor.pixelShiftOneGreen, pedited->raw.bayersensor.pixelShiftOneGreen); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", pedited, raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", pedited, raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", pedited, raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index b158d7d1f..8560cdc59 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -281,6 +281,7 @@ struct ToneCurveParams { int hlcompr; // Highlight Recovery's compression int hlcomprthresh; // Highlight Recovery's threshold bool histmatching; // histogram matching + bool clampOOG; // clamp out of gamut colours ToneCurveParams(); @@ -1295,7 +1296,6 @@ struct RAWParams { double pixelShiftSmoothFactor; bool pixelShiftExp0; bool pixelShiftLmmse; - bool pixelShiftOneGreen; bool pixelShiftEqualBright; bool pixelShiftEqualBrightChannel; bool pixelShiftNonGreenCross; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index b467c5564..4d1bfcf3c 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -519,8 +519,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { HDR, // EvTMFattalAmount ALLNORAW, // EvWBEnabled RGBCURVE, // EvRGBEnabled - LUMINANCECURVE, // EvLEnabled - DEMOSAIC // EvPixelShiftOneGreen + LUMINANCECURVE // EvLEnabled }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index b86a2f98a..f50321775 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -120,12 +120,12 @@ public: virtual std::string getOrientation (unsigned int frame = 0) const = 0; /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ - virtual bool getPixelShift (unsigned int frame = 0) const = 0; + virtual bool getPixelShift () const = 0; /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ virtual bool getHDR (unsigned int frame = 0) const = 0; /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ - virtual std::string getRawType (unsigned int frame) const = 0; + virtual std::string getImageType (unsigned int frame) const = 0; /** @return the sample format based on MetaData */ virtual IIOSampleFormat getSampleFormat (unsigned int frame = 0) const = 0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 17ecb6730..0e9629498 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1166,23 +1166,8 @@ private: LUTf CAMBrightCurveQ; float CAMMean = NAN; - if (params.sharpening.enabled) { - if (settings->ciecamfloat) { - float d, dj, yb; - ipf.ciecam_02float (cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); - } else { - double dd, dj; - ipf.ciecam_02 (cieView, adap, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, dj, 1); - } - } else { - if (settings->ciecamfloat) { - float d, dj, yb; - ipf.ciecam_02float (cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); - } else { - double dd, dj; - ipf.ciecam_02 (cieView, adap, 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, dj, 1); - } - } + float d, dj, yb; + ipf.ciecam_02float (cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, dj, yb, 1); } delete cieView; diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc index c7252d360..4d9a31b6f 100644 --- a/rtexif/pentaxattribs.cc +++ b/rtexif/pentaxattribs.cc @@ -44,6 +44,7 @@ public: choices[5] = "Premium"; choices[6] = "RAW (HDR enabled)"; choices[7] = "RAW (pixel shift enabled)"; + choices[8] = "RAW (pixel shift handheld mode enabled)"; choices[65535] = "n/a"; } }; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index b294c9fee..73fea1aa3 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -130,11 +130,6 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA pixelShiftShowMotionMaskOnly->set_tooltip_text (M("TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP")); pixelShiftFrame->pack_start(*pixelShiftShowMotionMaskOnly); -#ifdef PIXELSHIFTDEV - pixelShiftAutomatic = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTADAPTIVE"), multiImage)); - pixelShiftAutomatic->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftAutomatic); -#endif pixelShiftGreen = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTGREEN"), multiImage)); pixelShiftGreen->setCheckBoxListener (this); pixelShiftOptions->pack_start(*pixelShiftGreen); @@ -194,139 +189,11 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA pixelShiftOptions->pack_start(*pixelShiftMedian); -#ifdef PIXELSHIFTDEV - pixelShiftMedian3 = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTMEDIAN3"), multiImage)); - pixelShiftMedian3->setCheckBoxListener (this); - pixelShiftMedian3->set_tooltip_text (M("TP_RAW_PIXELSHIFTMEDIAN3_TOOLTIP")); - pixelShiftOptions->pack_start(*pixelShiftMedian3); - - pixelShiftNonGreenCross2 = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENCROSS2"), multiImage)); - pixelShiftNonGreenCross2->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenCross2); - - pixelShiftNonGreenAmaze = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENAMAZE"), multiImage)); - pixelShiftNonGreenAmaze->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenAmaze); - - pixelShiftNonGreenHorizontal = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENHORIZONTAL"), multiImage)); - pixelShiftNonGreenHorizontal->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenHorizontal); - - pixelShiftNonGreenVertical = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENVERTICAL"), multiImage)); - pixelShiftNonGreenVertical->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenVertical); - - pixelShiftExp0 = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTEXP0"), multiImage)); - pixelShiftExp0->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftExp0); -#endif pixelShiftLmmse = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTLMMSE"), multiImage)); pixelShiftLmmse->setCheckBoxListener (this); pixelShiftLmmse->set_tooltip_text (M("TP_RAW_PIXELSHIFTLMMSE_TOOLTIP")); pixelShiftOptions->pack_start(*pixelShiftLmmse); -// pixelShiftOneGreen = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTONEGREEN"), multiImage)); -// pixelShiftOneGreen->setCheckBoxListener (this); -// pixelShiftOneGreen->set_tooltip_text (M("TP_RAW_PIXELSHIFTONEGREEN_TOOLTIP")); -// pixelShiftOptions->pack_start(*pixelShiftOneGreen); - -#ifdef PIXELSHIFTDEV - pixelShiftMotion = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMOTION"), 0, 100, 1, 70)); - pixelShiftMotion->setAdjusterListener (this); - pixelShiftMotion->set_tooltip_text (M("TP_RAW_PIXELSHIFTMOTION_TOOLTIP")); - - if (pixelShiftMotion->delay < options.adjusterMaxDelay) { - pixelShiftMotion->delay = options.adjusterMaxDelay; - } - pixelShiftMotion->show(); - pixelShiftOptions->pack_start(*pixelShiftMotion); - - Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); - hb2->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_PIXELSHIFTMOTIONCORRECTION") + ": ")), Gtk::PACK_SHRINK, 0); - pixelShiftMotionCorrection = Gtk::manage (new MyComboBoxText ()); - pixelShiftMotionCorrection->append("1x1"); - pixelShiftMotionCorrection->append("1x2"); - pixelShiftMotionCorrection->append("3x3"); - pixelShiftMotionCorrection->append("5x5"); - pixelShiftMotionCorrection->append("7x7"); - pixelShiftMotionCorrection->append("3x3 new"); - pixelShiftMotionCorrection->set_active(0); - pixelShiftMotionCorrection->show(); - hb2->pack_start(*pixelShiftMotionCorrection); - pixelShiftOptions->pack_start(*hb2); - pixelShiftStddevFactorGreen = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTSTDDEVFACTORGREEN"), 2, 8, 0.1, 5)); - pixelShiftStddevFactorGreen->setAdjusterListener (this); - - if (pixelShiftStddevFactorGreen->delay < options.adjusterMaxDelay) { - pixelShiftStddevFactorGreen->delay = options.adjusterMaxDelay; - } - - pixelShiftStddevFactorGreen->show(); - pixelShiftOptions->pack_start(*pixelShiftStddevFactorGreen); - - pixelShiftStddevFactorRed = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTSTDDEVFACTORRED"), 1, 8, 0.1, 5)); - pixelShiftStddevFactorRed->setAdjusterListener (this); - - if (pixelShiftStddevFactorRed->delay < options.adjusterMaxDelay) { - pixelShiftStddevFactorRed->delay = options.adjusterMaxDelay; - } - - pixelShiftStddevFactorRed->show(); - pixelShiftOptions->pack_start(*pixelShiftStddevFactorRed); - - pixelShiftStddevFactorBlue = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTSTDDEVFACTORBLUE"), 1, 8, 0.1, 5)); - pixelShiftStddevFactorBlue->setAdjusterListener (this); - - if (pixelShiftStddevFactorBlue->delay < options.adjusterMaxDelay) { - pixelShiftStddevFactorBlue->delay = options.adjusterMaxDelay; - } - - pixelShiftStddevFactorBlue->show(); - pixelShiftOptions->pack_start(*pixelShiftStddevFactorBlue); -#endif - -#ifdef PIXELSHIFTDEV - pixelShiftNreadIso = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTNREADISO"), -2.0, 2.0, 0.05, 0.0)); - pixelShiftNreadIso->setAdjusterListener (this); - - if (pixelShiftNreadIso->delay < options.adjusterMaxDelay) { - pixelShiftNreadIso->delay = options.adjusterMaxDelay; - } - - pixelShiftNreadIso->show(); - pixelShiftOptions->pack_start(*pixelShiftNreadIso); - - - pixelShiftPrnu = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTPRNU"), 0.3, 2.0, 0.1, 1.0)); - pixelShiftPrnu->setAdjusterListener (this); - - if (pixelShiftPrnu->delay < options.adjusterMaxDelay) { - pixelShiftPrnu->delay = options.adjusterMaxDelay; - } - - pixelShiftPrnu->show(); - pixelShiftOptions->pack_start(*pixelShiftPrnu); - - pixelShiftSum = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMASKTHRESHOLD"), 1.0, 8.0, 0.1, 3.0)); - pixelShiftSum->setAdjusterListener (this); - - if (pixelShiftSum->delay < options.adjusterMaxDelay) { - pixelShiftSum->delay = options.adjusterMaxDelay; - } - - pixelShiftSum->show(); - pixelShiftOptions->pack_start(*pixelShiftSum); - - pixelShiftRedBlueWeight = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTREDBLUEWEIGHT"), 0.1, 1.0, 0.1, 0.7)); - pixelShiftRedBlueWeight->setAdjusterListener (this); - - if (pixelShiftRedBlueWeight->delay < options.adjusterMaxDelay) { - pixelShiftRedBlueWeight->delay = options.adjusterMaxDelay; - } - - pixelShiftRedBlueWeight->show(); - pixelShiftOptions->pack_start(*pixelShiftRedBlueWeight); -#endif pixelShiftFrame->pack_start(*pixelShiftOptions); pixelShiftOptions->hide(); @@ -336,9 +203,6 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA method->connect(method->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::methodChanged) )); imageNumber->connect(imageNumber->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::imageNumberChanged) )); pixelShiftMotionMethod->connect(pixelShiftMotionMethod->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::pixelShiftMotionMethodChanged) )); -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->connect(pixelShiftMotionCorrection->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::psMotionCorrectionChanged) )); -#endif } @@ -348,9 +212,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params method->block (true); imageNumber->block (true); //allEnhconn.block (true); -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->block (true); -#endif method->set_active(std::numeric_limits::max()); imageNumber->set_active(pp->raw.bayersensor.imageNum); @@ -381,7 +242,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params } pixelShiftSmooth->setValue (pp->raw.bayersensor.pixelShiftSmoothFactor); pixelShiftLmmse->setValue (pp->raw.bayersensor.pixelShiftLmmse); -// pixelShiftOneGreen->setValue (pp->raw.bayersensor.pixelShiftOneGreen); pixelShiftEqualBright->setValue (pp->raw.bayersensor.pixelShiftEqualBright); pixelShiftEqualBrightChannel->set_sensitive (pp->raw.bayersensor.pixelShiftEqualBright); pixelShiftEqualBrightChannel->setValue (pp->raw.bayersensor.pixelShiftEqualBrightChannel); @@ -394,32 +254,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params if (!batchMode) { pixelShiftSigma->set_sensitive (pp->raw.bayersensor.pixelShiftBlur); } -#ifdef PIXELSHIFTDEV - pixelShiftStddevFactorGreen->setValue (pp->raw.bayersensor.pixelShiftStddevFactorGreen); - pixelShiftStddevFactorRed->setValue (pp->raw.bayersensor.pixelShiftStddevFactorRed); - pixelShiftStddevFactorBlue->setValue (pp->raw.bayersensor.pixelShiftStddevFactorBlue); - pixelShiftSum->setValue (pp->raw.bayersensor.pixelShiftSum); - pixelShiftMedian3->setValue (pp->raw.bayersensor.pixelShiftMedian3); - if (!batchMode) { - pixelShiftMedian3->set_sensitive (pixelShiftMedian->getValue() != CheckValue::off); - } - pixelShiftAutomatic->setValue (pp->raw.bayersensor.pixelShiftAutomatic); - pixelShiftNonGreenHorizontal->setValue (pp->raw.bayersensor.pixelShiftNonGreenHorizontal); - pixelShiftNonGreenVertical->setValue (pp->raw.bayersensor.pixelShiftNonGreenVertical); - pixelShiftExp0->setValue (pp->raw.bayersensor.pixelShiftExp0); - pixelShiftNonGreenCross2->setValue (pp->raw.bayersensor.pixelShiftNonGreenCross2); - pixelShiftNonGreenAmaze->setValue (pp->raw.bayersensor.pixelShiftNonGreenAmaze); - pixelShiftMotion->setValue (pp->raw.bayersensor.pixelShiftMotion); - pixelShiftMotionCorrection->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrection); - if (!batchMode) { - pixelShiftHoleFill->set_sensitive (pixelShiftAutomatic->getValue () != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftBlur->set_sensitive(pixelShiftAutomatic->getValue () != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftSmooth->set_sensitive(pixelShiftAutomatic->getValue () != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5 && pixelShiftBlur->getValue() != CheckValue::off); - } - pixelShiftNreadIso->setValue (pp->raw.bayersensor.pixelShiftNreadIso); - pixelShiftPrnu->setValue (pp->raw.bayersensor.pixelShiftPrnu); - pixelShiftRedBlueWeight->setValue (pp->raw.bayersensor.pixelShiftRedBlueWeight); -#endif if(pedited) { ccSteps->setEditedState (pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); @@ -433,30 +267,12 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params pixelShiftBlur->setEdited (pedited->raw.bayersensor.pixelShiftBlur); pixelShiftSmooth->setEditedState ( pedited->raw.bayersensor.pixelShiftSmooth ? Edited : UnEdited); pixelShiftLmmse->setEdited (pedited->raw.bayersensor.pixelShiftLmmse); -// pixelShiftOneGreen->setEdited (pedited->raw.bayersensor.pixelShiftOneGreen); pixelShiftEqualBright->setEdited (pedited->raw.bayersensor.pixelShiftEqualBright); pixelShiftEqualBrightChannel->setEdited (pedited->raw.bayersensor.pixelShiftEqualBrightChannel); pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross); lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); pixelShiftEperIso->setEditedState ( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); -#ifdef PIXELSHIFTDEV - pixelShiftNreadIso->setEditedState ( pedited->raw.bayersensor.pixelShiftNreadIso ? Edited : UnEdited); - pixelShiftPrnu->setEditedState ( pedited->raw.bayersensor.pixelShiftPrnu ? Edited : UnEdited); - pixelShiftStddevFactorGreen->setEditedState ( pedited->raw.bayersensor.pixelShiftStddevFactorGreen ? Edited : UnEdited); - pixelShiftStddevFactorRed->setEditedState ( pedited->raw.bayersensor.pixelShiftStddevFactorRed ? Edited : UnEdited); - pixelShiftStddevFactorBlue->setEditedState ( pedited->raw.bayersensor.pixelShiftStddevFactorBlue ? Edited : UnEdited); - pixelShiftSum->setEditedState ( pedited->raw.bayersensor.pixelShiftSum ? Edited : UnEdited); - pixelShiftAutomatic->setEdited (pedited->raw.bayersensor.pixelShiftAutomatic); - pixelShiftNonGreenHorizontal->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenHorizontal); - pixelShiftNonGreenVertical->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenVertical); - pixelShiftMedian3->setEdited (pedited->raw.bayersensor.pixelShiftMedian3); - pixelShiftExp0->setEdited (pedited->raw.bayersensor.pixelShiftExp0); - pixelShiftNonGreenCross2->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross2); - pixelShiftNonGreenAmaze->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenAmaze); - pixelShiftMotion->setEditedState ( pedited->raw.bayersensor.pixelShiftMotion ? Edited : UnEdited); - pixelShiftRedBlueWeight->setEditedState ( pedited->raw.bayersensor.pixelShiftRedBlueWeight ? Edited : UnEdited); -#endif if(!pedited->raw.bayersensor.method) { method->set_active(std::numeric_limits::max()); // No name @@ -464,11 +280,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params if(!pedited->raw.bayersensor.imageNum) { imageNumber->set_active_text(M("GENERAL_UNCHANGED")); } -#ifdef PIXELSHIFTDEV - if(!pedited->raw.bayersensor.pixelShiftMotionCorrection) { - pixelShiftMotionCorrection->set_active_text(M("GENERAL_UNCHANGED")); - } -#endif if(!pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod) { pixelShiftMotionMethod->set_active_text(M("GENERAL_UNCHANGED")); } @@ -511,9 +322,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params //lastALLen = pp->raw.bayersensor.all_enhance; method->block (false); -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->block (false); -#endif imageNumber->block (false); //allEnhconn.block (false); @@ -538,28 +346,9 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.pixelShiftBlur = pixelShiftBlur->getLastActive (); pp->raw.bayersensor.pixelShiftSmoothFactor = pixelShiftSmooth->getValue(); pp->raw.bayersensor.pixelShiftLmmse = pixelShiftLmmse->getLastActive (); -// pp->raw.bayersensor.pixelShiftOneGreen = pixelShiftOneGreen->getLastActive (); pp->raw.bayersensor.pixelShiftEqualBright = pixelShiftEqualBright->getLastActive (); pp->raw.bayersensor.pixelShiftEqualBrightChannel = pixelShiftEqualBrightChannel->getLastActive (); pp->raw.bayersensor.pixelShiftNonGreenCross = pixelShiftNonGreenCross->getLastActive (); -#ifdef PIXELSHIFTDEV - pp->raw.bayersensor.pixelShiftStddevFactorGreen = pixelShiftStddevFactorGreen->getValue(); - pp->raw.bayersensor.pixelShiftStddevFactorRed = pixelShiftStddevFactorRed->getValue(); - pp->raw.bayersensor.pixelShiftStddevFactorBlue = pixelShiftStddevFactorBlue->getValue(); - pp->raw.bayersensor.pixelShiftSum = pixelShiftSum->getValue(); - pp->raw.bayersensor.pixelShiftMedian3 = pixelShiftMedian3->getLastActive (); - pp->raw.bayersensor.pixelShiftMotion = pixelShiftMotion->getIntValue(); - pp->raw.bayersensor.pixelShiftMotionCorrection = (RAWParams::BayerSensor::ePSMotionCorrection)pixelShiftMotionCorrection->get_active_row_number(); - pp->raw.bayersensor.pixelShiftAutomatic = pixelShiftAutomatic->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenHorizontal = pixelShiftNonGreenHorizontal->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenVertical = pixelShiftNonGreenVertical->getLastActive (); - pp->raw.bayersensor.pixelShiftExp0 = pixelShiftExp0->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenCross2 = pixelShiftNonGreenCross2->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenAmaze = pixelShiftNonGreenAmaze->getLastActive (); - pp->raw.bayersensor.pixelShiftNreadIso = pixelShiftNreadIso->getValue(); - pp->raw.bayersensor.pixelShiftPrnu = pixelShiftPrnu->getValue(); - pp->raw.bayersensor.pixelShiftRedBlueWeight = pixelShiftRedBlueWeight->getValue(); -#endif int currentRow = method->get_active_row_number(); if( currentRow >= 0 && currentRow < std::numeric_limits::max()) { @@ -591,28 +380,9 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pedited->raw.bayersensor.pixelShiftBlur = !pixelShiftBlur->get_inconsistent(); pedited->raw.bayersensor.pixelShiftSmooth = pixelShiftSmooth->getEditedState(); pedited->raw.bayersensor.pixelShiftLmmse = !pixelShiftLmmse->get_inconsistent(); -// pedited->raw.bayersensor.pixelShiftOneGreen = !pixelShiftOneGreen->get_inconsistent(); pedited->raw.bayersensor.pixelShiftEqualBright = !pixelShiftEqualBright->get_inconsistent(); pedited->raw.bayersensor.pixelShiftEqualBrightChannel = !pixelShiftEqualBrightChannel->get_inconsistent(); pedited->raw.bayersensor.pixelShiftNonGreenCross = !pixelShiftNonGreenCross->get_inconsistent(); -#ifdef PIXELSHIFTDEV - pedited->raw.bayersensor.pixelShiftStddevFactorGreen = pixelShiftStddevFactorGreen->getEditedState (); - pedited->raw.bayersensor.pixelShiftStddevFactorRed = pixelShiftStddevFactorRed->getEditedState (); - pedited->raw.bayersensor.pixelShiftStddevFactorBlue = pixelShiftStddevFactorBlue->getEditedState (); - pedited->raw.bayersensor.pixelShiftSum = pixelShiftSum->getEditedState (); - pedited->raw.bayersensor.pixelShiftMedian3 = !pixelShiftMedian3->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftMotion = pixelShiftMotion->getEditedState (); - pedited->raw.bayersensor.pixelShiftMotionCorrection = pixelShiftMotionCorrection->get_active_text() != M("GENERAL_UNCHANGED"); - pedited->raw.bayersensor.pixelShiftAutomatic = !pixelShiftAutomatic->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenHorizontal = !pixelShiftNonGreenHorizontal->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenVertical = !pixelShiftNonGreenVertical->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftExp0 = !pixelShiftExp0->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenCross2 = !pixelShiftNonGreenCross2->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenAmaze = !pixelShiftNonGreenAmaze->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNreadIso = pixelShiftNreadIso->getEditedState (); - pedited->raw.bayersensor.pixelShiftPrnu = pixelShiftPrnu->getEditedState (); - pedited->raw.bayersensor.pixelShiftRedBlueWeight = pixelShiftRedBlueWeight->getEditedState (); -#endif } } @@ -620,10 +390,6 @@ void BayerProcess::setBatchMode(bool batchMode) { method->append (M("GENERAL_UNCHANGED")); method->set_active(std::numeric_limits::max()); // No name -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->append (M("GENERAL_UNCHANGED")); - pixelShiftMotionCorrection->set_active_text (M("GENERAL_UNCHANGED")); -#endif pixelShiftMotionMethod->append (M("GENERAL_UNCHANGED")); pixelShiftMotionMethod->set_active_text (M("GENERAL_UNCHANGED")); imageNumber->append (M("GENERAL_UNCHANGED")); @@ -632,16 +398,6 @@ void BayerProcess::setBatchMode(bool batchMode) ccSteps->showEditedCB (); dcbIterations->showEditedCB (); lmmseIterations->showEditedCB (); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->showEditedCB (); - pixelShiftSum->showEditedCB (); - pixelShiftStddevFactorGreen->showEditedCB (); - pixelShiftStddevFactorRed->showEditedCB (); - pixelShiftStddevFactorBlue->showEditedCB (); - pixelShiftNreadIso->showEditedCB (); - pixelShiftPrnu->showEditedCB (); - pixelShiftRedBlueWeight->showEditedCB (); -#endif pixelShiftEperIso->showEditedCB (); pixelShiftSigma->showEditedCB (); } @@ -650,16 +406,6 @@ void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams { dcbIterations->setDefault( defParams->raw.bayersensor.dcb_iterations); lmmseIterations->setDefault( defParams->raw.bayersensor.lmmse_iterations); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->setDefault( defParams->raw.bayersensor.pixelShiftMotion); - pixelShiftSum->setDefault( defParams->raw.bayersensor.pixelShiftSum); - pixelShiftStddevFactorGreen->setDefault( defParams->raw.bayersensor.pixelShiftStddevFactorGreen); - pixelShiftStddevFactorRed->setDefault( defParams->raw.bayersensor.pixelShiftStddevFactorRed); - pixelShiftStddevFactorBlue->setDefault( defParams->raw.bayersensor.pixelShiftStddevFactorBlue); - pixelShiftNreadIso->setDefault( defParams->raw.bayersensor.pixelShiftNreadIso); - pixelShiftPrnu->setDefault( defParams->raw.bayersensor.pixelShiftPrnu); - pixelShiftRedBlueWeight->setDefault( defParams->raw.bayersensor.pixelShiftRedBlueWeight); -#endif pixelShiftEperIso->setDefault( defParams->raw.bayersensor.pixelShiftEperIso); pixelShiftSigma->setDefault( defParams->raw.bayersensor.pixelShiftSigma); ccSteps->setDefault (defParams->raw.bayersensor.ccSteps); @@ -667,32 +413,12 @@ void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams if (pedited) { dcbIterations->setDefaultEditedState( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); lmmseIterations->setDefaultEditedState( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftMotion ? Edited : UnEdited); - pixelShiftSum->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftSum ? Edited : UnEdited); - pixelShiftStddevFactorGreen->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftStddevFactorGreen ? Edited : UnEdited); - pixelShiftStddevFactorRed->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftStddevFactorRed ? Edited : UnEdited); - pixelShiftStddevFactorBlue->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftStddevFactorBlue ? Edited : UnEdited); - pixelShiftNreadIso->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftNreadIso ? Edited : UnEdited); - pixelShiftPrnu->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftPrnu ? Edited : UnEdited); - pixelShiftRedBlueWeight->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftRedBlueWeight ? Edited : UnEdited); -#endif pixelShiftEperIso->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); ccSteps->setDefaultEditedState(pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); } else { dcbIterations->setDefaultEditedState( Irrelevant ); lmmseIterations->setDefaultEditedState( Irrelevant ); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->setDefaultEditedState( Irrelevant ); - pixelShiftSum->setDefaultEditedState( Irrelevant ); - pixelShiftStddevFactorGreen->setDefaultEditedState( Irrelevant ); - pixelShiftStddevFactorRed->setDefaultEditedState( Irrelevant ); - pixelShiftStddevFactorBlue->setDefaultEditedState( Irrelevant ); - pixelShiftNreadIso->setDefaultEditedState( Irrelevant ); - pixelShiftPrnu->setDefaultEditedState( Irrelevant ); - pixelShiftRedBlueWeight->setDefaultEditedState( Irrelevant ); -#endif pixelShiftEperIso->setDefaultEditedState( Irrelevant ); pixelShiftSigma->setDefaultEditedState( Irrelevant ); ccSteps->setDefaultEditedState(Irrelevant ); @@ -708,24 +434,6 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); } else if (a == lmmseIterations) { listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() ); -#ifdef PIXELSHIFTDEV - } else if (a == pixelShiftMotion) { - listener->panelChanged (EvPixelShiftMotion, a->getTextValue() ); - } else if (a == pixelShiftSum) { - listener->panelChanged (EvPixelShiftSum, a->getTextValue() ); - } else if (a == pixelShiftStddevFactorGreen) { - listener->panelChanged (EvPixelShiftStddevFactorGreen, a->getTextValue() ); - } else if (a == pixelShiftStddevFactorRed) { - listener->panelChanged (EvPixelShiftStddevFactorRed, a->getTextValue() ); - } else if (a == pixelShiftStddevFactorBlue) { - listener->panelChanged (EvPixelShiftStddevFactorBlue, a->getTextValue() ); - } else if (a == pixelShiftNreadIso) { - listener->panelChanged (EvPixelShiftNreadIso, a->getTextValue() ); - } else if (a == pixelShiftPrnu) { - listener->panelChanged (EvPixelShiftPrnu, a->getTextValue() ); - } else if (a == pixelShiftRedBlueWeight) { - listener->panelChanged (EvPixelShiftRedBlueWeight, a->getTextValue() ); -#endif } else if (a == pixelShiftEperIso) { listener->panelChanged (EvPixelShiftEperIso, a->getTextValue() ); } else if (a == pixelShiftSigma) { @@ -736,27 +444,6 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) } } -#ifdef PIXELSHIFTDEV -void BayerProcess::psMotionCorrectionChanged () -{ - if (!batchMode) { - if(pixelShiftMotionCorrection->get_active_row_number() == 5) { - pixelShiftBlur->set_sensitive(true); - pixelShiftHoleFill->set_sensitive(true); - pixelShiftSmooth->set_sensitive(pixelShiftBlur->getValue() != CheckValue::off); - } else { - pixelShiftBlur->set_sensitive(false); - pixelShiftHoleFill->set_sensitive(false); - pixelShiftSmooth->set_sensitive(false); - } - } - - if (listener) { - listener->panelChanged (EvPixelShiftMotionCorrection, pixelShiftMotionCorrection->get_active_text()); - } -} -#endif - void BayerProcess::methodChanged () { const int curSelection = method->get_active_row_number(); @@ -834,11 +521,6 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) listener->panelChanged (EvPixelShiftHoleFill, pixelShiftHoleFill->getValueAsStr ()); } } else if (c == pixelShiftMedian) { -#ifdef PIXELSHIFTDEV - if (!batchMode) { - pixelShiftMedian3->set_sensitive(newval != CheckValue::off); - } -#endif if (listener) { listener->panelChanged (EvPixelShiftMedian, pixelShiftMedian->getValueAsStr ()); } @@ -858,10 +540,6 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) if (listener) { listener->panelChanged (EvPixelShiftLmmse, pixelShiftLmmse->getValueAsStr ()); } -// } else if (c == pixelShiftOneGreen) { -// if (listener) { -// listener->panelChanged (EvPixelShiftOneGreen, pixelShiftOneGreen->getValueAsStr ()); -// } } else if (c == pixelShiftEqualBright) { if (!batchMode) { pixelShiftEqualBrightChannel->set_sensitive(newval != CheckValue::off); @@ -878,61 +556,6 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) listener->panelChanged (EvPixelShiftNonGreenCross, pixelShiftNonGreenCross->getValueAsStr ()); } } -#ifdef PIXELSHIFTDEV - else if (c == pixelShiftAutomatic) { - if (!batchMode) { - pixelShiftMotion->set_sensitive(newval != CheckValue::off); - pixelShiftEperIso->set_sensitive(newval != CheckValue::off); - pixelShiftNreadIso->set_sensitive(newval != CheckValue::off); - pixelShiftPrnu->set_sensitive(newval != CheckValue::off); - pixelShiftSigma->set_sensitive(newval != CheckValue::off); - pixelShiftSum->set_sensitive(newval != CheckValue::off); - pixelShiftRedBlueWeight->set_sensitive(newval != CheckValue::off); - pixelShiftStddevFactorGreen->set_sensitive(newval != CheckValue::off); - pixelShiftStddevFactorRed->set_sensitive(newval != CheckValue::off); - pixelShiftStddevFactorBlue->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenHorizontal->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenVertical->set_sensitive(newval != CheckValue::off); - pixelShiftHoleFill->set_sensitive(newval != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftMedian3->set_sensitive(newval != CheckValue::off && pixelShiftMedian->getValue () != CheckValue::off); - pixelShiftGreen->set_sensitive(newval != CheckValue::off); - pixelShiftBlur->set_sensitive(newval != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftSmooth->set_sensitive(newval != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5 && pixelShiftBlur->getValue () != CheckValue::off); - pixelShiftExp0->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenCross->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenCross2->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenAmaze->set_sensitive(newval != CheckValue::off); - } - - if (listener) { - listener->panelChanged (EvPixelShiftAutomatic, pixelShiftAutomatic->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenHorizontal) { - if (listener) { - listener->panelChanged (EvPixelShiftNonGreenHorizontal, pixelShiftNonGreenHorizontal->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenVertical) { - if (listener) { - listener->panelChanged (EvPixelShiftNonGreenVertical, pixelShiftNonGreenVertical->getValueAsStr ()); - } - } else if (c == pixelShiftMedian3) { - if (listener) { - listener->panelChanged (EvPixelShiftMedian3, pixelShiftMedian3->getValueAsStr ()); - } - } else if (c == pixelShiftExp0) { - if (listener) { - listener->panelChanged (EvPixelShiftExp0, pixelShiftExp0->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenCross2) { - if (listener) { - listener->panelChanged (EvPixelShiftGreenAmaze, pixelShiftNonGreenCross2->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenAmaze) { - if (listener) { - listener->panelChanged (EvPixelShiftNonGreenAmaze, pixelShiftNonGreenAmaze->getValueAsStr ()); - } - } -#endif } void BayerProcess::pixelShiftMotionMethodChanged () diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index e1a620474..48b445d90 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -49,31 +49,12 @@ protected: CheckBox* pixelShiftBlur; CheckBox* pixelShiftHoleFill; CheckBox* pixelShiftMedian; -// CheckBox* pixelShiftOneGreen; CheckBox* pixelShiftLmmse; CheckBox* pixelShiftEqualBright; CheckBox* pixelShiftEqualBrightChannel; Adjuster* pixelShiftSmooth; Adjuster* pixelShiftEperIso; Adjuster* pixelShiftSigma; -#ifdef PIXELSHIFTDEV - Adjuster* pixelShiftSum; - Adjuster* pixelShiftMotion; - MyComboBoxText* pixelShiftMotionCorrection; - CheckBox* pixelShiftAutomatic; - CheckBox* pixelShiftNonGreenHorizontal; - CheckBox* pixelShiftNonGreenVertical; - CheckBox* pixelShiftNonGreenCross2; - CheckBox* pixelShiftNonGreenAmaze; - CheckBox* pixelShiftExp0; - CheckBox* pixelShiftMedian3; - Adjuster* pixelShiftStddevFactorGreen; - Adjuster* pixelShiftStddevFactorRed; - Adjuster* pixelShiftStddevFactorBlue; - Adjuster* pixelShiftNreadIso; - Adjuster* pixelShiftPrnu; - Adjuster* pixelShiftRedBlueWeight; -#endif int oldMethod; IdleRegister idle_register; @@ -92,9 +73,6 @@ public: void checkBoxToggled (CheckBox* c, CheckValue newval); void pixelShiftMotionMethodChanged(); void FrameCountChanged(int n, int frameNum); -#ifdef PIXELSHIFTDEV - void psMotionCorrectionChanged (); -#endif }; #endif diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 9d177a05e..d204f1ff9 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -108,9 +108,9 @@ public: std::string getModel (unsigned int frame = 0) const { return camModel; } std::string getLens (unsigned int frame = 0) const { return lens; } std::string getOrientation (unsigned int frame = 0) const { return ""; } // TODO - bool getPixelShift (unsigned int frame = 0) const { return isPixelShift; } + bool getPixelShift () const { return isPixelShift; } bool getHDR (unsigned int frame = 0) const { return isHDR; } - std::string getRawType (unsigned int frame) const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } + std::string getImageType (unsigned int frame) const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat (unsigned int frame = 0) const { return sampleFormat; } }; #endif diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index 7f0ed5db7..d7e8f356a 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -41,7 +41,7 @@ DynamicProfilePanel::EditDialog::EditDialog (const Glib::ustring &title, Gtk::Wi add_optional (M ("EXIFFILTER_CAMERA"), has_camera_, camera_); add_optional (M ("EXIFFILTER_LENS"), has_lens_, lens_); - add_optional (M ("EXIFFILTER_RAWTYPE"), has_rawtype_, rawtype_); + add_optional (M ("EXIFFILTER_IMAGETYPE"), has_imagetype_, imagetype_); add_range (M ("EXIFFILTER_ISO"), iso_min_, iso_max_); add_range (M ("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_); @@ -82,8 +82,8 @@ void DynamicProfilePanel::EditDialog::set_rule ( has_lens_->set_active (rule.lens.enabled); lens_->set_text (rule.lens.value); - has_rawtype_->set_active (rule.rawType.enabled); - rawtype_->set_text (rule.rawType.value); + has_imagetype_->set_active (rule.imagetype.enabled); + imagetype_->set_text (rule.imagetype.value); profilepath_->updateProfileList(); @@ -116,8 +116,8 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() ret.lens.enabled = has_lens_->get_active(); ret.lens.value = lens_->get_text(); - ret.rawType.enabled = has_rawtype_->get_active(); - ret.rawType.value = rawtype_->get_text(); + ret.imagetype.enabled = has_imagetype_->get_active(); + ret.imagetype.value = imagetype_->get_text(); ret.profilepath = profilepath_->getFullPathFromActiveRow(); @@ -261,6 +261,16 @@ DynamicProfilePanel::DynamicProfilePanel(): *this, &DynamicProfilePanel::render_lens)); } + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_IMAGETYPE"), *cell); + col = treeview_.get_column (cols_count - 1); + + if (col) { + col->set_cell_data_func ( + *cell, sigc::mem_fun ( + *this, &DynamicProfilePanel::render_imagetype)); + } + cell = Gtk::manage (new Gtk::CellRendererText()); cols_count = treeview_.append_column (M ("EXIFFILTER_ISO"), *cell); col = treeview_.get_column (cols_count - 1); @@ -330,6 +340,7 @@ void DynamicProfilePanel::update_rule (Gtk::TreeModel::Row row, row[columns_.expcomp] = rule.expcomp; row[columns_.camera] = rule.camera; row[columns_.lens] = rule.lens; + row[columns_.imagetype] = rule.imagetype; row[columns_.profilepath] = rule.profilepath; } @@ -353,6 +364,7 @@ DynamicProfileRule DynamicProfilePanel::to_rule (Gtk::TreeModel::Row row, ret.camera = row[columns_.camera]; ret.lens = row[columns_.lens]; ret.profilepath = row[columns_.profilepath]; + ret.imagetype = row[columns_.imagetype]; return ret; } @@ -463,6 +475,12 @@ void DynamicProfilePanel::render_lens ( RENDER_OPTIONAL_ (lens); } +void DynamicProfilePanel::render_imagetype ( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_OPTIONAL_ (imagetype); +} + #undef RENDER_OPTIONAL_ void DynamicProfilePanel::on_button_up() diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index 26e816cb0..3b5bec4df 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -54,6 +54,7 @@ private: add (camera); add (lens); add (profilepath); + add (imagetype); } Gtk::TreeModelColumn> iso; @@ -63,6 +64,7 @@ private: Gtk::TreeModelColumn> expcomp; Gtk::TreeModelColumn camera; Gtk::TreeModelColumn lens; + Gtk::TreeModelColumn imagetype; Gtk::TreeModelColumn profilepath; }; @@ -74,6 +76,7 @@ private: void render_expcomp (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_camera (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_lens (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_imagetype (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_profilepath (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); class EditDialog: public Gtk::Dialog @@ -109,8 +112,8 @@ private: Gtk::CheckButton *has_lens_; Gtk::Entry *lens_; - Gtk::CheckButton *has_rawtype_; - Gtk::Entry *rawtype_; + Gtk::CheckButton *has_imagetype_; + Gtk::Entry *imagetype_; ProfileStoreComboBox *profilepath_; }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 868507ad0..adaf4e2d8 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -425,7 +425,6 @@ void ParamsEdited::set (bool v) raw.bayersensor.pixelShiftSmooth = v; raw.bayersensor.pixelShiftExp0 = v; raw.bayersensor.pixelShiftLmmse = v; - raw.bayersensor.pixelShiftOneGreen = v; raw.bayersensor.pixelShiftEqualBright = v; raw.bayersensor.pixelShiftEqualBrightChannel = v; raw.bayersensor.pixelShiftNonGreenCross = v; @@ -988,7 +987,6 @@ void ParamsEdited::initFrom (const std::vector raw.bayersensor.pixelShiftSmooth = raw.bayersensor.pixelShiftSmooth && p.raw.bayersensor.pixelShiftSmoothFactor == other.raw.bayersensor.pixelShiftSmoothFactor; raw.bayersensor.pixelShiftExp0 = raw.bayersensor.pixelShiftExp0 && p.raw.bayersensor.pixelShiftExp0 == other.raw.bayersensor.pixelShiftExp0; raw.bayersensor.pixelShiftLmmse = raw.bayersensor.pixelShiftLmmse && p.raw.bayersensor.pixelShiftLmmse == other.raw.bayersensor.pixelShiftLmmse; - raw.bayersensor.pixelShiftOneGreen = raw.bayersensor.pixelShiftOneGreen && p.raw.bayersensor.pixelShiftOneGreen == other.raw.bayersensor.pixelShiftOneGreen; raw.bayersensor.pixelShiftEqualBright = raw.bayersensor.pixelShiftEqualBright && p.raw.bayersensor.pixelShiftEqualBright == other.raw.bayersensor.pixelShiftEqualBright; raw.bayersensor.pixelShiftEqualBrightChannel = raw.bayersensor.pixelShiftEqualBrightChannel && p.raw.bayersensor.pixelShiftEqualBrightChannel == other.raw.bayersensor.pixelShiftEqualBrightChannel; raw.bayersensor.pixelShiftNonGreenCross = raw.bayersensor.pixelShiftNonGreenCross && p.raw.bayersensor.pixelShiftNonGreenCross == other.raw.bayersensor.pixelShiftNonGreenCross; @@ -2612,10 +2610,6 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelShiftLmmse = mods.raw.bayersensor.pixelShiftLmmse; } - if (raw.bayersensor.pixelShiftOneGreen) { - toEdit.raw.bayersensor.pixelShiftOneGreen = mods.raw.bayersensor.pixelShiftOneGreen; - } - if (raw.bayersensor.pixelShiftEqualBright) { toEdit.raw.bayersensor.pixelShiftEqualBright = mods.raw.bayersensor.pixelShiftEqualBright; } @@ -3159,7 +3153,7 @@ bool RAWParamsEdited::BayerSensor::isUnchanged() const return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq && pixelShiftMotion && pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod && pixelShiftStddevFactorGreen && pixelShiftStddevFactorRed && pixelShiftStddevFactorBlue && pixelShiftEperIso && pixelShiftNreadIso && pixelShiftPrnu && pixelShiftSigma && pixelShiftSum && pixelShiftRedBlueWeight && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly - && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftOneGreen && pixelShiftEqualBright && pixelShiftEqualBrightChannel + && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftEqualBright && pixelShiftEqualBrightChannel && linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 12c8ee86e..75a27f7fa 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -753,7 +753,6 @@ public: bool pixelShiftSmooth; bool pixelShiftExp0; bool pixelShiftLmmse; - bool pixelShiftOneGreen; bool pixelShiftEqualBright; bool pixelShiftEqualBrightChannel; bool pixelShiftNonGreenCross; From 3578529082cee5be0317670f02b3fa9a71a19859 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 14 Apr 2018 23:24:28 +0200 Subject: [PATCH 4/8] Pixelshift: further cleanup --- rtengine/pixelshift.cc | 11 ++--- rtengine/procevents.h | 28 +++++------ rtengine/procparams.cc | 87 --------------------------------- rtengine/procparams.h | 25 ---------- rtengine/refreshmap.cc | 34 ++++++------- rtgui/paramsedited.cc | 101 +-------------------------------------- rtgui/paramsedited.h | 16 ------- rtgui/partialpastedlg.cc | 16 ------- 8 files changed, 38 insertions(+), 280 deletions(-) diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 9b13597a0..5fcb391a7 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -305,14 +305,14 @@ BENCHFUN RAWParams::BayerSensor bayerParams = bayerParamsIn; - bayerParams.pixelShiftAutomatic = true; + bool motionDetection = true; if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO) { bool pixelShiftEqualBright = bayerParams.pixelShiftEqualBright; bayerParams.setPixelShiftDefaults(); bayerParams.pixelShiftEqualBright = pixelShiftEqualBright; } else if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::OFF) { - bayerParams.pixelShiftAutomatic = false; + motionDetection = false; bayerParams.pixelShiftShowMotion = false; } @@ -320,7 +320,7 @@ BENCHFUN const bool showOnlyMask = bayerParams.pixelShiftShowMotionMaskOnly && showMotion; const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; - if(bayerParams.pixelShiftAutomatic) { + if(motionDetection) { if(!showOnlyMask) { if(bayerParams.pixelShiftMedian) { // We need the demosaiced frames for motion correction if(bayerParams.pixelShiftLmmse) { @@ -368,7 +368,6 @@ BENCHFUN } } - const bool automatic = bayerParams.pixelShiftAutomatic; constexpr float stddevFactorGreen = 25.f; constexpr float stddevFactorRed = 25.f; constexpr float stddevFactorBlue = 25.f; @@ -551,7 +550,7 @@ BENCHFUN plistener->setProgress(0.0); } - if(automatic && blurMap && smoothFactor == 0.f && !showMotion) { + if(motionDetection && blurMap && smoothFactor == 0.f && !showMotion) { if(plistener) { plistener->setProgress(1.0); } @@ -696,7 +695,7 @@ BENCHFUN } - if(automatic) { + if(motionDetection) { // fill channels psRed and psBlue array2D psRed(winw + 32, winh); // increase width to avoid cache conflicts array2D psBlue(winw + 32, winh); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index dd43a9abe..a35a709f9 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -472,31 +472,31 @@ enum ProcEventCode { EvOBPCompens = 442, EvWBtempBias = 443, EvRawImageNum = 444, - EvPixelShiftMotion = 445, - EvPixelShiftMotionCorrection = 446, - EvPixelShiftStddevFactorGreen = 447, +// EvPixelShiftMotion = 445, +// EvPixelShiftMotionCorrection = 446, +// EvPixelShiftStddevFactorGreen = 447, EvPixelShiftEperIso = 448, - EvPixelShiftNreadIso = 449, - EvPixelShiftPrnu = 450, +// EvPixelShiftNreadIso = 449, +// EvPixelShiftPrnu = 450, EvPixelshiftShowMotion = 451, EvPixelshiftShowMotionMaskOnly = 452, - EvPixelShiftAutomatic = 453, +// EvPixelShiftAutomatic = 453, // EvPixelShiftNonGreenHorizontal = 454, // EvPixelShiftNonGreenVertical = 455, EvPixelShiftNonGreenCross = 456, - EvPixelShiftStddevFactorRed = 457, - EvPixelShiftStddevFactorBlue = 458, - EvPixelShiftGreenAmaze = 459, - EvPixelShiftNonGreenAmaze = 460, +// EvPixelShiftStddevFactorRed = 457, +// EvPixelShiftStddevFactorBlue = 458, +// EvPixelShiftGreenAmaze = 459, +// EvPixelShiftNonGreenAmaze = 460, EvPixelShiftGreen = 461, - EvPixelShiftRedBlueWeight = 462, +// EvPixelShiftRedBlueWeight = 462, EvPixelShiftBlur = 463, EvPixelShiftSigma = 464, - EvPixelShiftSum = 465, - EvPixelShiftExp0 = 466, +// EvPixelShiftSum = 465, +// EvPixelShiftExp0 = 466, EvPixelShiftHoleFill = 467, EvPixelShiftMedian = 468, - EvPixelShiftMedian3 = 469, +// EvPixelShiftMedian3 = 469, EvPixelShiftMotionMethod = 470, EvPixelShiftSmooth = 471, EvPixelShiftLmmse = 472, diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index a0857aed6..74adc4a6e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2355,36 +2355,20 @@ RAWParams::BayerSensor::BayerSensor() : greenthresh(0), dcb_iterations(2), lmmse_iterations(2), - pixelShiftMotion(0), - pixelShiftMotionCorrection(PSMotionCorrection::GRID_3X3_NEW), pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO), - pixelShiftStddevFactorGreen(5.0), - pixelShiftStddevFactorRed(5.0), - pixelShiftStddevFactorBlue(5.0), pixelShiftEperIso(0.0), - pixelShiftNreadIso(0.0), - pixelShiftPrnu(1.0), pixelShiftSigma(1.0), - pixelShiftSum(3.0), - pixelShiftRedBlueWeight(0.7), pixelShiftShowMotion(false), pixelShiftShowMotionMaskOnly(false), - pixelShiftAutomatic(true), -// pixelShiftNonGreenHorizontal(false), -// pixelShiftNonGreenVertical(false), pixelShiftHoleFill(true), pixelShiftMedian(false), - pixelShiftMedian3(false), pixelShiftGreen(true), pixelShiftBlur(true), pixelShiftSmoothFactor(0.7), - pixelShiftExp0(false), pixelShiftLmmse(false), pixelShiftEqualBright(false), pixelShiftEqualBrightChannel(false), pixelShiftNonGreenCross(true), - pixelShiftNonGreenCross2(false), - pixelShiftNonGreenAmaze(false), dcb_enhance(true), pdafLinesFilter(false) { @@ -2406,36 +2390,20 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const && greenthresh == other.greenthresh && dcb_iterations == other.dcb_iterations && lmmse_iterations == other.lmmse_iterations - && pixelShiftMotion == other.pixelShiftMotion - && pixelShiftMotionCorrection == other.pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod - && pixelShiftStddevFactorGreen == other.pixelShiftStddevFactorGreen - && pixelShiftStddevFactorRed == other.pixelShiftStddevFactorRed - && pixelShiftStddevFactorBlue == other.pixelShiftStddevFactorBlue && pixelShiftEperIso == other.pixelShiftEperIso - && pixelShiftNreadIso == other.pixelShiftNreadIso - && pixelShiftPrnu == other.pixelShiftPrnu && pixelShiftSigma == other.pixelShiftSigma - && pixelShiftSum == other.pixelShiftSum - && pixelShiftRedBlueWeight == other.pixelShiftRedBlueWeight && pixelShiftShowMotion == other.pixelShiftShowMotion && pixelShiftShowMotionMaskOnly == other.pixelShiftShowMotionMaskOnly - && pixelShiftAutomatic == other.pixelShiftAutomatic -// && pixelShiftNonGreenHorizontal == other.pixelShiftNonGreenHorizontal -// && pixelShiftNonGreenVertical == other.pixelShiftNonGreenVertical && pixelShiftHoleFill == other.pixelShiftHoleFill && pixelShiftMedian == other.pixelShiftMedian - && pixelShiftMedian3 == other.pixelShiftMedian3 && pixelShiftGreen == other.pixelShiftGreen && pixelShiftBlur == other.pixelShiftBlur && pixelShiftSmoothFactor == other.pixelShiftSmoothFactor - && pixelShiftExp0 == other.pixelShiftExp0 && pixelShiftLmmse == other.pixelShiftLmmse && pixelShiftEqualBright == other.pixelShiftEqualBright && pixelShiftEqualBrightChannel == other.pixelShiftEqualBrightChannel && pixelShiftNonGreenCross == other.pixelShiftNonGreenCross - && pixelShiftNonGreenCross2 == other.pixelShiftNonGreenCross2 - && pixelShiftNonGreenAmaze == other.pixelShiftNonGreenAmaze && dcb_enhance == other.dcb_enhance && pdafLinesFilter == other.pdafLinesFilter; } @@ -2447,34 +2415,18 @@ bool RAWParams::BayerSensor::operator !=(const BayerSensor& other) const void RAWParams::BayerSensor::setPixelShiftDefaults() { - pixelShiftMotion = 0; - pixelShiftMotionCorrection = RAWParams::BayerSensor::PSMotionCorrection::GRID_3X3_NEW; pixelShiftMotionCorrectionMethod = RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO; - pixelShiftStddevFactorGreen = 5.0; - pixelShiftStddevFactorRed = 5.0; - pixelShiftStddevFactorBlue = 5.0; pixelShiftEperIso = 0.0; - pixelShiftNreadIso = 0.0; - pixelShiftPrnu = 1.0; pixelShiftSigma = 1.0; - pixelShiftSum = 3.0; - pixelShiftRedBlueWeight = 0.7; - pixelShiftAutomatic = true; -// pixelShiftNonGreenHorizontal = false; -// pixelShiftNonGreenVertical = false; pixelShiftHoleFill = true; pixelShiftMedian = false; - pixelShiftMedian3 = false; pixelShiftGreen = true; pixelShiftBlur = true; pixelShiftSmoothFactor = 0.7; - pixelShiftExp0 = false; pixelShiftLmmse = false; pixelShiftEqualBright = false; pixelShiftEqualBrightChannel = false; pixelShiftNonGreenCross = true; - pixelShiftNonGreenCross2 = false; - pixelShiftNonGreenAmaze = false; } const std::vector& RAWParams::BayerSensor::getMethodStrings() @@ -3375,36 +3327,20 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbIterations, "RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbEnhance, "RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.lmmseIterations, "RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotion, "RAW Bayer", "PixelShiftMotion", raw.bayersensor.pixelShiftMotion, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrection, "RAW Bayer", "PixelShiftMotionCorrection", toUnderlying(raw.bayersensor.pixelShiftMotionCorrection), keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod, "RAW Bayer", "PixelShiftMotionCorrectionMethod", toUnderlying(raw.bayersensor.pixelShiftMotionCorrectionMethod), keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftStddevFactorGreen, "RAW Bayer", "pixelShiftStddevFactorGreen", raw.bayersensor.pixelShiftStddevFactorGreen, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftStddevFactorRed, "RAW Bayer", "pixelShiftStddevFactorRed", raw.bayersensor.pixelShiftStddevFactorRed, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftStddevFactorBlue, "RAW Bayer", "pixelShiftStddevFactorBlue", raw.bayersensor.pixelShiftStddevFactorBlue, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEperIso, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNreadIso, "RAW Bayer", "PixelShiftNreadIso", raw.bayersensor.pixelShiftNreadIso, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftPrnu, "RAW Bayer", "PixelShiftPrnu", raw.bayersensor.pixelShiftPrnu, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSigma, "RAW Bayer", "PixelShiftSigma", raw.bayersensor.pixelShiftSigma, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSum, "RAW Bayer", "PixelShiftSum", raw.bayersensor.pixelShiftSum, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftRedBlueWeight, "RAW Bayer", "PixelShiftRedBlueWeight", raw.bayersensor.pixelShiftRedBlueWeight, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotion, "RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelShiftShowMotion, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly, "RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelShiftShowMotionMaskOnly, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftAutomatic, "RAW Bayer", "pixelShiftAutomatic", raw.bayersensor.pixelShiftAutomatic, keyFile); -// saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenHorizontal, "RAW Bayer", "pixelShiftNonGreenHorizontal", raw.bayersensor.pixelShiftNonGreenHorizontal, keyFile); -// saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenVertical, "RAW Bayer", "pixelShiftNonGreenVertical", raw.bayersensor.pixelShiftNonGreenVertical, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftHoleFill, "RAW Bayer", "pixelShiftHoleFill", raw.bayersensor.pixelShiftHoleFill, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian, "RAW Bayer", "pixelShiftMedian", raw.bayersensor.pixelShiftMedian, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian3, "RAW Bayer", "pixelShiftMedian3", raw.bayersensor.pixelShiftMedian3, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftGreen, "RAW Bayer", "pixelShiftGreen", raw.bayersensor.pixelShiftGreen, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftBlur, "RAW Bayer", "pixelShiftBlur", raw.bayersensor.pixelShiftBlur, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSmooth, "RAW Bayer", "pixelShiftSmoothFactor", raw.bayersensor.pixelShiftSmoothFactor, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftExp0, "RAW Bayer", "pixelShiftExp0", raw.bayersensor.pixelShiftExp0, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftLmmse, "RAW Bayer", "pixelShiftLmmse", raw.bayersensor.pixelShiftLmmse, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBright, "RAW Bayer", "pixelShiftEqualBright", raw.bayersensor.pixelShiftEqualBright, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBrightChannel, "RAW Bayer", "pixelShiftEqualBrightChannel", raw.bayersensor.pixelShiftEqualBrightChannel, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross, "RAW Bayer", "pixelShiftNonGreenCross", raw.bayersensor.pixelShiftNonGreenCross, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross2, "RAW Bayer", "pixelShiftNonGreenCross2", raw.bayersensor.pixelShiftNonGreenCross2, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenAmaze, "RAW Bayer", "pixelShiftNonGreenAmaze", raw.bayersensor.pixelShiftNonGreenAmaze, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pdafLinesFilter, "RAW Bayer", "PDAFLinesFilter", raw.bayersensor.pdafLinesFilter, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.method, "RAW X-Trans", "Method", raw.xtranssensor.method, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile); @@ -4700,15 +4636,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftMotion", pedited, raw.bayersensor.pixelShiftMotion, pedited->raw.bayersensor.pixelShiftMotion); - - if (keyFile.has_key ("RAW Bayer", "PixelShiftMotionCorrection")) { - raw.bayersensor.pixelShiftMotionCorrection = (RAWParams::BayerSensor::PSMotionCorrection)keyFile.get_integer ("RAW Bayer", "PixelShiftMotionCorrection"); - - if (pedited) { - pedited->raw.bayersensor.pixelShiftMotionCorrection = true; - } - } if (keyFile.has_key ("RAW Bayer", "PixelShiftMotionCorrectionMethod")) { raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)keyFile.get_integer ("RAW Bayer", "PixelShiftMotionCorrectionMethod"); @@ -4718,33 +4645,19 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftStddevFactorGreen", pedited, raw.bayersensor.pixelShiftStddevFactorGreen, pedited->raw.bayersensor.pixelShiftStddevFactorGreen); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftStddevFactorRed", pedited, raw.bayersensor.pixelShiftStddevFactorRed, pedited->raw.bayersensor.pixelShiftStddevFactorRed); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftStddevFactorBlue", pedited, raw.bayersensor.pixelShiftStddevFactorBlue, pedited->raw.bayersensor.pixelShiftStddevFactorBlue); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftEperIso", pedited, raw.bayersensor.pixelShiftEperIso, pedited->raw.bayersensor.pixelShiftEperIso); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftNreadIso", pedited, raw.bayersensor.pixelShiftNreadIso, pedited->raw.bayersensor.pixelShiftNreadIso); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftPrnu", pedited, raw.bayersensor.pixelShiftPrnu, pedited->raw.bayersensor.pixelShiftPrnu); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSigma", pedited, raw.bayersensor.pixelShiftSigma, pedited->raw.bayersensor.pixelShiftSigma); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSum", pedited, raw.bayersensor.pixelShiftSum, pedited->raw.bayersensor.pixelShiftSum); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftRedBlueWeight", pedited, raw.bayersensor.pixelShiftRedBlueWeight, pedited->raw.bayersensor.pixelShiftRedBlueWeight); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", pedited, raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", pedited, raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftAutomatic", pedited, raw.bayersensor.pixelShiftAutomatic, pedited->raw.bayersensor.pixelShiftAutomatic); -// assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenHorizontal", pedited, raw.bayersensor.pixelShiftNonGreenHorizontal, pedited->raw.bayersensor.pixelShiftNonGreenHorizontal); -// assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenVertical", pedited, raw.bayersensor.pixelShiftNonGreenVertical, pedited->raw.bayersensor.pixelShiftNonGreenVertical); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftHoleFill", pedited, raw.bayersensor.pixelShiftHoleFill, pedited->raw.bayersensor.pixelShiftHoleFill); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian", pedited, raw.bayersensor.pixelShiftMedian, pedited->raw.bayersensor.pixelShiftMedian); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian3", pedited, raw.bayersensor.pixelShiftMedian3, pedited->raw.bayersensor.pixelShiftMedian3); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftGreen", pedited, raw.bayersensor.pixelShiftGreen, pedited->raw.bayersensor.pixelShiftGreen); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftBlur", pedited, raw.bayersensor.pixelShiftBlur, pedited->raw.bayersensor.pixelShiftBlur); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", pedited, raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftExp0", pedited, raw.bayersensor.pixelShiftExp0, pedited->raw.bayersensor.pixelShiftExp0); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftLmmse", pedited, raw.bayersensor.pixelShiftLmmse, pedited->raw.bayersensor.pixelShiftLmmse); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", pedited, raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", pedited, raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", pedited, raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross2", pedited, raw.bayersensor.pixelShiftNonGreenCross2, pedited->raw.bayersensor.pixelShiftNonGreenCross2); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenAmaze", pedited, raw.bayersensor.pixelShiftNonGreenAmaze, pedited->raw.bayersensor.pixelShiftNonGreenAmaze); assignFromKeyfile(keyFile, "RAW Bayer", "PDAFLinesFilter", pedited, raw.bayersensor.pdafLinesFilter, pedited->raw.bayersensor.pdafLinesFilter); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 8560cdc59..1800a8a01 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1237,15 +1237,6 @@ struct RAWParams { PIXELSHIFT }; - enum class PSMotionCorrection { - GRID_1X1, - GRID_1X2, - GRID_3X3, - GRID_5X5, - GRID_7X7, - GRID_3X3_NEW - }; - enum class PSMotionCorrectionMethod { OFF, AUTO, @@ -1271,36 +1262,20 @@ struct RAWParams { int greenthresh; int dcb_iterations; int lmmse_iterations; - int pixelShiftMotion; - PSMotionCorrection pixelShiftMotionCorrection; PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod; - double pixelShiftStddevFactorGreen; - double pixelShiftStddevFactorRed; - double pixelShiftStddevFactorBlue; double pixelShiftEperIso; - double pixelShiftNreadIso; - double pixelShiftPrnu; double pixelShiftSigma; - double pixelShiftSum; - double pixelShiftRedBlueWeight; bool pixelShiftShowMotion; bool pixelShiftShowMotionMaskOnly; - bool pixelShiftAutomatic; - bool pixelShiftNonGreenHorizontal; - bool pixelShiftNonGreenVertical; bool pixelShiftHoleFill; bool pixelShiftMedian; - bool pixelShiftMedian3; bool pixelShiftGreen; bool pixelShiftBlur; double pixelShiftSmoothFactor; - bool pixelShiftExp0; bool pixelShiftLmmse; bool pixelShiftEqualBright; bool pixelShiftEqualBrightChannel; bool pixelShiftNonGreenCross; - bool pixelShiftNonGreenCross2; - bool pixelShiftNonGreenAmaze; bool dcb_enhance; bool pdafLinesFilter; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 4d1bfcf3c..89ddbceb2 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -472,36 +472,36 @@ int refreshmap[rtengine::NUMOFEVENTS] = { OUTPUTPROFILE, // EvOBPCompens ALLNORAW, // EvWBtempBias DARKFRAME, // EvRawImageNum - DEMOSAIC, // EvPixelShiftMotion - DEMOSAIC, // EvPixelShiftMotionCorrection - DEMOSAIC, // EvPixelShiftStddevFactorGreen + 0, // unused + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftEperIso - DEMOSAIC, // EvPixelShiftNreadIso - DEMOSAIC, // EvPixelShiftPrnu + 0, // unused + 0, // unused DEMOSAIC, // EvPixelshiftShowMotion DEMOSAIC, // EvPixelshiftShowMotionMaskOnly - DEMOSAIC, // EvPixelShiftAutomatic - DEMOSAIC, // EvPixelShiftNonGreenHorizontal - DEMOSAIC, // EvPixelShiftNonGreenVertical + 0, // unused + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftNonGreenCross - DEMOSAIC, // EvPixelShiftStddevFactorRed - DEMOSAIC, // EvPixelShiftStddevFactorBlue - DEMOSAIC, // EvPixelShiftNonGreenCross2 - DEMOSAIC, // EvPixelShiftNonGreenAmaze + 0, // unused + 0, // unused + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftGreen - DEMOSAIC, // EvPixelShiftRedBlueWeight + 0, // unused DEMOSAIC, // EvPixelShiftBlur DEMOSAIC, // EvPixelShiftSigma - DEMOSAIC, // EvPixelShiftSum - DEMOSAIC, // EvPixelShiftExp0 + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftHoleFill DEMOSAIC, // EvPixelShiftMedian - DEMOSAIC, // EvPixelShiftMedian3 + 0, // unused DEMOSAIC, // EvPixelShiftMotionMethod DEMOSAIC, // EvPixelShiftSmooth DEMOSAIC, // EvPixelShiftLmmse DEMOSAIC, // EvPixelShiftEqualBright - DEMOSAIC, // EvPixelShiftEqualBrightChannel + DEMOSAIC, // EvPixelShiftEqualBrightChannel LUMINANCECURVE, // EvCATtempout LUMINANCECURVE, // EvCATgreenout LUMINANCECURVE, // EvCATybout diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 59d0eb615..994483aef 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -401,36 +401,20 @@ void ParamsEdited::set (bool v) raw.bayersensor.dcbEnhance = v; //raw.bayersensor.allEnhance = v; raw.bayersensor.lmmseIterations = v; - raw.bayersensor.pixelShiftMotion = v; - raw.bayersensor.pixelShiftMotionCorrection = v; raw.bayersensor.pixelShiftMotionCorrectionMethod = v; - raw.bayersensor.pixelShiftStddevFactorGreen = v; - raw.bayersensor.pixelShiftStddevFactorRed = v; - raw.bayersensor.pixelShiftStddevFactorBlue = v; raw.bayersensor.pixelShiftEperIso = v; - raw.bayersensor.pixelShiftNreadIso = v; - raw.bayersensor.pixelShiftPrnu = v; raw.bayersensor.pixelShiftSigma = v; - raw.bayersensor.pixelShiftSum = v; - raw.bayersensor.pixelShiftRedBlueWeight = v; raw.bayersensor.pixelShiftShowMotion = v; raw.bayersensor.pixelShiftShowMotionMaskOnly = v; - raw.bayersensor.pixelShiftAutomatic = v; - raw.bayersensor.pixelShiftNonGreenHorizontal = v; - raw.bayersensor.pixelShiftNonGreenVertical = v; raw.bayersensor.pixelShiftHoleFill = v; raw.bayersensor.pixelShiftMedian = v; - raw.bayersensor.pixelShiftMedian3 = v; raw.bayersensor.pixelShiftGreen = v; raw.bayersensor.pixelShiftBlur = v; raw.bayersensor.pixelShiftSmooth = v; - raw.bayersensor.pixelShiftExp0 = v; raw.bayersensor.pixelShiftLmmse = v; raw.bayersensor.pixelShiftEqualBright = v; raw.bayersensor.pixelShiftEqualBrightChannel = v; raw.bayersensor.pixelShiftNonGreenCross = v; - raw.bayersensor.pixelShiftNonGreenCross2 = v; - raw.bayersensor.pixelShiftNonGreenAmaze = v; raw.bayersensor.greenEq = v; raw.bayersensor.linenoise = v; raw.bayersensor.linenoiseDirection = v; @@ -964,36 +948,20 @@ void ParamsEdited::initFrom (const std::vector raw.bayersensor.dcbEnhance = raw.bayersensor.dcbEnhance && p.raw.bayersensor.dcb_enhance == other.raw.bayersensor.dcb_enhance; //raw.bayersensor.allEnhance = raw.bayersensor.allEnhance && p.raw.bayersensor.all_enhance == other.raw.bayersensor.all_enhance; raw.bayersensor.lmmseIterations = raw.bayersensor.lmmseIterations && p.raw.bayersensor.lmmse_iterations == other.raw.bayersensor.lmmse_iterations; - raw.bayersensor.pixelShiftMotion = raw.bayersensor.pixelShiftMotion && p.raw.bayersensor.pixelShiftMotion == other.raw.bayersensor.pixelShiftMotion; - raw.bayersensor.pixelShiftMotionCorrection = raw.bayersensor.pixelShiftMotionCorrection && p.raw.bayersensor.pixelShiftMotionCorrection == other.raw.bayersensor.pixelShiftMotionCorrection; raw.bayersensor.pixelShiftMotionCorrectionMethod = raw.bayersensor.pixelShiftMotionCorrectionMethod && p.raw.bayersensor.pixelShiftMotionCorrectionMethod == other.raw.bayersensor.pixelShiftMotionCorrectionMethod; - raw.bayersensor.pixelShiftStddevFactorGreen = raw.bayersensor.pixelShiftStddevFactorGreen && p.raw.bayersensor.pixelShiftStddevFactorGreen == other.raw.bayersensor.pixelShiftStddevFactorGreen; - raw.bayersensor.pixelShiftStddevFactorRed = raw.bayersensor.pixelShiftStddevFactorRed && p.raw.bayersensor.pixelShiftStddevFactorRed == other.raw.bayersensor.pixelShiftStddevFactorRed; - raw.bayersensor.pixelShiftStddevFactorBlue = raw.bayersensor.pixelShiftStddevFactorBlue && p.raw.bayersensor.pixelShiftStddevFactorBlue == other.raw.bayersensor.pixelShiftStddevFactorBlue; raw.bayersensor.pixelShiftEperIso = raw.bayersensor.pixelShiftEperIso && p.raw.bayersensor.pixelShiftEperIso == other.raw.bayersensor.pixelShiftEperIso; - raw.bayersensor.pixelShiftNreadIso = raw.bayersensor.pixelShiftNreadIso && p.raw.bayersensor.pixelShiftNreadIso == other.raw.bayersensor.pixelShiftNreadIso; - raw.bayersensor.pixelShiftPrnu = raw.bayersensor.pixelShiftPrnu && p.raw.bayersensor.pixelShiftPrnu == other.raw.bayersensor.pixelShiftPrnu; raw.bayersensor.pixelShiftSigma = raw.bayersensor.pixelShiftSigma && p.raw.bayersensor.pixelShiftSigma == other.raw.bayersensor.pixelShiftSigma; - raw.bayersensor.pixelShiftSum = raw.bayersensor.pixelShiftSum && p.raw.bayersensor.pixelShiftSum == other.raw.bayersensor.pixelShiftSum; - raw.bayersensor.pixelShiftRedBlueWeight = raw.bayersensor.pixelShiftRedBlueWeight && p.raw.bayersensor.pixelShiftRedBlueWeight == other.raw.bayersensor.pixelShiftRedBlueWeight; raw.bayersensor.pixelShiftShowMotion = raw.bayersensor.pixelShiftShowMotion && p.raw.bayersensor.pixelShiftShowMotion == other.raw.bayersensor.pixelShiftShowMotion; raw.bayersensor.pixelShiftShowMotionMaskOnly = raw.bayersensor.pixelShiftShowMotionMaskOnly && p.raw.bayersensor.pixelShiftShowMotionMaskOnly == other.raw.bayersensor.pixelShiftShowMotionMaskOnly; - raw.bayersensor.pixelShiftAutomatic = raw.bayersensor.pixelShiftAutomatic && p.raw.bayersensor.pixelShiftAutomatic == other.raw.bayersensor.pixelShiftAutomatic; - raw.bayersensor.pixelShiftNonGreenHorizontal = raw.bayersensor.pixelShiftNonGreenHorizontal && p.raw.bayersensor.pixelShiftNonGreenHorizontal == other.raw.bayersensor.pixelShiftNonGreenHorizontal; - raw.bayersensor.pixelShiftNonGreenVertical = raw.bayersensor.pixelShiftNonGreenVertical && p.raw.bayersensor.pixelShiftNonGreenVertical == other.raw.bayersensor.pixelShiftNonGreenVertical; raw.bayersensor.pixelShiftHoleFill = raw.bayersensor.pixelShiftHoleFill && p.raw.bayersensor.pixelShiftHoleFill == other.raw.bayersensor.pixelShiftHoleFill; raw.bayersensor.pixelShiftMedian = raw.bayersensor.pixelShiftMedian && p.raw.bayersensor.pixelShiftMedian == other.raw.bayersensor.pixelShiftMedian; - raw.bayersensor.pixelShiftMedian3 = raw.bayersensor.pixelShiftMedian3 && p.raw.bayersensor.pixelShiftMedian3 == other.raw.bayersensor.pixelShiftMedian3; raw.bayersensor.pixelShiftGreen = raw.bayersensor.pixelShiftGreen && p.raw.bayersensor.pixelShiftGreen == other.raw.bayersensor.pixelShiftGreen; raw.bayersensor.pixelShiftBlur = raw.bayersensor.pixelShiftBlur && p.raw.bayersensor.pixelShiftBlur == other.raw.bayersensor.pixelShiftBlur; raw.bayersensor.pixelShiftSmooth = raw.bayersensor.pixelShiftSmooth && p.raw.bayersensor.pixelShiftSmoothFactor == other.raw.bayersensor.pixelShiftSmoothFactor; - raw.bayersensor.pixelShiftExp0 = raw.bayersensor.pixelShiftExp0 && p.raw.bayersensor.pixelShiftExp0 == other.raw.bayersensor.pixelShiftExp0; raw.bayersensor.pixelShiftLmmse = raw.bayersensor.pixelShiftLmmse && p.raw.bayersensor.pixelShiftLmmse == other.raw.bayersensor.pixelShiftLmmse; raw.bayersensor.pixelShiftEqualBright = raw.bayersensor.pixelShiftEqualBright && p.raw.bayersensor.pixelShiftEqualBright == other.raw.bayersensor.pixelShiftEqualBright; raw.bayersensor.pixelShiftEqualBrightChannel = raw.bayersensor.pixelShiftEqualBrightChannel && p.raw.bayersensor.pixelShiftEqualBrightChannel == other.raw.bayersensor.pixelShiftEqualBrightChannel; raw.bayersensor.pixelShiftNonGreenCross = raw.bayersensor.pixelShiftNonGreenCross && p.raw.bayersensor.pixelShiftNonGreenCross == other.raw.bayersensor.pixelShiftNonGreenCross; - raw.bayersensor.pixelShiftNonGreenCross2 = raw.bayersensor.pixelShiftNonGreenCross2 && p.raw.bayersensor.pixelShiftNonGreenCross2 == other.raw.bayersensor.pixelShiftNonGreenCross2; - raw.bayersensor.pixelShiftNonGreenAmaze = raw.bayersensor.pixelShiftNonGreenAmaze && p.raw.bayersensor.pixelShiftNonGreenAmaze == other.raw.bayersensor.pixelShiftNonGreenAmaze; raw.bayersensor.greenEq = raw.bayersensor.greenEq && p.raw.bayersensor.greenthresh == other.raw.bayersensor.greenthresh; raw.bayersensor.linenoise = raw.bayersensor.linenoise && p.raw.bayersensor.linenoise == other.raw.bayersensor.linenoise; raw.bayersensor.linenoiseDirection = raw.bayersensor.linenoiseDirection && p.raw.bayersensor.linenoiseDirection == other.raw.bayersensor.linenoiseDirection; @@ -2516,54 +2484,18 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.lmmse_iterations = mods.raw.bayersensor.lmmse_iterations; } - if (raw.bayersensor.pixelShiftMotion) { - toEdit.raw.bayersensor.pixelShiftMotion = mods.raw.bayersensor.pixelShiftMotion; - } - - if (raw.bayersensor.pixelShiftMotionCorrection) { - toEdit.raw.bayersensor.pixelShiftMotionCorrection = mods.raw.bayersensor.pixelShiftMotionCorrection; - } - if (raw.bayersensor.pixelShiftMotionCorrectionMethod) { toEdit.raw.bayersensor.pixelShiftMotionCorrectionMethod = mods.raw.bayersensor.pixelShiftMotionCorrectionMethod; } - if (raw.bayersensor.pixelShiftStddevFactorGreen) { - toEdit.raw.bayersensor.pixelShiftStddevFactorGreen = mods.raw.bayersensor.pixelShiftStddevFactorGreen; - } - - if (raw.bayersensor.pixelShiftStddevFactorRed) { - toEdit.raw.bayersensor.pixelShiftStddevFactorRed = mods.raw.bayersensor.pixelShiftStddevFactorRed; - } - - if (raw.bayersensor.pixelShiftStddevFactorBlue) { - toEdit.raw.bayersensor.pixelShiftStddevFactorBlue = mods.raw.bayersensor.pixelShiftStddevFactorBlue; - } - if (raw.bayersensor.pixelShiftEperIso) { toEdit.raw.bayersensor.pixelShiftEperIso = mods.raw.bayersensor.pixelShiftEperIso; } - if (raw.bayersensor.pixelShiftNreadIso) { - toEdit.raw.bayersensor.pixelShiftNreadIso = mods.raw.bayersensor.pixelShiftNreadIso; - } - - if (raw.bayersensor.pixelShiftPrnu) { - toEdit.raw.bayersensor.pixelShiftPrnu = mods.raw.bayersensor.pixelShiftPrnu; - } - if (raw.bayersensor.pixelShiftSigma) { toEdit.raw.bayersensor.pixelShiftSigma = mods.raw.bayersensor.pixelShiftSigma; } - if (raw.bayersensor.pixelShiftSum) { - toEdit.raw.bayersensor.pixelShiftSum = mods.raw.bayersensor.pixelShiftSum; - } - - if (raw.bayersensor.pixelShiftRedBlueWeight) { - toEdit.raw.bayersensor.pixelShiftRedBlueWeight = mods.raw.bayersensor.pixelShiftRedBlueWeight; - } - if (raw.bayersensor.pixelShiftShowMotion) { toEdit.raw.bayersensor.pixelShiftShowMotion = mods.raw.bayersensor.pixelShiftShowMotion; } @@ -2572,18 +2504,6 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelShiftShowMotionMaskOnly = mods.raw.bayersensor.pixelShiftShowMotionMaskOnly; } - if (raw.bayersensor.pixelShiftAutomatic) { - toEdit.raw.bayersensor.pixelShiftAutomatic = mods.raw.bayersensor.pixelShiftAutomatic; - } - - if (raw.bayersensor.pixelShiftNonGreenHorizontal) { - toEdit.raw.bayersensor.pixelShiftNonGreenHorizontal = mods.raw.bayersensor.pixelShiftNonGreenHorizontal; - } - - if (raw.bayersensor.pixelShiftNonGreenVertical) { - toEdit.raw.bayersensor.pixelShiftNonGreenVertical = mods.raw.bayersensor.pixelShiftNonGreenVertical; - } - if (raw.bayersensor.pixelShiftHoleFill) { toEdit.raw.bayersensor.pixelShiftHoleFill = mods.raw.bayersensor.pixelShiftHoleFill; } @@ -2592,10 +2512,6 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelShiftMedian = mods.raw.bayersensor.pixelShiftMedian; } - if (raw.bayersensor.pixelShiftMedian3) { - toEdit.raw.bayersensor.pixelShiftMedian3 = mods.raw.bayersensor.pixelShiftMedian3; - } - if (raw.bayersensor.pixelShiftGreen) { toEdit.raw.bayersensor.pixelShiftGreen = mods.raw.bayersensor.pixelShiftGreen; } @@ -2608,10 +2524,6 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelShiftSmoothFactor = mods.raw.bayersensor.pixelShiftSmoothFactor; } - if (raw.bayersensor.pixelShiftExp0) { - toEdit.raw.bayersensor.pixelShiftExp0 = mods.raw.bayersensor.pixelShiftExp0; - } - if (raw.bayersensor.pixelShiftLmmse) { toEdit.raw.bayersensor.pixelShiftLmmse = mods.raw.bayersensor.pixelShiftLmmse; } @@ -2628,14 +2540,6 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.raw.bayersensor.pixelShiftNonGreenCross = mods.raw.bayersensor.pixelShiftNonGreenCross; } - if (raw.bayersensor.pixelShiftNonGreenCross2) { - toEdit.raw.bayersensor.pixelShiftNonGreenCross2 = mods.raw.bayersensor.pixelShiftNonGreenCross2; - } - - if (raw.bayersensor.pixelShiftNonGreenAmaze) { - toEdit.raw.bayersensor.pixelShiftNonGreenAmaze = mods.raw.bayersensor.pixelShiftNonGreenAmaze; - } - if (raw.bayersensor.greenEq) { toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; } @@ -3157,9 +3061,8 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten bool RAWParamsEdited::BayerSensor::isUnchanged() const { return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq - && pixelShiftMotion && pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod && pixelShiftStddevFactorGreen && pixelShiftStddevFactorRed && pixelShiftStddevFactorBlue && pixelShiftEperIso - && pixelShiftNreadIso && pixelShiftPrnu && pixelShiftSigma && pixelShiftSum && pixelShiftRedBlueWeight && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly - && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftEqualBright && pixelShiftEqualBrightChannel + && pixelShiftMotionCorrectionMethod && pixelShiftEperIso && pixelShiftSigma && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly + && pixelShiftHoleFill && pixelShiftMedian && pixelShiftNonGreenCross && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftLmmse && pixelShiftEqualBright && pixelShiftEqualBrightChannel && linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c09b23255..e28a83a6f 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -729,36 +729,20 @@ public: bool dcbIterations; bool dcbEnhance; bool lmmseIterations; - bool pixelShiftMotion; - bool pixelShiftMotionCorrection; bool pixelShiftMotionCorrectionMethod; - bool pixelShiftStddevFactorGreen; - bool pixelShiftStddevFactorRed; - bool pixelShiftStddevFactorBlue; bool pixelShiftEperIso; - bool pixelShiftNreadIso; - bool pixelShiftPrnu; bool pixelShiftSigma; - bool pixelShiftSum; - bool pixelShiftRedBlueWeight; bool pixelShiftShowMotion; bool pixelShiftShowMotionMaskOnly; - bool pixelShiftAutomatic; - bool pixelShiftNonGreenHorizontal; - bool pixelShiftNonGreenVertical; bool pixelShiftHoleFill; bool pixelShiftMedian; - bool pixelShiftMedian3; bool pixelShiftGreen; bool pixelShiftBlur; bool pixelShiftSmooth; - bool pixelShiftExp0; bool pixelShiftLmmse; bool pixelShiftEqualBright; bool pixelShiftEqualBrightChannel; bool pixelShiftNonGreenCross; - bool pixelShiftNonGreenCross2; - bool pixelShiftNonGreenAmaze; //bool allEnhance; bool greenEq; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 4828e90dc..c9ed1cd14 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -846,34 +846,18 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param } if (!raw_pixelshift->get_active ()) { - filterPE.raw.bayersensor.pixelShiftAutomatic = falsePE.raw.bayersensor.pixelShiftAutomatic; filterPE.raw.bayersensor.pixelShiftBlur = falsePE.raw.bayersensor.pixelShiftBlur; filterPE.raw.bayersensor.pixelShiftEperIso = falsePE.raw.bayersensor.pixelShiftEperIso; filterPE.raw.bayersensor.pixelShiftEqualBright = falsePE.raw.bayersensor.pixelShiftEqualBright; filterPE.raw.bayersensor.pixelShiftEqualBrightChannel = falsePE.raw.bayersensor.pixelShiftEqualBrightChannel; - filterPE.raw.bayersensor.pixelShiftExp0 = falsePE.raw.bayersensor.pixelShiftExp0; filterPE.raw.bayersensor.pixelShiftGreen = falsePE.raw.bayersensor.pixelShiftGreen; filterPE.raw.bayersensor.pixelShiftHoleFill = falsePE.raw.bayersensor.pixelShiftHoleFill; filterPE.raw.bayersensor.pixelShiftLmmse = falsePE.raw.bayersensor.pixelShiftLmmse; filterPE.raw.bayersensor.pixelShiftMedian = falsePE.raw.bayersensor.pixelShiftMedian; - filterPE.raw.bayersensor.pixelShiftMedian3 = falsePE.raw.bayersensor.pixelShiftMedian3; - filterPE.raw.bayersensor.pixelShiftMotion = falsePE.raw.bayersensor.pixelShiftMotion; - filterPE.raw.bayersensor.pixelShiftMotionCorrection = falsePE.raw.bayersensor.pixelShiftMotionCorrection; filterPE.raw.bayersensor.pixelShiftMotionCorrectionMethod = falsePE.raw.bayersensor.pixelShiftMotionCorrectionMethod; - filterPE.raw.bayersensor.pixelShiftNonGreenAmaze = falsePE.raw.bayersensor.pixelShiftNonGreenAmaze; filterPE.raw.bayersensor.pixelShiftNonGreenCross = falsePE.raw.bayersensor.pixelShiftNonGreenCross; - filterPE.raw.bayersensor.pixelShiftNonGreenCross2 = falsePE.raw.bayersensor.pixelShiftNonGreenCross2; - filterPE.raw.bayersensor.pixelShiftNonGreenHorizontal = falsePE.raw.bayersensor.pixelShiftNonGreenHorizontal; - filterPE.raw.bayersensor.pixelShiftNonGreenVertical = falsePE.raw.bayersensor.pixelShiftNonGreenVertical; - filterPE.raw.bayersensor.pixelShiftNreadIso = falsePE.raw.bayersensor.pixelShiftNreadIso; - filterPE.raw.bayersensor.pixelShiftPrnu = falsePE.raw.bayersensor.pixelShiftPrnu; - filterPE.raw.bayersensor.pixelShiftRedBlueWeight = falsePE.raw.bayersensor.pixelShiftRedBlueWeight; filterPE.raw.bayersensor.pixelShiftSigma = falsePE.raw.bayersensor.pixelShiftSigma; filterPE.raw.bayersensor.pixelShiftSmooth = falsePE.raw.bayersensor.pixelShiftSmooth; - filterPE.raw.bayersensor.pixelShiftStddevFactorBlue = falsePE.raw.bayersensor.pixelShiftStddevFactorBlue; - filterPE.raw.bayersensor.pixelShiftStddevFactorGreen = falsePE.raw.bayersensor.pixelShiftStddevFactorGreen; - filterPE.raw.bayersensor.pixelShiftStddevFactorRed = falsePE.raw.bayersensor.pixelShiftStddevFactorRed; - filterPE.raw.bayersensor.pixelShiftSum = falsePE.raw.bayersensor.pixelShiftSum; filterPE.raw.bayersensor.pixelShiftShowMotion = falsePE.raw.bayersensor.pixelShiftShowMotion; filterPE.raw.bayersensor.pixelShiftShowMotionMaskOnly = falsePE.raw.bayersensor.pixelShiftShowMotionMaskOnly; } From 7a215019554c84d8de13be931bb9c57f5043a485 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Wed, 18 Apr 2018 08:13:22 +0200 Subject: [PATCH 5/8] Removed VersionInfoVersion from InnoSetup script, #4507 --- tools/win/InnoSetup/WindowsInnoSetup.iss.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/win/InnoSetup/WindowsInnoSetup.iss.in b/tools/win/InnoSetup/WindowsInnoSetup.iss.in index 235d64968..6814d9c74 100644 --- a/tools/win/InnoSetup/WindowsInnoSetup.iss.in +++ b/tools/win/InnoSetup/WindowsInnoSetup.iss.in @@ -38,7 +38,7 @@ AppId={#MyAppName}{#MyAppVersion} AppName={#MyAppName} AppVersion={#MyAppVersion} -VersionInfoVersion={#MyAppVersionNumeric} +;VersionInfoVersion={#MyAppVersionNumeric} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} From 52968a9766b9d0ffb768e1d1774aa50e88e163e1 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 18 Apr 2018 13:16:56 +0200 Subject: [PATCH 6/8] Made xtrans_demosaic an own compilation unit --- rtengine/CMakeLists.txt | 1 + rtengine/demosaic_algos.cc | 988 --------------------------------- rtengine/xtrans_demosaic.cc | 1020 +++++++++++++++++++++++++++++++++++ 3 files changed, 1021 insertions(+), 988 deletions(-) create mode 100644 rtengine/xtrans_demosaic.cc diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 0693f919f..769569b21 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -120,6 +120,7 @@ set(RTENGINESOURCEFILES histmatching.cc pdaflinesfilter.cc gamutwarning.cc + xtrans_demosaic.cc ) if(LENSFUN_HAS_LOAD_DIRECTORY) diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 89387a9b4..582b00629 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -3845,994 +3845,6 @@ BENCHFUN } } -const double xyz_rgb[3][3] = { // XYZ from RGB - { 0.412453, 0.357580, 0.180423 }, - { 0.212671, 0.715160, 0.072169 }, - { 0.019334, 0.119193, 0.950227 } -}; -const float d65_white[3] = { 0.950456, 1, 1.088754 }; - -void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) -{ - static LUTf cbrt(0x14000); - static bool cbrtinit = false; - - if (!rgb) { - if(!cbrtinit) { - for (int i = 0; i < 0x14000; i++) { - double r = i / 65535.0; - cbrt[i] = r > Color::eps ? std::cbrt(r) : (Color::kappa * r + 16.0) / 116.0; - } - - cbrtinit = true; - } - - return; - } - -#ifdef __SSE2__ - vfloat c116v = F2V(116.f); - vfloat c16v = F2V(16.f); - vfloat c500v = F2V(500.f); - vfloat c200v = F2V(200.f); - vfloat xyz_camv[3][3]; - - for(int i = 0; i < 3; i++) - for(int j = 0; j < 3; j++) { - xyz_camv[i][j] = F2V(xyz_cam[i][j]); - } - -#endif // __SSE2__ - - for(int i = 0; i < height; i++) { - int j = 0; -#ifdef __SSE2__ - - for(; j < labWidth - 3; j += 4) { - vfloat redv, greenv, bluev; - vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[i * width + j], redv, greenv, bluev); - vfloat xyz0v = redv * xyz_camv[0][0] + greenv * xyz_camv[0][1] + bluev * xyz_camv[0][2]; - vfloat xyz1v = redv * xyz_camv[1][0] + greenv * xyz_camv[1][1] + bluev * xyz_camv[1][2]; - vfloat xyz2v = redv * xyz_camv[2][0] + greenv * xyz_camv[2][1] + bluev * xyz_camv[2][2]; - xyz0v = cbrt[_mm_cvtps_epi32(xyz0v)]; - xyz1v = cbrt[_mm_cvtps_epi32(xyz1v)]; - xyz2v = cbrt[_mm_cvtps_epi32(xyz2v)]; - - STVFU(l[i * labWidth + j], c116v * xyz1v - c16v); - STVFU(a[i * labWidth + j], c500v * (xyz0v - xyz1v)); - STVFU(b[i * labWidth + j], c200v * (xyz1v - xyz2v)); - } - -#endif - - for(; j < labWidth; j++) { - float xyz[3] = {0.5f, 0.5f, 0.5f}; - - for(int c = 0; c < 3; c++) { - float val = rgb[i * width + j][c]; - xyz[0] += xyz_cam[0][c] * val; - xyz[1] += xyz_cam[1][c] * val; - xyz[2] += xyz_cam[2][c] * val; - } - - xyz[0] = cbrt[(int) xyz[0]]; - xyz[1] = cbrt[(int) xyz[1]]; - xyz[2] = cbrt[(int) xyz[2]]; - - l[i * labWidth + j] = 116 * xyz[1] - 16; - a[i * labWidth + j] = 500 * (xyz[0] - xyz[1]); - b[i * labWidth + j] = 200 * (xyz[1] - xyz[2]); - } - } -} - - -#define fcol(row,col) xtrans[(row)%6][(col)%6] -#define isgreen(row,col) (xtrans[(row)%3][(col)%3]&1) - -void RawImageSource::xtransborder_interpolate (int border) -{ - const int height = H, width = W; - - int xtrans[6][6]; - ri->getXtransMatrix(xtrans); - - for (int row = 0; row < height; row++) - for (int col = 0; col < width; col++) { - if (col == border && row >= border && row < height - border) { - col = width - border; - } - - float sum[6] = {0.f}; - - for (int y = MAX(0, row - 1); y <= MIN(row + 1, height - 1); y++) - for (int x = MAX(0, col - 1); x <= MIN(col + 1, width - 1); x++) { - int f = fcol(y, x); - sum[f] += rawData[y][x]; - sum[f + 3]++; - } - - switch(fcol(row, col)) { - case 0: - red[row][col] = rawData[row][col]; - green[row][col] = (sum[1] / sum[4]); - blue[row][col] = (sum[2] / sum[5]); - break; - - case 1: - if(sum[3] == 0.f) { // at the 4 corner pixels it can happen, that we have only green pixels in 2x2 area - red[row][col] = green[row][col] = blue[row][col] = rawData[row][col]; - } else { - red[row][col] = (sum[0] / sum[3]); - green[row][col] = rawData[row][col]; - blue[row][col] = (sum[2] / sum[5]); - } - - break; - - case 2: - red[row][col] = (sum[0] / sum[3]); - green[row][col] = (sum[1] / sum[4]); - blue[row][col] = rawData[row][col]; - } - } -} - -/* - Frank Markesteijn's algorithm for Fuji X-Trans sensors - adapted to RT by Ingo Weyrich 2014 -*/ -// override CLIP function to test unclipped output -#define CLIP(x) (x) -void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) -{ - BENCHFUN - constexpr int ts = 114; /* Tile Size */ - constexpr int tsh = ts / 2; /* half of Tile Size */ - - double progress = 0.0; - const bool plistenerActive = plistener; - - if (plistenerActive) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "Xtrans")); - plistener->setProgress (progress); - } - - int xtrans[6][6]; - ri->getXtransMatrix(xtrans); - - constexpr short orth[12] = { 1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1 }, - patt[2][16] = { { 0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0, 0, 0, 0 }, - { 0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1, -1, -1, 1 } - }, - dir[4] = { 1, ts, ts + 1, ts - 1 }; - - // sgrow/sgcol is the offset in the sensor matrix of the solitary - // green pixels - ushort sgrow = 0, sgcol = 0; - - const int height = H, width = W; - - if (settings->verbose) { - printf("%d-pass X-Trans interpolation using %s conversion...\n", passes, useCieLab ? "lab" : "yuv"); - } - - xtransborder_interpolate(6); - - float xyz_cam[3][3]; - { - float rgb_cam[3][4]; - ri->getRgbCam(rgb_cam); - int k; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (xyz_cam[i][j] = k = 0; k < 3; k++) { - xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; - } - } - - /* Map a green hexagon around each non-green pixel and vice versa: */ - short allhex[2][3][3][8]; - { - int gint, d, h, v, ng, row, col, c; - - for (row = 0; row < 3; row++) - for (col = 0; col < 3; col++) { - gint = isgreen(row, col); - - for (ng = d = 0; d < 10; d += 2) { - if (isgreen(row + orth[d] + 6, col + orth[d + 2] + 6)) { - ng = 0; - } else { - ng++; - } - - if (ng == 4) { - // if there are four non-green pixels adjacent in cardinal - // directions, this is the solitary green pixel - sgrow = row; - sgcol = col; - } - - if (ng == gint + 1) - FORC(8) { - v = orth[d] * patt[gint][c * 2] + orth[d + 1] * patt[gint][c * 2 + 1]; - h = orth[d + 2] * patt[gint][c * 2] + orth[d + 3] * patt[gint][c * 2 + 1]; - allhex[0][row][col][c ^ (gint * 2 & d)] = h + v * width; - allhex[1][row][col][c ^ (gint * 2 & d)] = h + v * ts; - } - } - } - - } - - if(plistenerActive) { - progress += 0.05; - plistener->setProgress(progress); - } - - - double progressInc = 36.0 * (1.0 - progress) / ((H * W) / ((ts - 16) * (ts - 16))); - const int ndir = 4 << (passes > 1); - cielab (nullptr, nullptr, nullptr, nullptr, 0, 0, 0, nullptr); - struct s_minmaxgreen { - float min; - float max; - }; - - int RightShift[3]; - - for(int row = 0; row < 3; row++) { - // count number of green pixels in three cols - int greencount = 0; - - for(int col = 0; col < 3; col++) { - greencount += isgreen(row, col); - } - - RightShift[row] = (greencount == 2); - } - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - int progressCounter = 0; - int c; - float color[3][6]; - - float *buffer = (float *) malloc ((ts * ts * (ndir * 4 + 3) + 128) * sizeof(float)); - float (*rgb)[ts][ts][3] = (float(*)[ts][ts][3]) buffer; - float (*lab)[ts - 8][ts - 8] = (float (*)[ts - 8][ts - 8])(buffer + ts * ts * (ndir * 3)); - float (*drv)[ts - 10][ts - 10] = (float (*)[ts - 10][ts - 10]) (buffer + ts * ts * (ndir * 3 + 3)); - uint8_t (*homo)[ts][ts] = (uint8_t (*)[ts][ts]) (lab); // we can reuse the lab-buffer because they are not used together - s_minmaxgreen (*greenminmaxtile)[tsh] = (s_minmaxgreen(*)[tsh]) (lab); // we can reuse the lab-buffer because they are not used together - uint8_t (*homosum)[ts][ts] = (uint8_t (*)[ts][ts]) (drv); // we can reuse the drv-buffer because they are not used together - uint8_t (*homosummax)[ts] = (uint8_t (*)[ts]) homo[ndir - 1]; // we can reuse the homo-buffer because they are not used together - -#ifdef _OPENMP - #pragma omp for collapse(2) schedule(dynamic) nowait -#endif - - for (int top = 3; top < height - 19; top += ts - 16) - for (int left = 3; left < width - 19; left += ts - 16) { - int mrow = MIN (top + ts, height - 3); - int mcol = MIN (left + ts, width - 3); - - /* Set greenmin and greenmax to the minimum and maximum allowed values: */ - for (int row = top; row < mrow; row++) { - // find first non-green pixel - int leftstart = left; - - for(; leftstart < mcol; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); - - if(coloffset == 3) { - short *hex = allhex[0][row % 3][leftstart % 3]; - - for (int col = leftstart; col < mcol; col += coloffset) { - float minval = FLT_MAX; - float maxval = 0.f; - float *pix = &rawData[row][col]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - } - } else { - float minval = FLT_MAX; - float maxval = 0.f; - int col = leftstart; - - if(coloffset == 2) { - minval = FLT_MAX; - maxval = 0.f; - float *pix = &rawData[row][col]; - short *hex = allhex[0][row % 3][col % 3]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - col += 2; - } - - short *hex = allhex[0][row % 3][col % 3]; - - for (; col < mcol - 1; col += 3) { - minval = FLT_MAX; - maxval = 0.f; - float *pix = &rawData[row][col]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - greenminmaxtile[row - top][(col + 1 - left) >> 1].min = minval; - greenminmaxtile[row - top][(col + 1 - left) >> 1].max = maxval; - } - - if(col < mcol) { - minval = FLT_MAX; - maxval = 0.f; - float *pix = &rawData[row][col]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - } - } - } - - memset(rgb, 0, ts * ts * 3 * sizeof(float)); - - for (int row = top; row < mrow; row++) - for (int col = left; col < mcol; col++) { - rgb[0][row - top][col - left][fcol(row, col)] = rawData[row][col]; - } - - for(int c = 0; c < 3; c++) { - memcpy (rgb[c + 1], rgb[0], sizeof * rgb); - } - - /* Interpolate green horizontally, vertically, and along both diagonals: */ - for (int row = top; row < mrow; row++) { - // find first non-green pixel - int leftstart = left; - - for(; leftstart < mcol; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); - - if(coloffset == 3) { - short *hex = allhex[0][row % 3][leftstart % 3]; - - for (int col = leftstart; col < mcol; col += coloffset) { - float *pix = &rawData[row][col]; - float color[4]; - color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - - 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); - color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + - 0.359375f * (pix[0] - pix[-hex[2]]); - - for(int c = 0; c < 2; c++) - color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * - (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); - - for(int c = 0; c < 4; c++) { - rgb[c][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } else { - short *hexmod[2]; - hexmod[0] = allhex[0][row % 3][leftstart % 3]; - hexmod[1] = allhex[0][row % 3][(leftstart + coloffset) % 3]; - - for (int col = leftstart, hexindex = 0; col < mcol; col += coloffset, coloffset ^= 3, hexindex ^= 1) { - float *pix = &rawData[row][col]; - short *hex = hexmod[hexindex]; - float color[4]; - color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - - 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); - color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + - 0.359375f * (pix[0] - pix[-hex[2]]); - - for(int c = 0; c < 2; c++) - color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * - (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); - - for(int c = 0; c < 4; c++) { - rgb[c ^ 1][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } - } - - for (int pass = 0; pass < passes; pass++) { - if (pass == 1) { - memcpy (rgb += 4, buffer, 4 * sizeof * rgb); - } - - /* Recalculate green from interpolated values of closer pixels: */ - if (pass) { - for (int row = top + 2; row < mrow - 2; row++) { - int leftstart = left + 2; - - for(; leftstart < mcol - 2; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); - - if(coloffset == 3) { - int f = fcol(row, leftstart); - short *hex = allhex[1][row % 3][leftstart % 3]; - - for (int col = leftstart; col < mcol - 2; col += coloffset, f ^= 2) { - for (int d = 3; d < 6; d++) { - float (*rix)[3] = &rgb[(d - 2)][row - top][col - left]; - float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) - - rix[-2 * hex[d]][f]) + rix[0][f]; - rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } else { - int f = fcol(row, leftstart); - short *hexmod[2]; - hexmod[0] = allhex[1][row % 3][leftstart % 3]; - hexmod[1] = allhex[1][row % 3][(leftstart + coloffset) % 3]; - - for (int col = leftstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2), hexindex ^= 1 ) { - short *hex = hexmod[hexindex]; - - for (int d = 3; d < 6; d++) { - float (*rix)[3] = &rgb[(d - 2) ^ 1][row - top][col - left]; - float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) - - rix[-2 * hex[d]][f]) + rix[0][f]; - rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } - } - } - - /* Interpolate red and blue values for solitary green pixels: */ - int sgstartcol = (left - sgcol + 4) / 3 * 3 + sgcol; - - for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) { - for (int col = sgstartcol, h = fcol(row, col + 1); col < mcol - 2; col += 3, h ^= 2) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - float diff[6] = {0.f}; - - for (int i = 1, d = 0; d < 6; d++, i ^= ts ^ 1, h ^= 2) { - for (int c = 0; c < 2; c++, h ^= 2) { - float g = rix[0][1] + rix[0][1] - rix[i << c][1] - rix[-i << c][1]; - color[h][d] = g + rix[i << c][h] + rix[-i << c][h]; - - if (d > 1) - diff[d] += SQR (rix[i << c][1] - rix[-i << c][1] - - rix[i << c][h] + rix[-i << c][h]) + SQR(g); - } - - if (d > 2 && (d & 1)) // 3, 5 - if (diff[d - 1] < diff[d]) - for(int c = 0; c < 2; c++) { - color[c * 2][d] = color[c * 2][d - 1]; - } - - if ((d & 1) || d < 2) { // d: 0, 1, 3, 5 - for(int c = 0; c < 2; c++) { - rix[0][c * 2] = CLIP(0.5f * color[c * 2][d]); - } - - rix += ts * ts; - } - } - } - } - - /* Interpolate red for blue pixels and vice versa: */ - for (int row = top + 3; row < mrow - 3; row++) { - int leftstart = left + 3; - - for(; leftstart < mcol - 1; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1); - c = (row - sgrow) % 3 ? ts : 1; - int h = 3 * (c ^ ts ^ 1); - - if(coloffset == 3) { - int f = 2 - fcol(row, leftstart); - - for (int col = leftstart; col < mcol - 3; col += coloffset, f ^= 2) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - - for (int d = 0; d < 4; d++, rix += ts * ts) { - int i = d > 1 || ((d ^ c) & 1) || - ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; - - rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); - } - } - } else { - coloffset = fcol(row, leftstart + 1) == 1 ? 2 : 1; - int f = 2 - fcol(row, leftstart); - - for (int col = leftstart; col < mcol - 3; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2) ) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - - for (int d = 0; d < 4; d++, rix += ts * ts) { - int i = d > 1 || ((d ^ c) & 1) || - ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; - - rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); - } - } - } - } - - /* Fill in red and blue for 2x2 blocks of green: */ - // Find first row of 2x2 green - int topstart = top + 2; - - for(; topstart < mrow - 2; topstart++) - if((topstart - sgrow) % 3) { - break; - } - - int leftstart = left + 2; - - for(; leftstart < mcol - 2; leftstart++) - if((leftstart - sgcol) % 3) { - break; - } - - int coloffsetstart = 2 - (fcol(topstart, leftstart + 1) & 1); - - for (int row = topstart; row < mrow - 2; row++) { - if ((row - sgrow) % 3) { - short *hexmod[2]; - hexmod[0] = allhex[1][row % 3][leftstart % 3]; - hexmod[1] = allhex[1][row % 3][(leftstart + coloffsetstart) % 3]; - - for (int col = leftstart, coloffset = coloffsetstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, hexindex ^= 1) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - short *hex = hexmod[hexindex]; - - for (int d = 0; d < ndir; d += 2, rix += ts * ts) { - if (hex[d] + hex[d + 1]) { - float g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; - - for (c = 0; c < 4; c += 2) { - rix[0][c] = CLIP((g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.33333333f); - } - } else { - float g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; - - for (c = 0; c < 4; c += 2) { - rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.5f); - } - } - } - } - } - } - } - -// end of multipass part - rgb = (float(*)[ts][ts][3]) buffer; - mrow -= top; - mcol -= left; - - if(useCieLab) { - /* Convert to CIELab and differentiate in all directions: */ - // Original dcraw algorithm uses CIELab as perceptual space - // (presumably coming from original AHD) and converts taking - // camera matrix into account. We use this in RT. - for (int d = 0; d < ndir; d++) { - float *l = &lab[0][0][0]; - float *a = &lab[1][0][0]; - float *b = &lab[2][0][0]; - cielab(&rgb[d][4][4], l, a, b, ts, mrow - 8, ts - 8, xyz_cam); - int f = dir[d & 3]; - f = f == 1 ? 1 : f - 8; - - for (int row = 5; row < mrow - 5; row++) -#ifdef _OPENMP - #pragma omp simd -#endif - for (int col = 5; col < mcol - 5; col++) { - float *l = &lab[0][row - 4][col - 4]; - float *a = &lab[1][row - 4][col - 4]; - float *b = &lab[2][row - 4][col - 4]; - - float g = 2 * l[0] - l[f] - l[-f]; - drv[d][row - 5][col - 5] = SQR(g) - + SQR((2 * a[0] - a[f] - a[-f] + g * 2.1551724f)) - + SQR((2 * b[0] - b[f] - b[-f] - g * 0.86206896f)); - } - - } - } else { - // For 1-pass demosaic we use YPbPr which requires much - // less code and is nearly indistinguishable. It assumes the - // camera RGB is roughly linear. - for (int d = 0; d < ndir; d++) { - float (*yuv)[ts - 8][ts - 8] = lab; // we use the lab buffer, which has the same dimensions -#ifdef __SSE2__ - vfloat zd2627v = F2V(0.2627f); - vfloat zd6780v = F2V(0.6780f); - vfloat zd0593v = F2V(0.0593f); - vfloat zd56433v = F2V(0.56433f); - vfloat zd67815v = F2V(0.67815f); -#endif - - for (int row = 4; row < mrow - 4; row++) { - int col = 4; -#ifdef __SSE2__ - - for (; col < mcol - 7; col += 4) { - // use ITU-R BT.2020 YPbPr, which is great, but could use - // a better/simpler choice? note that imageop.h provides - // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, - // which appears less good with specular highlights - vfloat redv, greenv, bluev; - vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[d][row][col], redv, greenv, bluev); - vfloat yv = zd2627v * redv + zd6780v * bluev + zd0593v * greenv; - STVFU(yuv[0][row - 4][col - 4], yv); - STVFU(yuv[1][row - 4][col - 4], (bluev - yv) * zd56433v); - STVFU(yuv[2][row - 4][col - 4], (redv - yv) * zd67815v); - } - -#endif - - for (; col < mcol - 4; col++) { - // use ITU-R BT.2020 YPbPr, which is great, but could use - // a better/simpler choice? note that imageop.h provides - // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, - // which appears less good with specular highlights - float y = 0.2627f * rgb[d][row][col][0] + 0.6780f * rgb[d][row][col][1] + 0.0593f * rgb[d][row][col][2]; - yuv[0][row - 4][col - 4] = y; - yuv[1][row - 4][col - 4] = (rgb[d][row][col][2] - y) * 0.56433f; - yuv[2][row - 4][col - 4] = (rgb[d][row][col][0] - y) * 0.67815f; - } - } - - int f = dir[d & 3]; - f = f == 1 ? 1 : f - 8; - - for (int row = 5; row < mrow - 5; row++) - for (int col = 5; col < mcol - 5; col++) { - float *y = &yuv[0][row - 4][col - 4]; - float *u = &yuv[1][row - 4][col - 4]; - float *v = &yuv[2][row - 4][col - 4]; - drv[d][row - 5][col - 5] = SQR(2 * y[0] - y[f] - y[-f]) - + SQR(2 * u[0] - u[f] - u[-f]) - + SQR(2 * v[0] - v[f] - v[-f]); - } - } - } - - /* Build homogeneity maps from the derivatives: */ -#ifdef __SSE2__ - vfloat eightv = F2V(8.f); - vfloat zerov = F2V(0.f); - vfloat onev = F2V(1.f); -#endif - - for (int row = 6; row < mrow - 6; row++) { - int col = 6; -#ifdef __SSE2__ - - for (; col < mcol - 9; col += 4) { - vfloat tr1v = vminf(LVFU(drv[0][row - 5][col - 5]), LVFU(drv[1][row - 5][col - 5])); - vfloat tr2v = vminf(LVFU(drv[2][row - 5][col - 5]), LVFU(drv[3][row - 5][col - 5])); - - if(ndir > 4) { - vfloat tr3v = vminf(LVFU(drv[4][row - 5][col - 5]), LVFU(drv[5][row - 5][col - 5])); - vfloat tr4v = vminf(LVFU(drv[6][row - 5][col - 5]), LVFU(drv[7][row - 5][col - 5])); - tr1v = vminf(tr1v, tr3v); - tr1v = vminf(tr1v, tr4v); - } - - tr1v = vminf(tr1v, tr2v); - tr1v = tr1v * eightv; - - for (int d = 0; d < ndir; d++) { - uint8_t tempstore[16]; - vfloat tempv = zerov; - - for (int v = -1; v <= 1; v++) { - for (int h = -1; h <= 1; h++) { - tempv += vselfzero(vmaskf_le(LVFU(drv[d][row + v - 5][col + h - 5]), tr1v), onev); - } - } - - _mm_storeu_si128((__m128i*)&tempstore, _mm_cvtps_epi32(tempv)); - homo[d][row][col] = tempstore[0]; - homo[d][row][col + 1] = tempstore[4]; - homo[d][row][col + 2] = tempstore[8]; - homo[d][row][col + 3] = tempstore[12]; - - } - } - -#endif - - for (; col < mcol - 6; col++) { - float tr = drv[0][row - 5][col - 5] < drv[1][row - 5][col - 5] ? drv[0][row - 5][col - 5] : drv[1][row - 5][col - 5]; - - for (int d = 2; d < ndir; d++) { - tr = (drv[d][row - 5][col - 5] < tr ? drv[d][row - 5][col - 5] : tr); - } - - tr *= 8; - - for (int d = 0; d < ndir; d++) { - uint8_t temp = 0; - - for (int v = -1; v <= 1; v++) { - for (int h = -1; h <= 1; h++) { - temp += (drv[d][row + v - 5][col + h - 5] <= tr ? 1 : 0); - } - } - - homo[d][row][col] = temp; - } - } - } - - if (height - top < ts + 4) { - mrow = height - top + 2; - } - - if (width - left < ts + 4) { - mcol = width - left + 2; - } - - - /* Build 5x5 sum of homogeneity maps */ - const int startcol = MIN(left, 8); - - for(int d = 0; d < ndir; d++) { - for (int row = MIN(top, 8); row < mrow - 8; row++) { - int col = startcol; -#ifdef __SSE2__ - int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; - - // crunching 16 values at once is faster than summing up column sums - for (; col < endcol; col += 16) { - vint v5sumv = (vint)ZEROV; - - for(int v = -2; v <= 2; v++) - for(int h = -2; h <= 2; h++) { - v5sumv = _mm_adds_epu8( _mm_loadu_si128((vint*)&homo[d][row + v][col + h]), v5sumv); - } - - _mm_storeu_si128((vint*)&homosum[d][row][col], v5sumv); - } - -#endif - - if(col < mcol - 8) { - int v5sum[5] = {0}; - - for(int v = -2; v <= 2; v++) - for(int h = -2; h <= 2; h++) { - v5sum[2 + h] += homo[d][row + v][col + h]; - } - - int blocksum = v5sum[0] + v5sum[1] + v5sum[2] + v5sum[3] + v5sum[4]; - homosum[d][row][col] = blocksum; - col++; - - // now we can subtract a column of five from blocksum and get new colsum of 5 - for (int voffset = 0; col < mcol - 8; col++, voffset++) { - int colsum = homo[d][row - 2][col + 2] + homo[d][row - 1][col + 2] + homo[d][row][col + 2] + homo[d][row + 1][col + 2] + homo[d][row + 2][col + 2]; - voffset = voffset == 5 ? 0 : voffset; // faster than voffset %= 5; - blocksum -= v5sum[voffset]; - blocksum += colsum; - v5sum[voffset] = colsum; - homosum[d][row][col] = blocksum; - } - } - } - } - - // calculate maximum of homogeneity maps per pixel. Vectorized calculation is a tiny bit faster than on the fly calculation in next step -#ifdef __SSE2__ - vint maskv = _mm_set1_epi8(31); -#endif - - for (int row = MIN(top, 8); row < mrow - 8; row++) { - int col = startcol; -#ifdef __SSE2__ - int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; - - for (; col < endcol; col += 16) { - vint maxval1 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[0][row][col]), _mm_loadu_si128((vint*)&homosum[1][row][col])); - vint maxval2 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[2][row][col]), _mm_loadu_si128((vint*)&homosum[3][row][col])); - - if(ndir > 4) { - vint maxval3 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[4][row][col]), _mm_loadu_si128((vint*)&homosum[5][row][col])); - vint maxval4 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[6][row][col]), _mm_loadu_si128((vint*)&homosum[7][row][col])); - maxval1 = _mm_max_epu8(maxval1, maxval3); - maxval1 = _mm_max_epu8(maxval1, maxval4); - } - - maxval1 = _mm_max_epu8(maxval1, maxval2); - // there is no shift intrinsic for epu8. Shift using epi32 and mask the wrong bits out - vint subv = _mm_srli_epi32( maxval1, 3 ); - subv = _mm_and_si128(subv, maskv); - maxval1 = _mm_subs_epu8(maxval1, subv); - _mm_storeu_si128((vint*)&homosummax[row][col], maxval1); - } - -#endif - - for (; col < mcol - 8; col ++) { - uint8_t maxval = homosum[0][row][col]; - - for(int d = 1; d < ndir; d++) { - maxval = maxval < homosum[d][row][col] ? homosum[d][row][col] : maxval; - } - - maxval -= maxval >> 3; - homosummax[row][col] = maxval; - } - } - - - /* Average the most homogeneous pixels for the final result: */ - uint8_t hm[8] = {}; - - for (int row = MIN(top, 8); row < mrow - 8; row++) - for (int col = MIN(left, 8); col < mcol - 8; col++) { - - for (int d = 0; d < 4; d++) { - hm[d] = homosum[d][row][col]; - } - - for (int d = 4; d < ndir; d++) { - hm[d] = homosum[d][row][col]; - - if (hm[d - 4] < hm[d]) { - hm[d - 4] = 0; - } else if (hm[d - 4] > hm[d]) { - hm[d] = 0; - } - } - - float avg[4] = {0.f}; - - uint8_t maxval = homosummax[row][col]; - - for (int d = 0; d < ndir; d++) - if (hm[d] >= maxval) { - FORC3 avg[c] += rgb[d][row][col][c]; - avg[3]++; - } - - red[row + top][col + left] = avg[0] / avg[3]; - green[row + top][col + left] = avg[1] / avg[3]; - blue[row + top][col + left] = avg[2] / avg[3]; - } - - if(plistenerActive && ((++progressCounter) % 32 == 0)) { -#ifdef _OPENMP - #pragma omp critical (xtransdemosaic) -#endif - { - progress += progressInc; - progress = min(1.0, progress); - plistener->setProgress (progress); - } - } - - - } - - free(buffer); - } - -} -#undef CLIP -void RawImageSource::fast_xtrans_interpolate () -{ - if (settings->verbose) { - printf("fast X-Trans interpolation...\n"); - } - - double progress = 0.0; - const bool plistenerActive = plistener; - - if (plistenerActive) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); - plistener->setProgress (progress); - } - - const int height = H, width = W; - - xtransborder_interpolate (1); - int xtrans[6][6]; - ri->getXtransMatrix(xtrans); - - #pragma omp parallel for - - for(int row = 1; row < height - 1; row++) { - for(int col = 1; col < width - 1; col++) { - float sum[3] = {0.f}; - - for(int v = -1; v <= 1; v++) { - for(int h = -1; h <= 1; h++) { - sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)]; - } - } - - switch(fcol(row, col)) { - case 0: - red[row][col] = rawData[row][col]; - green[row][col] = sum[1] * 0.2f; - blue[row][col] = sum[2] * 0.33333333f; - break; - - case 1: - red[row][col] = sum[0] * 0.5f; - green[row][col] = rawData[row][col]; - blue[row][col] = sum[2] * 0.5f; - break; - - case 2: - red[row][col] = sum[0] * 0.33333333f; - green[row][col] = sum[1] * 0.2f; - blue[row][col] = rawData[row][col]; - break; - } - } - } - - if (plistenerActive) { - plistener->setProgress (1.0); - } -} -#undef fcol -#undef isgreen - - #undef TILEBORDER #undef TILESIZE #undef CACHESIZE diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc new file mode 100644 index 000000000..a8e964ad0 --- /dev/null +++ b/rtengine/xtrans_demosaic.cc @@ -0,0 +1,1020 @@ +//////////////////////////////////////////////////////////////// +// +// Xtrans demosaic algorithm +// +// code dated: April 18, 2018 +// +// xtrans_demosaic.cc 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. +// +// This program 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 this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include "rtengine.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "../rtgui/multilangmgr.h" +#include "opthelper.h" +#include "StopWatch.h" + +namespace rtengine +{ +const double xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } +}; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; + +void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) +{ + static LUTf cbrt(0x14000); + static bool cbrtinit = false; + + if (!rgb) { + if(!cbrtinit) { + for (int i = 0; i < 0x14000; i++) { + double r = i / 65535.0; + cbrt[i] = r > Color::eps ? std::cbrt(r) : (Color::kappa * r + 16.0) / 116.0; + } + + cbrtinit = true; + } + + return; + } + +#ifdef __SSE2__ + vfloat c116v = F2V(116.f); + vfloat c16v = F2V(16.f); + vfloat c500v = F2V(500.f); + vfloat c200v = F2V(200.f); + vfloat xyz_camv[3][3]; + + for(int i = 0; i < 3; i++) + for(int j = 0; j < 3; j++) { + xyz_camv[i][j] = F2V(xyz_cam[i][j]); + } + +#endif // __SSE2__ + + for(int i = 0; i < height; i++) { + int j = 0; +#ifdef __SSE2__ + + for(; j < labWidth - 3; j += 4) { + vfloat redv, greenv, bluev; + vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[i * width + j], redv, greenv, bluev); + vfloat xyz0v = redv * xyz_camv[0][0] + greenv * xyz_camv[0][1] + bluev * xyz_camv[0][2]; + vfloat xyz1v = redv * xyz_camv[1][0] + greenv * xyz_camv[1][1] + bluev * xyz_camv[1][2]; + vfloat xyz2v = redv * xyz_camv[2][0] + greenv * xyz_camv[2][1] + bluev * xyz_camv[2][2]; + xyz0v = cbrt[_mm_cvtps_epi32(xyz0v)]; + xyz1v = cbrt[_mm_cvtps_epi32(xyz1v)]; + xyz2v = cbrt[_mm_cvtps_epi32(xyz2v)]; + + STVFU(l[i * labWidth + j], c116v * xyz1v - c16v); + STVFU(a[i * labWidth + j], c500v * (xyz0v - xyz1v)); + STVFU(b[i * labWidth + j], c200v * (xyz1v - xyz2v)); + } + +#endif + + for(; j < labWidth; j++) { + float xyz[3] = {0.5f, 0.5f, 0.5f}; + + for(int c = 0; c < 3; c++) { + float val = rgb[i * width + j][c]; + xyz[0] += xyz_cam[0][c] * val; + xyz[1] += xyz_cam[1][c] * val; + xyz[2] += xyz_cam[2][c] * val; + } + + xyz[0] = cbrt[(int) xyz[0]]; + xyz[1] = cbrt[(int) xyz[1]]; + xyz[2] = cbrt[(int) xyz[2]]; + + l[i * labWidth + j] = 116 * xyz[1] - 16; + a[i * labWidth + j] = 500 * (xyz[0] - xyz[1]); + b[i * labWidth + j] = 200 * (xyz[1] - xyz[2]); + } + } +} + + +#define fcol(row,col) xtrans[(row)%6][(col)%6] +#define isgreen(row,col) (xtrans[(row)%3][(col)%3]&1) + +void RawImageSource::xtransborder_interpolate (int border) +{ + const int height = H, width = W; + + int xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) { + if (col == border && row >= border && row < height - border) { + col = width - border; + } + + float sum[6] = {0.f}; + + for (int y = MAX(0, row - 1); y <= MIN(row + 1, height - 1); y++) + for (int x = MAX(0, col - 1); x <= MIN(col + 1, width - 1); x++) { + int f = fcol(y, x); + sum[f] += rawData[y][x]; + sum[f + 3]++; + } + + switch(fcol(row, col)) { + case 0: + red[row][col] = rawData[row][col]; + green[row][col] = (sum[1] / sum[4]); + blue[row][col] = (sum[2] / sum[5]); + break; + + case 1: + if(sum[3] == 0.f) { // at the 4 corner pixels it can happen, that we have only green pixels in 2x2 area + red[row][col] = green[row][col] = blue[row][col] = rawData[row][col]; + } else { + red[row][col] = (sum[0] / sum[3]); + green[row][col] = rawData[row][col]; + blue[row][col] = (sum[2] / sum[5]); + } + + break; + + case 2: + red[row][col] = (sum[0] / sum[3]); + green[row][col] = (sum[1] / sum[4]); + blue[row][col] = rawData[row][col]; + } + } +} + +/* + Frank Markesteijn's algorithm for Fuji X-Trans sensors + adapted to RT by Ingo Weyrich 2014 +*/ +// override CLIP function to test unclipped output +#define CLIP(x) (x) +void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) +{ + BENCHFUN + constexpr int ts = 114; /* Tile Size */ + constexpr int tsh = ts / 2; /* half of Tile Size */ + + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "Xtrans")); + plistener->setProgress (progress); + } + + int xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + constexpr short orth[12] = { 1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1 }, + patt[2][16] = { { 0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0, 0, 0, 0 }, + { 0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1, -1, -1, 1 } + }, + dir[4] = { 1, ts, ts + 1, ts - 1 }; + + // sgrow/sgcol is the offset in the sensor matrix of the solitary + // green pixels + ushort sgrow = 0, sgcol = 0; + + const int height = H, width = W; + +// if (settings->verbose) { +// printf("%d-pass X-Trans interpolation using %s conversion...\n", passes, useCieLab ? "lab" : "yuv"); +// } + + xtransborder_interpolate(6); + + float xyz_cam[3][3]; + { + float rgb_cam[3][4]; + ri->getRgbCam(rgb_cam); + int k; + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (xyz_cam[i][j] = k = 0; k < 3; k++) { + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + } + } + + /* Map a green hexagon around each non-green pixel and vice versa: */ + short allhex[2][3][3][8]; + { + int gint, d, h, v, ng, row, col; + + for (row = 0; row < 3; row++) + for (col = 0; col < 3; col++) { + gint = isgreen(row, col); + + for (ng = d = 0; d < 10; d += 2) { + if (isgreen(row + orth[d] + 6, col + orth[d + 2] + 6)) { + ng = 0; + } else { + ng++; + } + + if (ng == 4) { + // if there are four non-green pixels adjacent in cardinal + // directions, this is the solitary green pixel + sgrow = row; + sgcol = col; + } + + if (ng == gint + 1) { + for (int c = 0; c < 8; c++) { + v = orth[d] * patt[gint][c * 2] + orth[d + 1] * patt[gint][c * 2 + 1]; + h = orth[d + 2] * patt[gint][c * 2] + orth[d + 3] * patt[gint][c * 2 + 1]; + allhex[0][row][col][c ^ (gint * 2 & d)] = h + v * width; + allhex[1][row][col][c ^ (gint * 2 & d)] = h + v * ts; + } + } + } + } + + } + + if(plistenerActive) { + progress += 0.05; + plistener->setProgress(progress); + } + + + double progressInc = 36.0 * (1.0 - progress) / ((H * W) / ((ts - 16) * (ts - 16))); + const int ndir = 4 << (passes > 1); + cielab (nullptr, nullptr, nullptr, nullptr, 0, 0, 0, nullptr); + struct s_minmaxgreen { + float min; + float max; + }; + + int RightShift[3]; + + for(int row = 0; row < 3; row++) { + // count number of green pixels in three cols + int greencount = 0; + + for(int col = 0; col < 3; col++) { + greencount += isgreen(row, col); + } + + RightShift[row] = (greencount == 2); + } + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + int progressCounter = 0; + int c; + float color[3][6]; + + float *buffer = (float *) malloc ((ts * ts * (ndir * 4 + 3) + 128) * sizeof(float)); + float (*rgb)[ts][ts][3] = (float(*)[ts][ts][3]) buffer; + float (*lab)[ts - 8][ts - 8] = (float (*)[ts - 8][ts - 8])(buffer + ts * ts * (ndir * 3)); + float (*drv)[ts - 10][ts - 10] = (float (*)[ts - 10][ts - 10]) (buffer + ts * ts * (ndir * 3 + 3)); + uint8_t (*homo)[ts][ts] = (uint8_t (*)[ts][ts]) (lab); // we can reuse the lab-buffer because they are not used together + s_minmaxgreen (*greenminmaxtile)[tsh] = (s_minmaxgreen(*)[tsh]) (lab); // we can reuse the lab-buffer because they are not used together + uint8_t (*homosum)[ts][ts] = (uint8_t (*)[ts][ts]) (drv); // we can reuse the drv-buffer because they are not used together + uint8_t (*homosummax)[ts] = (uint8_t (*)[ts]) homo[ndir - 1]; // we can reuse the homo-buffer because they are not used together + +#ifdef _OPENMP + #pragma omp for collapse(2) schedule(dynamic) nowait +#endif + + for (int top = 3; top < height - 19; top += ts - 16) + for (int left = 3; left < width - 19; left += ts - 16) { + int mrow = MIN (top + ts, height - 3); + int mcol = MIN (left + ts, width - 3); + + /* Set greenmin and greenmax to the minimum and maximum allowed values: */ + for (int row = top; row < mrow; row++) { + // find first non-green pixel + int leftstart = left; + + for(; leftstart < mcol; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); + + if(coloffset == 3) { + short *hex = allhex[0][row % 3][leftstart % 3]; + + for (int col = leftstart; col < mcol; col += coloffset) { + float minval = FLT_MAX; + float maxval = 0.f; + float *pix = &rawData[row][col]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + } + } else { + float minval = FLT_MAX; + float maxval = 0.f; + int col = leftstart; + + if(coloffset == 2) { + minval = FLT_MAX; + maxval = 0.f; + float *pix = &rawData[row][col]; + short *hex = allhex[0][row % 3][col % 3]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + col += 2; + } + + short *hex = allhex[0][row % 3][col % 3]; + + for (; col < mcol - 1; col += 3) { + minval = FLT_MAX; + maxval = 0.f; + float *pix = &rawData[row][col]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + greenminmaxtile[row - top][(col + 1 - left) >> 1].min = minval; + greenminmaxtile[row - top][(col + 1 - left) >> 1].max = maxval; + } + + if(col < mcol) { + minval = FLT_MAX; + maxval = 0.f; + float *pix = &rawData[row][col]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + } + } + } + + memset(rgb, 0, ts * ts * 3 * sizeof(float)); + + for (int row = top; row < mrow; row++) + for (int col = left; col < mcol; col++) { + rgb[0][row - top][col - left][fcol(row, col)] = rawData[row][col]; + } + + for(int c = 0; c < 3; c++) { + memcpy (rgb[c + 1], rgb[0], sizeof * rgb); + } + + /* Interpolate green horizontally, vertically, and along both diagonals: */ + for (int row = top; row < mrow; row++) { + // find first non-green pixel + int leftstart = left; + + for(; leftstart < mcol; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); + + if(coloffset == 3) { + short *hex = allhex[0][row % 3][leftstart % 3]; + + for (int col = leftstart; col < mcol; col += coloffset) { + float *pix = &rawData[row][col]; + float color[4]; + color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - + 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); + color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + + 0.359375f * (pix[0] - pix[-hex[2]]); + + for(int c = 0; c < 2; c++) + color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * + (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); + + for(int c = 0; c < 4; c++) { + rgb[c][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } else { + short *hexmod[2]; + hexmod[0] = allhex[0][row % 3][leftstart % 3]; + hexmod[1] = allhex[0][row % 3][(leftstart + coloffset) % 3]; + + for (int col = leftstart, hexindex = 0; col < mcol; col += coloffset, coloffset ^= 3, hexindex ^= 1) { + float *pix = &rawData[row][col]; + short *hex = hexmod[hexindex]; + float color[4]; + color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - + 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); + color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + + 0.359375f * (pix[0] - pix[-hex[2]]); + + for(int c = 0; c < 2; c++) + color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * + (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); + + for(int c = 0; c < 4; c++) { + rgb[c ^ 1][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } + } + + for (int pass = 0; pass < passes; pass++) { + if (pass == 1) { + memcpy (rgb += 4, buffer, 4 * sizeof * rgb); + } + + /* Recalculate green from interpolated values of closer pixels: */ + if (pass) { + for (int row = top + 2; row < mrow - 2; row++) { + int leftstart = left + 2; + + for(; leftstart < mcol - 2; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); + + if(coloffset == 3) { + int f = fcol(row, leftstart); + short *hex = allhex[1][row % 3][leftstart % 3]; + + for (int col = leftstart; col < mcol - 2; col += coloffset, f ^= 2) { + for (int d = 3; d < 6; d++) { + float (*rix)[3] = &rgb[(d - 2)][row - top][col - left]; + float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) + - rix[-2 * hex[d]][f]) + rix[0][f]; + rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } else { + int f = fcol(row, leftstart); + short *hexmod[2]; + hexmod[0] = allhex[1][row % 3][leftstart % 3]; + hexmod[1] = allhex[1][row % 3][(leftstart + coloffset) % 3]; + + for (int col = leftstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2), hexindex ^= 1 ) { + short *hex = hexmod[hexindex]; + + for (int d = 3; d < 6; d++) { + float (*rix)[3] = &rgb[(d - 2) ^ 1][row - top][col - left]; + float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) + - rix[-2 * hex[d]][f]) + rix[0][f]; + rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } + } + } + + /* Interpolate red and blue values for solitary green pixels: */ + int sgstartcol = (left - sgcol + 4) / 3 * 3 + sgcol; + + for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) { + for (int col = sgstartcol, h = fcol(row, col + 1); col < mcol - 2; col += 3, h ^= 2) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + float diff[6] = {0.f}; + + for (int i = 1, d = 0; d < 6; d++, i ^= ts ^ 1, h ^= 2) { + for (int c = 0; c < 2; c++, h ^= 2) { + float g = rix[0][1] + rix[0][1] - rix[i << c][1] - rix[-i << c][1]; + color[h][d] = g + rix[i << c][h] + rix[-i << c][h]; + + if (d > 1) + diff[d] += SQR (rix[i << c][1] - rix[-i << c][1] + - rix[i << c][h] + rix[-i << c][h]) + SQR(g); + } + + if (d > 2 && (d & 1)) // 3, 5 + if (diff[d - 1] < diff[d]) + for(int c = 0; c < 2; c++) { + color[c * 2][d] = color[c * 2][d - 1]; + } + + if ((d & 1) || d < 2) { // d: 0, 1, 3, 5 + for(int c = 0; c < 2; c++) { + rix[0][c * 2] = CLIP(0.5f * color[c * 2][d]); + } + + rix += ts * ts; + } + } + } + } + + /* Interpolate red for blue pixels and vice versa: */ + for (int row = top + 3; row < mrow - 3; row++) { + int leftstart = left + 3; + + for(; leftstart < mcol - 1; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1); + c = (row - sgrow) % 3 ? ts : 1; + int h = 3 * (c ^ ts ^ 1); + + if(coloffset == 3) { + int f = 2 - fcol(row, leftstart); + + for (int col = leftstart; col < mcol - 3; col += coloffset, f ^= 2) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + + for (int d = 0; d < 4; d++, rix += ts * ts) { + int i = d > 1 || ((d ^ c) & 1) || + ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; + + rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); + } + } + } else { + coloffset = fcol(row, leftstart + 1) == 1 ? 2 : 1; + int f = 2 - fcol(row, leftstart); + + for (int col = leftstart; col < mcol - 3; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2) ) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + + for (int d = 0; d < 4; d++, rix += ts * ts) { + int i = d > 1 || ((d ^ c) & 1) || + ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; + + rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); + } + } + } + } + + /* Fill in red and blue for 2x2 blocks of green: */ + // Find first row of 2x2 green + int topstart = top + 2; + + for(; topstart < mrow - 2; topstart++) + if((topstart - sgrow) % 3) { + break; + } + + int leftstart = left + 2; + + for(; leftstart < mcol - 2; leftstart++) + if((leftstart - sgcol) % 3) { + break; + } + + int coloffsetstart = 2 - (fcol(topstart, leftstart + 1) & 1); + + for (int row = topstart; row < mrow - 2; row++) { + if ((row - sgrow) % 3) { + short *hexmod[2]; + hexmod[0] = allhex[1][row % 3][leftstart % 3]; + hexmod[1] = allhex[1][row % 3][(leftstart + coloffsetstart) % 3]; + + for (int col = leftstart, coloffset = coloffsetstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, hexindex ^= 1) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + short *hex = hexmod[hexindex]; + + for (int d = 0; d < ndir; d += 2, rix += ts * ts) { + if (hex[d] + hex[d + 1]) { + float g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; + + for (c = 0; c < 4; c += 2) { + rix[0][c] = CLIP((g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.33333333f); + } + } else { + float g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; + + for (c = 0; c < 4; c += 2) { + rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.5f); + } + } + } + } + } + } + } + +// end of multipass part + rgb = (float(*)[ts][ts][3]) buffer; + mrow -= top; + mcol -= left; + + if(useCieLab) { + /* Convert to CIELab and differentiate in all directions: */ + // Original dcraw algorithm uses CIELab as perceptual space + // (presumably coming from original AHD) and converts taking + // camera matrix into account. We use this in RT. + for (int d = 0; d < ndir; d++) { + float *l = &lab[0][0][0]; + float *a = &lab[1][0][0]; + float *b = &lab[2][0][0]; + cielab(&rgb[d][4][4], l, a, b, ts, mrow - 8, ts - 8, xyz_cam); + int f = dir[d & 3]; + f = f == 1 ? 1 : f - 8; + + for (int row = 5; row < mrow - 5; row++) +#ifdef _OPENMP + #pragma omp simd +#endif + for (int col = 5; col < mcol - 5; col++) { + float *l = &lab[0][row - 4][col - 4]; + float *a = &lab[1][row - 4][col - 4]; + float *b = &lab[2][row - 4][col - 4]; + + float g = 2 * l[0] - l[f] - l[-f]; + drv[d][row - 5][col - 5] = SQR(g) + + SQR((2 * a[0] - a[f] - a[-f] + g * 2.1551724f)) + + SQR((2 * b[0] - b[f] - b[-f] - g * 0.86206896f)); + } + + } + } else { + // For 1-pass demosaic we use YPbPr which requires much + // less code and is nearly indistinguishable. It assumes the + // camera RGB is roughly linear. + for (int d = 0; d < ndir; d++) { + float (*yuv)[ts - 8][ts - 8] = lab; // we use the lab buffer, which has the same dimensions +#ifdef __SSE2__ + vfloat zd2627v = F2V(0.2627f); + vfloat zd6780v = F2V(0.6780f); + vfloat zd0593v = F2V(0.0593f); + vfloat zd56433v = F2V(0.56433f); + vfloat zd67815v = F2V(0.67815f); +#endif + + for (int row = 4; row < mrow - 4; row++) { + int col = 4; +#ifdef __SSE2__ + + for (; col < mcol - 7; col += 4) { + // use ITU-R BT.2020 YPbPr, which is great, but could use + // a better/simpler choice? note that imageop.h provides + // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, + // which appears less good with specular highlights + vfloat redv, greenv, bluev; + vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[d][row][col], redv, greenv, bluev); + vfloat yv = zd2627v * redv + zd6780v * bluev + zd0593v * greenv; + STVFU(yuv[0][row - 4][col - 4], yv); + STVFU(yuv[1][row - 4][col - 4], (bluev - yv) * zd56433v); + STVFU(yuv[2][row - 4][col - 4], (redv - yv) * zd67815v); + } + +#endif + + for (; col < mcol - 4; col++) { + // use ITU-R BT.2020 YPbPr, which is great, but could use + // a better/simpler choice? note that imageop.h provides + // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, + // which appears less good with specular highlights + float y = 0.2627f * rgb[d][row][col][0] + 0.6780f * rgb[d][row][col][1] + 0.0593f * rgb[d][row][col][2]; + yuv[0][row - 4][col - 4] = y; + yuv[1][row - 4][col - 4] = (rgb[d][row][col][2] - y) * 0.56433f; + yuv[2][row - 4][col - 4] = (rgb[d][row][col][0] - y) * 0.67815f; + } + } + + int f = dir[d & 3]; + f = f == 1 ? 1 : f - 8; + + for (int row = 5; row < mrow - 5; row++) + for (int col = 5; col < mcol - 5; col++) { + float *y = &yuv[0][row - 4][col - 4]; + float *u = &yuv[1][row - 4][col - 4]; + float *v = &yuv[2][row - 4][col - 4]; + drv[d][row - 5][col - 5] = SQR(2 * y[0] - y[f] - y[-f]) + + SQR(2 * u[0] - u[f] - u[-f]) + + SQR(2 * v[0] - v[f] - v[-f]); + } + } + } + + /* Build homogeneity maps from the derivatives: */ +#ifdef __SSE2__ + vfloat eightv = F2V(8.f); + vfloat zerov = F2V(0.f); + vfloat onev = F2V(1.f); +#endif + + for (int row = 6; row < mrow - 6; row++) { + int col = 6; +#ifdef __SSE2__ + + for (; col < mcol - 9; col += 4) { + vfloat tr1v = vminf(LVFU(drv[0][row - 5][col - 5]), LVFU(drv[1][row - 5][col - 5])); + vfloat tr2v = vminf(LVFU(drv[2][row - 5][col - 5]), LVFU(drv[3][row - 5][col - 5])); + + if(ndir > 4) { + vfloat tr3v = vminf(LVFU(drv[4][row - 5][col - 5]), LVFU(drv[5][row - 5][col - 5])); + vfloat tr4v = vminf(LVFU(drv[6][row - 5][col - 5]), LVFU(drv[7][row - 5][col - 5])); + tr1v = vminf(tr1v, tr3v); + tr1v = vminf(tr1v, tr4v); + } + + tr1v = vminf(tr1v, tr2v); + tr1v = tr1v * eightv; + + for (int d = 0; d < ndir; d++) { + uint8_t tempstore[16]; + vfloat tempv = zerov; + + for (int v = -1; v <= 1; v++) { + for (int h = -1; h <= 1; h++) { + tempv += vselfzero(vmaskf_le(LVFU(drv[d][row + v - 5][col + h - 5]), tr1v), onev); + } + } + + _mm_storeu_si128((__m128i*)&tempstore, _mm_cvtps_epi32(tempv)); + homo[d][row][col] = tempstore[0]; + homo[d][row][col + 1] = tempstore[4]; + homo[d][row][col + 2] = tempstore[8]; + homo[d][row][col + 3] = tempstore[12]; + + } + } + +#endif + + for (; col < mcol - 6; col++) { + float tr = drv[0][row - 5][col - 5] < drv[1][row - 5][col - 5] ? drv[0][row - 5][col - 5] : drv[1][row - 5][col - 5]; + + for (int d = 2; d < ndir; d++) { + tr = (drv[d][row - 5][col - 5] < tr ? drv[d][row - 5][col - 5] : tr); + } + + tr *= 8; + + for (int d = 0; d < ndir; d++) { + uint8_t temp = 0; + + for (int v = -1; v <= 1; v++) { + for (int h = -1; h <= 1; h++) { + temp += (drv[d][row + v - 5][col + h - 5] <= tr ? 1 : 0); + } + } + + homo[d][row][col] = temp; + } + } + } + + if (height - top < ts + 4) { + mrow = height - top + 2; + } + + if (width - left < ts + 4) { + mcol = width - left + 2; + } + + + /* Build 5x5 sum of homogeneity maps */ + const int startcol = MIN(left, 8); + + for(int d = 0; d < ndir; d++) { + for (int row = MIN(top, 8); row < mrow - 8; row++) { + int col = startcol; +#ifdef __SSE2__ + int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; + + // crunching 16 values at once is faster than summing up column sums + for (; col < endcol; col += 16) { + vint v5sumv = (vint)ZEROV; + + for(int v = -2; v <= 2; v++) + for(int h = -2; h <= 2; h++) { + v5sumv = _mm_adds_epu8( _mm_loadu_si128((vint*)&homo[d][row + v][col + h]), v5sumv); + } + + _mm_storeu_si128((vint*)&homosum[d][row][col], v5sumv); + } + +#endif + + if(col < mcol - 8) { + int v5sum[5] = {0}; + + for(int v = -2; v <= 2; v++) + for(int h = -2; h <= 2; h++) { + v5sum[2 + h] += homo[d][row + v][col + h]; + } + + int blocksum = v5sum[0] + v5sum[1] + v5sum[2] + v5sum[3] + v5sum[4]; + homosum[d][row][col] = blocksum; + col++; + + // now we can subtract a column of five from blocksum and get new colsum of 5 + for (int voffset = 0; col < mcol - 8; col++, voffset++) { + int colsum = homo[d][row - 2][col + 2] + homo[d][row - 1][col + 2] + homo[d][row][col + 2] + homo[d][row + 1][col + 2] + homo[d][row + 2][col + 2]; + voffset = voffset == 5 ? 0 : voffset; // faster than voffset %= 5; + blocksum -= v5sum[voffset]; + blocksum += colsum; + v5sum[voffset] = colsum; + homosum[d][row][col] = blocksum; + } + } + } + } + + // calculate maximum of homogeneity maps per pixel. Vectorized calculation is a tiny bit faster than on the fly calculation in next step +#ifdef __SSE2__ + vint maskv = _mm_set1_epi8(31); +#endif + + for (int row = MIN(top, 8); row < mrow - 8; row++) { + int col = startcol; +#ifdef __SSE2__ + int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; + + for (; col < endcol; col += 16) { + vint maxval1 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[0][row][col]), _mm_loadu_si128((vint*)&homosum[1][row][col])); + vint maxval2 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[2][row][col]), _mm_loadu_si128((vint*)&homosum[3][row][col])); + + if(ndir > 4) { + vint maxval3 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[4][row][col]), _mm_loadu_si128((vint*)&homosum[5][row][col])); + vint maxval4 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[6][row][col]), _mm_loadu_si128((vint*)&homosum[7][row][col])); + maxval1 = _mm_max_epu8(maxval1, maxval3); + maxval1 = _mm_max_epu8(maxval1, maxval4); + } + + maxval1 = _mm_max_epu8(maxval1, maxval2); + // there is no shift intrinsic for epu8. Shift using epi32 and mask the wrong bits out + vint subv = _mm_srli_epi32( maxval1, 3 ); + subv = _mm_and_si128(subv, maskv); + maxval1 = _mm_subs_epu8(maxval1, subv); + _mm_storeu_si128((vint*)&homosummax[row][col], maxval1); + } + +#endif + + for (; col < mcol - 8; col ++) { + uint8_t maxval = homosum[0][row][col]; + + for(int d = 1; d < ndir; d++) { + maxval = maxval < homosum[d][row][col] ? homosum[d][row][col] : maxval; + } + + maxval -= maxval >> 3; + homosummax[row][col] = maxval; + } + } + + + /* Average the most homogeneous pixels for the final result: */ + uint8_t hm[8] = {}; + + for (int row = MIN(top, 8); row < mrow - 8; row++) + for (int col = MIN(left, 8); col < mcol - 8; col++) { + + for (int d = 0; d < 4; d++) { + hm[d] = homosum[d][row][col]; + } + + for (int d = 4; d < ndir; d++) { + hm[d] = homosum[d][row][col]; + + if (hm[d - 4] < hm[d]) { + hm[d - 4] = 0; + } else if (hm[d - 4] > hm[d]) { + hm[d] = 0; + } + } + + float avg[4] = {0.f}; + + uint8_t maxval = homosummax[row][col]; + + for (int d = 0; d < ndir; d++) + if (hm[d] >= maxval) { + for (int c = 0; c < 3; c++) { + avg[c] += rgb[d][row][col][c]; + } + avg[3]++; + } + + red[row + top][col + left] = avg[0] / avg[3]; + green[row + top][col + left] = avg[1] / avg[3]; + blue[row + top][col + left] = avg[2] / avg[3]; + } + + if(plistenerActive && ((++progressCounter) % 32 == 0)) { +#ifdef _OPENMP + #pragma omp critical (xtransdemosaic) +#endif + { + progress += progressInc; + progress = min(1.0, progress); + plistener->setProgress (progress); + } + } + + + } + + free(buffer); + } + +} +#undef CLIP +void RawImageSource::fast_xtrans_interpolate () +{ +// if (settings->verbose) { +// printf("fast X-Trans interpolation...\n"); +// } + + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); + plistener->setProgress (progress); + } + + const int height = H, width = W; + + xtransborder_interpolate (1); + int xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + #pragma omp parallel for + + for(int row = 1; row < height - 1; row++) { + for(int col = 1; col < width - 1; col++) { + float sum[3] = {0.f}; + + for(int v = -1; v <= 1; v++) { + for(int h = -1; h <= 1; h++) { + sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)]; + } + } + + switch(fcol(row, col)) { + case 0: + red[row][col] = rawData[row][col]; + green[row][col] = sum[1] * 0.2f; + blue[row][col] = sum[2] * 0.33333333f; + break; + + case 1: + red[row][col] = sum[0] * 0.5f; + green[row][col] = rawData[row][col]; + blue[row][col] = sum[2] * 0.5f; + break; + + case 2: + red[row][col] = sum[0] * 0.33333333f; + green[row][col] = sum[1] * 0.2f; + blue[row][col] = rawData[row][col]; + break; + } + } + } + + if (plistenerActive) { + plistener->setProgress (1.0); + } +} +#undef fcol +#undef isgreen +} \ No newline at end of file From 0207705c16e19c815340e6a174c20149981fb23c Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 18 Apr 2018 15:00:21 +0200 Subject: [PATCH 7/8] Pixelshift: renamed 'ISO-adaption' slider to 'sensitivity' slider. Changed calculation of sensitivity. Some cleanups --- rtdata/languages/default | 24 +++---------------- rtdata/profiles/Pixel Shift/PS ISO High.pp3 | 4 ++-- rtdata/profiles/Pixel Shift/PS ISO Low.pp3 | 4 ++-- rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 | 4 ++-- rtdata/profiles/Pixel Shift/PS No Motion.pp3 | 4 ++-- rtengine/pixelshift.cc | 2 +- rtengine/procparams.cc | 3 +++ rtgui/ppversion.h | 4 +++- 8 files changed, 18 insertions(+), 31 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e4dd9e4ed..96a277b7a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1782,52 +1782,34 @@ TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (ste TP_RAW_MONO;Mono TP_RAW_NONE;None (Shows sensor pattern) TP_RAW_PIXELSHIFT;Pixel Shift -TP_RAW_PIXELSHIFTADAPTIVE;Adaptive detection TP_RAW_PIXELSHIFTBLUR;Blur motion mask -TP_RAW_PIXELSHIFTEPERISO;ISO adaption -TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value of 0 should work fine for base ISO.\nIncrease the value to improve motion detection for higher ISO.\nIncrease in small steps and watch the motion mask while increasing. +TP_RAW_PIXELSHIFTEPERISO;Sensitivity +TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value of 0 should work fine for base ISO.\nHigher values increase sensitivity of motion detection.\nChange in small steps and watch the motion mask while changing.\nIncrease sensitivity for underexposed or high ISO images. TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalize brightness of frames TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalize per channel TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Enabled: Equalize the RGB channels individually.\nDisabled: Use same equalization factor for all channels. TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalize the brightness of the frames to the brightness of the selected frame.\nIf there are overexposed areas in the frames select the brightest frame to avoid magenta colour cast in overexposed areas or enable motion correction. -TP_RAW_PIXELSHIFTEXP0;Experimental TP_RAW_PIXELSHIFTGREEN;Check green channel for motion TP_RAW_PIXELSHIFTHOLEFILL;Fill holes in motion mask TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Fill holes in motion mask TP_RAW_PIXELSHIFTLMMSE;Use LMMSE for moving parts TP_RAW_PIXELSHIFTLMMSE_TOOLTIP;Use LMMSE instead of AMaZE for areas of motion.\nUseful for high ISO images. -TP_RAW_PIXELSHIFTMASKTHRESHOLD;3x3 new threshold TP_RAW_PIXELSHIFTMEDIAN;Use median for moving parts -TP_RAW_PIXELSHIFTMEDIAN3;Exclude selected frame from median -TP_RAW_PIXELSHIFTMEDIAN3_TOOLTIP;Excludes selected frame from median.\nUseful if moving objects overlap in frame 2 and 3 TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Use median of all frames instead of selected frame for regions with motion.\nRemoves objects which are at different places in all frames.\nGives motion effect on slow moving (overlapping) objects. TP_RAW_PIXELSHIFTMM_AUTO;Automatic TP_RAW_PIXELSHIFTMM_CUSTOM;Custom TP_RAW_PIXELSHIFTMM_OFF;Off -TP_RAW_PIXELSHIFTMOTION;Motion detection level (deprecated) -TP_RAW_PIXELSHIFTMOTIONCORRECTION;Green motion correction size TP_RAW_PIXELSHIFTMOTIONMETHOD;Motion Correction TP_RAW_PIXELSHIFTMOTION_TOOLTIP;0 means no motion detection.\n1 - 99 means motion will be detected according to this value. Increase value to increase detection rate.\n100 means the AMaZE-demosaiced frame will be used. -TP_RAW_PIXELSHIFTNONGREENAMAZE;Check red/blue AMaZE TP_RAW_PIXELSHIFTNONGREENCROSS;Check red/blue channels for motion -TP_RAW_PIXELSHIFTNONGREENCROSS2;Check green AMaZE -TP_RAW_PIXELSHIFTNONGREENHORIZONTAL;Check red/blue horizontal -TP_RAW_PIXELSHIFTNONGREENVERTICAL;Check red/blue vertical -TP_RAW_PIXELSHIFTNREADISO;nRead -TP_RAW_PIXELSHIFTPRNU;PRNU (%) -TP_RAW_PIXELSHIFTREDBLUEWEIGHT;Red&Blue weight TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Show only motion mask TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Shows the motion mask without the image. -TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a mask showing the regions with motion. +TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a green mask showing the regions with motion. TP_RAW_PIXELSHIFTSIGMA;Blur radius TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;The default radius of 1.0 usually fits well for base ISO.\nIncrease the value for high ISO shots, 5.0 is a good starting point.\nWatch the motion mask while changing the value. TP_RAW_PIXELSHIFTSMOOTH;Smooth transitions TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Smooth transitions between areas with motion and areas without.\nSet to 0 to disable transition smoothing.\nSet to 1 to either get the AMaZE/LMMSE result of the selected frame (depending on whether "Use LMMSE" is selected), or the median of all four frames if "Use median" is selected. -TP_RAW_PIXELSHIFTSTDDEVFACTORBLUE;StdDev factor Blue -TP_RAW_PIXELSHIFTSTDDEVFACTORGREEN;StdDev factor Green -TP_RAW_PIXELSHIFTSTDDEVFACTORRED;StdDev factor Red -TP_RAW_RCD;RCD TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix diff --git a/rtdata/profiles/Pixel Shift/PS ISO High.pp3 b/rtdata/profiles/Pixel Shift/PS ISO High.pp3 index 2c9927e93..87af3febd 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO High.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO High.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [RAW] CA=true diff --git a/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 index cbf2e6c74..62374cb69 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [Sharpening] Enabled=true diff --git a/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 index 2c83094c2..16463b1b0 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [RAW] CA=true diff --git a/rtdata/profiles/Pixel Shift/PS No Motion.pp3 b/rtdata/profiles/Pixel Shift/PS No Motion.pp3 index 7a73881a1..8f0cce13b 100644 --- a/rtdata/profiles/Pixel Shift/PS No Motion.pp3 +++ b/rtdata/profiles/Pixel Shift/PS No Motion.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [Sharpening] Enabled=true diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 5fcb391a7..5aac37d20 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -577,7 +577,7 @@ BENCHFUN eperIsoModel = ePerIsoK70; } - eperIsoModel *= pow(2.f, eperIso); + eperIsoModel *= pow(2.f, eperIso - 1.f); eperIso = eperIsoModel * (100.f / (rawWpCorrection * idata->getISOSpeed())); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 74adc4a6e..946aacec4 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -4646,6 +4646,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftEperIso", pedited, raw.bayersensor.pixelShiftEperIso, pedited->raw.bayersensor.pixelShiftEperIso); + if (ppVersion < 332) { + raw.bayersensor.pixelShiftEperIso += 1.0; + } assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSigma", pedited, raw.bayersensor.pixelShiftSigma, pedited->raw.bayersensor.pixelShiftSigma); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", pedited, raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", pedited, raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index e2838c2c0..f3ef28f4a 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -1,11 +1,13 @@ #pragma once // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 331 +#define PPVERSION 332 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 332 2018-18-04 + changed pixelShiftEperIso calculation 331 2018-14-02 changed wavelet.Lmethod to int 330 2018-20-01 From e518e7923e3e1433012073fa140ad221e3722180 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Thu, 19 Apr 2018 20:53:41 +0200 Subject: [PATCH 8/8] Better raw crop for Pentax K-S1 --- rtengine/camconst.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index cfe7412d8..35cb524a1 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2004,6 +2004,11 @@ Camera constants: "ranges": { "white": 4080 } // nominal at ISO200 4094 }, + { + "make_model": [ "PENTAX K-S1" ], + "raw_crop": [ 0, 0, -8, 0 ] + }, + { // Quality B, Intemediate ISO samples missing, Pentax_DNG WLtags are after BL sutraction and not valid "make_model": [ "RICOH PENTAX K-70", "PENTAX K-70" ], //"dcraw_matrix": [ 8050,-2061,-1264,-4359,12953,1515,-1096,1965,6075 ], // PENTAX DNG D65