diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index bad95a4d8..46a62cc4b 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -106,6 +106,10 @@ bool LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) //end of linear equation solver } +namespace rtengine { + extern const Settings* settings; +} + using namespace std; using namespace rtengine; @@ -701,7 +705,9 @@ float* RawImageSource::CA_correct_RT( blockvar[dir][c] = blocksqave[dir][c] / blockdenom[dir][c] - SQR(blockave[dir][c] / blockdenom[dir][c]); } else { processpasstwo = false; - std::cout << "blockdenom vanishes" << std::endl; + if (settings->verbose) { + std::cout << "blockdenom vanishes" << std::endl; + } break; } } @@ -801,7 +807,9 @@ float* RawImageSource::CA_correct_RT( numpar = 4; if (numblox[1] < 10) { - std::cout << "numblox = " << numblox[1] << std::endl; + if (settings->verbose) { + std::cout << "numblox = " << numblox[1] << std::endl; + } processpasstwo = false; } } diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 4dbfe80f9..7f481e104 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2250,6 +2250,11 @@ Camera constants: } }, + { // Quality C, only raw crop + "make_model": "Samsung EX2F", + "raw_crop": [ 16, 7, -4, -4 ] + }, + { // Quality B, corrections for raw crop vs dcraw9.21, matched to Samsung's default "make_model": "Samsung NX mini", "dcraw_matrix": [ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 ], // dng 8.6 d65 diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 6f41e2520..3b190b943 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1484,6 +1484,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT delete labView; delete baseImg; + /* // calculate scale if (params.coarse.rotate == 90 || params.coarse.rotate == 270) { myscale = scale * thumbImg->getWidth() / fh; @@ -1492,19 +1493,20 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT } myscale = 1.0 / myscale; - /* // apply crop - if (params.crop.enabled) { - int ix = 0; - for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { - readyImg->data[ix++] /= 3; - readyImg->data[ix++] /= 3; - readyImg->data[ix++] /= 3; - } - else - ix += 3; - }*/ + // apply crop + if (params.crop.enabled) { + int ix = 0; + for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + } + else + ix += 3; + } + */ return readyImg; } diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 575afd54b..1364855b0 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -51,7 +51,7 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0), imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr), - pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr), + pmlistener(nullptr), pmhlistener(nullptr), scrollAccum(0.0), observedCropWin(nullptr), crop_custom_ratio(0.f) { initZoomSteps(); @@ -295,11 +295,16 @@ void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y, } else { delta = deltaY; } - if (delta == 0.0 && direction == GDK_SCROLL_SMOOTH) { - // sometimes this case happens. To avoid zooming into the wrong direction in this case, we just do nothing - return; + + if (direction == GDK_SCROLL_SMOOTH) { + scrollAccum += delta; + //Only change zoom level if we've accumulated +/- 1.0 of deltas. This conditional handles the previous delta=0.0 case + if (abs(scrollAccum) < 1.0) { + return; + } } - bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && delta < 0.0); + bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && scrollAccum < 0.0); + scrollAccum = 0.0; if ((state & GDK_CONTROL_MASK) && onArea(ColorPicker, x, y)) { // resizing a color picker if (isUp) { diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 26edf69ee..8c944cf0a 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -102,6 +102,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed PointerMotionListener* pmlistener; PointerMotionListener* pmhlistener; std::list listeners; + double scrollAccum; CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 8b518335c..87a48a7ea 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -255,17 +255,20 @@ void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rten const bool resize = !preview || prew != img->getWidth(); prew = img->getWidth (); - GThreadLock lock; - // Check if image has been rotated since last time rotated = preview && newLandscape != landscape; if (resize) { - delete [] preview; + if (preview) { + delete [] preview; + } preview = new guint8 [prew * preh * 3]; } memcpy(preview, img->getData(), prew * preh * 3); + { + GThreadLock lock; updateBackBuffer (); + } } landscape = newLandscape; @@ -318,24 +321,36 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->y = action_y + (y - press_y) / scale; cropParams->h += oy - cropParams->y; cropgl->cropHeight1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeH2 && cropgl) { cropParams->h = action_y + (y - press_y) / scale; cropgl->cropHeight2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeW1 && cropgl) { int ox = cropParams->x; cropParams->x = action_x + (x - press_x) / scale; cropParams->w += ox - cropParams->x; cropgl->cropWidth1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeW2 && cropgl) { cropParams->w = action_x + (x - press_x) / scale; cropgl->cropWidth2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeTL && cropgl) { int ox = cropParams->x; @@ -345,7 +360,10 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->y = action_y + (y - press_y) / scale; cropParams->h += oy - cropParams->y; cropgl->cropTopLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeTR && cropgl) { cropParams->w = action_x + (x - press_x) / scale; @@ -353,7 +371,10 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->y = action_y + (y - press_y) / scale; cropParams->h += oy - cropParams->y; cropgl->cropTopRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeBL && cropgl) { int ox = cropParams->x; @@ -361,19 +382,28 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->w += ox - cropParams->x; cropParams->h = action_y + (y - press_y) / scale; cropgl->cropBottomLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SResizeBR && cropgl) { cropParams->w = action_x + (x - press_x) / scale; cropParams->h = action_y + (y - press_y) / scale; cropgl->cropBottomRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SCropMove && cropgl) { cropParams->x = action_x + (x - press_x) / scale; cropParams->y = action_y + (y - press_y) / scale; cropgl->cropMoved (cropParams->x, cropParams->y, cropParams->w, cropParams->h); + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } else if (state == SCropSelecting && cropgl) { int cx1 = press_x, cy1 = press_y; @@ -396,7 +426,10 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams->h = cy1 - cy2 + 1; } + { + MYREADERLOCK(l, lockRW); updateBackBuffer (); + } parent->redrawNeeded (this); } @@ -564,6 +597,7 @@ bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, i bool FileBrowserEntry::onArea (CursorArea a, int x, int y) { + MYREADERLOCK(l, lockRW); if (!drawable || !preview) { return false; } @@ -764,6 +798,8 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) int y2 = action_y; int x2 = action_x; + { + MYREADERLOCK(l, lockRW); if (x2 < prex + ofsX + startx) { y2 = y1 - (double)(y1 - y2) * (x1 - (prex + ofsX + startx)) / (x1 - x2); x2 = prex + ofsX + startx; @@ -779,6 +815,7 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) x2 = x1 - (double)(x1 - x2) * (y1 - (preh + prey + ofsY + starty - 1)) / (y1 - y2); y2 = preh + prey + ofsY + starty - 1; } + } cr->set_line_width (1.5); cr->set_source_rgb (1.0, 1.0, 1.0); diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index ec0bf6588..19762fd92 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -971,9 +971,8 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { - if (abs(event->delta_y) > 0.1) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lowerBound, upperBound); - } + value2 = rtengine::LIM(value + event->delta_y * step, lowerBound, upperBound); + if (value2 != value) { scroll->set_value(value2); } diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 12da0cc0d..b82df7ebf 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -142,7 +142,7 @@ HistogramPanel::HistogramPanel () showGreen->set_image (showGreen->get_active() ? *greenImage : *greenImage_g); showBlue->set_image (showBlue->get_active() ? *blueImage : *blueImage_g); showValue->set_image (showValue->get_active() ? *valueImage : *valueImage_g); - showChro->set_image (showChro->get_active() ? *chroImage : *chroImage_g); + showChro->set_image (showChro->get_active() ? *chroImage : *chroImage_g); showRAW->set_image (showRAW->get_active() ? *rawImage : *rawImage_g); if (options.histogramDrawMode == 0) showMode->set_image(*mode0Image); @@ -151,6 +151,8 @@ HistogramPanel::HistogramPanel () else showMode->set_image(*mode2Image); showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g); + + raw_toggled(); // Make sure the luma/chroma toggles are enabled or disabled setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); setExpandAlignProperties(showGreen, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -502,7 +504,7 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin if (needBlue) { // Blue - cc->set_source_rgb(0.0, 0.0, 1.0); + cc->set_source_rgb(0.0, 0.4, 1.0); if (options.histogramDrawMode < 2) { cc->move_to(b * (winw - 1.) / 255.0 + 0.5*s, 0); cc->line_to(b * (winw - 1.) / 255.0 + 0.5*s, winh - 0); @@ -962,7 +964,7 @@ void HistogramArea::updateBackBuffer () if (needBlue) { drawCurve(cr, bhchanged, realhistheight, w, h); - cr->set_source_rgb (0.0, 0.0, 1.0); + cr->set_source_rgb (0.0, 0.4, 1.0); cr->stroke (); drawMarks(cr, bhchanged, realhistheight, w, ui, oi); } diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index caf7d7b97..13709d8f7 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -79,10 +79,19 @@ void ThumbBrowserBase::scroll (int direction, double deltaX, double deltaY) delta = deltaY; } if (direction == GDK_SCROLL_SMOOTH && delta == 0.0) { - // sometimes this case happens. To avoid scrolling the wrong direction in this case, we just do nothing + // sometimes this case happens. To avoid scrolling the wrong direction in this case, we just do nothing + // This is probably no longer necessary now that coef is no longer quantized to +/-1.0 but why waste CPU cycles? return; } - double coef = direction == GDK_SCROLL_DOWN || (direction == GDK_SCROLL_SMOOTH && delta > 0.0) ? +1.0 : -1.0; + //GDK_SCROLL_SMOOTH can come in as many events with small deltas, don't quantize these to +/-1.0 so trackpads work well + double coef; + if(direction == GDK_SCROLL_SMOOTH) { + coef = delta; + } else if (direction == GDK_SCROLL_DOWN) { + coef = +1.0; + } else { + coef = -1.0; + } // GUI already acquired when here if (direction == GDK_SCROLL_UP || direction == GDK_SCROLL_DOWN || direction == GDK_SCROLL_SMOOTH) { diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index e660e794b..4dacb1adf 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -494,6 +494,7 @@ void ThumbBrowserEntryBase::resize (int h) height = h; int old_preh = preh; + int old_prew = prew; // dimensions of the button set int bsw = 0, bsh = 0; @@ -555,9 +556,11 @@ void ThumbBrowserEntryBase::resize (int h) width = bsw + 2 * sideMargin + 2 * borderWidth; } - if (preh != old_preh) { - delete [] preview; - preview = nullptr; + if (preh != old_preh || prew != old_prew) { // if new thumbnail height or new orientation + if (preview) { + delete [] preview; + preview = nullptr; + } refreshThumbnailImage (); } else if (backBuffer) { backBuffer->setDirty(true); // This will force a backBuffer update on queue_draw diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 0bcdd470a..e3196778c 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -49,17 +49,17 @@ class Thumbnail rtengine::Thumbnail* tpp; int tw, th; // dimensions of timgdata (it stores tpp->width and tpp->height in processed mode for simplicity) float imgRatio; // hack to avoid rounding error -// double scale; // portion of the sizes of the processed thumbnail image and the full scale image +// double scale; // portion of the sizes of the processed thumbnail image and the full scale image const std::unique_ptr pparams; bool pparamsValid; bool imageLoading; // these are the data of the result image of the last getthumbnailimage call (for caching purposes) - unsigned char* lastImg; - int lastW; - int lastH; - double lastScale; + unsigned char* lastImg; // pointer to the processed and scaled base ImageIO image + int lastW; // non rotated width of the cached ImageIO image + int lastH; // non rotated height of the cached ImageIO image + double lastScale; // scale of the cached ImageIO image // exif & date/time strings Glib::ustring exifString;