diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 6f4db62a9..bc39211d2 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -505,14 +505,6 @@ RawImageSource::~RawImageSource() delete greenCache; delete blueCache; - for (size_t i = 0; i < numFrames; ++i) { - delete riFrames[i]; - } - - for (size_t i = 0; i + 1 < numFrames; ++i) { - delete rawDataBuffer[i]; - } - if (camProfile) { cmsCloseProfile(camProfile); } @@ -1219,11 +1211,13 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) return errCode; } - numFrames = firstFrameOnly ? (numFrames < 7 ? 1 : ri->getFrameCount()) : ri->getFrameCount(); + const bool isHasselblad = ri->get_maker() == "Hasselblad"; + + numFrames = firstFrameOnly && (numFrames < 7 || !isHasselblad) ? 1 : ri->getFrameCount(); errCode = 0; - if (numFrames >= 7) { + if (numFrames >= 7 && isHasselblad) { // 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) { @@ -1232,6 +1226,9 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) numFrames = 6; } + riFrames.clear(); + riFrames.resize(numFrames); + #ifdef _OPENMP #pragma omp parallel #endif @@ -1243,10 +1240,10 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) for (unsigned int i = 0; i < numFrames; ++i) { if (i == 0) { - riFrames[i] = ri; + riFrames[i].reset(ri); errCodeThr = riFrames[i]->loadRaw(true, i + 1, true, plistener, 0.8); } else { - riFrames[i] = new RawImage(fname); + riFrames[i].reset(new RawImage(fname)); errCodeThr = riFrames[i]->loadRaw(true, i + 1); } } @@ -1259,6 +1256,9 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) } } } else if (numFrames > 1) { + riFrames.clear(); + riFrames.resize(numFrames); + #ifdef _OPENMP #pragma omp parallel #endif @@ -1271,10 +1271,10 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) for (unsigned int i = 0; i < numFrames; ++i) { if (i == 0) { - riFrames[i] = ri; + riFrames[i].reset(ri); errCodeThr = riFrames[i]->loadRaw(true, i, true, plistener, 0.8); } else { - riFrames[i] = new RawImage(fname); + riFrames[i].reset(new RawImage(fname)); errCodeThr = riFrames[i]->loadRaw(true, i); } } @@ -1287,9 +1287,13 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly) } } } else { - riFrames[0] = ri; - errCode = riFrames[0]->loadRaw(true, 0, true, plistener, 0.8); + riFrames.clear(); + riFrames.emplace_back(ri); + errCode = riFrames.back()->loadRaw(true, 0, true, plistener, 0.8); } + rawDataFrames.resize(riFrames.size()); + rawDataBuffer.clear(); + rawDataBuffer.resize(riFrames.size() - 1); if (!errCode) { for (unsigned int i = 0; i < numFrames; ++i) { @@ -1514,21 +1518,21 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens rawDataFrames[i] = &rawData; } else { if (!rawDataBuffer[bufferNumber]) { - rawDataBuffer[bufferNumber] = new array2D; + rawDataBuffer[bufferNumber].reset(new array2D); } - rawDataFrames[i] = rawDataBuffer[bufferNumber]; + rawDataFrames[i] = rawDataBuffer[bufferNumber].get(); ++bufferNumber; - copyOriginalPixels(raw, riFrames[i], rid, rif, *rawDataFrames[i], reddeha, greendeha, bluedeha); + copyOriginalPixels(raw, riFrames[i].get(), rid, rif, *rawDataFrames[i], reddeha, greendeha, bluedeha); } } } else if (numFrames == 2 && currFrame == 2) { // average the frames if (!rawDataBuffer[0]) { - rawDataBuffer[0] = new array2D; + rawDataBuffer[0].reset(new array2D); } - rawDataFrames[1] = rawDataBuffer[0]; - copyOriginalPixels(raw, riFrames[1], rid, rif, *rawDataFrames[1], reddeha, greendeha, bluedeha); + rawDataFrames[1] = rawDataBuffer[0].get(); + copyOriginalPixels(raw, riFrames[1].get(), rid, rif, *rawDataFrames[1], reddeha, greendeha, bluedeha); copyOriginalPixels(raw, ri, rid, rif, rawData, reddeha, greendeha, bluedeha); for (int i = 0; i < H; ++i) { @@ -2581,9 +2585,8 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara void RawImageSource::flush() { - for (size_t i = 0; i + 1 < numFrames; ++i) { - delete rawDataBuffer[i]; - rawDataBuffer[i] = nullptr; + for (auto &buffer : rawDataBuffer) { + buffer.reset(); } if (rawData) { diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 1fef1a5cf..cff3b97eb 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "array2D.h" #include "colortemp.h" @@ -78,13 +79,13 @@ protected: bool rgbSourceModified; RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc. - RawImage* riFrames[6] = {nullptr}; + std::vector> riFrames; 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[6] = {nullptr}; - array2D *rawDataBuffer[5] = {nullptr}; + std::vector *> rawDataFrames; + std::vector>> rawDataBuffer; // the interpolated green plane: array2D green; @@ -204,12 +205,12 @@ public: static void init (); static void cleanup (); void setCurrentFrame(unsigned int frameNum) override { - if (numFrames == 2 && frameNum == 2) { // special case for averaging of two frames + if (numFrames == 2 && frameNum == 2 && riFrames.size() >= 1) { // special case for averaging of two frames currFrame = frameNum; - ri = riFrames[0]; - } else { + ri = riFrames[0].get(); + } else if (riFrames.size() > std::min(numFrames - 1, frameNum)) { currFrame = std::min(numFrames - 1, frameNum); - ri = riFrames[currFrame]; + ri = riFrames[currFrame].get(); } } int getFrameCount() override {return numFrames;} diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 5ef3a777c..f89e11510 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -745,7 +745,7 @@ void BayerProcess::FrameCountChanged(int n, int frameNum) imageNumber->remove_all(); imageNumber->append("1"); - for (int i = 2; i <= std::min(n, 6); ++i) { + for (int i = 2; i <= n; ++i) { std::ostringstream entry; entry << i; imageNumber->append(entry.str());