Support demosaiced floating point DNGs with LibRaw

This commit is contained in:
Lawrence Lee 2024-12-08 14:34:56 -08:00
parent b0117b7a60
commit fd445d00a6
No known key found for this signature in database
GPG Key ID: 048FF2B76A63895F
3 changed files with 48 additions and 9 deletions

View File

@ -465,6 +465,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
{ {
ifname = filename.c_str(); ifname = filename.c_str();
image = nullptr; image = nullptr;
image_from_float.reset();
verbose = settings->verbose; verbose = settings->verbose;
oprof = nullptr; oprof = nullptr;
@ -531,7 +532,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
} else if (err != LIBRAW_SUCCESS) { } else if (err != LIBRAW_SUCCESS) {
decoder = Decoder::LIBRAW; decoder = Decoder::LIBRAW;
return err; return err;
} else if (libraw->is_floating_point() && libraw->imgdata.idata.dng_version) { } else if (libraw->is_floating_point() && libraw->imgdata.idata.dng_version && libraw->imgdata.idata.filters) {
return err; return err;
} }
@ -785,6 +786,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
(this->*load_raw)(); (this->*load_raw)();
} else if (decoder == Decoder::LIBRAW) { } else if (decoder == Decoder::LIBRAW) {
libraw->imgdata.rawparams.shot_select = shot_select; libraw->imgdata.rawparams.shot_select = shot_select;
libraw->imgdata.rawparams.options &= ~LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT;
int err = libraw->open_buffer(ifp->data, ifp->size); int err = libraw->open_buffer(ifp->data, ifp->size);
if (err) { if (err) {
@ -810,6 +812,24 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
float_raw_image[idx] = rd.float_image[idx]; float_raw_image[idx] = rd.float_image[idx];
} }
} }
} else if (rd.float3_image) {
const auto image_size = static_cast<unsigned int>(height) * static_cast<unsigned int>(width);
try {
image_from_float.reset(new std::remove_pointer<dcrawImage_t>::type[image_size]);
} catch (const std::bad_alloc &e) {
return 200;
}
std::fill(&image_from_float[0][0], &image_from_float[0][0] + image_size, 0);
float_raw_image = new float[3 * raw_width * raw_height];
for (int y = 0; y < raw_height; ++y) {
for (int x = 0; x < raw_width; ++x) {
const size_t idx = y * raw_width + x;
for (int c = 0; c < 3; ++c) {
float_raw_image[3 * idx + c] = rd.float3_image[idx][c];
}
}
}
} else { } else {
#ifdef LIBRAW_USE_OPENMP #ifdef LIBRAW_USE_OPENMP
MyMutex::MyLock lock(*librawMutex); MyMutex::MyLock lock(*librawMutex);
@ -1101,9 +1121,14 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog
return 0; return 0;
} }
DCraw::dcrawImage_t RawImage::get_image()
{
return image ? image : image_from_float.get();
}
float** RawImage::compress_image(unsigned int frameNum, bool freeImage) float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
{ {
if (!image) { if (!image && !image_from_float) {
return nullptr; return nullptr;
} }
@ -1139,7 +1164,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
} }
// copy pixel raw data: the compressed format earns space // copy pixel raw data: the compressed format earns space
if (float_raw_image) { if (float_raw_image && filters) {
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
@ -1149,6 +1174,20 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
this->data[row][col] = float_raw_image[(row + top_margin) * raw_width + col + left_margin]; this->data[row][col] = float_raw_image[(row + top_margin) * raw_width + col + left_margin];
} }
delete [] float_raw_image;
float_raw_image = nullptr;
} else if (float_raw_image) {
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++) {
for (int c = 0; c < 3; ++c) {
this->data[row][3 * col + c] = float_raw_image[3 * ((row + top_margin) * raw_width + col + left_margin) + c];
}
}
delete [] float_raw_image; delete [] float_raw_image;
float_raw_image = nullptr; float_raw_image = nullptr;
} else if (merged_pixelshift.is_merged_pixelshift) { } else if (merged_pixelshift.is_merged_pixelshift) {
@ -1240,6 +1279,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage)
libraw->recycle(); libraw->recycle();
} }
image = nullptr; image = nullptr;
image_from_float.reset();
} }
return data; return data;

View File

@ -54,10 +54,7 @@ public:
filters &= ~((filters & 0x55555555) << 1); filters &= ~((filters & 0x55555555) << 1);
} }
} }
dcrawImage_t get_image() dcrawImage_t get_image();
{
return image;
}
float** compress_image(unsigned int frameNum, bool freeImage = true); // revert to compressed pixels format and release image data float** compress_image(unsigned int frameNum, bool freeImage = true); // revert to compressed pixels format and release image data
float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column
unsigned prefilters; // original filters saved ( used for 4 color processing ) unsigned prefilters; // original filters saved ( used for 4 color processing )
@ -78,6 +75,7 @@ protected:
int maximum_c4[4]; int maximum_c4[4];
Decoder decoder{Decoder::DCRAW}; Decoder decoder{Decoder::DCRAW};
std::unique_ptr<LibRaw> libraw; std::unique_ptr<LibRaw> libraw;
std::unique_ptr<std::remove_pointer<dcrawImage_t>::type[]> image_from_float;
bool isFoveon() const bool isFoveon() const
{ {
return is_foveon; return is_foveon;

View File

@ -237,13 +237,14 @@ void scale_colors (rtengine::RawImage *ri, float scale_mul[4], float cblack[4],
} }
} }
} else if (isFloat) { } else if (isFloat) {
const auto colors = ri->get_colors();
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for if(multiThread) #pragma omp parallel for if(multiThread)
#endif #endif
for (int row = 0; row < height; ++row) { for (int row = 0; row < height; ++row) {
for (int col = 0; col < width; ++col) { for (int col = 0; col < width; ++col) {
for (int i = 0; i < ri->get_colors(); ++i) { for (int i = 0; i < colors; ++i) {
float val = float_raw_image[(row + top_margin) * raw_width + col + left_margin + i]; float val = float_raw_image[colors * ((row + top_margin) * raw_width + col + left_margin) + i];
val -= cblack[i]; val -= cblack[i];
val *= scale_mul[i]; val *= scale_mul[i];
image[row * width + col][i] = val; image[row * width + col][i] = val;