From 8fa477793defe51ff892a957c8d5740d9c60194c Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 11 Nov 2017 18:31:37 +0100 Subject: [PATCH] Speedup for initial thumb creation from raw files, fixes #4109 --- rtengine/rtthumbnail.cc | 242 ++++++++++++++++------------------------ 1 file changed, 99 insertions(+), 143 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 8398ea2d2..5572984f9 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -38,7 +38,6 @@ #include "improccoordinator.h" #include - namespace { @@ -659,69 +658,18 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati tpp->scale = (double) height / (rotate_90 ? w : h); } - // generate histogram for auto exposure + // generate histogram for auto exposure, also calculate autoWB tpp->aeHistCompression = 3; - tpp->aeHistogram (65536 >> tpp->aeHistCompression); + tpp->aeHistogram(65536 >> tpp->aeHistCompression); tpp->aeHistogram.clear(); - int radd = 4; - int gadd = 4; - int badd = 4; - if (!filter) { - radd = gadd = badd = 1; - } + const unsigned int add = filter ? 1 : 4 / ri->get_colors(); - for (int i = 8; i < height - 8; i++) { - int start, end; - - if (ri->get_FujiWidth() != 0) { - int fw = ri->get_FujiWidth(); - start = ABS (fw - i) + 8; - end = min (height + width - fw - i, fw + i) - 8; - } else { - start = 8; - end = width - 8; - } - - if (ri->get_colors() == 1) { - for (int j = start; j < end; j++) { - tpp->aeHistogram[ ((int) (image[i * width + j][0])) >> tpp->aeHistCompression] += radd; - tpp->aeHistogram[ ((int) (image[i * width + j][0])) >> tpp->aeHistCompression] += gadd; - tpp->aeHistogram[ ((int) (image[i * width + j][0])) >> tpp->aeHistCompression] += badd; - } - } else if (ri->getSensorType() == ST_BAYER) { - for (int j = start; j < end; j++) - if (FISGREEN (filter, i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbGreen * image[i * width + j][1])) >> tpp->aeHistCompression] += gadd; - } else if (FISRED (filter, i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbRed * image[i * width + j][0])) >> tpp->aeHistCompression] += radd; - } else if (FISBLUE (filter, i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbBlue * image[i * width + j][2])) >> tpp->aeHistCompression] += badd; - } - } else if (ri->getSensorType() == ST_FUJI_XTRANS) { - for (int j = start; j < end; j++) - if (ri->ISXTRANSGREEN (i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbGreen * image[i * width + j][1])) >> tpp->aeHistCompression] += gadd; - } else if (ri->ISXTRANSRED (i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbRed * image[i * width + j][0])) >> tpp->aeHistCompression] += radd; - } else if (ri->ISXTRANSBLUE (i, j)) { - tpp->aeHistogram[ ((int) (tpp->camwbBlue * image[i * width + j][2])) >> tpp->aeHistCompression] += badd; - } - } else { /* if(ri->getSensorType()==ST_FOVEON) */ - for (int j = start; j < end; j++) { - tpp->aeHistogram[ ((int) (image[i * width + j][0] * 2.f)) >> tpp->aeHistCompression] += radd; - tpp->aeHistogram[ ((int) (image[i * width + j][1])) >> tpp->aeHistCompression] += gadd; - tpp->aeHistogram[ ((int) (image[i * width + j][2] * 0.5f)) >> tpp->aeHistCompression] += badd; - } - } - } - - // generate autoWB - double avg_r = 0; - double avg_g = 0; - double avg_b = 0; - - unsigned int rn = 0, gn = 0, bn = 0; + 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; @@ -735,110 +683,118 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati end = width - 32; } - if (ri->getSensorType() == ST_BAYER) { + if (ri->get_colors() == 1) { for (int j = start; j < end; j++) { - if (!filter) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d > 64000.) { - continue; - } - - avg_g += d; - avg_r += d; - avg_b += d; - rn++; - gn++; - bn++; - } else if (FISGREEN (filter, i, j)) { - double d = tpp->defGain * image[i * width + j][1]; - - if (d > 64000.) { - continue; - } - - avg_g += d; - gn++; - } else if (FISRED (filter, i, j)) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d > 64000.) { - continue; - } - - avg_r += d; - rn++; - } else if (FISBLUE (filter, i, j)) { - double d = tpp->defGain * image[i * width + j][2]; - - if (d > 64000.) { - continue; - } - - avg_b += d; - bn++; + tpp->aeHistogram[image[i * width + j][0] >> tpp->aeHistCompression]++; + } + } 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++; + } + } + n[c0] += n0; + n[c1] += n1; + pixSum[c0] += pixSum0; + pixSum[c1] += pixSum1; } else if (ri->getSensorType() == ST_FUJI_XTRANS) { - for (int j = start; j < end; j++) { + 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) { + 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 = tpp->defGain * image[i * width + j][1]; - - if (d > 64000.) { - continue; + double d = image[i * width + j][1]; + tpp->aeHistogram[(int)(camWb[1] * d)]++; + if (d <= clipval) { + pixSum[1] += d; + n[1]++; } - - avg_g += d; - gn++; } else if (ri->ISXTRANSRED (i, j)) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d > 64000.) { - continue; + double d = image[i * width + j][0]; + tpp->aeHistogram[(int)(camWb[0] * d)]++; + if (d <= clipval) { + pixSum[0] += d; + n[0]++; } - - avg_r += d; - rn++; } else if (ri->ISXTRANSBLUE (i, j)) { - double d = tpp->defGain * image[i * width + j][2]; - - if (d > 64000.) { - continue; + double d = image[i * width + j][2]; + tpp->aeHistogram[(int)(camWb[2] * d)]++; + if (d <= clipval) { + pixSum[2] += d; + n[2]++; } - - avg_b += d; - bn++; } } } else { /* if(ri->getSensorType()==ST_FOVEON) */ for (int j = start; j < end; j++) { - double d = tpp->defGain * image[i * width + j][0]; - - if (d <= 64000.) { - avg_r += d; - rn++; + double r = image[i * width + j][0]; + if (r <= clipval) { + pixSum[0] += r; + n[0]++; } - - d = tpp->defGain * image[i * width + j][1]; - - if (d <= 64000.) { - avg_g += d; - gn++; + double g = image[i * width + j][1]; + if (g <= clipval) { + pixSum[1] += g; + n[1]++; } - - d = tpp->defGain * image[i * width + j][2]; - - if (d <= 64000.) { - avg_b += d; - bn++; + 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; } } } - double reds = avg_r / std::max(rn, 1u) * tpp->camwbRed; - double greens = avg_g / std::max(gn, 1u) * tpp->camwbGreen; - double blues = avg_b / std::max(bn, 1u) * tpp->camwbBlue; + 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;