From 5ea18efeb862ec323e57eace05f98eec83812776 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 1 Sep 2019 20:22:42 +0200 Subject: [PATCH] RT crashes on loading Hasselblad H6D-100cMS pixelshift files, fixes #5433 --- rtengine/rawimagesource.cc | 36 ++++++++++++++++++++++++++++++++++-- rtengine/rawimagesource.h | 6 +++--- rtengine/rtthumbnail.cc | 11 +++++++++++ rtgui/bayerprocess.cc | 2 +- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index e8eb17c31..838d49ce9 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -999,11 +999,43 @@ int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly) if (errCode) { return errCode; } - numFrames = firstFrameOnly ? 1 : ri->getFrameCount(); + numFrames = firstFrameOnly ? (numFrames < 7 ? 1 : ri->getFrameCount()) : ri->getFrameCount(); errCode = 0; - if(numFrames > 1) { + if(numFrames >= 7) { + // special case to avoid crash when loading Hasselblad H6D-100cMS pixelshift files + // limit to 6 frames and skip first frame, as first frame is not bayer + if (firstFrameOnly) { + numFrames = 1; + } else { + numFrames = 6; + } +#ifdef _OPENMP99 + #pragma omp parallel +#endif + { + int errCodeThr = 0; +#ifdef _OPENMP99 + #pragma omp for nowait +#endif + for(unsigned int i = 0; i < numFrames; ++i) { + if(i == 0) { + riFrames[i] = ri; + errCodeThr = riFrames[i]->loadRaw (true, i + 1, true, plistener, 0.8); + } else { + riFrames[i] = new RawImage(fname); + errCodeThr = riFrames[i]->loadRaw (true, i + 1); + } + } +#ifdef _OPENMP99 + #pragma omp critical +#endif + { + errCode = errCodeThr ? errCodeThr : errCode; + } + } + } else if(numFrames > 1) { #ifdef _OPENMP #pragma omp parallel #endif diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 7c50991c0..940773271 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -74,13 +74,13 @@ protected: bool rgbSourceModified; RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc. - RawImage* riFrames[4] = {nullptr}; + RawImage* riFrames[6] = {nullptr}; unsigned int currFrame = 0; unsigned int numFrames = 0; int flatFieldAutoClipValue = 0; array2D rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column - array2D *rawDataFrames[4] = {nullptr}; - array2D *rawDataBuffer[3] = {nullptr}; + array2D *rawDataFrames[6] = {nullptr}; + array2D *rawDataBuffer[5] = {nullptr}; // the interpolated green plane: array2D green; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 2a35176e6..5efb75d48 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -547,6 +547,17 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati return nullptr; } + if (ri->getFrameCount() == 7) { + // special case for Hasselblad H6D-100cMS pixelshift files + // first frame is not bayer, load second frame + int r = ri->loadRaw (1, 1, 0); + + if ( r ) { + delete ri; + sensorType = ST_NONE; + return nullptr; + } + } sensorType = ri->getSensorType(); int width = ri->get_width(); diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 6f38f4c43..c361ded16 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -729,7 +729,7 @@ void BayerProcess::FrameCountChanged(int n, int frameNum) imageNumber->remove_all(); imageNumber->append("1"); - for (int i = 2; i <= std::min(n, 4); ++i) { + for (int i = 2; i <= std::min(n, 6); ++i) { std::ostringstream entry; entry << i; imageNumber->append(entry.str());