diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 02f6e42c5..ab55861f4 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -465,6 +465,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog { ifname = filename.c_str(); image = nullptr; + image_from_float.reset(); verbose = settings->verbose; oprof = nullptr; @@ -531,7 +532,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog } else if (err != LIBRAW_SUCCESS) { decoder = Decoder::LIBRAW; 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; } @@ -785,6 +786,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog (this->*load_raw)(); } else if (decoder == Decoder::LIBRAW) { 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); 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]; } } + } else if (rd.float3_image) { + const auto image_size = static_cast(height) * static_cast(width); + try { + image_from_float.reset(new std::remove_pointer::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 { #ifdef LIBRAW_USE_OPENMP MyMutex::MyLock lock(*librawMutex); @@ -1101,9 +1121,14 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog return 0; } +DCraw::dcrawImage_t RawImage::get_image() +{ + return image ? image : image_from_float.get(); +} + float** RawImage::compress_image(unsigned int frameNum, bool freeImage) { - if (!image) { + if (!image && !image_from_float) { return nullptr; } @@ -1139,7 +1164,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) } // copy pixel raw data: the compressed format earns space - if (float_raw_image) { + if (float_raw_image && filters) { #ifdef _OPENMP #pragma omp parallel for #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]; } + 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; float_raw_image = nullptr; } else if (merged_pixelshift.is_merged_pixelshift) { @@ -1240,6 +1279,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) libraw->recycle(); } image = nullptr; + image_from_float.reset(); } return data; diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index cc19998f8..c941ec92c 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -54,10 +54,7 @@ public: filters &= ~((filters & 0x55555555) << 1); } } - dcrawImage_t get_image() - { - return image; - } + dcrawImage_t get_image(); 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 unsigned prefilters; // original filters saved ( used for 4 color processing ) @@ -78,6 +75,7 @@ protected: int maximum_c4[4]; Decoder decoder{Decoder::DCRAW}; std::unique_ptr libraw; + std::unique_ptr::type[]> image_from_float; bool isFoveon() const { return is_foveon; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 4448a149a..8aab1956d 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -237,13 +237,14 @@ void scale_colors (rtengine::RawImage *ri, float scale_mul[4], float cblack[4], } } } else if (isFloat) { + const auto colors = ri->get_colors(); #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif for (int row = 0; row < height; ++row) { for (int col = 0; col < width; ++col) { - for (int i = 0; i < ri->get_colors(); ++i) { - float val = float_raw_image[(row + top_margin) * raw_width + col + left_margin + i]; + for (int i = 0; i < colors; ++i) { + float val = float_raw_image[colors * ((row + top_margin) * raw_width + col + left_margin) + i]; val -= cblack[i]; val *= scale_mul[i]; image[row * width + col][i] = val;