Allow reading more than 6 sub-frames
This allows all images to be read from a Canon burst raw file. Refactor raw image source to use unique_ptr.
This commit is contained in:
parent
00360a6dbb
commit
860306dc35
@ -505,14 +505,6 @@ RawImageSource::~RawImageSource()
|
|||||||
delete greenCache;
|
delete greenCache;
|
||||||
delete blueCache;
|
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) {
|
if (camProfile) {
|
||||||
cmsCloseProfile(camProfile);
|
cmsCloseProfile(camProfile);
|
||||||
}
|
}
|
||||||
@ -1219,11 +1211,13 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
|
|||||||
return errCode;
|
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;
|
errCode = 0;
|
||||||
|
|
||||||
if (numFrames >= 7) {
|
if (numFrames >= 7 && isHasselblad) {
|
||||||
// special case to avoid crash when loading Hasselblad H6D-100cMS pixelshift files
|
// 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
|
// limit to 6 frames and skip first frame, as first frame is not bayer
|
||||||
if (firstFrameOnly) {
|
if (firstFrameOnly) {
|
||||||
@ -1232,6 +1226,9 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
|
|||||||
numFrames = 6;
|
numFrames = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
riFrames.clear();
|
||||||
|
riFrames.resize(numFrames);
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
@ -1243,10 +1240,10 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
|
|||||||
|
|
||||||
for (unsigned int i = 0; i < numFrames; ++i) {
|
for (unsigned int i = 0; i < numFrames; ++i) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
riFrames[i] = ri;
|
riFrames[i].reset(ri);
|
||||||
errCodeThr = riFrames[i]->loadRaw(true, i + 1, true, plistener, 0.8);
|
errCodeThr = riFrames[i]->loadRaw(true, i + 1, true, plistener, 0.8);
|
||||||
} else {
|
} else {
|
||||||
riFrames[i] = new RawImage(fname);
|
riFrames[i].reset(new RawImage(fname));
|
||||||
errCodeThr = riFrames[i]->loadRaw(true, i + 1);
|
errCodeThr = riFrames[i]->loadRaw(true, i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1259,6 +1256,9 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (numFrames > 1) {
|
} else if (numFrames > 1) {
|
||||||
|
riFrames.clear();
|
||||||
|
riFrames.resize(numFrames);
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
@ -1271,10 +1271,10 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
|
|||||||
for (unsigned int i = 0; i < numFrames; ++i)
|
for (unsigned int i = 0; i < numFrames; ++i)
|
||||||
{
|
{
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
riFrames[i] = ri;
|
riFrames[i].reset(ri);
|
||||||
errCodeThr = riFrames[i]->loadRaw(true, i, true, plistener, 0.8);
|
errCodeThr = riFrames[i]->loadRaw(true, i, true, plistener, 0.8);
|
||||||
} else {
|
} else {
|
||||||
riFrames[i] = new RawImage(fname);
|
riFrames[i].reset(new RawImage(fname));
|
||||||
errCodeThr = riFrames[i]->loadRaw(true, i);
|
errCodeThr = riFrames[i]->loadRaw(true, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1287,9 +1287,13 @@ int RawImageSource::load(const Glib::ustring &fname, bool firstFrameOnly)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
riFrames[0] = ri;
|
riFrames.clear();
|
||||||
errCode = riFrames[0]->loadRaw(true, 0, true, plistener, 0.8);
|
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) {
|
if (!errCode) {
|
||||||
for (unsigned int i = 0; i < numFrames; ++i) {
|
for (unsigned int i = 0; i < numFrames; ++i) {
|
||||||
@ -1514,21 +1518,21 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
|
|||||||
rawDataFrames[i] = &rawData;
|
rawDataFrames[i] = &rawData;
|
||||||
} else {
|
} else {
|
||||||
if (!rawDataBuffer[bufferNumber]) {
|
if (!rawDataBuffer[bufferNumber]) {
|
||||||
rawDataBuffer[bufferNumber] = new array2D<float>;
|
rawDataBuffer[bufferNumber].reset(new array2D<float>);
|
||||||
}
|
}
|
||||||
|
|
||||||
rawDataFrames[i] = rawDataBuffer[bufferNumber];
|
rawDataFrames[i] = rawDataBuffer[bufferNumber].get();
|
||||||
++bufferNumber;
|
++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
|
} else if (numFrames == 2 && currFrame == 2) { // average the frames
|
||||||
if (!rawDataBuffer[0]) {
|
if (!rawDataBuffer[0]) {
|
||||||
rawDataBuffer[0] = new array2D<float>;
|
rawDataBuffer[0].reset(new array2D<float>);
|
||||||
}
|
}
|
||||||
|
|
||||||
rawDataFrames[1] = rawDataBuffer[0];
|
rawDataFrames[1] = rawDataBuffer[0].get();
|
||||||
copyOriginalPixels(raw, riFrames[1], rid, rif, *rawDataFrames[1], reddeha, greendeha, bluedeha);
|
copyOriginalPixels(raw, riFrames[1].get(), rid, rif, *rawDataFrames[1], reddeha, greendeha, bluedeha);
|
||||||
copyOriginalPixels(raw, ri, rid, rif, rawData, reddeha, greendeha, bluedeha);
|
copyOriginalPixels(raw, ri, rid, rif, rawData, reddeha, greendeha, bluedeha);
|
||||||
|
|
||||||
for (int i = 0; i < H; ++i) {
|
for (int i = 0; i < H; ++i) {
|
||||||
@ -2581,9 +2585,8 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara
|
|||||||
|
|
||||||
void RawImageSource::flush()
|
void RawImageSource::flush()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i + 1 < numFrames; ++i) {
|
for (auto &buffer : rawDataBuffer) {
|
||||||
delete rawDataBuffer[i];
|
buffer.reset();
|
||||||
rawDataBuffer[i] = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawData) {
|
if (rawData) {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "array2D.h"
|
#include "array2D.h"
|
||||||
#include "colortemp.h"
|
#include "colortemp.h"
|
||||||
@ -78,13 +79,13 @@ protected:
|
|||||||
bool rgbSourceModified;
|
bool rgbSourceModified;
|
||||||
|
|
||||||
RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc.
|
RawImage* ri; // Copy of raw pixels, NOT corrected for initial gain, blackpoint etc.
|
||||||
RawImage* riFrames[6] = {nullptr};
|
std::vector<std::unique_ptr<RawImage>> riFrames;
|
||||||
unsigned int currFrame = 0;
|
unsigned int currFrame = 0;
|
||||||
unsigned int numFrames = 0;
|
unsigned int numFrames = 0;
|
||||||
int flatFieldAutoClipValue = 0;
|
int flatFieldAutoClipValue = 0;
|
||||||
array2D<float> rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column
|
array2D<float> rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column
|
||||||
array2D<float> *rawDataFrames[6] = {nullptr};
|
std::vector<array2D<float> *> rawDataFrames;
|
||||||
array2D<float> *rawDataBuffer[5] = {nullptr};
|
std::vector<std::unique_ptr<array2D<float>>> rawDataBuffer;
|
||||||
|
|
||||||
// the interpolated green plane:
|
// the interpolated green plane:
|
||||||
array2D<float> green;
|
array2D<float> green;
|
||||||
@ -204,12 +205,12 @@ public:
|
|||||||
static void init ();
|
static void init ();
|
||||||
static void cleanup ();
|
static void cleanup ();
|
||||||
void setCurrentFrame(unsigned int frameNum) override {
|
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;
|
currFrame = frameNum;
|
||||||
ri = riFrames[0];
|
ri = riFrames[0].get();
|
||||||
} else {
|
} else if (riFrames.size() > std::min(numFrames - 1, frameNum)) {
|
||||||
currFrame = std::min(numFrames - 1, frameNum);
|
currFrame = std::min(numFrames - 1, frameNum);
|
||||||
ri = riFrames[currFrame];
|
ri = riFrames[currFrame].get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int getFrameCount() override {return numFrames;}
|
int getFrameCount() override {return numFrames;}
|
||||||
|
@ -745,7 +745,7 @@ void BayerProcess::FrameCountChanged(int n, int frameNum)
|
|||||||
|
|
||||||
imageNumber->remove_all();
|
imageNumber->remove_all();
|
||||||
imageNumber->append("1");
|
imageNumber->append("1");
|
||||||
for (int i = 2; i <= std::min(n, 6); ++i) {
|
for (int i = 2; i <= n; ++i) {
|
||||||
std::ostringstream entry;
|
std::ostringstream entry;
|
||||||
entry << i;
|
entry << i;
|
||||||
imageNumber->append(entry.str());
|
imageNumber->append(entry.str());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user