From 2c949cf011c77505f61aa1e875ceb766ccdad2e5 Mon Sep 17 00:00:00 2001 From: Oliver Duis Date: Mon, 25 Apr 2011 10:21:31 +0200 Subject: [PATCH] RAW histogram mode; see issue #639 --- rtdata/languages/default | 2 + rtengine/imagesource.h | 6 +- rtengine/improccoordinator.cc | 14 ++- rtengine/improccoordinator.h | 1 + rtengine/rawimagesource.cc | 72 +++++++++--- rtengine/rawimagesource.h | 9 +- rtengine/rtengine.h | 5 +- rtengine/simpleprocess.cc | 2 +- rtengine/stdimagesource.cc | 3 +- rtengine/stdimagesource.h | 2 +- rtgui/editorpanel.cc | 5 +- rtgui/editorpanel.h | 3 +- rtgui/histogrampanel.cc | 199 ++++++---------------------------- rtgui/histogrampanel.h | 21 ++-- rtgui/rawexposure.cc | 2 +- 15 files changed, 138 insertions(+), 208 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 30c81217c..99d3092ca 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -151,11 +151,13 @@ HISTOGRAM_BUTTON_B;B HISTOGRAM_BUTTON_G;G HISTOGRAM_BUTTON_L;L HISTOGRAM_BUTTON_R;R +HISTOGRAM_BUTTON_RAW;Raw HISTOGRAM_LABEL;Histogram HISTOGRAM_TOOLTIP_B;Show/Hide BLUE histogram HISTOGRAM_TOOLTIP_G;Show/Hide GREEN histogram HISTOGRAM_TOOLTIP_L;Show/Hide CIELAB Luminance histogram HISTOGRAM_TOOLTIP_R;Show/Hide RED histogram +HISTOGRAM_TOOLTIP_RAW;Show/Hide RAW histogram HISTORY_CHANGED;Changed HISTORY_CUSTOMCURVE;Custom Curve HISTORY_DELSNAPSHOT;Del diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 9908ff78c..05a65bdcb 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -87,7 +87,11 @@ class ImageSource : public InitialImage { void increaseRef () { references++; } void decreaseRef () { references--; if (!references) delete this; } - virtual int getAEHistogram (LUTu & histogram, int& histcompr) {return 0;} + + virtual void getAutoExpHistogram (LUTu & histogram, int& histcompr)=0; + virtual void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { + histRedRaw.clear(); histGreenRaw.clear(); histBlueRaw.clear(); // only some sources will supply this + } // functions inherited from the InitialImage interface virtual Glib::ustring getFileName () { return fileName; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index dceda03a7..9589c8840 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -47,9 +47,9 @@ ImProcCoordinator::ImProcCoordinator () lhist16(65536); histCropped(65536); - histRed(65536); - histGreen(65536); - histBlue(256); + histRed(256); histRedRaw(256); + histGreen(256); histGreenRaw(256); + histBlue(256); histBlueRaw(256); histLuma(256); histToneCurve(256); histLCurve(256); @@ -111,8 +111,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { } progress ("Applying white balance, color correction & sRBG conversion...",100*readyphase/numofphases); - if ( todo & M_PREPROC) + if ( todo & M_PREPROC) { imgsrc->preprocess( rp ); + imgsrc->getRAWHistogram( histRedRaw, histGreenRaw, histBlueRaw ); + } if( todo & M_RAW){ fineDetailsProcessed = highDetailNeeded; @@ -178,7 +180,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { if (todo & M_AUTOEXP) { if (params.toneCurve.autoexp) { LUTu aehist; int aehistcompr; - imgsrc->getAEHistogram (aehist, aehistcompr); + imgsrc->getAutoExpHistogram (aehist, aehistcompr); ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.black); if (aeListener) aeListener->autoExpChanged (params.toneCurve.expcomp, params.toneCurve.black); @@ -289,7 +291,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { hy2 = MIN(pH,MAX(0,(params.crop.y+params.crop.h) / scale)); } updateHistograms (hx1, hy1, hx2, hy2); // just RGBL, not the tone curves - hListener->histogramChanged (histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve); + hListener->histogramChanged (histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histRedRaw, histGreenRaw, histBlueRaw); } progress ("Ready",100*readyphase/numofphases); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 0126ea6c8..7afd75065 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -81,6 +81,7 @@ class ImProcCoordinator : public StagedImageProcessor { LUTu histCropped; LUTu histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, bcabhist; + LUTu histRedRaw, histGreenRaw, histBlueRaw; int fw, fh, tr, fullw, fullh; int pW, pH; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 7ca8ae6f9..b614cb898 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1861,7 +1861,7 @@ void RawImageSource::hlRecovery (std::string method, float* red, float* green, f //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -int RawImageSource::getAEHistogram (LUTu & histogram, int& histcompr) { +void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { histcompr = 3; @@ -1870,16 +1870,9 @@ int RawImageSource::getAEHistogram (LUTu & histogram, int& histcompr) { for (int i=border; iget_FujiWidth(); - start = ABS(fw-i) + border; - end = MIN( H+ W-fw-i, fw+i) - border; - } - else { - start = border; - end = W-border; - } - if (ri->isBayer()) + getRowStartEnd (i, start, end); + + if (ri->isBayer()) { for (int j=start; jISGREEN(i,j)) histogram[CLIP((int)(camwb_green*rawData[i][j]))>>histcompr]+=4; @@ -1887,6 +1880,7 @@ int RawImageSource::getAEHistogram (LUTu & histogram, int& histcompr) { histogram[CLIP((int)(camwb_red*rawData[i][j]))>>histcompr]+=4; else if (ri->ISBLUE(i,j)) histogram[CLIP((int)(camwb_blue*rawData[i][j]))>>histcompr]+=4; + } } else { for (int j=start; j<3*end; j++) { histogram[CLIP((int)(camwb_red*rawData[i][j+0]))>>histcompr]++; @@ -1894,9 +1888,61 @@ int RawImageSource::getAEHistogram (LUTu & histogram, int& histcompr) { histogram[CLIP((int)(camwb_blue*rawData[i][j+2]))>>histcompr]++; } } - } - return 1; +} + +// Histogram MUST be 256 in size; gamma is applied, blackpoint and gain also +void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { + + histRedRaw.clear(); histGreenRaw.clear(); histBlueRaw.clear(); + + float mult = 65535.0 / ri->get_white(); + + for (int i=border; iisBayer()) { + for (int j=start; jISGREEN(i,j)) { + idx = CLIP((int)CurveFactory::gamma(mult*(ri->data[i][j]-cblack[0]))); + histGreenRaw[idx>>8]++; + } else if (ri->ISRED(i,j)) { + idx = CLIP((int)CurveFactory::gamma(mult*(ri->data[i][j]-cblack[1]))); + histRedRaw[idx>>8]++; + } else if (ri->ISBLUE(i,j)) { + idx = CLIP((int)CurveFactory::gamma(mult*(ri->data[i][j]-cblack[2]))); + histBlueRaw[idx>>8]++; + } + } + } else { + for (int j=start; j<3*end; j++) { + idx = CLIP((int)CurveFactory::gamma(mult*(ri->data[i][j]-cblack[0]))); + histRedRaw[idx>>8]++; + + idx = CLIP((int)CurveFactory::gamma(mult*(ri->data[i][j+1]-cblack[1]))); + histGreenRaw[idx>>8]++; + + idx = CLIP((int)CurveFactory::gamma(mult*(ri->data[i][j+2]-cblack[2]))); + histBlueRaw[idx>>8]++; + } + } + } + + // since there are twice as many greens, correct for it + if (ri->isBayer()) for (int i=0;i<256;i++) histGreenRaw[i]>>=1; +} + +void RawImageSource::getRowStartEnd (int x, int &start, int &end) { + if (fuji) { + int fw = ri->get_FujiWidth(); + start = ABS(fw-x) + border; + end = MIN( H+ W-fw-x, fw+x) - border; + } + else { + start = border; + end = W-border; + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 9c40077fb..7daef1748 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -78,14 +78,14 @@ class RawImageSource : public ImageSource { cmsHPROFILE camProfile; cmsHPROFILE embProfile; - RawImage* ri; // Copy of raw pixels + RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc. // to accelerate CIELAB conversion: double lc00, lc01, lc02, lc10, lc11, lc12, lc20, lc21, lc22; double* cache; int threshold; - float** rawData; // holds pixel values, data[i][j] corresponds to the ith row and jth column + float** rawData; // holds preprocessed pixel values, data[i][j] corresponds to the ith row and jth column // the interpolated green plane: float** green; @@ -109,6 +109,8 @@ class RawImageSource : public ImageSource { void updateHLRecoveryMap_ColorPropagation (); void HLRecovery_ColorPropagation (float* red, float* green, float* blue, int i, int sx1, int width, int skip); unsigned FC(int row, int col){ return ri->FC(row,col); } + inline void getRowStartEnd (int x, int &start, int &end); + public: RawImageSource (); ~RawImageSource (); @@ -132,7 +134,8 @@ class RawImageSource : public ImageSource { ImageData* getImageData () { return idata; } void setProgressListener (ProgressListener* pl) { plistener = pl; } - int getAEHistogram (LUTu & histogram, int& histcompr); + void getAutoExpHistogram (LUTu & histogram, int& histcompr); + void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); static void colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], double& defgain); static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], double& defgain); diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 90dfd9d27..cbce0b301 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -204,8 +204,9 @@ namespace rtengine { * @param histGreen is the array of size 256 containing the histogram of the green channel * @param histBlue is the array of size 256 containing the histogram of the blue channel * @param histLuma is the array of size 256 containing the histogram of the luminance channel - * other for curves backgrounds */ - virtual void histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve,LUTu & histLCurve) {} + * other for curves backgrounds, histRAW is RAW without colors */ + virtual void histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, + LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) {} }; /** This listener is used when the auto exposure has been recomputed (e.g. when the clipping ratio changed). */ diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 65534c394..4fe698a16 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -140,7 +140,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p if (params.toneCurve.autoexp) { LUTu aehist; int aehistcompr; - imgsrc->getAEHistogram (aehist, aehistcompr); + imgsrc->getAutoExpHistogram (aehist, aehistcompr); ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), params.toneCurve.clip, br, bl); } diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 2b5532825..5d7c5bc92 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -531,7 +531,7 @@ void StdImageSource::hlRecovery (unsigned short* red, unsigned short* green, uns rtengine::hlRecovery (red, green, blue, img->height, img->width, i, sx1, sx2, skip, needhr, hrmap); } */ -int StdImageSource::getAEHistogram (LUTu & histogram, int& histcompr) { +void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { histcompr = 3; @@ -544,7 +544,6 @@ int StdImageSource::getAEHistogram (LUTu & histogram, int& histcompr) { histogram[(int)CurveFactory::igamma_srgb (img->g[i][j])>>histcompr]++; histogram[(int)CurveFactory::igamma_srgb (img->b[i][j])>>histcompr]++; } - return 1; } ColorTemp StdImageSource::getAutoWB () { diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index c8ec984b7..ae2d50f16 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -49,7 +49,7 @@ class StdImageSource : public ImageSource { ColorTemp getAutoWB (); ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); - int getAEHistogram (LUTu &histogram, int& histcompr); + void getAutoExpHistogram (LUTu &histogram, int& histcompr); double getDefGain () { return 0.0; } double getGamma () { return 0.0; } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index aae885c0e..743c42488 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1287,9 +1287,10 @@ void EditorPanel::beforeAfterToggled () { } } -void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve) { +void EditorPanel::histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, + LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { - histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma); + histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw); tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index e691d8a08..ada625ca0 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -149,7 +149,8 @@ class EditorPanel : public Gtk::VBox, void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params); // HistogramListener - void histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve); + void histogramChanged (LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histToneCurve, LUTu & histLCurve, + LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); // event handlers void info_toggled (); diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 2b3461440..a1fddcafd 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -29,16 +29,19 @@ HistogramPanel::HistogramPanel () { showGreen = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_G"))); showBlue = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_B"))); showValue = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_L"))); + showRAW = Gtk::manage (new Gtk::ToggleButton (M("HISTOGRAM_BUTTON_RAW"))); Gtk::VBox* vbox = Gtk::manage (new Gtk::VBox (false, 0)); showRed->set_active (true); showGreen->set_active (true); showBlue->set_active (true); showValue->set_active (true); + showRAW->set_active (false); vbox->pack_start (*showRed, Gtk::PACK_SHRINK, 2); vbox->pack_start (*showGreen, Gtk::PACK_SHRINK, 2); vbox->pack_start (*showBlue, Gtk::PACK_SHRINK, 2); vbox->pack_start (*showValue, Gtk::PACK_SHRINK, 2); + vbox->pack_end (*showRAW, Gtk::PACK_SHRINK, 2); pack_start (*histogramArea); pack_end (*vbox, Gtk::PACK_SHRINK, 2); @@ -46,6 +49,7 @@ HistogramPanel::HistogramPanel () { showGreen->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); showBlue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); showValue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); + showRAW->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::rgbv_toggled) ); show_all (); @@ -53,6 +57,7 @@ HistogramPanel::HistogramPanel () { showGreen->set_tooltip_text (M("HISTOGRAM_TOOLTIP_G")); showBlue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_B")); showValue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_L")); + showRAW->set_tooltip_text (M("HISTOGRAM_TOOLTIP_RAW")); rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &HistogramPanel::resized) ); } @@ -72,17 +77,12 @@ void HistogramPanel::resized (Gtk::Allocation& req) { void HistogramPanel::rgbv_toggled () { - histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active()); + histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showRAW->get_active()); histogramArea->queue_draw (); } HistogramArea::HistogramArea () : - valid(false), showFull(true), oldwidth(-1), needVal(true), needRed(true), needGreen(true), needBlue(true) { - - lhist(256); - rhist(256); - ghist(256); - bhist(256); + valid(false), showFull(true), oldwidth(-1), needLuma(true), needRed(true), needGreen(true), needBlue(true), rawMode(false) { haih = new HistogramAreaIdleHelper; haih->harea = this; @@ -101,12 +101,13 @@ HistogramArea::~HistogramArea () { } -void HistogramArea::updateOptions (bool r, bool g, bool b, bool v) { +void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool raw) { needRed = r; needGreen = g; needBlue = b; - needVal = v; + needLuma = l; + rawMode = raw; renderHistogram (); } @@ -134,13 +135,13 @@ int histupdate (void* data) { return 0; } -void HistogramArea::update (LUTu & rh, LUTu & gh, LUTu & bh, LUTu & lh) { +void HistogramArea::update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw) { - if (rh) { - lhist=lh; - rhist=rh; - ghist=gh; - bhist=bh; + if (histRed) { + lhist=histLuma; + rhist=histRed; ghist=histGreen; bhist=histBlue; + rhistRaw=histRedRaw; ghistRaw=histGreenRaw; bhistRaw=histBlueRaw; + valid = true; } else @@ -167,6 +168,10 @@ void HistogramArea::renderHistogram () { backBuffer->draw_rectangle (bgc, true, 0, 0, winw, winh); if (valid) { + // For RAW mode use the other hists + LUTu& rh = rawMode ? rhistRaw : rhist; + LUTu& gh = rawMode ? ghistRaw : ghist; + LUTu& bh = rawMode ? bhistRaw : bhist; // compute height of the full histogram (realheight) and // does not take into account 0 and 255 values @@ -174,14 +179,14 @@ void HistogramArea::renderHistogram () { int fullhistheight = 0; for (int i=1; i<255; i++) { - if (needVal && lhist[i]>fullhistheight) + if (needLuma && lhist[i]>fullhistheight) fullhistheight = lhist[i]; - if (needRed && rhist[i]>fullhistheight) - fullhistheight = rhist[i]; - if (needGreen && ghist[i]>fullhistheight) - fullhistheight = ghist[i]; - if (needBlue && bhist[i]>fullhistheight) - fullhistheight = bhist[i]; + if (needRed && (rawMode?rhistRaw:rhist)[i]>fullhistheight) + fullhistheight = rh[i]; + if (needGreen && (rawMode?ghistRaw:ghist)[i]>fullhistheight) + fullhistheight = gh[i]; + if (needBlue && (rawMode?bhistRaw:bhist)[i]>fullhistheight) + fullhistheight = bh[i]; } int realhistheight = fullhistheight; @@ -192,7 +197,7 @@ void HistogramArea::renderHistogram () { int area = 0; for (int i=0; ii) || (needRed && rhist[j]>i) || (needGreen && ghist[j]>i) || (needBlue && bhist[j]>i)) + if ((needLuma && !rawMode && lhist[j]>i) || (needRed && rh[j]>i) || (needGreen && gh[j]>i) || (needBlue && bh[j]>i)) area++; if (area1thres==0 && (double)area / (256*(i+1)) < 0.3) area1thres = i; @@ -214,7 +219,7 @@ void HistogramArea::renderHistogram () { int ui = 0, oi = 0; - if (needVal) { + if (needLuma && !rawMode) { drawCurve(cr, lhist, realhistheight, winw, winh); cr->set_source_rgb (0.75, 0.75, 0.75); cr->fill_preserve (); @@ -224,162 +229,28 @@ void HistogramArea::renderHistogram () { drawMarks(cr, lhist, realhistheight, winw, ui, oi); } if (needRed) { - drawCurve(cr, rhist, realhistheight, winw, winh); + drawCurve(cr, rh, realhistheight, winw, winh); cr->set_source_rgb (1.0, 0.0, 0.0); cr->stroke (); - drawMarks(cr, rhist, realhistheight, winw, ui, oi); + drawMarks(cr, rh, realhistheight, winw, ui, oi); } if (needGreen) { - drawCurve(cr, ghist, realhistheight, winw, winh); + drawCurve(cr, gh, realhistheight, winw, winh); cr->set_source_rgb (0.0, 1.0, 0.0); cr->stroke (); - drawMarks(cr, ghist, realhistheight, winw, ui, oi); + drawMarks(cr, gh, realhistheight, winw, ui, oi); } if (needBlue) { - drawCurve(cr, bhist, realhistheight, winw, winh); + drawCurve(cr, bh, realhistheight, winw, winh); cr->set_source_rgb (0.0, 0.0, 1.0); cr->stroke (); - drawMarks(cr, bhist, realhistheight, winw, ui, oi); + drawMarks(cr, bh, realhistheight, winw, ui, oi); } } -/* - - // scale histogram to width winw-1 - - int* vval = new int[winw-1]; - int* vred = new int[winw-1]; - int* vgreen = new int[winw-1]; - int* vblue = new int[winw-1]; - - memset (vval, 0, sizeof(int)*(winw-1)); - memset (vred, 0, sizeof(int)*(winw-1)); - memset (vgreen, 0, sizeof(int)*(winw-1)); - memset (vblue, 0, sizeof(int)*(winw-1)); - - int index = 0; - double scale = 256.0 / (winw-2); - for (int i=0; i<=winw-2; i++) { - int samples = 0; - while (index < 256 && (int)(index/scale) == i) { - vval[i] += lhist[index]; - vred[i] += rhist[index]; - vgreen[i] += ghist[index]; - vblue[i] += bhist[index]; - index++; - samples++; - } - if (samples>0) { - vval[i] /= samples; - vred[i] /= samples; - vgreen[i] /= samples; - vblue[i] /= samples; - } - } - - // compute height of the full histogram (realheight) and - - int fullhistheight = 0; - for (int i=0; i<=winw-2; i++) { - if (needVal && vval[i]>fullhistheight) - fullhistheight = vval[i]; - if (needRed && vred[i]>fullhistheight) - fullhistheight = vred[i]; - if (needGreen && vgreen[i]>fullhistheight) - fullhistheight = vgreen[i]; - if (needBlue && vblue[i]>fullhistheight) - fullhistheight = vblue[i]; - } - - // compute two hights, one for the magnified view and one for the threshold - - int realhistheight = fullhistheight; - - if (!showFull) { - int area1thres = 0; - int area2thres = 0; - int area = 0; - for (int i=0; ii) || (needRed && vred[j]>i) || (needGreen && vgreen[j]>i) || (needBlue && vblue[j]>i)) - area++; - if (area1thres==0 && (double)area / ((winw-1)*(i+1)) < 0.3) - area1thres = i; - if (area2thres==0 && (double)area / ((winw-1)*(i+1)) < 0.3) - area2thres = i; - if (area1thres && area2thres) - break; - } - if (area1thres>0 && area2thres>0 && area1thres cr = backBuffer->create_cairo_context(); - cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - cr->set_line_width (1.0); - if (needVal) { - cr->move_to (0, winh-1); - cr->set_source_rgb (0.75, 0.75, 0.75); - for (int i=0; i<=winw-2; i++) { - int val = (int)(vval[i] * (double)(winh-2) / realhistheight); - if (val>winh-1) - val = winh-1; - if (i>0) - cr->line_to (i+1, winh-1-val); - } - cr->fill_preserve (); - cr->set_source_rgb (0.5, 0.5, 0.5); - cr->stroke (); - } - if (needRed) { - cr->move_to (0, winh-1); - cr->set_source_rgb (1.0, 0.0, 0.0); - for (int i=0; i<=winw-2; i++) { - int val = (int)(vred[i] * (double)(winh-2) / realhistheight); - if (val>winh-1) - val = winh-1; - if (i>0) - cr->line_to (i+1, winh-1-val); - } - cr->stroke (); - } - if (needGreen) { - cr->move_to (0, winh-1); - cr->set_source_rgb (0.0, 1.0, 0.0); - for (int i=0; i<=winw-2; i++) { - int val = (int)(vgreen[i] * (double)(winh-2) / realhistheight); - if (val>winh-1) - val = winh-1; - if (i>0) - cr->line_to (i+1, winh-1-val); - } - cr->stroke (); - } - if (needBlue) { - cr->move_to (0, winh-1); - cr->set_source_rgb (0.0, 0.0, 1.0); - for (int i=0; i<=winw-2; i++) { - int val = (int)(vblue[i] * (double)(winh-2) / realhistheight); - if (val>winh-1) - val = winh-1; - if (i>0) - cr->line_to (i+1, winh-1-val); - } - cr->stroke (); - } - - delete [] vval; - delete [] vred; - delete [] vgreen; - delete [] vblue; - } -*/ bgc->set_foreground (mgray); backBuffer->draw_rectangle (bgc, false, 0, 0, winw-1, winh-1); diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index befdb4671..523b20175 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -45,18 +45,14 @@ class HistogramArea : public Gtk::DrawingArea { Gdk::Color lgray; Gdk::Color mgray; Gdk::Color dgray; - LUTu lhist; - LUTu rhist; - LUTu ghist; - LUTu bhist; + LUTu lhist, rhist, ghist, bhist; + LUTu lhistRaw, rhistRaw, ghistRaw, bhistRaw; + bool valid; bool showFull; int oldwidth, oldheight; - bool needVal; - bool needRed; - bool needGreen; - bool needBlue; + bool needLuma, needRed, needGreen, needBlue, rawMode; HistogramAreaIdleHelper* haih; @@ -66,8 +62,8 @@ class HistogramArea : public Gtk::DrawingArea { ~HistogramArea(); void renderHistogram (); - void update (LUTu &rh, LUTu &gh, LUTu &bh, LUTu &lh); - void updateOptions (bool r, bool g, bool b, bool v); + void update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw); + void updateOptions (bool r, bool g, bool b, bool l, bool raw); void on_realize(); bool on_expose_event(GdkEventExpose* event); bool on_button_press_event (GdkEventButton* event); @@ -88,6 +84,7 @@ class HistogramPanel : public Gtk::HBox { Gtk::ToggleButton* showGreen; Gtk::ToggleButton* showBlue; Gtk::ToggleButton* showValue; + Gtk::ToggleButton* showRAW; sigc::connection rconn; @@ -95,7 +92,9 @@ class HistogramPanel : public Gtk::HBox { HistogramPanel (); - void histogramChanged (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma) { histogramArea->update (histRed, histGreen, histBlue, histLuma); } + void histogramChanged (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw) { + histogramArea->update (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw); + } void rgbv_toggled (); void resized (Gtk::Allocation& req); }; diff --git a/rtgui/rawexposure.cc b/rtgui/rawexposure.cc index 20895a0d7..6a4d827f0 100644 --- a/rtgui/rawexposure.cc +++ b/rtgui/rawexposure.cc @@ -72,7 +72,7 @@ void RAWExposure::adjusterChanged (Adjuster* a, double newval) Glib::ustring value = a->getTextValue(); if (a == PexPos) listener->panelChanged (EvPreProcessExpCorrLinear, value ); - else if (a == PexPreser) + else if (a == PexPreser && ABS(PexPos->getValue()-1.0)>0.0001) // update takes long, only do it if it would have an effect listener->panelChanged (EvPreProcessExpCorrPH, value ); } }