diff --git a/rtengine/eahd_demosaic.cc b/rtengine/eahd_demosaic.cc index 62eee47a4..5f247378a 100644 --- a/rtengine/eahd_demosaic.cc +++ b/rtengine/eahd_demosaic.cc @@ -35,10 +35,203 @@ using namespace std; namespace rtengine { -#define DIST(a,b) (std::fabs(a-b)) +inline void RawImageSource::convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob) +{ -extern const Settings* settings; -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + for (int j = 0; j < W; j++) { + float r = ar[j]; + float g = ag[j]; + float b = ab[j]; + + float x = lc00 * r + lc01 * g + lc02 * b; + float y = lc10 * r + lc11 * g + lc12 * b; + float z = lc20 * r + lc21 * g + lc22 * b; + + if (y > threshold) { + oL[j] = cache[(int)y]; + } else { + oL[j] = float(903.3f * y / MAXVALF); + } + + oa[j] = 500.f * ((x > threshold ? cache[(int)x] : 7.787f * x / MAXVALF + 16.f / 116.f) - (y > threshold ? cache[(int)y] : 7.787f * y / MAXVALF + 16.f / 116.f)); + ob[j] = 200.f * ((y > threshold ? cache[(int)y] : 7.787f * y / MAXVALF + 16.f / 116.f) - (z > threshold ? cache[(int)z] : 7.787f * z / MAXVALF + 16.f / 116.f)); + } +} + +inline void RawImageSource::interpolate_row_g (float* agh, float* agv, int i) +{ + + for (int j = 0; j < W; j++) { + if (ri->ISGREEN(i, j)) { + agh[j] = rawData[i][j]; + agv[j] = rawData[i][j]; + } else { + int gh = 0; + int gv = 0; + + if (j > 1 && j < W - 2) { + gh = (-rawData[i][j - 2] + 2 * rawData[i][j - 1] + 2 * rawData[i][j] + 2 * rawData[i][j + 1] - rawData[i][j + 2]) / 4; + int maxgh = max(rawData[i][j - 1], rawData[i][j + 1]); + int mingh = min(rawData[i][j - 1], rawData[i][j + 1]); + + if (gh > maxgh) { + gh = maxgh; + } else if (gh < mingh) { + gh = mingh; + } + } else if (j == 0) { + gh = rawData[i][1]; + } else if (j == 1) { + gh = (rawData[i][0] + rawData[i][2]) / 2; + } else if (j == W - 1) { + gh = rawData[i][W - 2]; + } else if (j == W - 2) { + gh = (rawData[i][W - 1] + rawData[i][W - 3]) / 2; + } + + if (i > 1 && i < H - 2) { + gv = (-rawData[i - 2][j] + 2 * rawData[i - 1][j] + 2 * rawData[i][j] + 2 * rawData[i + 1][j] - rawData[i + 2][j]) / 4; + int maxgv = max(rawData[i - 1][j], rawData[i + 1][j]); + int mingv = min(rawData[i - 1][j], rawData[i + 1][j]); + + if (gv > maxgv) { + gv = maxgv; + } else if (gv < mingv) { + gv = mingv; + } + } else if (i == 0) { + gv = rawData[1][j]; + } else if (i == 1) { + gv = (rawData[0][j] + rawData[2][j]) / 2; + } else if (i == H - 1) { + gv = rawData[H - 2][j]; + } else if (i == H - 2) { + gv = (rawData[H - 1][j] + rawData[H - 3][j]) / 2; + } + + agh[j] = gh; + agv[j] = gv; + } + } +} + +inline void RawImageSource::interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i) +{ + const auto getPg = [pg](int index) { + return + pg + ? pg[index] + : 0.f; + }; + + const auto getNg = [ng](int index) { + return + ng + ? ng[index] + : 0.f; + }; + + float *nonGreen1 = ar; + float *nonGreen2 = ab; + + if ((ri->ISBLUE(i, 0) || ri->ISBLUE(i, 1))) { + std::swap(nonGreen1, nonGreen2); + } + int j = FC(i, 0) & 1; + if (j) { + // linear R-G interp. horizontally + float val1; + + val1 = cg[0] + rawData[i][1] - cg[1]; + + nonGreen1[0] = CLIP(val1); + // linear B-G interp. vertically + float val2; + + if (i == 0) { + val2 = getNg(0) + rawData[1][0] - cg[0]; + } else if (i == H - 1) { + val2 = getPg(0) + rawData[H - 2][0] - cg[0]; + } else { + val2 = cg[0] + (rawData[i - 1][0] - getPg(0) + rawData[i + 1][0] - getNg(0)) / 2; + } + + nonGreen2[0] = val2; + } + // RGRGR or GRGRGR line + for (; j < W - 1; j += 2) { + // nonGreen of row is simple + nonGreen1[j] = rawData[i][j]; + // non green of next row: cross interpolation + float nonGreen = 0.f; + int n = 0; + + if (i > 0) { + if (j > 0) { + nonGreen += rawData[i - 1][j - 1] - getPg(j - 1); + n++; + } + nonGreen += rawData[i - 1][j + 1] - getPg(j + 1); + n++; + } + + if (i < H - 1) { + if (j > 0) { + nonGreen += rawData[i + 1][j - 1] - getNg(j - 1); + n++; + } + nonGreen += rawData[i + 1][j + 1] - getNg(j + 1); + n++; + } + + nonGreen2[j] = cg[j] + nonGreen / n; + + // linear R-G interp. horizontally + float val1; + + if (j == W - 2) { + val1 = cg[W - 1] + rawData[i][W - 2] - cg[W - 2]; + } else { + val1 = cg[j + 1] + (rawData[i][j] - cg[j] + rawData[i][j + 2] - cg[j + 2]) / 2; + } + + nonGreen1[j + 1] = CLIP(val1); + // linear B-G interp. vertically + float val2; + + if (i == 0) { + val2 = getNg(j + 1) + rawData[1][j + 1] - cg[j + 1]; + } else if (i == H - 1) { + val2 = getPg(j + 1) + rawData[H - 2][j + 1] - cg[j + 1]; + } else { + val2 = cg[j + 1] + (rawData[i - 1][j + 1] - getPg(j + 1) + rawData[i + 1][j + 1] - getNg(j + 1)) / 2; + } + + nonGreen2[j + 1] = val2; + } + + if(j == W - 1) { + // nonGreen of row is simple + nonGreen1[j] = rawData[i][j]; + // non green of next row: cross interpolation + float nonGreen = 0.f; + int n = 0; + + if (i > 0) { + nonGreen += rawData[i - 1][j - 1] - getPg(j - 1); + n++; + } + + if (i < H - 1) { + nonGreen += rawData[i + 1][j - 1] - getNg(j - 1); + n++; + } + + nonGreen2[j] = cg[j] + nonGreen / n; + } +} + +#define DIST(a,b) (std::fabs(a-b)) void RawImageSource::eahd_demosaic () { diff --git a/rtengine/rawimagesource_i.h b/rtengine/rawimagesource_i.h index fb85e4933..b24115e0a 100644 --- a/rtengine/rawimagesource_i.h +++ b/rtengine/rawimagesource_i.h @@ -58,202 +58,6 @@ inline void RawImageSource::convert_to_RGB (float &r, float &g, float &b, const b = Y - 1.105f * I + 1.702f * Q; } -inline void RawImageSource::convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob) -{ - - for (int j = 0; j < W; j++) { - float r = ar[j]; - float g = ag[j]; - float b = ab[j]; - - float x = lc00 * r + lc01 * g + lc02 * b; - float y = lc10 * r + lc11 * g + lc12 * b; - float z = lc20 * r + lc21 * g + lc22 * b; - - if (y > threshold) { - oL[j] = cache[(int)y]; - } else { - oL[j] = float(903.3f * y / MAXVALF); - } - - oa[j] = 500.f * ((x > threshold ? cache[(int)x] : 7.787f * x / MAXVALF + 16.f / 116.f) - (y > threshold ? cache[(int)y] : 7.787f * y / MAXVALF + 16.f / 116.f)); - ob[j] = 200.f * ((y > threshold ? cache[(int)y] : 7.787f * y / MAXVALF + 16.f / 116.f) - (z > threshold ? cache[(int)z] : 7.787f * z / MAXVALF + 16.f / 116.f)); - } -} - -inline void RawImageSource::interpolate_row_g (float* agh, float* agv, int i) -{ - - for (int j = 0; j < W; j++) { - if (ri->ISGREEN(i, j)) { - agh[j] = rawData[i][j]; - agv[j] = rawData[i][j]; - } else { - int gh = 0; - int gv = 0; - - if (j > 1 && j < W - 2) { - gh = (-rawData[i][j - 2] + 2 * rawData[i][j - 1] + 2 * rawData[i][j] + 2 * rawData[i][j + 1] - rawData[i][j + 2]) / 4; - int maxgh = max(rawData[i][j - 1], rawData[i][j + 1]); - int mingh = min(rawData[i][j - 1], rawData[i][j + 1]); - - if (gh > maxgh) { - gh = maxgh; - } else if (gh < mingh) { - gh = mingh; - } - } else if (j == 0) { - gh = rawData[i][1]; - } else if (j == 1) { - gh = (rawData[i][0] + rawData[i][2]) / 2; - } else if (j == W - 1) { - gh = rawData[i][W - 2]; - } else if (j == W - 2) { - gh = (rawData[i][W - 1] + rawData[i][W - 3]) / 2; - } - - if (i > 1 && i < H - 2) { - gv = (-rawData[i - 2][j] + 2 * rawData[i - 1][j] + 2 * rawData[i][j] + 2 * rawData[i + 1][j] - rawData[i + 2][j]) / 4; - int maxgv = max(rawData[i - 1][j], rawData[i + 1][j]); - int mingv = min(rawData[i - 1][j], rawData[i + 1][j]); - - if (gv > maxgv) { - gv = maxgv; - } else if (gv < mingv) { - gv = mingv; - } - } else if (i == 0) { - gv = rawData[1][j]; - } else if (i == 1) { - gv = (rawData[0][j] + rawData[2][j]) / 2; - } else if (i == H - 1) { - gv = rawData[H - 2][j]; - } else if (i == H - 2) { - gv = (rawData[H - 1][j] + rawData[H - 3][j]) / 2; - } - - agh[j] = gh; - agv[j] = gv; - } - } -} - -inline void RawImageSource::interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i) -{ - const auto getPg = [pg](int index) { - return - pg - ? pg[index] - : 0.f; - }; - - const auto getNg = [ng](int index) { - return - ng - ? ng[index] - : 0.f; - }; - - float *nonGreen1 = ar; - float *nonGreen2 = ab; - - if ((ri->ISBLUE(i, 0) || ri->ISBLUE(i, 1))) { - std::swap(nonGreen1, nonGreen2); - } - int j = FC(i, 0) & 1; - if (j) { - // linear R-G interp. horizontally - float val1; - - val1 = cg[0] + rawData[i][1] - cg[1]; - - nonGreen1[0] = CLIP(val1); - // linear B-G interp. vertically - float val2; - - if (i == 0) { - val2 = getNg(0) + rawData[1][0] - cg[0]; - } else if (i == H - 1) { - val2 = getPg(0) + rawData[H - 2][0] - cg[0]; - } else { - val2 = cg[0] + (rawData[i - 1][0] - getPg(0) + rawData[i + 1][0] - getNg(0)) / 2; - } - - nonGreen2[0] = val2; - } - // RGRGR or GRGRGR line - for (; j < W - 1; j += 2) { - // nonGreen of row is simple - nonGreen1[j] = rawData[i][j]; - // non green of next row: cross interpolation - float nonGreen = 0.f; - int n = 0; - - if (i > 0) { - if (j > 0) { - nonGreen += rawData[i - 1][j - 1] - getPg(j - 1); - n++; - } - nonGreen += rawData[i - 1][j + 1] - getPg(j + 1); - n++; - } - - if (i < H - 1) { - if (j > 0) { - nonGreen += rawData[i + 1][j - 1] - getNg(j - 1); - n++; - } - nonGreen += rawData[i + 1][j + 1] - getNg(j + 1); - n++; - } - - nonGreen2[j] = cg[j] + nonGreen / n; - - // linear R-G interp. horizontally - float val1; - - if (j == W - 2) { - val1 = cg[W - 1] + rawData[i][W - 2] - cg[W - 2]; - } else { - val1 = cg[j + 1] + (rawData[i][j] - cg[j] + rawData[i][j + 2] - cg[j + 2]) / 2; - } - - nonGreen1[j + 1] = CLIP(val1); - // linear B-G interp. vertically - float val2; - - if (i == 0) { - val2 = getNg(j + 1) + rawData[1][j + 1] - cg[j + 1]; - } else if (i == H - 1) { - val2 = getPg(j + 1) + rawData[H - 2][j + 1] - cg[j + 1]; - } else { - val2 = cg[j + 1] + (rawData[i - 1][j + 1] - getPg(j + 1) + rawData[i + 1][j + 1] - getNg(j + 1)) / 2; - } - - nonGreen2[j + 1] = val2; - } - - if(j == W - 1) { - // nonGreen of row is simple - nonGreen1[j] = rawData[i][j]; - // non green of next row: cross interpolation - float nonGreen = 0.f; - int n = 0; - - if (i > 0) { - nonGreen += rawData[i - 1][j - 1] - getPg(j - 1); - n++; - } - - if (i < H - 1) { - nonGreen += rawData[i + 1][j - 1] - getNg(j - 1); - n++; - } - - nonGreen2[j] = cg[j] + nonGreen / n; - } -} - inline void RawImageSource::interpolate_row_rb_mul_pp (const array2D &rawData, float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip) {