From 1f080e0438e8e88270f8cd5612d86e724d699efb Mon Sep 17 00:00:00 2001 From: Hombre Date: Sun, 11 Dec 2016 17:17:36 +0100 Subject: [PATCH 1/2] Bugfix: RT could crash while displaying Color Pickers (no issue) --- rtgui/cropwindow.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 10b188a21..20dd3eb9d 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -2083,10 +2083,15 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) } LockableColorPicker::Validity validity = checkValidity (hoveredPicker, cropPos); hoveredPicker->setValidity (validity); + + { + MyMutex::MyLock lock(cropHandler.cimg); + if (validity == LockableColorPicker::Validity::INSIDE) { cropHandler.colorPick(cropPos, r, g, b, rpreview, gpreview, bpreview, hoveredPicker->getSize()); hoveredPicker->setRGB (r, g, b, rpreview, gpreview, bpreview); } + } } void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery) { @@ -2450,6 +2455,7 @@ void CropWindow::drawObservedFrame (Cairo::RefPtr cr, int rw, in void CropWindow::cropImageUpdated () { + MyMutex::MyLock lock(cropHandler.cimg); for (auto colorPicker : colorPickers) { Coord imgPos, cropPos; From 23f17bd9bc0d1413e3919285b23e5dd978429676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Tue, 13 Dec 2016 20:44:05 +0100 Subject: [PATCH 2/2] Fully check thumb data size (#3529) Also, take rotation into account when falling back to `Thumbnail::loadFromRaw()`. --- rtengine/rawimage.h | 16 ++++++++-------- rtengine/rtthumbnail.cc | 41 +++++++++++++++++++++++++++++++++++++---- rtgui/cropwindow.cc | 10 +++++----- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 88ef5d710..b741a7ffc 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -274,37 +274,37 @@ public: { return profile_data; } - IMFILE *get_file() + IMFILE *get_file() const { return ifp; } bool is_supportedThumb() const ; bool is_jpegThumb() const ; bool is_ppmThumb() const ; - int get_thumbOffset() + int get_thumbOffset() const { return int(thumb_offset); } - int get_thumbWidth() + int get_thumbWidth() const { return int(thumb_width); } - int get_thumbHeight() + int get_thumbHeight() const { return int(thumb_height); } - int get_thumbBPS() + int get_thumbBPS() const { return thumb_load_raw ? 16 : 8; } bool get_thumbSwap() const; - unsigned get_thumbLength() + unsigned get_thumbLength() const { return thumb_length; } - bool zeroIsBad() + bool zeroIsBad() const { - return zero_is_bad == 1 ? true : false; + return zero_is_bad == 1; } public: diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 4710f3fe8..77e260985 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -41,6 +41,25 @@ #include "StopWatch.h" +namespace +{ + + bool checkRawImageThumb(const rtengine::RawImage& raw_image) + { + if (!raw_image.is_supportedThumb()) { + return false; + } + + const std::size_t length = + fdata(raw_image.get_thumbOffset(), raw_image.get_file())[1] != 0xD8 && raw_image.is_ppmThumb() + ? raw_image.get_thumbWidth() * raw_image.get_thumbHeight() * (raw_image.get_thumbBPS() / 8) * 3 + : raw_image.get_thumbLength(); + + return raw_image.get_thumbOffset() + length < raw_image.get_file()->size; + } + +} + extern Options options; namespace rtengine @@ -175,8 +194,8 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL int err = 1; - // see if it is something we support - if ( ri->is_supportedThumb() && ri->get_thumbOffset() < ri->get_file()->size ) { + // See if it is something we support + if (checkRawImageThumb(*ri)) { const char* data((const char*)fdata(ri->get_thumbOffset(), ri->get_file())); if ( (unsigned char)data[1] == 0xd8 ) { @@ -491,6 +510,17 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tmph = high; } + const bool rotate_90 = + rotate + && ( + ri->get_rotateDegree() == 90 + || ri->get_rotateDegree() == 270 + ); + + if (rotate_90) { + std::swap(tmpw, tmph); + } + if (fixwh == 1) { // fix height, scale width w = tmpw * h / tmph; } else { @@ -501,8 +531,11 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati delete tpp->thumbImg; } - tpp->thumbImg = nullptr; - tpp->thumbImg = resizeTo(w, h, TI_Bilinear, tmpImg); + if (rotate_90) { + tpp->thumbImg = resizeTo(h, w, TI_Bilinear, tmpImg); + } else { + tpp->thumbImg = resizeTo(w, h, TI_Bilinear, tmpImg); + } delete tmpImg; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 20dd3eb9d..0fc3359bc 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -2085,12 +2085,12 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) hoveredPicker->setValidity (validity); { - MyMutex::MyLock lock(cropHandler.cimg); + MyMutex::MyLock lock(cropHandler.cimg); - if (validity == LockableColorPicker::Validity::INSIDE) { - cropHandler.colorPick(cropPos, r, g, b, rpreview, gpreview, bpreview, hoveredPicker->getSize()); - hoveredPicker->setRGB (r, g, b, rpreview, gpreview, bpreview); - } + if (validity == LockableColorPicker::Validity::INSIDE) { + cropHandler.colorPick(cropPos, r, g, b, rpreview, gpreview, bpreview, hoveredPicker->getSize()); + hoveredPicker->setRGB (r, g, b, rpreview, gpreview, bpreview); + } } } void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery)