diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 516640978..05d4bead8 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -395,7 +395,7 @@ RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname) return rml; } -Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool multiThread) +Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching) { RawImage *ri = new RawImage (fname); unsigned int tempImageNum = 0; @@ -427,10 +427,9 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tpp->greenMultiplier = ri->get_pre_mul (1); tpp->blueMultiplier = ri->get_pre_mul (2); - //ri->scale_colors(); float pre_mul[4], scale_mul[4], cblack[4]; ri->get_colorsCoeff (pre_mul, scale_mul, cblack, false); - scale_colors (ri, scale_mul, cblack, multiThread); + scale_colors (ri, scale_mul, cblack, forHistogramMatching); // enable multithreading when forHistogramMatching is true ri->pre_interpolate(); @@ -672,154 +671,155 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati } else { tpp->scale = (double) height / (rotate_90 ? w : h); } + if(!forHistogramMatching) { // we don't need this for histogram matching - // generate histogram for auto exposure, also calculate autoWB - tpp->aeHistCompression = 3; - tpp->aeHistogram(65536 >> tpp->aeHistCompression); - tpp->aeHistogram.clear(); + // generate histogram for auto exposure, also calculate autoWB + tpp->aeHistCompression = 3; + tpp->aeHistogram(65536 >> tpp->aeHistCompression); + tpp->aeHistogram.clear(); - const unsigned int add = filter ? 1 : 4 / ri->get_colors(); + const unsigned int add = filter ? 1 : 4 / ri->get_colors(); - double pixSum[3] = {0.0}; - unsigned int n[3] = {0}; - const double compression = pow(2.0, tpp->aeHistCompression); - const double camWb[3] = {tpp->camwbRed / compression, tpp->camwbGreen / compression, tpp->camwbBlue / compression}; - const double clipval = 64000.0 / tpp->defGain; + double pixSum[3] = {0.0}; + unsigned int n[3] = {0}; + const double compression = pow(2.0, tpp->aeHistCompression); + const double camWb[3] = {tpp->camwbRed / compression, tpp->camwbGreen / compression, tpp->camwbBlue / compression}; + const double clipval = 64000.0 / tpp->defGain; - for (int i = 32; i < height - 32; i++) { - int start, end; + for (int i = 32; i < height - 32; i++) { + int start, end; - if (ri->get_FujiWidth() != 0) { - int fw = ri->get_FujiWidth(); - start = ABS (fw - i) + 32; - end = min (height + width - fw - i, fw + i) - 32; - } else { - start = 32; - end = width - 32; - } - - if (ri->get_colors() == 1) { - for (int j = start; j < end; j++) { - tpp->aeHistogram[image[i * width + j][0] >> tpp->aeHistCompression]++; + if (ri->get_FujiWidth() != 0) { + int fw = ri->get_FujiWidth(); + start = ABS (fw - i) + 32; + end = min (height + width - fw - i, fw + i) - 32; + } else { + start = 32; + end = width - 32; } - } else if (ri->getSensorType() == ST_BAYER) { - int c0 = ri->FC(i, start); - int c1 = ri->FC(i, start + 1); - int j = start; - int n0 = 0; - int n1 = 0; - double pixSum0 = 0.0; - double pixSum1 = 0.0; - for (; j < end - 1; j+=2) { - double v0 = image[i * width + j][c0]; - tpp->aeHistogram[(int)(camWb[c0] * v0)]++; - if (v0 <= clipval) { - pixSum0 += v0; - n0++; + + if (ri->get_colors() == 1) { + for (int j = start; j < end; j++) { + tpp->aeHistogram[image[i * width + j][0] >> tpp->aeHistCompression]++; } - double v1 = image[i * width + j + 1][c1]; - tpp->aeHistogram[(int)(camWb[c1] * v1)]++; - if (v1 <= clipval) { - pixSum1 += v1; - n1++; + } else if (ri->getSensorType() == ST_BAYER) { + int c0 = ri->FC(i, start); + int c1 = ri->FC(i, start + 1); + int j = start; + int n0 = 0; + int n1 = 0; + double pixSum0 = 0.0; + double pixSum1 = 0.0; + for (; j < end - 1; j+=2) { + double v0 = image[i * width + j][c0]; + tpp->aeHistogram[(int)(camWb[c0] * v0)]++; + if (v0 <= clipval) { + pixSum0 += v0; + n0++; + } + double v1 = image[i * width + j + 1][c1]; + tpp->aeHistogram[(int)(camWb[c1] * v1)]++; + if (v1 <= clipval) { + pixSum1 += v1; + n1++; + } } - } - if (j < end) { - double v0 = image[i * width + j][c0]; - tpp->aeHistogram[(int)(camWb[c0] * v0)]++; - if (v0 <= clipval) { - pixSum0 += v0; - n0++; + if (j < end) { + double v0 = image[i * width + j][c0]; + tpp->aeHistogram[(int)(camWb[c0] * v0)]++; + if (v0 <= clipval) { + pixSum0 += v0; + n0++; + } } - } - n[c0] += n0; - n[c1] += n1; - pixSum[c0] += pixSum0; - pixSum[c1] += pixSum1; - } else if (ri->getSensorType() == ST_FUJI_XTRANS) { - int c[6]; - for(int cc = 0; cc < 6; ++cc) { - c[cc] = ri->XTRANSFC(i, start + cc); - } - int j = start; - for (; j < end - 5; j += 6) { + n[c0] += n0; + n[c1] += n1; + pixSum[c0] += pixSum0; + pixSum[c1] += pixSum1; + } else if (ri->getSensorType() == ST_FUJI_XTRANS) { + int c[6]; for(int cc = 0; cc < 6; ++cc) { - double d = image[i * width + j + cc][c[cc]]; - tpp->aeHistogram[(int)(camWb[c[cc]] * d)]++; - if (d <= clipval) { - pixSum[c[cc]] += d; - n[c[cc]]++; + c[cc] = ri->XTRANSFC(i, start + cc); + } + int j = start; + for (; j < end - 5; j += 6) { + for(int cc = 0; cc < 6; ++cc) { + double d = image[i * width + j + cc][c[cc]]; + tpp->aeHistogram[(int)(camWb[c[cc]] * d)]++; + if (d <= clipval) { + pixSum[c[cc]] += d; + n[c[cc]]++; + } } } - } - for (; j < end; j++) { - if (ri->ISXTRANSGREEN (i, j)) { - double d = image[i * width + j][1]; - tpp->aeHistogram[(int)(camWb[1] * d)]++; - if (d <= clipval) { - pixSum[1] += d; - n[1]++; + for (; j < end; j++) { + if (ri->ISXTRANSGREEN (i, j)) { + double d = image[i * width + j][1]; + tpp->aeHistogram[(int)(camWb[1] * d)]++; + if (d <= clipval) { + pixSum[1] += d; + n[1]++; + } + } else if (ri->ISXTRANSRED (i, j)) { + double d = image[i * width + j][0]; + tpp->aeHistogram[(int)(camWb[0] * d)]++; + if (d <= clipval) { + pixSum[0] += d; + n[0]++; + } + } else if (ri->ISXTRANSBLUE (i, j)) { + double d = image[i * width + j][2]; + tpp->aeHistogram[(int)(camWb[2] * d)]++; + if (d <= clipval) { + pixSum[2] += d; + n[2]++; + } } - } else if (ri->ISXTRANSRED (i, j)) { - double d = image[i * width + j][0]; - tpp->aeHistogram[(int)(camWb[0] * d)]++; - if (d <= clipval) { - pixSum[0] += d; + } + } else { /* if(ri->getSensorType()==ST_FOVEON) */ + for (int j = start; j < end; j++) { + double r = image[i * width + j][0]; + if (r <= clipval) { + pixSum[0] += r; n[0]++; } - } else if (ri->ISXTRANSBLUE (i, j)) { - double d = image[i * width + j][2]; - tpp->aeHistogram[(int)(camWb[2] * d)]++; - if (d <= clipval) { - pixSum[2] += d; + double g = image[i * width + j][1]; + if (g <= clipval) { + pixSum[1] += g; + n[1]++; + } + tpp->aeHistogram[((int)g) >> tpp->aeHistCompression] += add; + double b = image[i * width + j][2]; + if (b <= clipval) { + pixSum[2] += b; n[2]++; } + tpp->aeHistogram[((int) (b * 0.5f)) >> tpp->aeHistCompression] += add; } } - } else { /* if(ri->getSensorType()==ST_FOVEON) */ - for (int j = start; j < end; j++) { - double r = image[i * width + j][0]; - if (r <= clipval) { - pixSum[0] += r; - n[0]++; - } - double g = image[i * width + j][1]; - if (g <= clipval) { - pixSum[1] += g; - n[1]++; - } - tpp->aeHistogram[((int)g) >> tpp->aeHistCompression] += add; - double b = image[i * width + j][2]; - if (b <= clipval) { - pixSum[2] += b; - n[2]++; - } - tpp->aeHistogram[((int) (b * 0.5f)) >> tpp->aeHistCompression] += add; - } } + if (ri->get_colors() == 1) { + pixSum[0] = pixSum[1] = pixSum[2] = 1.; + n[0] = n[1] = n[2] = 1; + } + pixSum[0] *= tpp->defGain; + pixSum[1] *= tpp->defGain; + pixSum[2] *= tpp->defGain; + + double reds = pixSum[0] / std::max(n[0], 1u) * tpp->camwbRed; + double greens = pixSum[1] / std::max(n[1], 1u) * tpp->camwbGreen; + double blues = pixSum[2] / std::max(n[2], 1u) * tpp->camwbBlue; + + tpp->redAWBMul = ri->get_rgb_cam (0, 0) * reds + ri->get_rgb_cam (0, 1) * greens + ri->get_rgb_cam (0, 2) * blues; + tpp->greenAWBMul = ri->get_rgb_cam (1, 0) * reds + ri->get_rgb_cam (1, 1) * greens + ri->get_rgb_cam (1, 2) * blues; + tpp->blueAWBMul = ri->get_rgb_cam (2, 0) * reds + ri->get_rgb_cam (2, 1) * greens + ri->get_rgb_cam (2, 2) * blues; + tpp->wbEqual = wbEq; + tpp->wbTempBias = 0.0; + + ColorTemp cTemp; + cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen); } - if (ri->get_colors() == 1) { - pixSum[0] = pixSum[1] = pixSum[2] = 1.; - n[0] = n[1] = n[2] = 1; - } - pixSum[0] *= tpp->defGain; - pixSum[1] *= tpp->defGain; - pixSum[2] *= tpp->defGain; - - double reds = pixSum[0] / std::max(n[0], 1u) * tpp->camwbRed; - double greens = pixSum[1] / std::max(n[1], 1u) * tpp->camwbGreen; - double blues = pixSum[2] / std::max(n[2], 1u) * tpp->camwbBlue; - - tpp->redAWBMul = ri->get_rgb_cam (0, 0) * reds + ri->get_rgb_cam (0, 1) * greens + ri->get_rgb_cam (0, 2) * blues; - tpp->greenAWBMul = ri->get_rgb_cam (1, 0) * reds + ri->get_rgb_cam (1, 1) * greens + ri->get_rgb_cam (1, 2) * blues; - tpp->blueAWBMul = ri->get_rgb_cam (2, 0) * reds + ri->get_rgb_cam (2, 1) * greens + ri->get_rgb_cam (2, 2) * blues; - tpp->wbEqual = wbEq; - tpp->wbTempBias = 0.0; - - ColorTemp cTemp; - cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen); - if (rotate && ri->get_rotateDegree() > 0) { tpp->thumbImg->rotate (ri->get_rotateDegree()); } @@ -930,7 +930,7 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int } // Full thumbnail processing, second stage if complete profile exists -IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale, bool forMonitor, bool multiThread) +IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale, bool forMonitor, bool forHistogramMatching) { unsigned int imgNum = 0; if (isRaw) { @@ -1062,7 +1062,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT int fh = baseImg->getHeight(); //ColorTemp::CAT02 (baseImg, ¶ms) ;//perhaps not good! - ImProcFunctions ipf (¶ms, multiThread); + ImProcFunctions ipf (¶ms, forHistogramMatching); // enable multithreading when forHistogramMatching is true ipf.setScale (sqrt (double (fw * fw + fh * fh)) / sqrt (double (thumbImg->getWidth() * thumbImg->getWidth() + thumbImg->getHeight() * thumbImg->getHeight()))*scale); ipf.updateColorProfiles (ICCStore::getInstance()->getDefaultMonitorProfileName(), options.rtSettings.monitorIntent, false, false); diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h index 987114742..be1340f3c 100644 --- a/rtengine/rtthumbnail.h +++ b/rtengine/rtthumbnail.h @@ -71,13 +71,13 @@ public: void init (); - IImage8* processImage (const procparams::ProcParams& pparams, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& scale, bool forMonitor=true, bool multiThread = false); + IImage8* processImage (const procparams::ProcParams& pparams, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& scale, bool forMonitor=true, bool forHistogramMatching = false); IImage8* quickProcessImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp); int getImageWidth (const procparams::ProcParams& pparams, int rheight, float &ratio); void getDimensions (int& w, int& h, double& scaleFac); static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false); - static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool multiThread = false); + static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching = false); static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false); static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname);