diff --git a/rtdata/languages/default b/rtdata/languages/default index 256dcccb9..6a87d6ee9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -56,6 +56,7 @@ EXIFFILTER_CAMERA;Camera EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) EXIFFILTER_FILETYPE;File type EXIFFILTER_FOCALLEN;Focal length +EXIFFILTER_IMAGETYPE;Image type EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Lens EXIFFILTER_METADATAFILTER;Enable metadata filters @@ -1809,54 +1810,34 @@ TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (ste TP_RAW_MONO;Mono TP_RAW_NONE;None (Shows sensor pattern) TP_RAW_PIXELSHIFT;Pixel Shift -TP_RAW_PIXELSHIFTADAPTIVE;Adaptive detection TP_RAW_PIXELSHIFTBLUR;Blur motion mask -TP_RAW_PIXELSHIFTEPERISO;ISO adaption -TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value of 0 should work fine for base ISO.\nIncrease the value to improve motion detection for higher ISO.\nIncrease in small steps and watch the motion mask while increasing. +TP_RAW_PIXELSHIFTEPERISO;Sensitivity +TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value of 0 should work fine for base ISO.\nHigher values increase sensitivity of motion detection.\nChange in small steps and watch the motion mask while changing.\nIncrease sensitivity for underexposed or high ISO images. TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalize brightness of frames TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalize per channel TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Enabled: Equalize the RGB channels individually.\nDisabled: Use same equalization factor for all channels. TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalize the brightness of the frames to the brightness of the selected frame.\nIf there are overexposed areas in the frames select the brightest frame to avoid magenta colour cast in overexposed areas or enable motion correction. -TP_RAW_PIXELSHIFTEXP0;Experimental TP_RAW_PIXELSHIFTGREEN;Check green channel for motion TP_RAW_PIXELSHIFTHOLEFILL;Fill holes in motion mask TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Fill holes in motion mask TP_RAW_PIXELSHIFTLMMSE;Use LMMSE for moving parts TP_RAW_PIXELSHIFTLMMSE_TOOLTIP;Use LMMSE instead of AMaZE for areas of motion.\nUseful for high ISO images. -TP_RAW_PIXELSHIFTMASKTHRESHOLD;3x3 new threshold TP_RAW_PIXELSHIFTMEDIAN;Use median for moving parts -TP_RAW_PIXELSHIFTMEDIAN3;Exclude selected frame from median -TP_RAW_PIXELSHIFTMEDIAN3_TOOLTIP;Excludes selected frame from median.\nUseful if moving objects overlap in frame 2 and 3 TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Use median of all frames instead of selected frame for regions with motion.\nRemoves objects which are at different places in all frames.\nGives motion effect on slow moving (overlapping) objects. TP_RAW_PIXELSHIFTMM_AUTO;Automatic TP_RAW_PIXELSHIFTMM_CUSTOM;Custom TP_RAW_PIXELSHIFTMM_OFF;Off -TP_RAW_PIXELSHIFTMOTION;Motion detection level (deprecated) -TP_RAW_PIXELSHIFTMOTIONCORRECTION;Green motion correction size TP_RAW_PIXELSHIFTMOTIONMETHOD;Motion Correction TP_RAW_PIXELSHIFTMOTION_TOOLTIP;0 means no motion detection.\n1 - 99 means motion will be detected according to this value. Increase value to increase detection rate.\n100 means the AMaZE-demosaiced frame will be used. -TP_RAW_PIXELSHIFTNONGREENAMAZE;Check red/blue AMaZE TP_RAW_PIXELSHIFTNONGREENCROSS;Check red/blue channels for motion -TP_RAW_PIXELSHIFTNONGREENCROSS2;Check green AMaZE -TP_RAW_PIXELSHIFTNONGREENHORIZONTAL;Check red/blue horizontal -TP_RAW_PIXELSHIFTNONGREENVERTICAL;Check red/blue vertical -TP_RAW_PIXELSHIFTNREADISO;nRead -TP_RAW_PIXELSHIFTONEGREEN;Use one green instead of average -TP_RAW_PIXELSHIFTONEGREEN_TOOLTIP;Use one green instead of averaging two greens for regions without motion. -TP_RAW_PIXELSHIFTPRNU;PRNU (%) -TP_RAW_PIXELSHIFTREDBLUEWEIGHT;Red&Blue weight TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Show only motion mask TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Shows the motion mask without the image. -TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a mask showing the regions with motion. +TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a green mask showing the regions with motion. TP_RAW_PIXELSHIFTSIGMA;Blur radius TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;The default radius of 1.0 usually fits well for base ISO.\nIncrease the value for high ISO shots, 5.0 is a good starting point.\nWatch the motion mask while changing the value. TP_RAW_PIXELSHIFTSMOOTH;Smooth transitions TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Smooth transitions between areas with motion and areas without.\nSet to 0 to disable transition smoothing.\nSet to 1 to either get the AMaZE/LMMSE result of the selected frame (depending on whether "Use LMMSE" is selected), or the median of all four frames if "Use median" is selected. -TP_RAW_PIXELSHIFTSTDDEVFACTORBLUE;StdDev factor Blue -TP_RAW_PIXELSHIFTSTDDEVFACTORGREEN;StdDev factor Green -TP_RAW_PIXELSHIFTSTDDEVFACTORRED;StdDev factor Red -TP_RAW_RCD;RCD TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix diff --git a/rtdata/profiles/Pixel Shift/PS ISO High.pp3 b/rtdata/profiles/Pixel Shift/PS ISO High.pp3 index 2c9927e93..87af3febd 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO High.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO High.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [RAW] CA=true diff --git a/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 index cbf2e6c74..62374cb69 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO Low.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [Sharpening] Enabled=true diff --git a/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 b/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 index 2c83094c2..16463b1b0 100644 --- a/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 +++ b/rtdata/profiles/Pixel Shift/PS ISO Medium.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [RAW] CA=true diff --git a/rtdata/profiles/Pixel Shift/PS No Motion.pp3 b/rtdata/profiles/Pixel Shift/PS No Motion.pp3 index 7a73881a1..8f0cce13b 100644 --- a/rtdata/profiles/Pixel Shift/PS No Motion.pp3 +++ b/rtdata/profiles/Pixel Shift/PS No Motion.pp3 @@ -1,6 +1,6 @@ [Version] -AppVersion=5.0-r1-gtk3-503-g9e1fc78 -Version=326 +AppVersion=5.4 +Version=332 [Sharpening] Enabled=true diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 0693f919f..769569b21 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -120,6 +120,7 @@ set(RTENGINESOURCEFILES histmatching.cc pdaflinesfilter.cc gamutwarning.cc + xtrans_demosaic.cc ) if(LENSFUN_HAS_LOAD_DIRECTORY) diff --git a/rtengine/LUT.h b/rtengine/LUT.h index c0a63037a..15ae988e3 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -74,8 +74,9 @@ // Bit representations of flags enum { - LUT_CLIP_BELOW = 1 << 0, - LUT_CLIP_ABOVE = 1 << 1 + LUT_CLIP_OFF, // LUT does not clip input values + LUT_CLIP_BELOW, // LUT clips input values at lower bound + LUT_CLIP_ABOVE // LUT clips input values at upper bound }; template @@ -111,7 +112,7 @@ public: /// The user have to handle it itself, even if some method can (re)initialize it bool dirty; - LUT(int s, int flags = 0xfffffff) + LUT(int s, int flags = LUT_CLIP_BELOW | LUT_CLIP_ABOVE, bool initZero = false) { #ifndef NDEBUG @@ -137,8 +138,11 @@ public: sizeiv = _mm_set1_epi32( (int)(size - 1) ); sizev = F2V( size - 1 ); #endif + if (initZero) { + clear(); + } } - void operator ()(int s, int flags = 0xfffffff) + void operator ()(int s, int flags = LUT_CLIP_BELOW | LUT_CLIP_ABOVE, bool initZero = false) { #ifndef NDEBUG @@ -167,6 +171,10 @@ public: sizeiv = _mm_set1_epi32( (int)(size - 1) ); sizev = F2V( size - 1 ); #endif + if (initZero) { + clear(); + } + } LUT() @@ -616,7 +624,7 @@ public: } // share the buffer with another LUT, handy for same data but different clip flags - void share(const LUT &source, int flags = 0xfffffff) + void share(const LUT &source, int flags = LUT_CLIP_BELOW | LUT_CLIP_ABOVE) { if (owner && data) { delete[] data; diff --git a/rtengine/camconst.json b/rtengine/camconst.json index cfe7412d8..35cb524a1 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2004,6 +2004,11 @@ Camera constants: "ranges": { "white": 4080 } // nominal at ISO200 4094 }, + { + "make_model": [ "PENTAX K-S1" ], + "raw_crop": [ 0, 0, -8, 0 ] + }, + { // Quality B, Intemediate ISO samples missing, Pentax_DNG WLtags are after BL sutraction and not valid "make_model": [ "RICOH PENTAX K-70", "PENTAX K-70" ], //"dcraw_matrix": [ 8050,-2061,-1264,-4359,12953,1515,-1096,1965,6075 ], // PENTAX DNG D65 diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc index 89387a9b4..582b00629 100644 --- a/rtengine/demosaic_algos.cc +++ b/rtengine/demosaic_algos.cc @@ -3845,994 +3845,6 @@ BENCHFUN } } -const double xyz_rgb[3][3] = { // XYZ from RGB - { 0.412453, 0.357580, 0.180423 }, - { 0.212671, 0.715160, 0.072169 }, - { 0.019334, 0.119193, 0.950227 } -}; -const float d65_white[3] = { 0.950456, 1, 1.088754 }; - -void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) -{ - static LUTf cbrt(0x14000); - static bool cbrtinit = false; - - if (!rgb) { - if(!cbrtinit) { - for (int i = 0; i < 0x14000; i++) { - double r = i / 65535.0; - cbrt[i] = r > Color::eps ? std::cbrt(r) : (Color::kappa * r + 16.0) / 116.0; - } - - cbrtinit = true; - } - - return; - } - -#ifdef __SSE2__ - vfloat c116v = F2V(116.f); - vfloat c16v = F2V(16.f); - vfloat c500v = F2V(500.f); - vfloat c200v = F2V(200.f); - vfloat xyz_camv[3][3]; - - for(int i = 0; i < 3; i++) - for(int j = 0; j < 3; j++) { - xyz_camv[i][j] = F2V(xyz_cam[i][j]); - } - -#endif // __SSE2__ - - for(int i = 0; i < height; i++) { - int j = 0; -#ifdef __SSE2__ - - for(; j < labWidth - 3; j += 4) { - vfloat redv, greenv, bluev; - vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[i * width + j], redv, greenv, bluev); - vfloat xyz0v = redv * xyz_camv[0][0] + greenv * xyz_camv[0][1] + bluev * xyz_camv[0][2]; - vfloat xyz1v = redv * xyz_camv[1][0] + greenv * xyz_camv[1][1] + bluev * xyz_camv[1][2]; - vfloat xyz2v = redv * xyz_camv[2][0] + greenv * xyz_camv[2][1] + bluev * xyz_camv[2][2]; - xyz0v = cbrt[_mm_cvtps_epi32(xyz0v)]; - xyz1v = cbrt[_mm_cvtps_epi32(xyz1v)]; - xyz2v = cbrt[_mm_cvtps_epi32(xyz2v)]; - - STVFU(l[i * labWidth + j], c116v * xyz1v - c16v); - STVFU(a[i * labWidth + j], c500v * (xyz0v - xyz1v)); - STVFU(b[i * labWidth + j], c200v * (xyz1v - xyz2v)); - } - -#endif - - for(; j < labWidth; j++) { - float xyz[3] = {0.5f, 0.5f, 0.5f}; - - for(int c = 0; c < 3; c++) { - float val = rgb[i * width + j][c]; - xyz[0] += xyz_cam[0][c] * val; - xyz[1] += xyz_cam[1][c] * val; - xyz[2] += xyz_cam[2][c] * val; - } - - xyz[0] = cbrt[(int) xyz[0]]; - xyz[1] = cbrt[(int) xyz[1]]; - xyz[2] = cbrt[(int) xyz[2]]; - - l[i * labWidth + j] = 116 * xyz[1] - 16; - a[i * labWidth + j] = 500 * (xyz[0] - xyz[1]); - b[i * labWidth + j] = 200 * (xyz[1] - xyz[2]); - } - } -} - - -#define fcol(row,col) xtrans[(row)%6][(col)%6] -#define isgreen(row,col) (xtrans[(row)%3][(col)%3]&1) - -void RawImageSource::xtransborder_interpolate (int border) -{ - const int height = H, width = W; - - int xtrans[6][6]; - ri->getXtransMatrix(xtrans); - - for (int row = 0; row < height; row++) - for (int col = 0; col < width; col++) { - if (col == border && row >= border && row < height - border) { - col = width - border; - } - - float sum[6] = {0.f}; - - for (int y = MAX(0, row - 1); y <= MIN(row + 1, height - 1); y++) - for (int x = MAX(0, col - 1); x <= MIN(col + 1, width - 1); x++) { - int f = fcol(y, x); - sum[f] += rawData[y][x]; - sum[f + 3]++; - } - - switch(fcol(row, col)) { - case 0: - red[row][col] = rawData[row][col]; - green[row][col] = (sum[1] / sum[4]); - blue[row][col] = (sum[2] / sum[5]); - break; - - case 1: - if(sum[3] == 0.f) { // at the 4 corner pixels it can happen, that we have only green pixels in 2x2 area - red[row][col] = green[row][col] = blue[row][col] = rawData[row][col]; - } else { - red[row][col] = (sum[0] / sum[3]); - green[row][col] = rawData[row][col]; - blue[row][col] = (sum[2] / sum[5]); - } - - break; - - case 2: - red[row][col] = (sum[0] / sum[3]); - green[row][col] = (sum[1] / sum[4]); - blue[row][col] = rawData[row][col]; - } - } -} - -/* - Frank Markesteijn's algorithm for Fuji X-Trans sensors - adapted to RT by Ingo Weyrich 2014 -*/ -// override CLIP function to test unclipped output -#define CLIP(x) (x) -void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) -{ - BENCHFUN - constexpr int ts = 114; /* Tile Size */ - constexpr int tsh = ts / 2; /* half of Tile Size */ - - double progress = 0.0; - const bool plistenerActive = plistener; - - if (plistenerActive) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "Xtrans")); - plistener->setProgress (progress); - } - - int xtrans[6][6]; - ri->getXtransMatrix(xtrans); - - constexpr short orth[12] = { 1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1 }, - patt[2][16] = { { 0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0, 0, 0, 0 }, - { 0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1, -1, -1, 1 } - }, - dir[4] = { 1, ts, ts + 1, ts - 1 }; - - // sgrow/sgcol is the offset in the sensor matrix of the solitary - // green pixels - ushort sgrow = 0, sgcol = 0; - - const int height = H, width = W; - - if (settings->verbose) { - printf("%d-pass X-Trans interpolation using %s conversion...\n", passes, useCieLab ? "lab" : "yuv"); - } - - xtransborder_interpolate(6); - - float xyz_cam[3][3]; - { - float rgb_cam[3][4]; - ri->getRgbCam(rgb_cam); - int k; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - for (xyz_cam[i][j] = k = 0; k < 3; k++) { - xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; - } - } - - /* Map a green hexagon around each non-green pixel and vice versa: */ - short allhex[2][3][3][8]; - { - int gint, d, h, v, ng, row, col, c; - - for (row = 0; row < 3; row++) - for (col = 0; col < 3; col++) { - gint = isgreen(row, col); - - for (ng = d = 0; d < 10; d += 2) { - if (isgreen(row + orth[d] + 6, col + orth[d + 2] + 6)) { - ng = 0; - } else { - ng++; - } - - if (ng == 4) { - // if there are four non-green pixels adjacent in cardinal - // directions, this is the solitary green pixel - sgrow = row; - sgcol = col; - } - - if (ng == gint + 1) - FORC(8) { - v = orth[d] * patt[gint][c * 2] + orth[d + 1] * patt[gint][c * 2 + 1]; - h = orth[d + 2] * patt[gint][c * 2] + orth[d + 3] * patt[gint][c * 2 + 1]; - allhex[0][row][col][c ^ (gint * 2 & d)] = h + v * width; - allhex[1][row][col][c ^ (gint * 2 & d)] = h + v * ts; - } - } - } - - } - - if(plistenerActive) { - progress += 0.05; - plistener->setProgress(progress); - } - - - double progressInc = 36.0 * (1.0 - progress) / ((H * W) / ((ts - 16) * (ts - 16))); - const int ndir = 4 << (passes > 1); - cielab (nullptr, nullptr, nullptr, nullptr, 0, 0, 0, nullptr); - struct s_minmaxgreen { - float min; - float max; - }; - - int RightShift[3]; - - for(int row = 0; row < 3; row++) { - // count number of green pixels in three cols - int greencount = 0; - - for(int col = 0; col < 3; col++) { - greencount += isgreen(row, col); - } - - RightShift[row] = (greencount == 2); - } - -#ifdef _OPENMP - #pragma omp parallel -#endif - { - int progressCounter = 0; - int c; - float color[3][6]; - - float *buffer = (float *) malloc ((ts * ts * (ndir * 4 + 3) + 128) * sizeof(float)); - float (*rgb)[ts][ts][3] = (float(*)[ts][ts][3]) buffer; - float (*lab)[ts - 8][ts - 8] = (float (*)[ts - 8][ts - 8])(buffer + ts * ts * (ndir * 3)); - float (*drv)[ts - 10][ts - 10] = (float (*)[ts - 10][ts - 10]) (buffer + ts * ts * (ndir * 3 + 3)); - uint8_t (*homo)[ts][ts] = (uint8_t (*)[ts][ts]) (lab); // we can reuse the lab-buffer because they are not used together - s_minmaxgreen (*greenminmaxtile)[tsh] = (s_minmaxgreen(*)[tsh]) (lab); // we can reuse the lab-buffer because they are not used together - uint8_t (*homosum)[ts][ts] = (uint8_t (*)[ts][ts]) (drv); // we can reuse the drv-buffer because they are not used together - uint8_t (*homosummax)[ts] = (uint8_t (*)[ts]) homo[ndir - 1]; // we can reuse the homo-buffer because they are not used together - -#ifdef _OPENMP - #pragma omp for collapse(2) schedule(dynamic) nowait -#endif - - for (int top = 3; top < height - 19; top += ts - 16) - for (int left = 3; left < width - 19; left += ts - 16) { - int mrow = MIN (top + ts, height - 3); - int mcol = MIN (left + ts, width - 3); - - /* Set greenmin and greenmax to the minimum and maximum allowed values: */ - for (int row = top; row < mrow; row++) { - // find first non-green pixel - int leftstart = left; - - for(; leftstart < mcol; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); - - if(coloffset == 3) { - short *hex = allhex[0][row % 3][leftstart % 3]; - - for (int col = leftstart; col < mcol; col += coloffset) { - float minval = FLT_MAX; - float maxval = 0.f; - float *pix = &rawData[row][col]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - } - } else { - float minval = FLT_MAX; - float maxval = 0.f; - int col = leftstart; - - if(coloffset == 2) { - minval = FLT_MAX; - maxval = 0.f; - float *pix = &rawData[row][col]; - short *hex = allhex[0][row % 3][col % 3]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - col += 2; - } - - short *hex = allhex[0][row % 3][col % 3]; - - for (; col < mcol - 1; col += 3) { - minval = FLT_MAX; - maxval = 0.f; - float *pix = &rawData[row][col]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - greenminmaxtile[row - top][(col + 1 - left) >> 1].min = minval; - greenminmaxtile[row - top][(col + 1 - left) >> 1].max = maxval; - } - - if(col < mcol) { - minval = FLT_MAX; - maxval = 0.f; - float *pix = &rawData[row][col]; - - for(int c = 0; c < 6; c++) { - float val = pix[hex[c]]; - - minval = minval < val ? minval : val; - maxval = maxval > val ? maxval : val; - } - - greenminmaxtile[row - top][(col - left) >> 1].min = minval; - greenminmaxtile[row - top][(col - left) >> 1].max = maxval; - } - } - } - - memset(rgb, 0, ts * ts * 3 * sizeof(float)); - - for (int row = top; row < mrow; row++) - for (int col = left; col < mcol; col++) { - rgb[0][row - top][col - left][fcol(row, col)] = rawData[row][col]; - } - - for(int c = 0; c < 3; c++) { - memcpy (rgb[c + 1], rgb[0], sizeof * rgb); - } - - /* Interpolate green horizontally, vertically, and along both diagonals: */ - for (int row = top; row < mrow; row++) { - // find first non-green pixel - int leftstart = left; - - for(; leftstart < mcol; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); - - if(coloffset == 3) { - short *hex = allhex[0][row % 3][leftstart % 3]; - - for (int col = leftstart; col < mcol; col += coloffset) { - float *pix = &rawData[row][col]; - float color[4]; - color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - - 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); - color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + - 0.359375f * (pix[0] - pix[-hex[2]]); - - for(int c = 0; c < 2; c++) - color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * - (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); - - for(int c = 0; c < 4; c++) { - rgb[c][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } else { - short *hexmod[2]; - hexmod[0] = allhex[0][row % 3][leftstart % 3]; - hexmod[1] = allhex[0][row % 3][(leftstart + coloffset) % 3]; - - for (int col = leftstart, hexindex = 0; col < mcol; col += coloffset, coloffset ^= 3, hexindex ^= 1) { - float *pix = &rawData[row][col]; - short *hex = hexmod[hexindex]; - float color[4]; - color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - - 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); - color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + - 0.359375f * (pix[0] - pix[-hex[2]]); - - for(int c = 0; c < 2; c++) - color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * - (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); - - for(int c = 0; c < 4; c++) { - rgb[c ^ 1][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } - } - - for (int pass = 0; pass < passes; pass++) { - if (pass == 1) { - memcpy (rgb += 4, buffer, 4 * sizeof * rgb); - } - - /* Recalculate green from interpolated values of closer pixels: */ - if (pass) { - for (int row = top + 2; row < mrow - 2; row++) { - int leftstart = left + 2; - - for(; leftstart < mcol - 2; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); - - if(coloffset == 3) { - int f = fcol(row, leftstart); - short *hex = allhex[1][row % 3][leftstart % 3]; - - for (int col = leftstart; col < mcol - 2; col += coloffset, f ^= 2) { - for (int d = 3; d < 6; d++) { - float (*rix)[3] = &rgb[(d - 2)][row - top][col - left]; - float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) - - rix[-2 * hex[d]][f]) + rix[0][f]; - rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } else { - int f = fcol(row, leftstart); - short *hexmod[2]; - hexmod[0] = allhex[1][row % 3][leftstart % 3]; - hexmod[1] = allhex[1][row % 3][(leftstart + coloffset) % 3]; - - for (int col = leftstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2), hexindex ^= 1 ) { - short *hex = hexmod[hexindex]; - - for (int d = 3; d < 6; d++) { - float (*rix)[3] = &rgb[(d - 2) ^ 1][row - top][col - left]; - float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) - - rix[-2 * hex[d]][f]) + rix[0][f]; - rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); - } - } - } - } - } - - /* Interpolate red and blue values for solitary green pixels: */ - int sgstartcol = (left - sgcol + 4) / 3 * 3 + sgcol; - - for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) { - for (int col = sgstartcol, h = fcol(row, col + 1); col < mcol - 2; col += 3, h ^= 2) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - float diff[6] = {0.f}; - - for (int i = 1, d = 0; d < 6; d++, i ^= ts ^ 1, h ^= 2) { - for (int c = 0; c < 2; c++, h ^= 2) { - float g = rix[0][1] + rix[0][1] - rix[i << c][1] - rix[-i << c][1]; - color[h][d] = g + rix[i << c][h] + rix[-i << c][h]; - - if (d > 1) - diff[d] += SQR (rix[i << c][1] - rix[-i << c][1] - - rix[i << c][h] + rix[-i << c][h]) + SQR(g); - } - - if (d > 2 && (d & 1)) // 3, 5 - if (diff[d - 1] < diff[d]) - for(int c = 0; c < 2; c++) { - color[c * 2][d] = color[c * 2][d - 1]; - } - - if ((d & 1) || d < 2) { // d: 0, 1, 3, 5 - for(int c = 0; c < 2; c++) { - rix[0][c * 2] = CLIP(0.5f * color[c * 2][d]); - } - - rix += ts * ts; - } - } - } - } - - /* Interpolate red for blue pixels and vice versa: */ - for (int row = top + 3; row < mrow - 3; row++) { - int leftstart = left + 3; - - for(; leftstart < mcol - 1; leftstart++) - if(!isgreen(row, leftstart)) { - break; - } - - int coloffset = (RightShift[row % 3] == 1 ? 3 : 1); - c = (row - sgrow) % 3 ? ts : 1; - int h = 3 * (c ^ ts ^ 1); - - if(coloffset == 3) { - int f = 2 - fcol(row, leftstart); - - for (int col = leftstart; col < mcol - 3; col += coloffset, f ^= 2) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - - for (int d = 0; d < 4; d++, rix += ts * ts) { - int i = d > 1 || ((d ^ c) & 1) || - ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; - - rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); - } - } - } else { - coloffset = fcol(row, leftstart + 1) == 1 ? 2 : 1; - int f = 2 - fcol(row, leftstart); - - for (int col = leftstart; col < mcol - 3; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2) ) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - - for (int d = 0; d < 4; d++, rix += ts * ts) { - int i = d > 1 || ((d ^ c) & 1) || - ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; - - rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); - } - } - } - } - - /* Fill in red and blue for 2x2 blocks of green: */ - // Find first row of 2x2 green - int topstart = top + 2; - - for(; topstart < mrow - 2; topstart++) - if((topstart - sgrow) % 3) { - break; - } - - int leftstart = left + 2; - - for(; leftstart < mcol - 2; leftstart++) - if((leftstart - sgcol) % 3) { - break; - } - - int coloffsetstart = 2 - (fcol(topstart, leftstart + 1) & 1); - - for (int row = topstart; row < mrow - 2; row++) { - if ((row - sgrow) % 3) { - short *hexmod[2]; - hexmod[0] = allhex[1][row % 3][leftstart % 3]; - hexmod[1] = allhex[1][row % 3][(leftstart + coloffsetstart) % 3]; - - for (int col = leftstart, coloffset = coloffsetstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, hexindex ^= 1) { - float (*rix)[3] = &rgb[0][row - top][col - left]; - short *hex = hexmod[hexindex]; - - for (int d = 0; d < ndir; d += 2, rix += ts * ts) { - if (hex[d] + hex[d + 1]) { - float g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; - - for (c = 0; c < 4; c += 2) { - rix[0][c] = CLIP((g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.33333333f); - } - } else { - float g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; - - for (c = 0; c < 4; c += 2) { - rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.5f); - } - } - } - } - } - } - } - -// end of multipass part - rgb = (float(*)[ts][ts][3]) buffer; - mrow -= top; - mcol -= left; - - if(useCieLab) { - /* Convert to CIELab and differentiate in all directions: */ - // Original dcraw algorithm uses CIELab as perceptual space - // (presumably coming from original AHD) and converts taking - // camera matrix into account. We use this in RT. - for (int d = 0; d < ndir; d++) { - float *l = &lab[0][0][0]; - float *a = &lab[1][0][0]; - float *b = &lab[2][0][0]; - cielab(&rgb[d][4][4], l, a, b, ts, mrow - 8, ts - 8, xyz_cam); - int f = dir[d & 3]; - f = f == 1 ? 1 : f - 8; - - for (int row = 5; row < mrow - 5; row++) -#ifdef _OPENMP - #pragma omp simd -#endif - for (int col = 5; col < mcol - 5; col++) { - float *l = &lab[0][row - 4][col - 4]; - float *a = &lab[1][row - 4][col - 4]; - float *b = &lab[2][row - 4][col - 4]; - - float g = 2 * l[0] - l[f] - l[-f]; - drv[d][row - 5][col - 5] = SQR(g) - + SQR((2 * a[0] - a[f] - a[-f] + g * 2.1551724f)) - + SQR((2 * b[0] - b[f] - b[-f] - g * 0.86206896f)); - } - - } - } else { - // For 1-pass demosaic we use YPbPr which requires much - // less code and is nearly indistinguishable. It assumes the - // camera RGB is roughly linear. - for (int d = 0; d < ndir; d++) { - float (*yuv)[ts - 8][ts - 8] = lab; // we use the lab buffer, which has the same dimensions -#ifdef __SSE2__ - vfloat zd2627v = F2V(0.2627f); - vfloat zd6780v = F2V(0.6780f); - vfloat zd0593v = F2V(0.0593f); - vfloat zd56433v = F2V(0.56433f); - vfloat zd67815v = F2V(0.67815f); -#endif - - for (int row = 4; row < mrow - 4; row++) { - int col = 4; -#ifdef __SSE2__ - - for (; col < mcol - 7; col += 4) { - // use ITU-R BT.2020 YPbPr, which is great, but could use - // a better/simpler choice? note that imageop.h provides - // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, - // which appears less good with specular highlights - vfloat redv, greenv, bluev; - vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[d][row][col], redv, greenv, bluev); - vfloat yv = zd2627v * redv + zd6780v * bluev + zd0593v * greenv; - STVFU(yuv[0][row - 4][col - 4], yv); - STVFU(yuv[1][row - 4][col - 4], (bluev - yv) * zd56433v); - STVFU(yuv[2][row - 4][col - 4], (redv - yv) * zd67815v); - } - -#endif - - for (; col < mcol - 4; col++) { - // use ITU-R BT.2020 YPbPr, which is great, but could use - // a better/simpler choice? note that imageop.h provides - // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, - // which appears less good with specular highlights - float y = 0.2627f * rgb[d][row][col][0] + 0.6780f * rgb[d][row][col][1] + 0.0593f * rgb[d][row][col][2]; - yuv[0][row - 4][col - 4] = y; - yuv[1][row - 4][col - 4] = (rgb[d][row][col][2] - y) * 0.56433f; - yuv[2][row - 4][col - 4] = (rgb[d][row][col][0] - y) * 0.67815f; - } - } - - int f = dir[d & 3]; - f = f == 1 ? 1 : f - 8; - - for (int row = 5; row < mrow - 5; row++) - for (int col = 5; col < mcol - 5; col++) { - float *y = &yuv[0][row - 4][col - 4]; - float *u = &yuv[1][row - 4][col - 4]; - float *v = &yuv[2][row - 4][col - 4]; - drv[d][row - 5][col - 5] = SQR(2 * y[0] - y[f] - y[-f]) - + SQR(2 * u[0] - u[f] - u[-f]) - + SQR(2 * v[0] - v[f] - v[-f]); - } - } - } - - /* Build homogeneity maps from the derivatives: */ -#ifdef __SSE2__ - vfloat eightv = F2V(8.f); - vfloat zerov = F2V(0.f); - vfloat onev = F2V(1.f); -#endif - - for (int row = 6; row < mrow - 6; row++) { - int col = 6; -#ifdef __SSE2__ - - for (; col < mcol - 9; col += 4) { - vfloat tr1v = vminf(LVFU(drv[0][row - 5][col - 5]), LVFU(drv[1][row - 5][col - 5])); - vfloat tr2v = vminf(LVFU(drv[2][row - 5][col - 5]), LVFU(drv[3][row - 5][col - 5])); - - if(ndir > 4) { - vfloat tr3v = vminf(LVFU(drv[4][row - 5][col - 5]), LVFU(drv[5][row - 5][col - 5])); - vfloat tr4v = vminf(LVFU(drv[6][row - 5][col - 5]), LVFU(drv[7][row - 5][col - 5])); - tr1v = vminf(tr1v, tr3v); - tr1v = vminf(tr1v, tr4v); - } - - tr1v = vminf(tr1v, tr2v); - tr1v = tr1v * eightv; - - for (int d = 0; d < ndir; d++) { - uint8_t tempstore[16]; - vfloat tempv = zerov; - - for (int v = -1; v <= 1; v++) { - for (int h = -1; h <= 1; h++) { - tempv += vselfzero(vmaskf_le(LVFU(drv[d][row + v - 5][col + h - 5]), tr1v), onev); - } - } - - _mm_storeu_si128((__m128i*)&tempstore, _mm_cvtps_epi32(tempv)); - homo[d][row][col] = tempstore[0]; - homo[d][row][col + 1] = tempstore[4]; - homo[d][row][col + 2] = tempstore[8]; - homo[d][row][col + 3] = tempstore[12]; - - } - } - -#endif - - for (; col < mcol - 6; col++) { - float tr = drv[0][row - 5][col - 5] < drv[1][row - 5][col - 5] ? drv[0][row - 5][col - 5] : drv[1][row - 5][col - 5]; - - for (int d = 2; d < ndir; d++) { - tr = (drv[d][row - 5][col - 5] < tr ? drv[d][row - 5][col - 5] : tr); - } - - tr *= 8; - - for (int d = 0; d < ndir; d++) { - uint8_t temp = 0; - - for (int v = -1; v <= 1; v++) { - for (int h = -1; h <= 1; h++) { - temp += (drv[d][row + v - 5][col + h - 5] <= tr ? 1 : 0); - } - } - - homo[d][row][col] = temp; - } - } - } - - if (height - top < ts + 4) { - mrow = height - top + 2; - } - - if (width - left < ts + 4) { - mcol = width - left + 2; - } - - - /* Build 5x5 sum of homogeneity maps */ - const int startcol = MIN(left, 8); - - for(int d = 0; d < ndir; d++) { - for (int row = MIN(top, 8); row < mrow - 8; row++) { - int col = startcol; -#ifdef __SSE2__ - int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; - - // crunching 16 values at once is faster than summing up column sums - for (; col < endcol; col += 16) { - vint v5sumv = (vint)ZEROV; - - for(int v = -2; v <= 2; v++) - for(int h = -2; h <= 2; h++) { - v5sumv = _mm_adds_epu8( _mm_loadu_si128((vint*)&homo[d][row + v][col + h]), v5sumv); - } - - _mm_storeu_si128((vint*)&homosum[d][row][col], v5sumv); - } - -#endif - - if(col < mcol - 8) { - int v5sum[5] = {0}; - - for(int v = -2; v <= 2; v++) - for(int h = -2; h <= 2; h++) { - v5sum[2 + h] += homo[d][row + v][col + h]; - } - - int blocksum = v5sum[0] + v5sum[1] + v5sum[2] + v5sum[3] + v5sum[4]; - homosum[d][row][col] = blocksum; - col++; - - // now we can subtract a column of five from blocksum and get new colsum of 5 - for (int voffset = 0; col < mcol - 8; col++, voffset++) { - int colsum = homo[d][row - 2][col + 2] + homo[d][row - 1][col + 2] + homo[d][row][col + 2] + homo[d][row + 1][col + 2] + homo[d][row + 2][col + 2]; - voffset = voffset == 5 ? 0 : voffset; // faster than voffset %= 5; - blocksum -= v5sum[voffset]; - blocksum += colsum; - v5sum[voffset] = colsum; - homosum[d][row][col] = blocksum; - } - } - } - } - - // calculate maximum of homogeneity maps per pixel. Vectorized calculation is a tiny bit faster than on the fly calculation in next step -#ifdef __SSE2__ - vint maskv = _mm_set1_epi8(31); -#endif - - for (int row = MIN(top, 8); row < mrow - 8; row++) { - int col = startcol; -#ifdef __SSE2__ - int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; - - for (; col < endcol; col += 16) { - vint maxval1 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[0][row][col]), _mm_loadu_si128((vint*)&homosum[1][row][col])); - vint maxval2 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[2][row][col]), _mm_loadu_si128((vint*)&homosum[3][row][col])); - - if(ndir > 4) { - vint maxval3 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[4][row][col]), _mm_loadu_si128((vint*)&homosum[5][row][col])); - vint maxval4 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[6][row][col]), _mm_loadu_si128((vint*)&homosum[7][row][col])); - maxval1 = _mm_max_epu8(maxval1, maxval3); - maxval1 = _mm_max_epu8(maxval1, maxval4); - } - - maxval1 = _mm_max_epu8(maxval1, maxval2); - // there is no shift intrinsic for epu8. Shift using epi32 and mask the wrong bits out - vint subv = _mm_srli_epi32( maxval1, 3 ); - subv = _mm_and_si128(subv, maskv); - maxval1 = _mm_subs_epu8(maxval1, subv); - _mm_storeu_si128((vint*)&homosummax[row][col], maxval1); - } - -#endif - - for (; col < mcol - 8; col ++) { - uint8_t maxval = homosum[0][row][col]; - - for(int d = 1; d < ndir; d++) { - maxval = maxval < homosum[d][row][col] ? homosum[d][row][col] : maxval; - } - - maxval -= maxval >> 3; - homosummax[row][col] = maxval; - } - } - - - /* Average the most homogeneous pixels for the final result: */ - uint8_t hm[8] = {}; - - for (int row = MIN(top, 8); row < mrow - 8; row++) - for (int col = MIN(left, 8); col < mcol - 8; col++) { - - for (int d = 0; d < 4; d++) { - hm[d] = homosum[d][row][col]; - } - - for (int d = 4; d < ndir; d++) { - hm[d] = homosum[d][row][col]; - - if (hm[d - 4] < hm[d]) { - hm[d - 4] = 0; - } else if (hm[d - 4] > hm[d]) { - hm[d] = 0; - } - } - - float avg[4] = {0.f}; - - uint8_t maxval = homosummax[row][col]; - - for (int d = 0; d < ndir; d++) - if (hm[d] >= maxval) { - FORC3 avg[c] += rgb[d][row][col][c]; - avg[3]++; - } - - red[row + top][col + left] = avg[0] / avg[3]; - green[row + top][col + left] = avg[1] / avg[3]; - blue[row + top][col + left] = avg[2] / avg[3]; - } - - if(plistenerActive && ((++progressCounter) % 32 == 0)) { -#ifdef _OPENMP - #pragma omp critical (xtransdemosaic) -#endif - { - progress += progressInc; - progress = min(1.0, progress); - plistener->setProgress (progress); - } - } - - - } - - free(buffer); - } - -} -#undef CLIP -void RawImageSource::fast_xtrans_interpolate () -{ - if (settings->verbose) { - printf("fast X-Trans interpolation...\n"); - } - - double progress = 0.0; - const bool plistenerActive = plistener; - - if (plistenerActive) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); - plistener->setProgress (progress); - } - - const int height = H, width = W; - - xtransborder_interpolate (1); - int xtrans[6][6]; - ri->getXtransMatrix(xtrans); - - #pragma omp parallel for - - for(int row = 1; row < height - 1; row++) { - for(int col = 1; col < width - 1; col++) { - float sum[3] = {0.f}; - - for(int v = -1; v <= 1; v++) { - for(int h = -1; h <= 1; h++) { - sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)]; - } - } - - switch(fcol(row, col)) { - case 0: - red[row][col] = rawData[row][col]; - green[row][col] = sum[1] * 0.2f; - blue[row][col] = sum[2] * 0.33333333f; - break; - - case 1: - red[row][col] = sum[0] * 0.5f; - green[row][col] = rawData[row][col]; - blue[row][col] = sum[2] * 0.5f; - break; - - case 2: - red[row][col] = sum[0] * 0.33333333f; - green[row][col] = sum[1] * 0.2f; - blue[row][col] = rawData[row][col]; - break; - } - } - } - - if (plistenerActive) { - plistener->setProgress (1.0); - } -} -#undef fcol -#undef isgreen - - #undef TILEBORDER #undef TILESIZE #undef CACHESIZE diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 1afc04446..7b7f2a517 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -80,7 +80,8 @@ bool DynamicProfileRule::matches (const rtengine::FramesMetaData *im) const && shutterspeed (im->getShutterSpeed()) && expcomp (im->getExpComp()) && camera (im->getCamera()) - && lens (im->getLens())); + && lens (im->getLens()) + && imagetype(im->getImageType(0))); } namespace @@ -208,6 +209,7 @@ bool DynamicProfileRules::loadRules() get_double_range (rule.expcomp, kf, group, "expcomp"); get_optional (rule.camera, kf, group, "camera"); get_optional (rule.lens, kf, group, "lens"); + get_optional (rule.imagetype, kf, group, "imagetype"); try { rule.profilepath = kf.get_string (group, "profilepath"); @@ -240,6 +242,7 @@ bool DynamicProfileRules::storeRules() set_double_range (kf, group, "expcomp", rule.expcomp); set_optional (kf, group, "camera", rule.camera); set_optional (kf, group, "lens", rule.lens); + set_optional (kf, group, "imagetype", rule.imagetype); kf.set_string (group, "profilepath", rule.profilepath); } diff --git a/rtengine/dynamicprofile.h b/rtengine/dynamicprofile.h index 4e6bbbba9..fc5c85e4c 100644 --- a/rtengine/dynamicprofile.h +++ b/rtengine/dynamicprofile.h @@ -59,6 +59,7 @@ public: Range expcomp; Optional camera; Optional lens; + Optional imagetype; Glib::ustring profilepath; }; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index eb213a8ea..3920b3d90 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -506,7 +506,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* if (!isHDR) { const rtexif::Tag* const q = mnote->findTag("Quality"); - if (q && q->toInt() == 7) { + if (q && (q->toInt() == 7 || q->toInt() == 8)) { isPixelShift = true; #if PRINT_HDR_PS_DETECTION printf("PixelShift detected ! -> \"Quality\" = 7\n"); @@ -692,6 +692,10 @@ bool FrameData::getHDR () const { return isHDR; } +std::string FrameData::getImageType () const +{ + return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; +} IIOSampleFormat FrameData::getSampleFormat () const { return sampleFormat; @@ -787,27 +791,30 @@ FrameData *FramesData::getFrameData (unsigned int frame) const return frames.empty() || frame >= frames.size() ? nullptr : frames.at(frame); } -bool FramesData::getPixelShift (unsigned int frame) const +bool FramesData::getPixelShift () const { - // So far only Pentax and Sony provide multi-frame HDR file. - // Only the first frame contains the HDR tag + // So far only Pentax and Sony provide multi-frame Pixel Shift files. + // Only the first frame contains the Pixel Shift tag // If more brand have to be supported, this rule may need // to evolve - //return frames.at(frame)->getPixelShift (); - return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getPixelShift (); + return frames.empty() ? false : frames.at(0)->getPixelShift (); } bool FramesData::getHDR (unsigned int frame) const { - // So far only Pentax provide multi-frame HDR file. + // So far only Pentax provides multi-frame HDR file. // Only the first frame contains the HDR tag // If more brand have to be supported, this rule may need // to evolve - //return frames.at(frame)->getHDR (); return frames.empty() || frame >= frames.size() ? false : frames.at(0)->getHDR (); } +std::string FramesData::getImageType (unsigned int frame) const +{ + return frames.empty() || frame >= frames.size() ? "STD" : frames.at(0)->getImageType(); +} + IIOSampleFormat FramesData::getSampleFormat (unsigned int frame) const { return frames.empty() || frame >= frames.size() ? IIOSF_UNKNOWN : frames.at(frame)->getSampleFormat (); diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index b9f955611..0427ee519 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -63,6 +63,7 @@ public: bool getPixelShift () const; bool getHDR () const; + std::string getImageType () const; IIOSampleFormat getSampleFormat () const; rtexif::TagDirectory* getExifData () const; procparams::IPTCPairs getIPTCData () const; @@ -102,8 +103,9 @@ public: unsigned int getRootCount () const; unsigned int getFrameCount () const; FrameData *getFrameData (unsigned int frame) const; - bool getPixelShift (unsigned int frame = 0) const; + bool getPixelShift () const; bool getHDR (unsigned int frame = 0) const; + std::string getImageType (unsigned int frame) const; IIOSampleFormat getSampleFormat (unsigned int frame = 0) const; rtexif::TagDirectory* getFrameExifData (unsigned int frame = 0) const; rtexif::TagDirectory* getRootExifData (unsigned int root = 0) const; diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 511e4c95d..5aac37d20 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -2,7 +2,7 @@ // // Algorithm for Pentax/Sony Pixel Shift raw files with motion detection // -// Copyright (C) 2016 - 2017 Ingo Weyrich +// Copyright (C) 2016 - 2018 Ingo Weyrich // // // pixelshift.cc is free software: you can redistribute it and/or modify @@ -26,7 +26,8 @@ #include "procparams.h" #include "gauss.h" #include "median.h" - +#define BENCHMARK +#include "StopWatch.h" namespace { @@ -63,16 +64,12 @@ float nonGreenDiffCross(float right, float left, float top, float bottom, float return std::min(hDiff, vDiff) - stddev; } -void paintMotionMask(int index, bool showMotion, bool showOnlyMask, float *maskDest, float *nonMaskDest0, float *nonMaskDest1) +void paintMotionMask(int index, bool showMotion, float *maskDest, float *nonMaskDest0, float *nonMaskDest1) { if(showMotion) { - if(!showOnlyMask) { - // if showMotion is enabled colourize the pixel - maskDest[index] = 13500.f; - nonMaskDest1[index] = nonMaskDest0[index] = 0.f; - } else { - maskDest[index] = nonMaskDest0[index] = nonMaskDest1[index] = 65535.f; - } + // if showMotion is enabled colourize the pixel + maskDest[index] = 13500.f; + nonMaskDest1[index] = nonMaskDest0[index] = 0.f; } } @@ -271,7 +268,7 @@ void floodFill4(int xStart, int xEnd, int yStart, int yEnd, array2D &ma } } -void calcFrameBrightnessFactor(unsigned int frame, uint32_t datalen, LUT *histo[4], float brightnessFactor[4]) +void calcFrameBrightnessFactor(unsigned int frame, uint32_t datalen, LUTu *histo[4], float brightnessFactor[4]) { float medians[4]; @@ -300,7 +297,7 @@ using namespace std; using namespace rtengine; void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RAWParams::BayerSensor &bayerParamsIn, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection) { - +BENCHFUN if(numFrames != 4) { // fallback for non pixelshift files amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue); return; @@ -308,23 +305,24 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA RAWParams::BayerSensor bayerParams = bayerParamsIn; - bayerParams.pixelShiftAutomatic = true; + bool motionDetection = true; if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO) { bool pixelShiftEqualBright = bayerParams.pixelShiftEqualBright; bayerParams.setPixelShiftDefaults(); bayerParams.pixelShiftEqualBright = pixelShiftEqualBright; } else if(bayerParams.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::OFF) { - bayerParams.pixelShiftAutomatic = false; + motionDetection = false; bayerParams.pixelShiftShowMotion = false; } const bool showMotion = bayerParams.pixelShiftShowMotion; const bool showOnlyMask = bayerParams.pixelShiftShowMotionMaskOnly && showMotion; + const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; - if(bayerParams.pixelShiftAutomatic) { + if(motionDetection) { if(!showOnlyMask) { - if(bayerParams.pixelShiftMedian) { // We need the amaze demosaiced frames for motion correction + if(bayerParams.pixelShiftMedian) { // We need the demosaiced frames for motion correction if(bayerParams.pixelShiftLmmse) { lmmse_interpolate_omp(winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.lmmse_iterations); } else { @@ -370,7 +368,6 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } } - const bool adaptive = bayerParams.pixelShiftAutomatic; constexpr float stddevFactorGreen = 25.f; constexpr float stddevFactorRed = 25.f; constexpr float stddevFactorBlue = 25.f; @@ -382,12 +379,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA constexpr float greenWeight = 2.f; const bool blurMap = bayerParams.pixelShiftBlur; const float sigma = bayerParams.pixelShiftSigma; - constexpr float threshold = 3.f + 9.f; + constexpr float noMotion = 0.99f; + constexpr float threshold = 3.f + 9 * noMotion; const bool holeFill = bayerParams.pixelShiftHoleFill; const bool equalBrightness = bayerParams.pixelShiftEqualBright; const bool equalChannel = bayerParams.pixelShiftEqualBrightChannel; - const bool smoothTransitions = blurMap && bayerParams.pixelShiftSmoothFactor > 0. && !showOnlyMask; - const float smoothFactor = 1.0 - bayerParams.pixelShiftSmoothFactor; + const bool smoothTransitions = blurMap && bayerParams.pixelShiftSmoothFactor > 0.; static const float nReadK3II[] = { 3.4f, // ISO 100 3.1f, // ISO 125 @@ -421,6 +418,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA static const float ePerIsoK3II = 0.35f; + // currently we use the same values for K-1 and K-1 Mark II, though for the K-1 Mark II the values seem a bit aggressive static const float nReadK1[] = { 3.45f, // ISO 100 3.15f, // ISO 125 3.45f, // ISO 160 @@ -454,15 +452,21 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA 2.4f, // ISO 102400 2.4f, // ISO 128000 2.4f, // ISO 160000 - 2.4f // ISO 204800 + 2.4f, // ISO 204800 + 2.4f, // ISO 256000 // these are for K-1 Mark II to avoid crashes when using high-ISO files + 2.4f, // ISO 320000 + 2.4f, // ISO 409600 + 2.4f, // ISO 512000 + 2.4f, // ISO 640000 + 2.4f // ISO 819200 }; static const float ePerIsoK1 = 0.75f; // currently nReadK70 is used for K-70 and KP - static const float nReadK70[] = { 4.0f, // ISO 100 - 4.0f, // ISO 125 - 4.0f, // ISO 160 + static const float nReadK70[] = { 4.0f, // ISO 100 + 4.0f, // ISO 125 + 4.0f, // ISO 160 4.0f, // ISO 200 4.0f, // ISO 250 4.0f, // ISO 320 @@ -504,40 +508,41 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA static const float ePerIsoK70 = 0.5f; - // preliminary ILCE-7RM3 data, good fidelity except from A) small innaccuracy at places - // due to integer scaling quantization, B) much different noise behavior of PDAF pixels + // preliminary ILCE-7RM3 data, good fidelity except from A) small inaccuracy at places + // due to integer scaling quantization, B) much different noise behaviour of PDAF pixels static const float nReadILCE7RM3[] = { 4.2f, // ISO 100 - 3.9f, // ISO 125 - 3.6f, // ISO 160 - 3.55f, // ISO 200 - 3.5f, // ISO 250 - 3.45f, // ISO 320 - 3.35f, // ISO 400 - 3.3f, // ISO 500 - 1.3f, // ISO 640 - 1.2f, // ISO 800 - 1.2f, // ISO 1000 - 1.2f, // ISO 1250 - 1.15f, // ISO 1600 - 1.2f, // ISO 2000 - 1.15f, // ISO 2500 - 1.15f, // ISO 3200 - 1.1f, // ISO 4000 - 1.1f, // ISO 5000 - 1.05f, // ISO 6400 - 1.05f, // ISO 8000 - 1.05f, // ISO 10000 - 1.0f, // ISO 12800 - 1.0f, // ISO 16000 - 1.0f, // ISO 20000 - 1.0f, // ISO 25600 - 1.0f, // ISO 32000 - 1.0f, // ISO 40000 - 1.0f, // ISO 51200 - 1.1f, // ISO 64000 - 1.1f, // ISO 80000 - 1.1f, // ISO 102400 - }; + 3.9f, // ISO 125 + 3.6f, // ISO 160 + 3.55f, // ISO 200 + 3.5f, // ISO 250 + 3.45f, // ISO 320 + 3.35f, // ISO 400 + 3.3f, // ISO 500 + 1.3f, // ISO 640 + 1.2f, // ISO 800 + 1.2f, // ISO 1000 + 1.2f, // ISO 1250 + 1.15f, // ISO 1600 + 1.2f, // ISO 2000 + 1.15f, // ISO 2500 + 1.15f, // ISO 3200 + 1.1f, // ISO 4000 + 1.1f, // ISO 5000 + 1.05f, // ISO 6400 + 1.05f, // ISO 8000 + 1.05f, // ISO 10000 + 1.0f, // ISO 12800 + 1.0f, // ISO 16000 + 1.0f, // ISO 20000 + 1.0f, // ISO 25600 + 1.0f, // ISO 32000 + 1.0f, // ISO 40000 + 1.0f, // ISO 51200 + 1.1f, // ISO 64000 + 1.1f, // ISO 80000 + 1.1f, // ISO 102400 + }; + static const float ePerIsoILCE7RM3 = 0.8f; if(plistener) { @@ -545,7 +550,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA plistener->setProgress(0.0); } - if(adaptive && blurMap && smoothFactor == 0.f && !showMotion) { + if(motionDetection && blurMap && smoothFactor == 0.f && !showMotion) { if(plistener) { plistener->setProgress(1.0); } @@ -553,8 +558,6 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA return; } - const float scaleGreen = 1.f / scale_mul[1]; - float nRead; float eperIsoModel; @@ -563,7 +566,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA if(model.find("K-3") != string::npos) { nRead = nReadK3II[nReadIndex]; eperIsoModel = ePerIsoK3II; - } else if(model.find("K-1") != string::npos) { + } else if(model.find("K-1") != string::npos) { // this also matches K-1 Mark II nRead = nReadK1[nReadIndex]; eperIsoModel = ePerIsoK1; } else if(model.find("ILCE-7RM3") != string::npos) { @@ -574,12 +577,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA eperIsoModel = ePerIsoK70; } - eperIsoModel *= pow(2.f, eperIso); + eperIsoModel *= pow(2.f, eperIso - 1.f); eperIso = eperIsoModel * (100.f / (rawWpCorrection * idata->getISOSpeed())); const float eperIsoRed = (eperIso / scale_mul[0]) * (65535.f / (c_white[0] - c_black[0])); - const float eperIsoGreen = (eperIso * scaleGreen) * (65535.f / (c_white[1] - c_black[1])); + const float eperIsoGreen = (eperIso / scale_mul[1]) * (65535.f / (c_white[1] - c_black[1])); const float eperIsoBlue = (eperIso / scale_mul[2]) * (65535.f / (c_white[2] - c_black[2])); const float clippedRed = 65535.f / scale_mul[0]; @@ -587,41 +590,35 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA nRead *= nRead; - // calculate average green brightness for each frame + // calculate channel median brightness for each frame float greenBrightness[4] = {1.f, 1.f, 1.f, 1.f}; float redBrightness[4] = {1.f, 1.f, 1.f, 1.f}; float blueBrightness[4] = {1.f, 1.f, 1.f, 1.f}; if(equalBrightness) { if(rawDirty) { - LUT *histogreen[4]; - LUT *histored[4]; - LUT *histoblue[4]; + LUTu *histogreen[4]; + LUTu *histored[4]; + LUTu *histoblue[4]; for(int i = 0; i < 4; ++i) { - histogreen[i] = new LUT(65536); - histogreen[i]->clear(); - histored[i] = new LUT(65536); - histored[i]->clear(); - histoblue[i] = new LUT(65536); - histoblue[i]->clear(); + histogreen[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + histored[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + histoblue[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); } #ifdef _OPENMP #pragma omp parallel #endif { - LUT *histogreenThr[4]; - LUT *historedThr[4]; - LUT *histoblueThr[4]; + LUTu *histogreenThr[4]; + LUTu *historedThr[4]; + LUTu *histoblueThr[4]; for(int i = 0; i < 4; ++i) { - histogreenThr[i] = new LUT(65536); - histogreenThr[i]->clear(); - historedThr[i] = new LUT(65536); - historedThr[i]->clear(); - histoblueThr[i] = new LUT(65536); - histoblueThr[i]->clear(); + histogreenThr[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + historedThr[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + histoblueThr[i] = new LUTu(65536, LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); } #ifdef _OPENMP @@ -698,7 +695,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } - if(adaptive) { + if(motionDetection) { // fill channels psRed and psBlue array2D psRed(winw + 32, winh); // increase width to avoid cache conflicts array2D psBlue(winw + 32, winh); @@ -711,8 +708,8 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA float *nonGreenDest0 = psRed[i]; float *nonGreenDest1 = psBlue[i]; float ngbright[2][4] = {{redBrightness[0], redBrightness[1], redBrightness[2], redBrightness[3]}, - {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} - }; + {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} + }; int ng = 0; int j = winx + 1; int c = FC(i, j); @@ -775,7 +772,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA unsigned int offset = FC(i, winx + border - offsX) & 1; for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { - psMask[i][j] = 1.f; + psMask[i][j] = noMotion; if(checkGreen) { if(greenDiff((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset], (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset], stddevFactorGreen, eperIsoGreen, nRead, prnu) > 0.f) { @@ -787,12 +784,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA if(checkNonGreenCross) { // check red cross - float redTop = psRed[i - 1][ j ]; - float redLeft = psRed[ i ][j - 1]; - float redCentre = psRed[ i ][ j ]; - float redRight = psRed[ i ][j + 1]; - float redBottom = psRed[i + 1][ j ]; - float redDiff = nonGreenDiffCross(redRight, redLeft, redTop, redBottom, redCentre, clippedRed, stddevFactorRed, eperIsoRed, nRead, prnu); + float redTop = psRed[i - 1][j]; + float redLeft = psRed[i][j - 1]; + float redCentre = psRed[i][j]; + float redRight = psRed[i][j + 1]; + float redBottom = psRed[i + 1][j]; + float redDiff = nonGreenDiffCross(redRight, redLeft, redTop, redBottom, redCentre, clippedRed, stddevFactorRed, eperIsoRed, nRead, prnu); if(redDiff > 0.f) { psMask[i][j] = redBlueWeight; @@ -800,12 +797,12 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } // check blue cross - float blueTop = psBlue[i - 1][ j ]; - float blueLeft = psBlue[ i ][j - 1]; - float blueCentre = psBlue[ i ][ j ]; - float blueRight = psBlue[ i ][j + 1]; - float blueBottom = psBlue[i + 1][ j ]; - float blueDiff = nonGreenDiffCross(blueRight, blueLeft, blueTop, blueBottom, blueCentre, clippedBlue, stddevFactorBlue, eperIsoBlue, nRead, prnu); + float blueTop = psBlue[i - 1][j]; + float blueLeft = psBlue[i][j - 1]; + float blueCentre = psBlue[i][j]; + float blueRight = psBlue[i][j + 1]; + float blueBottom = psBlue[i + 1][j]; + float blueDiff = nonGreenDiffCross(blueRight, blueLeft, blueTop, blueBottom, blueCentre, clippedBlue, stddevFactorBlue, eperIsoBlue, nRead, prnu); if(blueDiff > 0.f) { psMask[i][j] = redBlueWeight; @@ -829,7 +826,6 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA if(plistener) { plistener->setProgress(0.6); } - } array2D mask(winw, winh, ARRAY2D_CLEAR_DATA); @@ -885,7 +881,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA for(int i = winy + border - offsY; i < winh - (border + offsY); ++i) { #ifdef __SSE2__ - // pow() is expensive => precalculate blend factor using SSE + // pow() is expensive => pre calculate blend factor using SSE if(smoothTransitions) { // vfloat onev = F2V(1.f); vfloat smoothv = F2V(smoothFactor); @@ -912,38 +908,34 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA unsigned int offset = FC(i, winx + border - offsX) & 1; for(int j = winx + border - offsX; j < winw - (border + offsX); ++j, offset ^= 1) { - if(mask[i][j] == 255) { - paintMotionMask(j + offsX, showMotion, showOnlyMask, greenDest, redDest, blueDest); - } else if(showOnlyMask) { // we want only motion mask => paint areas without motion in pure black - redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = 0.f; - } else { - if(smoothTransitions) { + if(showOnlyMask) { + if(smoothTransitions) { // we want only motion mask => paint areas according to their motion (dark = no motion, bright = motion) #ifdef __SSE2__ - // use precalculated blend factor + // use pre calculated blend factor const float blend = psMask[i][j]; #else const float blend = smoothFactor == 0.f ? 1.f : pow_F(std::max(psMask[i][j] - 1.f, 0.f), smoothFactor); #endif - redDest[j + offsX] = intp(blend, redDest[j + offsX], psRed[i][j] ); - if(bayerParams.pixelShiftOneGreen) { - int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset; - int greenJ = (1 - offset != 0) ? j : j + 1; - int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset; - greenDest[j + offsX] = intp(blend, greenDest[j + offsX], (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]); - } else { - greenDest[j + offsX] = intp(blend, greenDest[j + offsX], ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f); - } - blueDest[j + offsX] = intp(blend, blueDest[j + offsX], psBlue[i][j]); + redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = blend * 32768.f; + } else { + redDest[j + offsX] = greenDest[j + offsX] = blueDest[j + offsX] = mask[i][j] == 255 ? 65535.f : 0.f; + } + } else if(mask[i][j] == 255) { + paintMotionMask(j + offsX, showMotion, greenDest, redDest, blueDest); + } else { + if(smoothTransitions) { +#ifdef __SSE2__ + // use pre calculated blend factor + const float blend = psMask[i][j]; +#else + const float blend = smoothFactor == 0.f ? 1.f : pow_F(std::max(psMask[i][j] - 1.f, 0.f), smoothFactor); +#endif + redDest[j + offsX] = intp(blend, showMotion ? 0.f : redDest[j + offsX], psRed[i][j] ); + greenDest[j + offsX] = intp(blend, showMotion ? 13500.f : greenDest[j + offsX], ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f); + blueDest[j + offsX] = intp(blend, showMotion ? 0.f : blueDest[j + offsX], psBlue[i][j]); } else { redDest[j + offsX] = psRed[i][j]; - if(bayerParams.pixelShiftOneGreen) { - int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset; - int greenJ = (1 - offset != 0) ? j : j + 1; - int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset; - greenDest[j + offsX] = (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]; - } else { - greenDest[j + offsX] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; - } + greenDest[j + offsX] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; blueDest[j + offsX] = psBlue[i][j]; } } @@ -952,7 +944,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA } else { // motion detection off => combine the 4 raw frames float ngbright[2][4] = {{redBrightness[0], redBrightness[1], redBrightness[2], redBrightness[3]}, - {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} + {blueBrightness[0], blueBrightness[1], blueBrightness[2], blueBrightness[3]} }; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -976,14 +968,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA for(; j < winw - 1; ++j) { // set red, green and blue values - if(bayerParams.pixelShiftOneGreen) { - int greenFrame = (1 - offset != 0) ? 1 - offset : 3 - offset; - int greenJ = (1 - offset != 0) ? j : j + 1; - int greenI = (1 - offset != 0) ? i - offset + 1 : i + offset; - green[i][j] = (*rawDataFrames[greenFrame])[greenI][greenJ] * greenBrightness[greenFrame]; - } else { - green[i][j] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; - } + green[i][j] = ((*rawDataFrames[1 - offset])[i - offset + 1][j] * greenBrightness[1 - offset] + (*rawDataFrames[3 - offset])[i + offset][j + 1] * greenBrightness[3 - offset]) * 0.5f; nonGreenDest0[j] = (*rawDataFrames[(offset << 1) + offset])[i][j + offset] * ngbright[ng][(offset << 1) + offset]; nonGreenDest1[j] = (*rawDataFrames[2 - offset])[i + 1][j - offset + 1] * ngbright[ng ^ 1][2 - offset]; offset ^= 1; // 0 => 1 or 1 => 0 diff --git a/rtengine/procevents.h b/rtengine/procevents.h index f5751c7d0..a35a709f9 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -472,31 +472,31 @@ enum ProcEventCode { EvOBPCompens = 442, EvWBtempBias = 443, EvRawImageNum = 444, - EvPixelShiftMotion = 445, - EvPixelShiftMotionCorrection = 446, - EvPixelShiftStddevFactorGreen = 447, +// EvPixelShiftMotion = 445, +// EvPixelShiftMotionCorrection = 446, +// EvPixelShiftStddevFactorGreen = 447, EvPixelShiftEperIso = 448, - EvPixelShiftNreadIso = 449, - EvPixelShiftPrnu = 450, +// EvPixelShiftNreadIso = 449, +// EvPixelShiftPrnu = 450, EvPixelshiftShowMotion = 451, EvPixelshiftShowMotionMaskOnly = 452, - EvPixelShiftAutomatic = 453, - EvPixelShiftNonGreenHorizontal = 454, - EvPixelShiftNonGreenVertical = 455, +// EvPixelShiftAutomatic = 453, +// EvPixelShiftNonGreenHorizontal = 454, +// EvPixelShiftNonGreenVertical = 455, EvPixelShiftNonGreenCross = 456, - EvPixelShiftStddevFactorRed = 457, - EvPixelShiftStddevFactorBlue = 458, - EvPixelShiftGreenAmaze = 459, - EvPixelShiftNonGreenAmaze = 460, +// EvPixelShiftStddevFactorRed = 457, +// EvPixelShiftStddevFactorBlue = 458, +// EvPixelShiftGreenAmaze = 459, +// EvPixelShiftNonGreenAmaze = 460, EvPixelShiftGreen = 461, - EvPixelShiftRedBlueWeight = 462, +// EvPixelShiftRedBlueWeight = 462, EvPixelShiftBlur = 463, EvPixelShiftSigma = 464, - EvPixelShiftSum = 465, - EvPixelShiftExp0 = 466, +// EvPixelShiftSum = 465, +// EvPixelShiftExp0 = 466, EvPixelShiftHoleFill = 467, EvPixelShiftMedian = 468, - EvPixelShiftMedian3 = 469, +// EvPixelShiftMedian3 = 469, EvPixelShiftMotionMethod = 470, EvPixelShiftSmooth = 471, EvPixelShiftLmmse = 472, @@ -520,7 +520,7 @@ enum ProcEventCode { EvWBEnabled = 490, EvRGBEnabled = 491, EvLEnabled = 492, - EvPixelShiftOneGreen = 493, +// EvPixelShiftOneGreen = 493, can be reused NUMOFEVENTS diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index fa8b3a1d7..d37bd3379 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2370,37 +2370,20 @@ RAWParams::BayerSensor::BayerSensor() : greenthresh(0), dcb_iterations(2), lmmse_iterations(2), - pixelShiftMotion(0), - pixelShiftMotionCorrection(PSMotionCorrection::GRID_3X3_NEW), pixelShiftMotionCorrectionMethod(PSMotionCorrectionMethod::AUTO), - pixelShiftStddevFactorGreen(5.0), - pixelShiftStddevFactorRed(5.0), - pixelShiftStddevFactorBlue(5.0), pixelShiftEperIso(0.0), - pixelShiftNreadIso(0.0), - pixelShiftPrnu(1.0), pixelShiftSigma(1.0), - pixelShiftSum(3.0), - pixelShiftRedBlueWeight(0.7), pixelShiftShowMotion(false), pixelShiftShowMotionMaskOnly(false), - pixelShiftAutomatic(true), - pixelShiftNonGreenHorizontal(false), - pixelShiftNonGreenVertical(false), pixelShiftHoleFill(true), pixelShiftMedian(false), - pixelShiftMedian3(false), pixelShiftGreen(true), pixelShiftBlur(true), pixelShiftSmoothFactor(0.7), - pixelShiftExp0(false), pixelShiftLmmse(false), - pixelShiftOneGreen(false), pixelShiftEqualBright(false), pixelShiftEqualBrightChannel(false), pixelShiftNonGreenCross(true), - pixelShiftNonGreenCross2(false), - pixelShiftNonGreenAmaze(false), dcb_enhance(true), pdafLinesFilter(false) { @@ -2422,37 +2405,20 @@ bool RAWParams::BayerSensor::operator ==(const BayerSensor& other) const && greenthresh == other.greenthresh && dcb_iterations == other.dcb_iterations && lmmse_iterations == other.lmmse_iterations - && pixelShiftMotion == other.pixelShiftMotion - && pixelShiftMotionCorrection == other.pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod == other.pixelShiftMotionCorrectionMethod - && pixelShiftStddevFactorGreen == other.pixelShiftStddevFactorGreen - && pixelShiftStddevFactorRed == other.pixelShiftStddevFactorRed - && pixelShiftStddevFactorBlue == other.pixelShiftStddevFactorBlue && pixelShiftEperIso == other.pixelShiftEperIso - && pixelShiftNreadIso == other.pixelShiftNreadIso - && pixelShiftPrnu == other.pixelShiftPrnu && pixelShiftSigma == other.pixelShiftSigma - && pixelShiftSum == other.pixelShiftSum - && pixelShiftRedBlueWeight == other.pixelShiftRedBlueWeight && pixelShiftShowMotion == other.pixelShiftShowMotion && pixelShiftShowMotionMaskOnly == other.pixelShiftShowMotionMaskOnly - && pixelShiftAutomatic == other.pixelShiftAutomatic - && pixelShiftNonGreenHorizontal == other.pixelShiftNonGreenHorizontal - && pixelShiftNonGreenVertical == other.pixelShiftNonGreenVertical && pixelShiftHoleFill == other.pixelShiftHoleFill && pixelShiftMedian == other.pixelShiftMedian - && pixelShiftMedian3 == other.pixelShiftMedian3 && pixelShiftGreen == other.pixelShiftGreen && pixelShiftBlur == other.pixelShiftBlur && pixelShiftSmoothFactor == other.pixelShiftSmoothFactor - && pixelShiftExp0 == other.pixelShiftExp0 && pixelShiftLmmse == other.pixelShiftLmmse - && pixelShiftOneGreen == other.pixelShiftOneGreen && pixelShiftEqualBright == other.pixelShiftEqualBright && pixelShiftEqualBrightChannel == other.pixelShiftEqualBrightChannel && pixelShiftNonGreenCross == other.pixelShiftNonGreenCross - && pixelShiftNonGreenCross2 == other.pixelShiftNonGreenCross2 - && pixelShiftNonGreenAmaze == other.pixelShiftNonGreenAmaze && dcb_enhance == other.dcb_enhance && pdafLinesFilter == other.pdafLinesFilter; } @@ -2464,35 +2430,18 @@ bool RAWParams::BayerSensor::operator !=(const BayerSensor& other) const void RAWParams::BayerSensor::setPixelShiftDefaults() { - pixelShiftMotion = 0; - pixelShiftMotionCorrection = RAWParams::BayerSensor::PSMotionCorrection::GRID_3X3_NEW; pixelShiftMotionCorrectionMethod = RAWParams::BayerSensor::PSMotionCorrectionMethod::AUTO; - pixelShiftStddevFactorGreen = 5.0; - pixelShiftStddevFactorRed = 5.0; - pixelShiftStddevFactorBlue = 5.0; pixelShiftEperIso = 0.0; - pixelShiftNreadIso = 0.0; - pixelShiftPrnu = 1.0; pixelShiftSigma = 1.0; - pixelShiftSum = 3.0; - pixelShiftRedBlueWeight = 0.7; - pixelShiftAutomatic = true; - pixelShiftNonGreenHorizontal = false; - pixelShiftNonGreenVertical = false; pixelShiftHoleFill = true; pixelShiftMedian = false; - pixelShiftMedian3 = false; pixelShiftGreen = true; pixelShiftBlur = true; pixelShiftSmoothFactor = 0.7; - pixelShiftExp0 = false; pixelShiftLmmse = false; - pixelShiftOneGreen = false; pixelShiftEqualBright = false; pixelShiftEqualBrightChannel = false; pixelShiftNonGreenCross = true; - pixelShiftNonGreenCross2 = false; - pixelShiftNonGreenAmaze = false; } const std::vector& RAWParams::BayerSensor::getMethodStrings() @@ -3397,37 +3346,20 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbIterations, "RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.dcbEnhance, "RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.lmmseIterations, "RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotion, "RAW Bayer", "PixelShiftMotion", raw.bayersensor.pixelShiftMotion, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrection, "RAW Bayer", "PixelShiftMotionCorrection", toUnderlying(raw.bayersensor.pixelShiftMotionCorrection), keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod, "RAW Bayer", "PixelShiftMotionCorrectionMethod", toUnderlying(raw.bayersensor.pixelShiftMotionCorrectionMethod), keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftStddevFactorGreen, "RAW Bayer", "pixelShiftStddevFactorGreen", raw.bayersensor.pixelShiftStddevFactorGreen, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftStddevFactorRed, "RAW Bayer", "pixelShiftStddevFactorRed", raw.bayersensor.pixelShiftStddevFactorRed, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftStddevFactorBlue, "RAW Bayer", "pixelShiftStddevFactorBlue", raw.bayersensor.pixelShiftStddevFactorBlue, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEperIso, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNreadIso, "RAW Bayer", "PixelShiftNreadIso", raw.bayersensor.pixelShiftNreadIso, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftPrnu, "RAW Bayer", "PixelShiftPrnu", raw.bayersensor.pixelShiftPrnu, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSigma, "RAW Bayer", "PixelShiftSigma", raw.bayersensor.pixelShiftSigma, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSum, "RAW Bayer", "PixelShiftSum", raw.bayersensor.pixelShiftSum, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftRedBlueWeight, "RAW Bayer", "PixelShiftRedBlueWeight", raw.bayersensor.pixelShiftRedBlueWeight, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotion, "RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelShiftShowMotion, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly, "RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelShiftShowMotionMaskOnly, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftAutomatic, "RAW Bayer", "pixelShiftAutomatic", raw.bayersensor.pixelShiftAutomatic, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenHorizontal, "RAW Bayer", "pixelShiftNonGreenHorizontal", raw.bayersensor.pixelShiftNonGreenHorizontal, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenVertical, "RAW Bayer", "pixelShiftNonGreenVertical", raw.bayersensor.pixelShiftNonGreenVertical, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftHoleFill, "RAW Bayer", "pixelShiftHoleFill", raw.bayersensor.pixelShiftHoleFill, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian, "RAW Bayer", "pixelShiftMedian", raw.bayersensor.pixelShiftMedian, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftMedian3, "RAW Bayer", "pixelShiftMedian3", raw.bayersensor.pixelShiftMedian3, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftGreen, "RAW Bayer", "pixelShiftGreen", raw.bayersensor.pixelShiftGreen, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftBlur, "RAW Bayer", "pixelShiftBlur", raw.bayersensor.pixelShiftBlur, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftSmooth, "RAW Bayer", "pixelShiftSmoothFactor", raw.bayersensor.pixelShiftSmoothFactor, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftExp0, "RAW Bayer", "pixelShiftExp0", raw.bayersensor.pixelShiftExp0, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftLmmse, "RAW Bayer", "pixelShiftLmmse", raw.bayersensor.pixelShiftLmmse, keyFile); -// saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftOneGreen, "RAW Bayer", "pixelShiftOneGreen", raw.bayersensor.pixelShiftOneGreen, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBright, "RAW Bayer", "pixelShiftEqualBright", raw.bayersensor.pixelShiftEqualBright, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftEqualBrightChannel, "RAW Bayer", "pixelShiftEqualBrightChannel", raw.bayersensor.pixelShiftEqualBrightChannel, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross, "RAW Bayer", "pixelShiftNonGreenCross", raw.bayersensor.pixelShiftNonGreenCross, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenCross2, "RAW Bayer", "pixelShiftNonGreenCross2", raw.bayersensor.pixelShiftNonGreenCross2, keyFile); - saveToKeyfile(!pedited || pedited->raw.bayersensor.pixelShiftNonGreenAmaze, "RAW Bayer", "pixelShiftNonGreenAmaze", raw.bayersensor.pixelShiftNonGreenAmaze, keyFile); saveToKeyfile(!pedited || pedited->raw.bayersensor.pdafLinesFilter, "RAW Bayer", "PDAFLinesFilter", raw.bayersensor.pdafLinesFilter, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.method, "RAW X-Trans", "Method", raw.xtranssensor.method, keyFile); saveToKeyfile(!pedited || pedited->raw.xtranssensor.ccSteps, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, keyFile); @@ -4757,15 +4689,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftMotion", pedited, raw.bayersensor.pixelShiftMotion, pedited->raw.bayersensor.pixelShiftMotion); - - if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrection")) { - raw.bayersensor.pixelShiftMotionCorrection = (RAWParams::BayerSensor::PSMotionCorrection)keyFile.get_integer("RAW Bayer", "PixelShiftMotionCorrection"); - - if (pedited) { - pedited->raw.bayersensor.pixelShiftMotionCorrection = true; - } - } if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) { raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)keyFile.get_integer("RAW Bayer", "PixelShiftMotionCorrectionMethod"); @@ -4775,34 +4698,22 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftStddevFactorGreen", pedited, raw.bayersensor.pixelShiftStddevFactorGreen, pedited->raw.bayersensor.pixelShiftStddevFactorGreen); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftStddevFactorRed", pedited, raw.bayersensor.pixelShiftStddevFactorRed, pedited->raw.bayersensor.pixelShiftStddevFactorRed); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftStddevFactorBlue", pedited, raw.bayersensor.pixelShiftStddevFactorBlue, pedited->raw.bayersensor.pixelShiftStddevFactorBlue); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftEperIso", pedited, raw.bayersensor.pixelShiftEperIso, pedited->raw.bayersensor.pixelShiftEperIso); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftNreadIso", pedited, raw.bayersensor.pixelShiftNreadIso, pedited->raw.bayersensor.pixelShiftNreadIso); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftPrnu", pedited, raw.bayersensor.pixelShiftPrnu, pedited->raw.bayersensor.pixelShiftPrnu); + if (ppVersion < 332) { + raw.bayersensor.pixelShiftEperIso += 1.0; + } assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSigma", pedited, raw.bayersensor.pixelShiftSigma, pedited->raw.bayersensor.pixelShiftSigma); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSum", pedited, raw.bayersensor.pixelShiftSum, pedited->raw.bayersensor.pixelShiftSum); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftRedBlueWeight", pedited, raw.bayersensor.pixelShiftRedBlueWeight, pedited->raw.bayersensor.pixelShiftRedBlueWeight); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", pedited, raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion); assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", pedited, raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftAutomatic", pedited, raw.bayersensor.pixelShiftAutomatic, pedited->raw.bayersensor.pixelShiftAutomatic); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenHorizontal", pedited, raw.bayersensor.pixelShiftNonGreenHorizontal, pedited->raw.bayersensor.pixelShiftNonGreenHorizontal); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenVertical", pedited, raw.bayersensor.pixelShiftNonGreenVertical, pedited->raw.bayersensor.pixelShiftNonGreenVertical); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftHoleFill", pedited, raw.bayersensor.pixelShiftHoleFill, pedited->raw.bayersensor.pixelShiftHoleFill); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian", pedited, raw.bayersensor.pixelShiftMedian, pedited->raw.bayersensor.pixelShiftMedian); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian3", pedited, raw.bayersensor.pixelShiftMedian3, pedited->raw.bayersensor.pixelShiftMedian3); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftGreen", pedited, raw.bayersensor.pixelShiftGreen, pedited->raw.bayersensor.pixelShiftGreen); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftBlur", pedited, raw.bayersensor.pixelShiftBlur, pedited->raw.bayersensor.pixelShiftBlur); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", pedited, raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftExp0", pedited, raw.bayersensor.pixelShiftExp0, pedited->raw.bayersensor.pixelShiftExp0); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftLmmse", pedited, raw.bayersensor.pixelShiftLmmse, pedited->raw.bayersensor.pixelShiftLmmse); -// assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftOneGreen", pedited, raw.bayersensor.pixelShiftOneGreen, pedited->raw.bayersensor.pixelShiftOneGreen); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", pedited, raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", pedited, raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel); assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", pedited, raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross2", pedited, raw.bayersensor.pixelShiftNonGreenCross2, pedited->raw.bayersensor.pixelShiftNonGreenCross2); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenAmaze", pedited, raw.bayersensor.pixelShiftNonGreenAmaze, pedited->raw.bayersensor.pixelShiftNonGreenAmaze); assignFromKeyfile(keyFile, "RAW Bayer", "PDAFLinesFilter", pedited, raw.bayersensor.pdafLinesFilter, pedited->raw.bayersensor.pdafLinesFilter); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 8d3d6d10b..2e7d17561 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1237,15 +1237,6 @@ struct RAWParams { PIXELSHIFT }; - enum class PSMotionCorrection { - GRID_1X1, - GRID_1X2, - GRID_3X3, - GRID_5X5, - GRID_7X7, - GRID_3X3_NEW - }; - enum class PSMotionCorrectionMethod { OFF, AUTO, @@ -1271,37 +1262,20 @@ struct RAWParams { int greenthresh; int dcb_iterations; int lmmse_iterations; - int pixelShiftMotion; - PSMotionCorrection pixelShiftMotionCorrection; PSMotionCorrectionMethod pixelShiftMotionCorrectionMethod; - double pixelShiftStddevFactorGreen; - double pixelShiftStddevFactorRed; - double pixelShiftStddevFactorBlue; double pixelShiftEperIso; - double pixelShiftNreadIso; - double pixelShiftPrnu; double pixelShiftSigma; - double pixelShiftSum; - double pixelShiftRedBlueWeight; bool pixelShiftShowMotion; bool pixelShiftShowMotionMaskOnly; - bool pixelShiftAutomatic; - bool pixelShiftNonGreenHorizontal; - bool pixelShiftNonGreenVertical; bool pixelShiftHoleFill; bool pixelShiftMedian; - bool pixelShiftMedian3; bool pixelShiftGreen; bool pixelShiftBlur; double pixelShiftSmoothFactor; - bool pixelShiftExp0; bool pixelShiftLmmse; - bool pixelShiftOneGreen; bool pixelShiftEqualBright; bool pixelShiftEqualBrightChannel; bool pixelShiftNonGreenCross; - bool pixelShiftNonGreenCross2; - bool pixelShiftNonGreenAmaze; bool dcb_enhance; bool pdafLinesFilter; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index b467c5564..89ddbceb2 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -472,36 +472,36 @@ int refreshmap[rtengine::NUMOFEVENTS] = { OUTPUTPROFILE, // EvOBPCompens ALLNORAW, // EvWBtempBias DARKFRAME, // EvRawImageNum - DEMOSAIC, // EvPixelShiftMotion - DEMOSAIC, // EvPixelShiftMotionCorrection - DEMOSAIC, // EvPixelShiftStddevFactorGreen + 0, // unused + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftEperIso - DEMOSAIC, // EvPixelShiftNreadIso - DEMOSAIC, // EvPixelShiftPrnu + 0, // unused + 0, // unused DEMOSAIC, // EvPixelshiftShowMotion DEMOSAIC, // EvPixelshiftShowMotionMaskOnly - DEMOSAIC, // EvPixelShiftAutomatic - DEMOSAIC, // EvPixelShiftNonGreenHorizontal - DEMOSAIC, // EvPixelShiftNonGreenVertical + 0, // unused + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftNonGreenCross - DEMOSAIC, // EvPixelShiftStddevFactorRed - DEMOSAIC, // EvPixelShiftStddevFactorBlue - DEMOSAIC, // EvPixelShiftNonGreenCross2 - DEMOSAIC, // EvPixelShiftNonGreenAmaze + 0, // unused + 0, // unused + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftGreen - DEMOSAIC, // EvPixelShiftRedBlueWeight + 0, // unused DEMOSAIC, // EvPixelShiftBlur DEMOSAIC, // EvPixelShiftSigma - DEMOSAIC, // EvPixelShiftSum - DEMOSAIC, // EvPixelShiftExp0 + 0, // unused + 0, // unused DEMOSAIC, // EvPixelShiftHoleFill DEMOSAIC, // EvPixelShiftMedian - DEMOSAIC, // EvPixelShiftMedian3 + 0, // unused DEMOSAIC, // EvPixelShiftMotionMethod DEMOSAIC, // EvPixelShiftSmooth DEMOSAIC, // EvPixelShiftLmmse DEMOSAIC, // EvPixelShiftEqualBright - DEMOSAIC, // EvPixelShiftEqualBrightChannel + DEMOSAIC, // EvPixelShiftEqualBrightChannel LUMINANCECURVE, // EvCATtempout LUMINANCECURVE, // EvCATgreenout LUMINANCECURVE, // EvCATybout @@ -519,8 +519,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { HDR, // EvTMFattalAmount ALLNORAW, // EvWBEnabled RGBCURVE, // EvRGBEnabled - LUMINANCECURVE, // EvLEnabled - DEMOSAIC // EvPixelShiftOneGreen + LUMINANCECURVE // EvLEnabled }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 8722fd095..898e635d2 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -120,9 +120,12 @@ public: virtual std::string getOrientation (unsigned int frame = 0) const = 0; /** @return true if the file is a PixelShift shot (Pentax and Sony bodies) */ - virtual bool getPixelShift (unsigned int frame = 0) const = 0; + virtual bool getPixelShift () const = 0; /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ virtual bool getHDR (unsigned int frame = 0) const = 0; + + /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ + virtual std::string getImageType (unsigned int frame) const = 0; /** @return the sample format based on MetaData */ virtual IIOSampleFormat getSampleFormat (unsigned int frame = 0) const = 0; diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc new file mode 100644 index 000000000..a8e964ad0 --- /dev/null +++ b/rtengine/xtrans_demosaic.cc @@ -0,0 +1,1020 @@ +//////////////////////////////////////////////////////////////// +// +// Xtrans demosaic algorithm +// +// code dated: April 18, 2018 +// +// xtrans_demosaic.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include "rtengine.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "../rtgui/multilangmgr.h" +#include "opthelper.h" +#include "StopWatch.h" + +namespace rtengine +{ +const double xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } +}; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; + +void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) +{ + static LUTf cbrt(0x14000); + static bool cbrtinit = false; + + if (!rgb) { + if(!cbrtinit) { + for (int i = 0; i < 0x14000; i++) { + double r = i / 65535.0; + cbrt[i] = r > Color::eps ? std::cbrt(r) : (Color::kappa * r + 16.0) / 116.0; + } + + cbrtinit = true; + } + + return; + } + +#ifdef __SSE2__ + vfloat c116v = F2V(116.f); + vfloat c16v = F2V(16.f); + vfloat c500v = F2V(500.f); + vfloat c200v = F2V(200.f); + vfloat xyz_camv[3][3]; + + for(int i = 0; i < 3; i++) + for(int j = 0; j < 3; j++) { + xyz_camv[i][j] = F2V(xyz_cam[i][j]); + } + +#endif // __SSE2__ + + for(int i = 0; i < height; i++) { + int j = 0; +#ifdef __SSE2__ + + for(; j < labWidth - 3; j += 4) { + vfloat redv, greenv, bluev; + vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[i * width + j], redv, greenv, bluev); + vfloat xyz0v = redv * xyz_camv[0][0] + greenv * xyz_camv[0][1] + bluev * xyz_camv[0][2]; + vfloat xyz1v = redv * xyz_camv[1][0] + greenv * xyz_camv[1][1] + bluev * xyz_camv[1][2]; + vfloat xyz2v = redv * xyz_camv[2][0] + greenv * xyz_camv[2][1] + bluev * xyz_camv[2][2]; + xyz0v = cbrt[_mm_cvtps_epi32(xyz0v)]; + xyz1v = cbrt[_mm_cvtps_epi32(xyz1v)]; + xyz2v = cbrt[_mm_cvtps_epi32(xyz2v)]; + + STVFU(l[i * labWidth + j], c116v * xyz1v - c16v); + STVFU(a[i * labWidth + j], c500v * (xyz0v - xyz1v)); + STVFU(b[i * labWidth + j], c200v * (xyz1v - xyz2v)); + } + +#endif + + for(; j < labWidth; j++) { + float xyz[3] = {0.5f, 0.5f, 0.5f}; + + for(int c = 0; c < 3; c++) { + float val = rgb[i * width + j][c]; + xyz[0] += xyz_cam[0][c] * val; + xyz[1] += xyz_cam[1][c] * val; + xyz[2] += xyz_cam[2][c] * val; + } + + xyz[0] = cbrt[(int) xyz[0]]; + xyz[1] = cbrt[(int) xyz[1]]; + xyz[2] = cbrt[(int) xyz[2]]; + + l[i * labWidth + j] = 116 * xyz[1] - 16; + a[i * labWidth + j] = 500 * (xyz[0] - xyz[1]); + b[i * labWidth + j] = 200 * (xyz[1] - xyz[2]); + } + } +} + + +#define fcol(row,col) xtrans[(row)%6][(col)%6] +#define isgreen(row,col) (xtrans[(row)%3][(col)%3]&1) + +void RawImageSource::xtransborder_interpolate (int border) +{ + const int height = H, width = W; + + int xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) { + if (col == border && row >= border && row < height - border) { + col = width - border; + } + + float sum[6] = {0.f}; + + for (int y = MAX(0, row - 1); y <= MIN(row + 1, height - 1); y++) + for (int x = MAX(0, col - 1); x <= MIN(col + 1, width - 1); x++) { + int f = fcol(y, x); + sum[f] += rawData[y][x]; + sum[f + 3]++; + } + + switch(fcol(row, col)) { + case 0: + red[row][col] = rawData[row][col]; + green[row][col] = (sum[1] / sum[4]); + blue[row][col] = (sum[2] / sum[5]); + break; + + case 1: + if(sum[3] == 0.f) { // at the 4 corner pixels it can happen, that we have only green pixels in 2x2 area + red[row][col] = green[row][col] = blue[row][col] = rawData[row][col]; + } else { + red[row][col] = (sum[0] / sum[3]); + green[row][col] = rawData[row][col]; + blue[row][col] = (sum[2] / sum[5]); + } + + break; + + case 2: + red[row][col] = (sum[0] / sum[3]); + green[row][col] = (sum[1] / sum[4]); + blue[row][col] = rawData[row][col]; + } + } +} + +/* + Frank Markesteijn's algorithm for Fuji X-Trans sensors + adapted to RT by Ingo Weyrich 2014 +*/ +// override CLIP function to test unclipped output +#define CLIP(x) (x) +void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) +{ + BENCHFUN + constexpr int ts = 114; /* Tile Size */ + constexpr int tsh = ts / 2; /* half of Tile Size */ + + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "Xtrans")); + plistener->setProgress (progress); + } + + int xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + constexpr short orth[12] = { 1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1 }, + patt[2][16] = { { 0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0, 0, 0, 0 }, + { 0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1, -1, -1, 1 } + }, + dir[4] = { 1, ts, ts + 1, ts - 1 }; + + // sgrow/sgcol is the offset in the sensor matrix of the solitary + // green pixels + ushort sgrow = 0, sgcol = 0; + + const int height = H, width = W; + +// if (settings->verbose) { +// printf("%d-pass X-Trans interpolation using %s conversion...\n", passes, useCieLab ? "lab" : "yuv"); +// } + + xtransborder_interpolate(6); + + float xyz_cam[3][3]; + { + float rgb_cam[3][4]; + ri->getRgbCam(rgb_cam); + int k; + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (xyz_cam[i][j] = k = 0; k < 3; k++) { + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + } + } + + /* Map a green hexagon around each non-green pixel and vice versa: */ + short allhex[2][3][3][8]; + { + int gint, d, h, v, ng, row, col; + + for (row = 0; row < 3; row++) + for (col = 0; col < 3; col++) { + gint = isgreen(row, col); + + for (ng = d = 0; d < 10; d += 2) { + if (isgreen(row + orth[d] + 6, col + orth[d + 2] + 6)) { + ng = 0; + } else { + ng++; + } + + if (ng == 4) { + // if there are four non-green pixels adjacent in cardinal + // directions, this is the solitary green pixel + sgrow = row; + sgcol = col; + } + + if (ng == gint + 1) { + for (int c = 0; c < 8; c++) { + v = orth[d] * patt[gint][c * 2] + orth[d + 1] * patt[gint][c * 2 + 1]; + h = orth[d + 2] * patt[gint][c * 2] + orth[d + 3] * patt[gint][c * 2 + 1]; + allhex[0][row][col][c ^ (gint * 2 & d)] = h + v * width; + allhex[1][row][col][c ^ (gint * 2 & d)] = h + v * ts; + } + } + } + } + + } + + if(plistenerActive) { + progress += 0.05; + plistener->setProgress(progress); + } + + + double progressInc = 36.0 * (1.0 - progress) / ((H * W) / ((ts - 16) * (ts - 16))); + const int ndir = 4 << (passes > 1); + cielab (nullptr, nullptr, nullptr, nullptr, 0, 0, 0, nullptr); + struct s_minmaxgreen { + float min; + float max; + }; + + int RightShift[3]; + + for(int row = 0; row < 3; row++) { + // count number of green pixels in three cols + int greencount = 0; + + for(int col = 0; col < 3; col++) { + greencount += isgreen(row, col); + } + + RightShift[row] = (greencount == 2); + } + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + int progressCounter = 0; + int c; + float color[3][6]; + + float *buffer = (float *) malloc ((ts * ts * (ndir * 4 + 3) + 128) * sizeof(float)); + float (*rgb)[ts][ts][3] = (float(*)[ts][ts][3]) buffer; + float (*lab)[ts - 8][ts - 8] = (float (*)[ts - 8][ts - 8])(buffer + ts * ts * (ndir * 3)); + float (*drv)[ts - 10][ts - 10] = (float (*)[ts - 10][ts - 10]) (buffer + ts * ts * (ndir * 3 + 3)); + uint8_t (*homo)[ts][ts] = (uint8_t (*)[ts][ts]) (lab); // we can reuse the lab-buffer because they are not used together + s_minmaxgreen (*greenminmaxtile)[tsh] = (s_minmaxgreen(*)[tsh]) (lab); // we can reuse the lab-buffer because they are not used together + uint8_t (*homosum)[ts][ts] = (uint8_t (*)[ts][ts]) (drv); // we can reuse the drv-buffer because they are not used together + uint8_t (*homosummax)[ts] = (uint8_t (*)[ts]) homo[ndir - 1]; // we can reuse the homo-buffer because they are not used together + +#ifdef _OPENMP + #pragma omp for collapse(2) schedule(dynamic) nowait +#endif + + for (int top = 3; top < height - 19; top += ts - 16) + for (int left = 3; left < width - 19; left += ts - 16) { + int mrow = MIN (top + ts, height - 3); + int mcol = MIN (left + ts, width - 3); + + /* Set greenmin and greenmax to the minimum and maximum allowed values: */ + for (int row = top; row < mrow; row++) { + // find first non-green pixel + int leftstart = left; + + for(; leftstart < mcol; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); + + if(coloffset == 3) { + short *hex = allhex[0][row % 3][leftstart % 3]; + + for (int col = leftstart; col < mcol; col += coloffset) { + float minval = FLT_MAX; + float maxval = 0.f; + float *pix = &rawData[row][col]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + } + } else { + float minval = FLT_MAX; + float maxval = 0.f; + int col = leftstart; + + if(coloffset == 2) { + minval = FLT_MAX; + maxval = 0.f; + float *pix = &rawData[row][col]; + short *hex = allhex[0][row % 3][col % 3]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + col += 2; + } + + short *hex = allhex[0][row % 3][col % 3]; + + for (; col < mcol - 1; col += 3) { + minval = FLT_MAX; + maxval = 0.f; + float *pix = &rawData[row][col]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + greenminmaxtile[row - top][(col + 1 - left) >> 1].min = minval; + greenminmaxtile[row - top][(col + 1 - left) >> 1].max = maxval; + } + + if(col < mcol) { + minval = FLT_MAX; + maxval = 0.f; + float *pix = &rawData[row][col]; + + for(int c = 0; c < 6; c++) { + float val = pix[hex[c]]; + + minval = minval < val ? minval : val; + maxval = maxval > val ? maxval : val; + } + + greenminmaxtile[row - top][(col - left) >> 1].min = minval; + greenminmaxtile[row - top][(col - left) >> 1].max = maxval; + } + } + } + + memset(rgb, 0, ts * ts * 3 * sizeof(float)); + + for (int row = top; row < mrow; row++) + for (int col = left; col < mcol; col++) { + rgb[0][row - top][col - left][fcol(row, col)] = rawData[row][col]; + } + + for(int c = 0; c < 3; c++) { + memcpy (rgb[c + 1], rgb[0], sizeof * rgb); + } + + /* Interpolate green horizontally, vertically, and along both diagonals: */ + for (int row = top; row < mrow; row++) { + // find first non-green pixel + int leftstart = left; + + for(; leftstart < mcol; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); + + if(coloffset == 3) { + short *hex = allhex[0][row % 3][leftstart % 3]; + + for (int col = leftstart; col < mcol; col += coloffset) { + float *pix = &rawData[row][col]; + float color[4]; + color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - + 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); + color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + + 0.359375f * (pix[0] - pix[-hex[2]]); + + for(int c = 0; c < 2; c++) + color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * + (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); + + for(int c = 0; c < 4; c++) { + rgb[c][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } else { + short *hexmod[2]; + hexmod[0] = allhex[0][row % 3][leftstart % 3]; + hexmod[1] = allhex[0][row % 3][(leftstart + coloffset) % 3]; + + for (int col = leftstart, hexindex = 0; col < mcol; col += coloffset, coloffset ^= 3, hexindex ^= 1) { + float *pix = &rawData[row][col]; + short *hex = hexmod[hexindex]; + float color[4]; + color[0] = 0.6796875f * (pix[hex[1]] + pix[hex[0]]) - + 0.1796875f * (pix[2 * hex[1]] + pix[2 * hex[0]]); + color[1] = 0.87109375f * pix[hex[3]] + pix[hex[2]] * 0.12890625f + + 0.359375f * (pix[0] - pix[-hex[2]]); + + for(int c = 0; c < 2; c++) + color[2 + c] = 0.640625f * pix[hex[4 + c]] + 0.359375f * pix[-2 * hex[4 + c]] + 0.12890625f * + (2.f * pix[0] - pix[3 * hex[4 + c]] - pix[-3 * hex[4 + c]]); + + for(int c = 0; c < 4; c++) { + rgb[c ^ 1][row - top][col - left][1] = LIM(color[c], greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } + } + + for (int pass = 0; pass < passes; pass++) { + if (pass == 1) { + memcpy (rgb += 4, buffer, 4 * sizeof * rgb); + } + + /* Recalculate green from interpolated values of closer pixels: */ + if (pass) { + for (int row = top + 2; row < mrow - 2; row++) { + int leftstart = left + 2; + + for(; leftstart < mcol - 2; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1 + (fcol(row, leftstart + 1) & 1)); + + if(coloffset == 3) { + int f = fcol(row, leftstart); + short *hex = allhex[1][row % 3][leftstart % 3]; + + for (int col = leftstart; col < mcol - 2; col += coloffset, f ^= 2) { + for (int d = 3; d < 6; d++) { + float (*rix)[3] = &rgb[(d - 2)][row - top][col - left]; + float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) + - rix[-2 * hex[d]][f]) + rix[0][f]; + rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } else { + int f = fcol(row, leftstart); + short *hexmod[2]; + hexmod[0] = allhex[1][row % 3][leftstart % 3]; + hexmod[1] = allhex[1][row % 3][(leftstart + coloffset) % 3]; + + for (int col = leftstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2), hexindex ^= 1 ) { + short *hex = hexmod[hexindex]; + + for (int d = 3; d < 6; d++) { + float (*rix)[3] = &rgb[(d - 2) ^ 1][row - top][col - left]; + float val = 0.33333333f * (rix[-2 * hex[d]][1] + 2 * (rix[hex[d]][1] - rix[hex[d]][f]) + - rix[-2 * hex[d]][f]) + rix[0][f]; + rix[0][1] = LIM(val, greenminmaxtile[row - top][(col - left) >> 1].min, greenminmaxtile[row - top][(col - left) >> 1].max); + } + } + } + } + } + + /* Interpolate red and blue values for solitary green pixels: */ + int sgstartcol = (left - sgcol + 4) / 3 * 3 + sgcol; + + for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) { + for (int col = sgstartcol, h = fcol(row, col + 1); col < mcol - 2; col += 3, h ^= 2) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + float diff[6] = {0.f}; + + for (int i = 1, d = 0; d < 6; d++, i ^= ts ^ 1, h ^= 2) { + for (int c = 0; c < 2; c++, h ^= 2) { + float g = rix[0][1] + rix[0][1] - rix[i << c][1] - rix[-i << c][1]; + color[h][d] = g + rix[i << c][h] + rix[-i << c][h]; + + if (d > 1) + diff[d] += SQR (rix[i << c][1] - rix[-i << c][1] + - rix[i << c][h] + rix[-i << c][h]) + SQR(g); + } + + if (d > 2 && (d & 1)) // 3, 5 + if (diff[d - 1] < diff[d]) + for(int c = 0; c < 2; c++) { + color[c * 2][d] = color[c * 2][d - 1]; + } + + if ((d & 1) || d < 2) { // d: 0, 1, 3, 5 + for(int c = 0; c < 2; c++) { + rix[0][c * 2] = CLIP(0.5f * color[c * 2][d]); + } + + rix += ts * ts; + } + } + } + } + + /* Interpolate red for blue pixels and vice versa: */ + for (int row = top + 3; row < mrow - 3; row++) { + int leftstart = left + 3; + + for(; leftstart < mcol - 1; leftstart++) + if(!isgreen(row, leftstart)) { + break; + } + + int coloffset = (RightShift[row % 3] == 1 ? 3 : 1); + c = (row - sgrow) % 3 ? ts : 1; + int h = 3 * (c ^ ts ^ 1); + + if(coloffset == 3) { + int f = 2 - fcol(row, leftstart); + + for (int col = leftstart; col < mcol - 3; col += coloffset, f ^= 2) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + + for (int d = 0; d < 4; d++, rix += ts * ts) { + int i = d > 1 || ((d ^ c) & 1) || + ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; + + rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); + } + } + } else { + coloffset = fcol(row, leftstart + 1) == 1 ? 2 : 1; + int f = 2 - fcol(row, leftstart); + + for (int col = leftstart; col < mcol - 3; col += coloffset, coloffset ^= 3, f = f ^ (coloffset & 2) ) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + + for (int d = 0; d < 4; d++, rix += ts * ts) { + int i = d > 1 || ((d ^ c) & 1) || + ((fabsf(rix[0][1] - rix[c][1]) + fabsf(rix[0][1] - rix[-c][1])) < 2.f * (fabsf(rix[0][1] - rix[h][1]) + fabsf(rix[0][1] - rix[-h][1]))) ? c : h; + + rix[0][f] = CLIP(rix[0][1] + 0.5f * (rix[i][f] + rix[-i][f] - rix[i][1] - rix[-i][1])); + } + } + } + } + + /* Fill in red and blue for 2x2 blocks of green: */ + // Find first row of 2x2 green + int topstart = top + 2; + + for(; topstart < mrow - 2; topstart++) + if((topstart - sgrow) % 3) { + break; + } + + int leftstart = left + 2; + + for(; leftstart < mcol - 2; leftstart++) + if((leftstart - sgcol) % 3) { + break; + } + + int coloffsetstart = 2 - (fcol(topstart, leftstart + 1) & 1); + + for (int row = topstart; row < mrow - 2; row++) { + if ((row - sgrow) % 3) { + short *hexmod[2]; + hexmod[0] = allhex[1][row % 3][leftstart % 3]; + hexmod[1] = allhex[1][row % 3][(leftstart + coloffsetstart) % 3]; + + for (int col = leftstart, coloffset = coloffsetstart, hexindex = 0; col < mcol - 2; col += coloffset, coloffset ^= 3, hexindex ^= 1) { + float (*rix)[3] = &rgb[0][row - top][col - left]; + short *hex = hexmod[hexindex]; + + for (int d = 0; d < ndir; d += 2, rix += ts * ts) { + if (hex[d] + hex[d + 1]) { + float g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; + + for (c = 0; c < 4; c += 2) { + rix[0][c] = CLIP((g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.33333333f); + } + } else { + float g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; + + for (c = 0; c < 4; c += 2) { + rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.5f); + } + } + } + } + } + } + } + +// end of multipass part + rgb = (float(*)[ts][ts][3]) buffer; + mrow -= top; + mcol -= left; + + if(useCieLab) { + /* Convert to CIELab and differentiate in all directions: */ + // Original dcraw algorithm uses CIELab as perceptual space + // (presumably coming from original AHD) and converts taking + // camera matrix into account. We use this in RT. + for (int d = 0; d < ndir; d++) { + float *l = &lab[0][0][0]; + float *a = &lab[1][0][0]; + float *b = &lab[2][0][0]; + cielab(&rgb[d][4][4], l, a, b, ts, mrow - 8, ts - 8, xyz_cam); + int f = dir[d & 3]; + f = f == 1 ? 1 : f - 8; + + for (int row = 5; row < mrow - 5; row++) +#ifdef _OPENMP + #pragma omp simd +#endif + for (int col = 5; col < mcol - 5; col++) { + float *l = &lab[0][row - 4][col - 4]; + float *a = &lab[1][row - 4][col - 4]; + float *b = &lab[2][row - 4][col - 4]; + + float g = 2 * l[0] - l[f] - l[-f]; + drv[d][row - 5][col - 5] = SQR(g) + + SQR((2 * a[0] - a[f] - a[-f] + g * 2.1551724f)) + + SQR((2 * b[0] - b[f] - b[-f] - g * 0.86206896f)); + } + + } + } else { + // For 1-pass demosaic we use YPbPr which requires much + // less code and is nearly indistinguishable. It assumes the + // camera RGB is roughly linear. + for (int d = 0; d < ndir; d++) { + float (*yuv)[ts - 8][ts - 8] = lab; // we use the lab buffer, which has the same dimensions +#ifdef __SSE2__ + vfloat zd2627v = F2V(0.2627f); + vfloat zd6780v = F2V(0.6780f); + vfloat zd0593v = F2V(0.0593f); + vfloat zd56433v = F2V(0.56433f); + vfloat zd67815v = F2V(0.67815f); +#endif + + for (int row = 4; row < mrow - 4; row++) { + int col = 4; +#ifdef __SSE2__ + + for (; col < mcol - 7; col += 4) { + // use ITU-R BT.2020 YPbPr, which is great, but could use + // a better/simpler choice? note that imageop.h provides + // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, + // which appears less good with specular highlights + vfloat redv, greenv, bluev; + vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[d][row][col], redv, greenv, bluev); + vfloat yv = zd2627v * redv + zd6780v * bluev + zd0593v * greenv; + STVFU(yuv[0][row - 4][col - 4], yv); + STVFU(yuv[1][row - 4][col - 4], (bluev - yv) * zd56433v); + STVFU(yuv[2][row - 4][col - 4], (redv - yv) * zd67815v); + } + +#endif + + for (; col < mcol - 4; col++) { + // use ITU-R BT.2020 YPbPr, which is great, but could use + // a better/simpler choice? note that imageop.h provides + // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, + // which appears less good with specular highlights + float y = 0.2627f * rgb[d][row][col][0] + 0.6780f * rgb[d][row][col][1] + 0.0593f * rgb[d][row][col][2]; + yuv[0][row - 4][col - 4] = y; + yuv[1][row - 4][col - 4] = (rgb[d][row][col][2] - y) * 0.56433f; + yuv[2][row - 4][col - 4] = (rgb[d][row][col][0] - y) * 0.67815f; + } + } + + int f = dir[d & 3]; + f = f == 1 ? 1 : f - 8; + + for (int row = 5; row < mrow - 5; row++) + for (int col = 5; col < mcol - 5; col++) { + float *y = &yuv[0][row - 4][col - 4]; + float *u = &yuv[1][row - 4][col - 4]; + float *v = &yuv[2][row - 4][col - 4]; + drv[d][row - 5][col - 5] = SQR(2 * y[0] - y[f] - y[-f]) + + SQR(2 * u[0] - u[f] - u[-f]) + + SQR(2 * v[0] - v[f] - v[-f]); + } + } + } + + /* Build homogeneity maps from the derivatives: */ +#ifdef __SSE2__ + vfloat eightv = F2V(8.f); + vfloat zerov = F2V(0.f); + vfloat onev = F2V(1.f); +#endif + + for (int row = 6; row < mrow - 6; row++) { + int col = 6; +#ifdef __SSE2__ + + for (; col < mcol - 9; col += 4) { + vfloat tr1v = vminf(LVFU(drv[0][row - 5][col - 5]), LVFU(drv[1][row - 5][col - 5])); + vfloat tr2v = vminf(LVFU(drv[2][row - 5][col - 5]), LVFU(drv[3][row - 5][col - 5])); + + if(ndir > 4) { + vfloat tr3v = vminf(LVFU(drv[4][row - 5][col - 5]), LVFU(drv[5][row - 5][col - 5])); + vfloat tr4v = vminf(LVFU(drv[6][row - 5][col - 5]), LVFU(drv[7][row - 5][col - 5])); + tr1v = vminf(tr1v, tr3v); + tr1v = vminf(tr1v, tr4v); + } + + tr1v = vminf(tr1v, tr2v); + tr1v = tr1v * eightv; + + for (int d = 0; d < ndir; d++) { + uint8_t tempstore[16]; + vfloat tempv = zerov; + + for (int v = -1; v <= 1; v++) { + for (int h = -1; h <= 1; h++) { + tempv += vselfzero(vmaskf_le(LVFU(drv[d][row + v - 5][col + h - 5]), tr1v), onev); + } + } + + _mm_storeu_si128((__m128i*)&tempstore, _mm_cvtps_epi32(tempv)); + homo[d][row][col] = tempstore[0]; + homo[d][row][col + 1] = tempstore[4]; + homo[d][row][col + 2] = tempstore[8]; + homo[d][row][col + 3] = tempstore[12]; + + } + } + +#endif + + for (; col < mcol - 6; col++) { + float tr = drv[0][row - 5][col - 5] < drv[1][row - 5][col - 5] ? drv[0][row - 5][col - 5] : drv[1][row - 5][col - 5]; + + for (int d = 2; d < ndir; d++) { + tr = (drv[d][row - 5][col - 5] < tr ? drv[d][row - 5][col - 5] : tr); + } + + tr *= 8; + + for (int d = 0; d < ndir; d++) { + uint8_t temp = 0; + + for (int v = -1; v <= 1; v++) { + for (int h = -1; h <= 1; h++) { + temp += (drv[d][row + v - 5][col + h - 5] <= tr ? 1 : 0); + } + } + + homo[d][row][col] = temp; + } + } + } + + if (height - top < ts + 4) { + mrow = height - top + 2; + } + + if (width - left < ts + 4) { + mcol = width - left + 2; + } + + + /* Build 5x5 sum of homogeneity maps */ + const int startcol = MIN(left, 8); + + for(int d = 0; d < ndir; d++) { + for (int row = MIN(top, 8); row < mrow - 8; row++) { + int col = startcol; +#ifdef __SSE2__ + int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; + + // crunching 16 values at once is faster than summing up column sums + for (; col < endcol; col += 16) { + vint v5sumv = (vint)ZEROV; + + for(int v = -2; v <= 2; v++) + for(int h = -2; h <= 2; h++) { + v5sumv = _mm_adds_epu8( _mm_loadu_si128((vint*)&homo[d][row + v][col + h]), v5sumv); + } + + _mm_storeu_si128((vint*)&homosum[d][row][col], v5sumv); + } + +#endif + + if(col < mcol - 8) { + int v5sum[5] = {0}; + + for(int v = -2; v <= 2; v++) + for(int h = -2; h <= 2; h++) { + v5sum[2 + h] += homo[d][row + v][col + h]; + } + + int blocksum = v5sum[0] + v5sum[1] + v5sum[2] + v5sum[3] + v5sum[4]; + homosum[d][row][col] = blocksum; + col++; + + // now we can subtract a column of five from blocksum and get new colsum of 5 + for (int voffset = 0; col < mcol - 8; col++, voffset++) { + int colsum = homo[d][row - 2][col + 2] + homo[d][row - 1][col + 2] + homo[d][row][col + 2] + homo[d][row + 1][col + 2] + homo[d][row + 2][col + 2]; + voffset = voffset == 5 ? 0 : voffset; // faster than voffset %= 5; + blocksum -= v5sum[voffset]; + blocksum += colsum; + v5sum[voffset] = colsum; + homosum[d][row][col] = blocksum; + } + } + } + } + + // calculate maximum of homogeneity maps per pixel. Vectorized calculation is a tiny bit faster than on the fly calculation in next step +#ifdef __SSE2__ + vint maskv = _mm_set1_epi8(31); +#endif + + for (int row = MIN(top, 8); row < mrow - 8; row++) { + int col = startcol; +#ifdef __SSE2__ + int endcol = row < mrow - 9 ? mcol - 8 : mcol - 23; + + for (; col < endcol; col += 16) { + vint maxval1 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[0][row][col]), _mm_loadu_si128((vint*)&homosum[1][row][col])); + vint maxval2 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[2][row][col]), _mm_loadu_si128((vint*)&homosum[3][row][col])); + + if(ndir > 4) { + vint maxval3 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[4][row][col]), _mm_loadu_si128((vint*)&homosum[5][row][col])); + vint maxval4 = _mm_max_epu8(_mm_loadu_si128((vint*)&homosum[6][row][col]), _mm_loadu_si128((vint*)&homosum[7][row][col])); + maxval1 = _mm_max_epu8(maxval1, maxval3); + maxval1 = _mm_max_epu8(maxval1, maxval4); + } + + maxval1 = _mm_max_epu8(maxval1, maxval2); + // there is no shift intrinsic for epu8. Shift using epi32 and mask the wrong bits out + vint subv = _mm_srli_epi32( maxval1, 3 ); + subv = _mm_and_si128(subv, maskv); + maxval1 = _mm_subs_epu8(maxval1, subv); + _mm_storeu_si128((vint*)&homosummax[row][col], maxval1); + } + +#endif + + for (; col < mcol - 8; col ++) { + uint8_t maxval = homosum[0][row][col]; + + for(int d = 1; d < ndir; d++) { + maxval = maxval < homosum[d][row][col] ? homosum[d][row][col] : maxval; + } + + maxval -= maxval >> 3; + homosummax[row][col] = maxval; + } + } + + + /* Average the most homogeneous pixels for the final result: */ + uint8_t hm[8] = {}; + + for (int row = MIN(top, 8); row < mrow - 8; row++) + for (int col = MIN(left, 8); col < mcol - 8; col++) { + + for (int d = 0; d < 4; d++) { + hm[d] = homosum[d][row][col]; + } + + for (int d = 4; d < ndir; d++) { + hm[d] = homosum[d][row][col]; + + if (hm[d - 4] < hm[d]) { + hm[d - 4] = 0; + } else if (hm[d - 4] > hm[d]) { + hm[d] = 0; + } + } + + float avg[4] = {0.f}; + + uint8_t maxval = homosummax[row][col]; + + for (int d = 0; d < ndir; d++) + if (hm[d] >= maxval) { + for (int c = 0; c < 3; c++) { + avg[c] += rgb[d][row][col][c]; + } + avg[3]++; + } + + red[row + top][col + left] = avg[0] / avg[3]; + green[row + top][col + left] = avg[1] / avg[3]; + blue[row + top][col + left] = avg[2] / avg[3]; + } + + if(plistenerActive && ((++progressCounter) % 32 == 0)) { +#ifdef _OPENMP + #pragma omp critical (xtransdemosaic) +#endif + { + progress += progressInc; + progress = min(1.0, progress); + plistener->setProgress (progress); + } + } + + + } + + free(buffer); + } + +} +#undef CLIP +void RawImageSource::fast_xtrans_interpolate () +{ +// if (settings->verbose) { +// printf("fast X-Trans interpolation...\n"); +// } + + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); + plistener->setProgress (progress); + } + + const int height = H, width = W; + + xtransborder_interpolate (1); + int xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + #pragma omp parallel for + + for(int row = 1; row < height - 1; row++) { + for(int col = 1; col < width - 1; col++) { + float sum[3] = {0.f}; + + for(int v = -1; v <= 1; v++) { + for(int h = -1; h <= 1; h++) { + sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)]; + } + } + + switch(fcol(row, col)) { + case 0: + red[row][col] = rawData[row][col]; + green[row][col] = sum[1] * 0.2f; + blue[row][col] = sum[2] * 0.33333333f; + break; + + case 1: + red[row][col] = sum[0] * 0.5f; + green[row][col] = rawData[row][col]; + blue[row][col] = sum[2] * 0.5f; + break; + + case 2: + red[row][col] = sum[0] * 0.33333333f; + green[row][col] = sum[1] * 0.2f; + blue[row][col] = rawData[row][col]; + break; + } + } + } + + if (plistenerActive) { + plistener->setProgress (1.0); + } +} +#undef fcol +#undef isgreen +} \ No newline at end of file diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc index c7252d360..4d9a31b6f 100644 --- a/rtexif/pentaxattribs.cc +++ b/rtexif/pentaxattribs.cc @@ -44,6 +44,7 @@ public: choices[5] = "Premium"; choices[6] = "RAW (HDR enabled)"; choices[7] = "RAW (pixel shift enabled)"; + choices[8] = "RAW (pixel shift handheld mode enabled)"; choices[65535] = "n/a"; } }; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index b294c9fee..73fea1aa3 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -130,11 +130,6 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA pixelShiftShowMotionMaskOnly->set_tooltip_text (M("TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP")); pixelShiftFrame->pack_start(*pixelShiftShowMotionMaskOnly); -#ifdef PIXELSHIFTDEV - pixelShiftAutomatic = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTADAPTIVE"), multiImage)); - pixelShiftAutomatic->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftAutomatic); -#endif pixelShiftGreen = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTGREEN"), multiImage)); pixelShiftGreen->setCheckBoxListener (this); pixelShiftOptions->pack_start(*pixelShiftGreen); @@ -194,139 +189,11 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA pixelShiftOptions->pack_start(*pixelShiftMedian); -#ifdef PIXELSHIFTDEV - pixelShiftMedian3 = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTMEDIAN3"), multiImage)); - pixelShiftMedian3->setCheckBoxListener (this); - pixelShiftMedian3->set_tooltip_text (M("TP_RAW_PIXELSHIFTMEDIAN3_TOOLTIP")); - pixelShiftOptions->pack_start(*pixelShiftMedian3); - - pixelShiftNonGreenCross2 = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENCROSS2"), multiImage)); - pixelShiftNonGreenCross2->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenCross2); - - pixelShiftNonGreenAmaze = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENAMAZE"), multiImage)); - pixelShiftNonGreenAmaze->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenAmaze); - - pixelShiftNonGreenHorizontal = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENHORIZONTAL"), multiImage)); - pixelShiftNonGreenHorizontal->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenHorizontal); - - pixelShiftNonGreenVertical = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTNONGREENVERTICAL"), multiImage)); - pixelShiftNonGreenVertical->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftNonGreenVertical); - - pixelShiftExp0 = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTEXP0"), multiImage)); - pixelShiftExp0->setCheckBoxListener (this); - pixelShiftOptions->pack_start(*pixelShiftExp0); -#endif pixelShiftLmmse = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTLMMSE"), multiImage)); pixelShiftLmmse->setCheckBoxListener (this); pixelShiftLmmse->set_tooltip_text (M("TP_RAW_PIXELSHIFTLMMSE_TOOLTIP")); pixelShiftOptions->pack_start(*pixelShiftLmmse); -// pixelShiftOneGreen = Gtk::manage (new CheckBox(M("TP_RAW_PIXELSHIFTONEGREEN"), multiImage)); -// pixelShiftOneGreen->setCheckBoxListener (this); -// pixelShiftOneGreen->set_tooltip_text (M("TP_RAW_PIXELSHIFTONEGREEN_TOOLTIP")); -// pixelShiftOptions->pack_start(*pixelShiftOneGreen); - -#ifdef PIXELSHIFTDEV - pixelShiftMotion = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMOTION"), 0, 100, 1, 70)); - pixelShiftMotion->setAdjusterListener (this); - pixelShiftMotion->set_tooltip_text (M("TP_RAW_PIXELSHIFTMOTION_TOOLTIP")); - - if (pixelShiftMotion->delay < options.adjusterMaxDelay) { - pixelShiftMotion->delay = options.adjusterMaxDelay; - } - pixelShiftMotion->show(); - pixelShiftOptions->pack_start(*pixelShiftMotion); - - Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); - hb2->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_PIXELSHIFTMOTIONCORRECTION") + ": ")), Gtk::PACK_SHRINK, 0); - pixelShiftMotionCorrection = Gtk::manage (new MyComboBoxText ()); - pixelShiftMotionCorrection->append("1x1"); - pixelShiftMotionCorrection->append("1x2"); - pixelShiftMotionCorrection->append("3x3"); - pixelShiftMotionCorrection->append("5x5"); - pixelShiftMotionCorrection->append("7x7"); - pixelShiftMotionCorrection->append("3x3 new"); - pixelShiftMotionCorrection->set_active(0); - pixelShiftMotionCorrection->show(); - hb2->pack_start(*pixelShiftMotionCorrection); - pixelShiftOptions->pack_start(*hb2); - pixelShiftStddevFactorGreen = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTSTDDEVFACTORGREEN"), 2, 8, 0.1, 5)); - pixelShiftStddevFactorGreen->setAdjusterListener (this); - - if (pixelShiftStddevFactorGreen->delay < options.adjusterMaxDelay) { - pixelShiftStddevFactorGreen->delay = options.adjusterMaxDelay; - } - - pixelShiftStddevFactorGreen->show(); - pixelShiftOptions->pack_start(*pixelShiftStddevFactorGreen); - - pixelShiftStddevFactorRed = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTSTDDEVFACTORRED"), 1, 8, 0.1, 5)); - pixelShiftStddevFactorRed->setAdjusterListener (this); - - if (pixelShiftStddevFactorRed->delay < options.adjusterMaxDelay) { - pixelShiftStddevFactorRed->delay = options.adjusterMaxDelay; - } - - pixelShiftStddevFactorRed->show(); - pixelShiftOptions->pack_start(*pixelShiftStddevFactorRed); - - pixelShiftStddevFactorBlue = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTSTDDEVFACTORBLUE"), 1, 8, 0.1, 5)); - pixelShiftStddevFactorBlue->setAdjusterListener (this); - - if (pixelShiftStddevFactorBlue->delay < options.adjusterMaxDelay) { - pixelShiftStddevFactorBlue->delay = options.adjusterMaxDelay; - } - - pixelShiftStddevFactorBlue->show(); - pixelShiftOptions->pack_start(*pixelShiftStddevFactorBlue); -#endif - -#ifdef PIXELSHIFTDEV - pixelShiftNreadIso = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTNREADISO"), -2.0, 2.0, 0.05, 0.0)); - pixelShiftNreadIso->setAdjusterListener (this); - - if (pixelShiftNreadIso->delay < options.adjusterMaxDelay) { - pixelShiftNreadIso->delay = options.adjusterMaxDelay; - } - - pixelShiftNreadIso->show(); - pixelShiftOptions->pack_start(*pixelShiftNreadIso); - - - pixelShiftPrnu = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTPRNU"), 0.3, 2.0, 0.1, 1.0)); - pixelShiftPrnu->setAdjusterListener (this); - - if (pixelShiftPrnu->delay < options.adjusterMaxDelay) { - pixelShiftPrnu->delay = options.adjusterMaxDelay; - } - - pixelShiftPrnu->show(); - pixelShiftOptions->pack_start(*pixelShiftPrnu); - - pixelShiftSum = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTMASKTHRESHOLD"), 1.0, 8.0, 0.1, 3.0)); - pixelShiftSum->setAdjusterListener (this); - - if (pixelShiftSum->delay < options.adjusterMaxDelay) { - pixelShiftSum->delay = options.adjusterMaxDelay; - } - - pixelShiftSum->show(); - pixelShiftOptions->pack_start(*pixelShiftSum); - - pixelShiftRedBlueWeight = Gtk::manage (new Adjuster (M("TP_RAW_PIXELSHIFTREDBLUEWEIGHT"), 0.1, 1.0, 0.1, 0.7)); - pixelShiftRedBlueWeight->setAdjusterListener (this); - - if (pixelShiftRedBlueWeight->delay < options.adjusterMaxDelay) { - pixelShiftRedBlueWeight->delay = options.adjusterMaxDelay; - } - - pixelShiftRedBlueWeight->show(); - pixelShiftOptions->pack_start(*pixelShiftRedBlueWeight); -#endif pixelShiftFrame->pack_start(*pixelShiftOptions); pixelShiftOptions->hide(); @@ -336,9 +203,6 @@ BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RA method->connect(method->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::methodChanged) )); imageNumber->connect(imageNumber->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::imageNumberChanged) )); pixelShiftMotionMethod->connect(pixelShiftMotionMethod->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::pixelShiftMotionMethodChanged) )); -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->connect(pixelShiftMotionCorrection->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::psMotionCorrectionChanged) )); -#endif } @@ -348,9 +212,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params method->block (true); imageNumber->block (true); //allEnhconn.block (true); -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->block (true); -#endif method->set_active(std::numeric_limits::max()); imageNumber->set_active(pp->raw.bayersensor.imageNum); @@ -381,7 +242,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params } pixelShiftSmooth->setValue (pp->raw.bayersensor.pixelShiftSmoothFactor); pixelShiftLmmse->setValue (pp->raw.bayersensor.pixelShiftLmmse); -// pixelShiftOneGreen->setValue (pp->raw.bayersensor.pixelShiftOneGreen); pixelShiftEqualBright->setValue (pp->raw.bayersensor.pixelShiftEqualBright); pixelShiftEqualBrightChannel->set_sensitive (pp->raw.bayersensor.pixelShiftEqualBright); pixelShiftEqualBrightChannel->setValue (pp->raw.bayersensor.pixelShiftEqualBrightChannel); @@ -394,32 +254,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params if (!batchMode) { pixelShiftSigma->set_sensitive (pp->raw.bayersensor.pixelShiftBlur); } -#ifdef PIXELSHIFTDEV - pixelShiftStddevFactorGreen->setValue (pp->raw.bayersensor.pixelShiftStddevFactorGreen); - pixelShiftStddevFactorRed->setValue (pp->raw.bayersensor.pixelShiftStddevFactorRed); - pixelShiftStddevFactorBlue->setValue (pp->raw.bayersensor.pixelShiftStddevFactorBlue); - pixelShiftSum->setValue (pp->raw.bayersensor.pixelShiftSum); - pixelShiftMedian3->setValue (pp->raw.bayersensor.pixelShiftMedian3); - if (!batchMode) { - pixelShiftMedian3->set_sensitive (pixelShiftMedian->getValue() != CheckValue::off); - } - pixelShiftAutomatic->setValue (pp->raw.bayersensor.pixelShiftAutomatic); - pixelShiftNonGreenHorizontal->setValue (pp->raw.bayersensor.pixelShiftNonGreenHorizontal); - pixelShiftNonGreenVertical->setValue (pp->raw.bayersensor.pixelShiftNonGreenVertical); - pixelShiftExp0->setValue (pp->raw.bayersensor.pixelShiftExp0); - pixelShiftNonGreenCross2->setValue (pp->raw.bayersensor.pixelShiftNonGreenCross2); - pixelShiftNonGreenAmaze->setValue (pp->raw.bayersensor.pixelShiftNonGreenAmaze); - pixelShiftMotion->setValue (pp->raw.bayersensor.pixelShiftMotion); - pixelShiftMotionCorrection->set_active ((int)pp->raw.bayersensor.pixelShiftMotionCorrection); - if (!batchMode) { - pixelShiftHoleFill->set_sensitive (pixelShiftAutomatic->getValue () != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftBlur->set_sensitive(pixelShiftAutomatic->getValue () != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftSmooth->set_sensitive(pixelShiftAutomatic->getValue () != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5 && pixelShiftBlur->getValue() != CheckValue::off); - } - pixelShiftNreadIso->setValue (pp->raw.bayersensor.pixelShiftNreadIso); - pixelShiftPrnu->setValue (pp->raw.bayersensor.pixelShiftPrnu); - pixelShiftRedBlueWeight->setValue (pp->raw.bayersensor.pixelShiftRedBlueWeight); -#endif if(pedited) { ccSteps->setEditedState (pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); @@ -433,30 +267,12 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params pixelShiftBlur->setEdited (pedited->raw.bayersensor.pixelShiftBlur); pixelShiftSmooth->setEditedState ( pedited->raw.bayersensor.pixelShiftSmooth ? Edited : UnEdited); pixelShiftLmmse->setEdited (pedited->raw.bayersensor.pixelShiftLmmse); -// pixelShiftOneGreen->setEdited (pedited->raw.bayersensor.pixelShiftOneGreen); pixelShiftEqualBright->setEdited (pedited->raw.bayersensor.pixelShiftEqualBright); pixelShiftEqualBrightChannel->setEdited (pedited->raw.bayersensor.pixelShiftEqualBrightChannel); pixelShiftNonGreenCross->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross); lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); pixelShiftEperIso->setEditedState ( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setEditedState ( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); -#ifdef PIXELSHIFTDEV - pixelShiftNreadIso->setEditedState ( pedited->raw.bayersensor.pixelShiftNreadIso ? Edited : UnEdited); - pixelShiftPrnu->setEditedState ( pedited->raw.bayersensor.pixelShiftPrnu ? Edited : UnEdited); - pixelShiftStddevFactorGreen->setEditedState ( pedited->raw.bayersensor.pixelShiftStddevFactorGreen ? Edited : UnEdited); - pixelShiftStddevFactorRed->setEditedState ( pedited->raw.bayersensor.pixelShiftStddevFactorRed ? Edited : UnEdited); - pixelShiftStddevFactorBlue->setEditedState ( pedited->raw.bayersensor.pixelShiftStddevFactorBlue ? Edited : UnEdited); - pixelShiftSum->setEditedState ( pedited->raw.bayersensor.pixelShiftSum ? Edited : UnEdited); - pixelShiftAutomatic->setEdited (pedited->raw.bayersensor.pixelShiftAutomatic); - pixelShiftNonGreenHorizontal->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenHorizontal); - pixelShiftNonGreenVertical->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenVertical); - pixelShiftMedian3->setEdited (pedited->raw.bayersensor.pixelShiftMedian3); - pixelShiftExp0->setEdited (pedited->raw.bayersensor.pixelShiftExp0); - pixelShiftNonGreenCross2->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenCross2); - pixelShiftNonGreenAmaze->setEdited (pedited->raw.bayersensor.pixelShiftNonGreenAmaze); - pixelShiftMotion->setEditedState ( pedited->raw.bayersensor.pixelShiftMotion ? Edited : UnEdited); - pixelShiftRedBlueWeight->setEditedState ( pedited->raw.bayersensor.pixelShiftRedBlueWeight ? Edited : UnEdited); -#endif if(!pedited->raw.bayersensor.method) { method->set_active(std::numeric_limits::max()); // No name @@ -464,11 +280,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params if(!pedited->raw.bayersensor.imageNum) { imageNumber->set_active_text(M("GENERAL_UNCHANGED")); } -#ifdef PIXELSHIFTDEV - if(!pedited->raw.bayersensor.pixelShiftMotionCorrection) { - pixelShiftMotionCorrection->set_active_text(M("GENERAL_UNCHANGED")); - } -#endif if(!pedited->raw.bayersensor.pixelShiftMotionCorrectionMethod) { pixelShiftMotionMethod->set_active_text(M("GENERAL_UNCHANGED")); } @@ -511,9 +322,6 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params //lastALLen = pp->raw.bayersensor.all_enhance; method->block (false); -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->block (false); -#endif imageNumber->block (false); //allEnhconn.block (false); @@ -538,28 +346,9 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pp->raw.bayersensor.pixelShiftBlur = pixelShiftBlur->getLastActive (); pp->raw.bayersensor.pixelShiftSmoothFactor = pixelShiftSmooth->getValue(); pp->raw.bayersensor.pixelShiftLmmse = pixelShiftLmmse->getLastActive (); -// pp->raw.bayersensor.pixelShiftOneGreen = pixelShiftOneGreen->getLastActive (); pp->raw.bayersensor.pixelShiftEqualBright = pixelShiftEqualBright->getLastActive (); pp->raw.bayersensor.pixelShiftEqualBrightChannel = pixelShiftEqualBrightChannel->getLastActive (); pp->raw.bayersensor.pixelShiftNonGreenCross = pixelShiftNonGreenCross->getLastActive (); -#ifdef PIXELSHIFTDEV - pp->raw.bayersensor.pixelShiftStddevFactorGreen = pixelShiftStddevFactorGreen->getValue(); - pp->raw.bayersensor.pixelShiftStddevFactorRed = pixelShiftStddevFactorRed->getValue(); - pp->raw.bayersensor.pixelShiftStddevFactorBlue = pixelShiftStddevFactorBlue->getValue(); - pp->raw.bayersensor.pixelShiftSum = pixelShiftSum->getValue(); - pp->raw.bayersensor.pixelShiftMedian3 = pixelShiftMedian3->getLastActive (); - pp->raw.bayersensor.pixelShiftMotion = pixelShiftMotion->getIntValue(); - pp->raw.bayersensor.pixelShiftMotionCorrection = (RAWParams::BayerSensor::ePSMotionCorrection)pixelShiftMotionCorrection->get_active_row_number(); - pp->raw.bayersensor.pixelShiftAutomatic = pixelShiftAutomatic->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenHorizontal = pixelShiftNonGreenHorizontal->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenVertical = pixelShiftNonGreenVertical->getLastActive (); - pp->raw.bayersensor.pixelShiftExp0 = pixelShiftExp0->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenCross2 = pixelShiftNonGreenCross2->getLastActive (); - pp->raw.bayersensor.pixelShiftNonGreenAmaze = pixelShiftNonGreenAmaze->getLastActive (); - pp->raw.bayersensor.pixelShiftNreadIso = pixelShiftNreadIso->getValue(); - pp->raw.bayersensor.pixelShiftPrnu = pixelShiftPrnu->getValue(); - pp->raw.bayersensor.pixelShiftRedBlueWeight = pixelShiftRedBlueWeight->getValue(); -#endif int currentRow = method->get_active_row_number(); if( currentRow >= 0 && currentRow < std::numeric_limits::max()) { @@ -591,28 +380,9 @@ void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pe pedited->raw.bayersensor.pixelShiftBlur = !pixelShiftBlur->get_inconsistent(); pedited->raw.bayersensor.pixelShiftSmooth = pixelShiftSmooth->getEditedState(); pedited->raw.bayersensor.pixelShiftLmmse = !pixelShiftLmmse->get_inconsistent(); -// pedited->raw.bayersensor.pixelShiftOneGreen = !pixelShiftOneGreen->get_inconsistent(); pedited->raw.bayersensor.pixelShiftEqualBright = !pixelShiftEqualBright->get_inconsistent(); pedited->raw.bayersensor.pixelShiftEqualBrightChannel = !pixelShiftEqualBrightChannel->get_inconsistent(); pedited->raw.bayersensor.pixelShiftNonGreenCross = !pixelShiftNonGreenCross->get_inconsistent(); -#ifdef PIXELSHIFTDEV - pedited->raw.bayersensor.pixelShiftStddevFactorGreen = pixelShiftStddevFactorGreen->getEditedState (); - pedited->raw.bayersensor.pixelShiftStddevFactorRed = pixelShiftStddevFactorRed->getEditedState (); - pedited->raw.bayersensor.pixelShiftStddevFactorBlue = pixelShiftStddevFactorBlue->getEditedState (); - pedited->raw.bayersensor.pixelShiftSum = pixelShiftSum->getEditedState (); - pedited->raw.bayersensor.pixelShiftMedian3 = !pixelShiftMedian3->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftMotion = pixelShiftMotion->getEditedState (); - pedited->raw.bayersensor.pixelShiftMotionCorrection = pixelShiftMotionCorrection->get_active_text() != M("GENERAL_UNCHANGED"); - pedited->raw.bayersensor.pixelShiftAutomatic = !pixelShiftAutomatic->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenHorizontal = !pixelShiftNonGreenHorizontal->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenVertical = !pixelShiftNonGreenVertical->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftExp0 = !pixelShiftExp0->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenCross2 = !pixelShiftNonGreenCross2->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNonGreenAmaze = !pixelShiftNonGreenAmaze->get_inconsistent(); - pedited->raw.bayersensor.pixelShiftNreadIso = pixelShiftNreadIso->getEditedState (); - pedited->raw.bayersensor.pixelShiftPrnu = pixelShiftPrnu->getEditedState (); - pedited->raw.bayersensor.pixelShiftRedBlueWeight = pixelShiftRedBlueWeight->getEditedState (); -#endif } } @@ -620,10 +390,6 @@ void BayerProcess::setBatchMode(bool batchMode) { method->append (M("GENERAL_UNCHANGED")); method->set_active(std::numeric_limits::max()); // No name -#ifdef PIXELSHIFTDEV - pixelShiftMotionCorrection->append (M("GENERAL_UNCHANGED")); - pixelShiftMotionCorrection->set_active_text (M("GENERAL_UNCHANGED")); -#endif pixelShiftMotionMethod->append (M("GENERAL_UNCHANGED")); pixelShiftMotionMethod->set_active_text (M("GENERAL_UNCHANGED")); imageNumber->append (M("GENERAL_UNCHANGED")); @@ -632,16 +398,6 @@ void BayerProcess::setBatchMode(bool batchMode) ccSteps->showEditedCB (); dcbIterations->showEditedCB (); lmmseIterations->showEditedCB (); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->showEditedCB (); - pixelShiftSum->showEditedCB (); - pixelShiftStddevFactorGreen->showEditedCB (); - pixelShiftStddevFactorRed->showEditedCB (); - pixelShiftStddevFactorBlue->showEditedCB (); - pixelShiftNreadIso->showEditedCB (); - pixelShiftPrnu->showEditedCB (); - pixelShiftRedBlueWeight->showEditedCB (); -#endif pixelShiftEperIso->showEditedCB (); pixelShiftSigma->showEditedCB (); } @@ -650,16 +406,6 @@ void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams { dcbIterations->setDefault( defParams->raw.bayersensor.dcb_iterations); lmmseIterations->setDefault( defParams->raw.bayersensor.lmmse_iterations); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->setDefault( defParams->raw.bayersensor.pixelShiftMotion); - pixelShiftSum->setDefault( defParams->raw.bayersensor.pixelShiftSum); - pixelShiftStddevFactorGreen->setDefault( defParams->raw.bayersensor.pixelShiftStddevFactorGreen); - pixelShiftStddevFactorRed->setDefault( defParams->raw.bayersensor.pixelShiftStddevFactorRed); - pixelShiftStddevFactorBlue->setDefault( defParams->raw.bayersensor.pixelShiftStddevFactorBlue); - pixelShiftNreadIso->setDefault( defParams->raw.bayersensor.pixelShiftNreadIso); - pixelShiftPrnu->setDefault( defParams->raw.bayersensor.pixelShiftPrnu); - pixelShiftRedBlueWeight->setDefault( defParams->raw.bayersensor.pixelShiftRedBlueWeight); -#endif pixelShiftEperIso->setDefault( defParams->raw.bayersensor.pixelShiftEperIso); pixelShiftSigma->setDefault( defParams->raw.bayersensor.pixelShiftSigma); ccSteps->setDefault (defParams->raw.bayersensor.ccSteps); @@ -667,32 +413,12 @@ void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams if (pedited) { dcbIterations->setDefaultEditedState( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); lmmseIterations->setDefaultEditedState( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftMotion ? Edited : UnEdited); - pixelShiftSum->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftSum ? Edited : UnEdited); - pixelShiftStddevFactorGreen->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftStddevFactorGreen ? Edited : UnEdited); - pixelShiftStddevFactorRed->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftStddevFactorRed ? Edited : UnEdited); - pixelShiftStddevFactorBlue->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftStddevFactorBlue ? Edited : UnEdited); - pixelShiftNreadIso->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftNreadIso ? Edited : UnEdited); - pixelShiftPrnu->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftPrnu ? Edited : UnEdited); - pixelShiftRedBlueWeight->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftRedBlueWeight ? Edited : UnEdited); -#endif pixelShiftEperIso->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftEperIso ? Edited : UnEdited); pixelShiftSigma->setDefaultEditedState( pedited->raw.bayersensor.pixelShiftSigma ? Edited : UnEdited); ccSteps->setDefaultEditedState(pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); } else { dcbIterations->setDefaultEditedState( Irrelevant ); lmmseIterations->setDefaultEditedState( Irrelevant ); -#ifdef PIXELSHIFTDEV - pixelShiftMotion->setDefaultEditedState( Irrelevant ); - pixelShiftSum->setDefaultEditedState( Irrelevant ); - pixelShiftStddevFactorGreen->setDefaultEditedState( Irrelevant ); - pixelShiftStddevFactorRed->setDefaultEditedState( Irrelevant ); - pixelShiftStddevFactorBlue->setDefaultEditedState( Irrelevant ); - pixelShiftNreadIso->setDefaultEditedState( Irrelevant ); - pixelShiftPrnu->setDefaultEditedState( Irrelevant ); - pixelShiftRedBlueWeight->setDefaultEditedState( Irrelevant ); -#endif pixelShiftEperIso->setDefaultEditedState( Irrelevant ); pixelShiftSigma->setDefaultEditedState( Irrelevant ); ccSteps->setDefaultEditedState(Irrelevant ); @@ -708,24 +434,6 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); } else if (a == lmmseIterations) { listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() ); -#ifdef PIXELSHIFTDEV - } else if (a == pixelShiftMotion) { - listener->panelChanged (EvPixelShiftMotion, a->getTextValue() ); - } else if (a == pixelShiftSum) { - listener->panelChanged (EvPixelShiftSum, a->getTextValue() ); - } else if (a == pixelShiftStddevFactorGreen) { - listener->panelChanged (EvPixelShiftStddevFactorGreen, a->getTextValue() ); - } else if (a == pixelShiftStddevFactorRed) { - listener->panelChanged (EvPixelShiftStddevFactorRed, a->getTextValue() ); - } else if (a == pixelShiftStddevFactorBlue) { - listener->panelChanged (EvPixelShiftStddevFactorBlue, a->getTextValue() ); - } else if (a == pixelShiftNreadIso) { - listener->panelChanged (EvPixelShiftNreadIso, a->getTextValue() ); - } else if (a == pixelShiftPrnu) { - listener->panelChanged (EvPixelShiftPrnu, a->getTextValue() ); - } else if (a == pixelShiftRedBlueWeight) { - listener->panelChanged (EvPixelShiftRedBlueWeight, a->getTextValue() ); -#endif } else if (a == pixelShiftEperIso) { listener->panelChanged (EvPixelShiftEperIso, a->getTextValue() ); } else if (a == pixelShiftSigma) { @@ -736,27 +444,6 @@ void BayerProcess::adjusterChanged (Adjuster* a, double newval) } } -#ifdef PIXELSHIFTDEV -void BayerProcess::psMotionCorrectionChanged () -{ - if (!batchMode) { - if(pixelShiftMotionCorrection->get_active_row_number() == 5) { - pixelShiftBlur->set_sensitive(true); - pixelShiftHoleFill->set_sensitive(true); - pixelShiftSmooth->set_sensitive(pixelShiftBlur->getValue() != CheckValue::off); - } else { - pixelShiftBlur->set_sensitive(false); - pixelShiftHoleFill->set_sensitive(false); - pixelShiftSmooth->set_sensitive(false); - } - } - - if (listener) { - listener->panelChanged (EvPixelShiftMotionCorrection, pixelShiftMotionCorrection->get_active_text()); - } -} -#endif - void BayerProcess::methodChanged () { const int curSelection = method->get_active_row_number(); @@ -834,11 +521,6 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) listener->panelChanged (EvPixelShiftHoleFill, pixelShiftHoleFill->getValueAsStr ()); } } else if (c == pixelShiftMedian) { -#ifdef PIXELSHIFTDEV - if (!batchMode) { - pixelShiftMedian3->set_sensitive(newval != CheckValue::off); - } -#endif if (listener) { listener->panelChanged (EvPixelShiftMedian, pixelShiftMedian->getValueAsStr ()); } @@ -858,10 +540,6 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) if (listener) { listener->panelChanged (EvPixelShiftLmmse, pixelShiftLmmse->getValueAsStr ()); } -// } else if (c == pixelShiftOneGreen) { -// if (listener) { -// listener->panelChanged (EvPixelShiftOneGreen, pixelShiftOneGreen->getValueAsStr ()); -// } } else if (c == pixelShiftEqualBright) { if (!batchMode) { pixelShiftEqualBrightChannel->set_sensitive(newval != CheckValue::off); @@ -878,61 +556,6 @@ void BayerProcess::checkBoxToggled (CheckBox* c, CheckValue newval) listener->panelChanged (EvPixelShiftNonGreenCross, pixelShiftNonGreenCross->getValueAsStr ()); } } -#ifdef PIXELSHIFTDEV - else if (c == pixelShiftAutomatic) { - if (!batchMode) { - pixelShiftMotion->set_sensitive(newval != CheckValue::off); - pixelShiftEperIso->set_sensitive(newval != CheckValue::off); - pixelShiftNreadIso->set_sensitive(newval != CheckValue::off); - pixelShiftPrnu->set_sensitive(newval != CheckValue::off); - pixelShiftSigma->set_sensitive(newval != CheckValue::off); - pixelShiftSum->set_sensitive(newval != CheckValue::off); - pixelShiftRedBlueWeight->set_sensitive(newval != CheckValue::off); - pixelShiftStddevFactorGreen->set_sensitive(newval != CheckValue::off); - pixelShiftStddevFactorRed->set_sensitive(newval != CheckValue::off); - pixelShiftStddevFactorBlue->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenHorizontal->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenVertical->set_sensitive(newval != CheckValue::off); - pixelShiftHoleFill->set_sensitive(newval != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftMedian3->set_sensitive(newval != CheckValue::off && pixelShiftMedian->getValue () != CheckValue::off); - pixelShiftGreen->set_sensitive(newval != CheckValue::off); - pixelShiftBlur->set_sensitive(newval != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5); - pixelShiftSmooth->set_sensitive(newval != CheckValue::off && pixelShiftMotionCorrection->get_active_row_number() == 5 && pixelShiftBlur->getValue () != CheckValue::off); - pixelShiftExp0->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenCross->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenCross2->set_sensitive(newval != CheckValue::off); - pixelShiftNonGreenAmaze->set_sensitive(newval != CheckValue::off); - } - - if (listener) { - listener->panelChanged (EvPixelShiftAutomatic, pixelShiftAutomatic->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenHorizontal) { - if (listener) { - listener->panelChanged (EvPixelShiftNonGreenHorizontal, pixelShiftNonGreenHorizontal->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenVertical) { - if (listener) { - listener->panelChanged (EvPixelShiftNonGreenVertical, pixelShiftNonGreenVertical->getValueAsStr ()); - } - } else if (c == pixelShiftMedian3) { - if (listener) { - listener->panelChanged (EvPixelShiftMedian3, pixelShiftMedian3->getValueAsStr ()); - } - } else if (c == pixelShiftExp0) { - if (listener) { - listener->panelChanged (EvPixelShiftExp0, pixelShiftExp0->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenCross2) { - if (listener) { - listener->panelChanged (EvPixelShiftGreenAmaze, pixelShiftNonGreenCross2->getValueAsStr ()); - } - } else if (c == pixelShiftNonGreenAmaze) { - if (listener) { - listener->panelChanged (EvPixelShiftNonGreenAmaze, pixelShiftNonGreenAmaze->getValueAsStr ()); - } - } -#endif } void BayerProcess::pixelShiftMotionMethodChanged () diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index e1a620474..48b445d90 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -49,31 +49,12 @@ protected: CheckBox* pixelShiftBlur; CheckBox* pixelShiftHoleFill; CheckBox* pixelShiftMedian; -// CheckBox* pixelShiftOneGreen; CheckBox* pixelShiftLmmse; CheckBox* pixelShiftEqualBright; CheckBox* pixelShiftEqualBrightChannel; Adjuster* pixelShiftSmooth; Adjuster* pixelShiftEperIso; Adjuster* pixelShiftSigma; -#ifdef PIXELSHIFTDEV - Adjuster* pixelShiftSum; - Adjuster* pixelShiftMotion; - MyComboBoxText* pixelShiftMotionCorrection; - CheckBox* pixelShiftAutomatic; - CheckBox* pixelShiftNonGreenHorizontal; - CheckBox* pixelShiftNonGreenVertical; - CheckBox* pixelShiftNonGreenCross2; - CheckBox* pixelShiftNonGreenAmaze; - CheckBox* pixelShiftExp0; - CheckBox* pixelShiftMedian3; - Adjuster* pixelShiftStddevFactorGreen; - Adjuster* pixelShiftStddevFactorRed; - Adjuster* pixelShiftStddevFactorBlue; - Adjuster* pixelShiftNreadIso; - Adjuster* pixelShiftPrnu; - Adjuster* pixelShiftRedBlueWeight; -#endif int oldMethod; IdleRegister idle_register; @@ -92,9 +73,6 @@ public: void checkBoxToggled (CheckBox* c, CheckValue newval); void pixelShiftMotionMethodChanged(); void FrameCountChanged(int n, int frameNum); -#ifdef PIXELSHIFTDEV - void psMotionCorrectionChanged (); -#endif }; #endif diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 71541cdb8..d204f1ff9 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -108,8 +108,9 @@ public: std::string getModel (unsigned int frame = 0) const { return camModel; } std::string getLens (unsigned int frame = 0) const { return lens; } std::string getOrientation (unsigned int frame = 0) const { return ""; } // TODO - bool getPixelShift (unsigned int frame = 0) const { return isPixelShift; } + bool getPixelShift () const { return isPixelShift; } bool getHDR (unsigned int frame = 0) const { return isHDR; } + std::string getImageType (unsigned int frame) const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat (unsigned int frame = 0) const { return sampleFormat; } }; #endif diff --git a/rtgui/dynamicprofilepanel.cc b/rtgui/dynamicprofilepanel.cc index c8a8a1644..d7e8f356a 100644 --- a/rtgui/dynamicprofilepanel.cc +++ b/rtgui/dynamicprofilepanel.cc @@ -41,6 +41,7 @@ DynamicProfilePanel::EditDialog::EditDialog (const Glib::ustring &title, Gtk::Wi add_optional (M ("EXIFFILTER_CAMERA"), has_camera_, camera_); add_optional (M ("EXIFFILTER_LENS"), has_lens_, lens_); + add_optional (M ("EXIFFILTER_IMAGETYPE"), has_imagetype_, imagetype_); add_range (M ("EXIFFILTER_ISO"), iso_min_, iso_max_); add_range (M ("EXIFFILTER_APERTURE"), fnumber_min_, fnumber_max_); @@ -81,6 +82,9 @@ void DynamicProfilePanel::EditDialog::set_rule ( has_lens_->set_active (rule.lens.enabled); lens_->set_text (rule.lens.value); + has_imagetype_->set_active (rule.imagetype.enabled); + imagetype_->set_text (rule.imagetype.value); + profilepath_->updateProfileList(); if (!profilepath_->setActiveRowFromFullPath (rule.profilepath)) { @@ -112,6 +116,9 @@ DynamicProfileRule DynamicProfilePanel::EditDialog::get_rule() ret.lens.enabled = has_lens_->get_active(); ret.lens.value = lens_->get_text(); + ret.imagetype.enabled = has_imagetype_->get_active(); + ret.imagetype.value = imagetype_->get_text(); + ret.profilepath = profilepath_->getFullPathFromActiveRow(); return ret; @@ -254,6 +261,16 @@ DynamicProfilePanel::DynamicProfilePanel(): *this, &DynamicProfilePanel::render_lens)); } + cell = Gtk::manage (new Gtk::CellRendererText()); + cols_count = treeview_.append_column (M ("EXIFFILTER_IMAGETYPE"), *cell); + col = treeview_.get_column (cols_count - 1); + + if (col) { + col->set_cell_data_func ( + *cell, sigc::mem_fun ( + *this, &DynamicProfilePanel::render_imagetype)); + } + cell = Gtk::manage (new Gtk::CellRendererText()); cols_count = treeview_.append_column (M ("EXIFFILTER_ISO"), *cell); col = treeview_.get_column (cols_count - 1); @@ -323,6 +340,7 @@ void DynamicProfilePanel::update_rule (Gtk::TreeModel::Row row, row[columns_.expcomp] = rule.expcomp; row[columns_.camera] = rule.camera; row[columns_.lens] = rule.lens; + row[columns_.imagetype] = rule.imagetype; row[columns_.profilepath] = rule.profilepath; } @@ -346,6 +364,7 @@ DynamicProfileRule DynamicProfilePanel::to_rule (Gtk::TreeModel::Row row, ret.camera = row[columns_.camera]; ret.lens = row[columns_.lens]; ret.profilepath = row[columns_.profilepath]; + ret.imagetype = row[columns_.imagetype]; return ret; } @@ -456,6 +475,12 @@ void DynamicProfilePanel::render_lens ( RENDER_OPTIONAL_ (lens); } +void DynamicProfilePanel::render_imagetype ( + Gtk::CellRenderer *cell, const Gtk::TreeModel::iterator &iter) +{ + RENDER_OPTIONAL_ (imagetype); +} + #undef RENDER_OPTIONAL_ void DynamicProfilePanel::on_button_up() diff --git a/rtgui/dynamicprofilepanel.h b/rtgui/dynamicprofilepanel.h index dca62f1e6..3b5bec4df 100644 --- a/rtgui/dynamicprofilepanel.h +++ b/rtgui/dynamicprofilepanel.h @@ -54,6 +54,7 @@ private: add (camera); add (lens); add (profilepath); + add (imagetype); } Gtk::TreeModelColumn> iso; @@ -63,6 +64,7 @@ private: Gtk::TreeModelColumn> expcomp; Gtk::TreeModelColumn camera; Gtk::TreeModelColumn lens; + Gtk::TreeModelColumn imagetype; Gtk::TreeModelColumn profilepath; }; @@ -74,6 +76,7 @@ private: void render_expcomp (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_camera (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_lens (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); + void render_imagetype (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); void render_profilepath (Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter); class EditDialog: public Gtk::Dialog @@ -109,6 +112,9 @@ private: Gtk::CheckButton *has_lens_; Gtk::Entry *lens_; + Gtk::CheckButton *has_imagetype_; + Gtk::Entry *imagetype_; + ProfileStoreComboBox *profilepath_; }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f02b1fd8e..b1f88230d 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -404,37 +404,20 @@ void ParamsEdited::set(bool v) raw.bayersensor.dcbEnhance = v; //raw.bayersensor.allEnhance = v; raw.bayersensor.lmmseIterations = v; - raw.bayersensor.pixelShiftMotion = v; - raw.bayersensor.pixelShiftMotionCorrection = v; raw.bayersensor.pixelShiftMotionCorrectionMethod = v; - raw.bayersensor.pixelShiftStddevFactorGreen = v; - raw.bayersensor.pixelShiftStddevFactorRed = v; - raw.bayersensor.pixelShiftStddevFactorBlue = v; raw.bayersensor.pixelShiftEperIso = v; - raw.bayersensor.pixelShiftNreadIso = v; - raw.bayersensor.pixelShiftPrnu = v; raw.bayersensor.pixelShiftSigma = v; - raw.bayersensor.pixelShiftSum = v; - raw.bayersensor.pixelShiftRedBlueWeight = v; raw.bayersensor.pixelShiftShowMotion = v; raw.bayersensor.pixelShiftShowMotionMaskOnly = v; - raw.bayersensor.pixelShiftAutomatic = v; - raw.bayersensor.pixelShiftNonGreenHorizontal = v; - raw.bayersensor.pixelShiftNonGreenVertical = v; raw.bayersensor.pixelShiftHoleFill = v; raw.bayersensor.pixelShiftMedian = v; - raw.bayersensor.pixelShiftMedian3 = v; raw.bayersensor.pixelShiftGreen = v; raw.bayersensor.pixelShiftBlur = v; raw.bayersensor.pixelShiftSmooth = v; - raw.bayersensor.pixelShiftExp0 = v; raw.bayersensor.pixelShiftLmmse = v; - raw.bayersensor.pixelShiftOneGreen = v; raw.bayersensor.pixelShiftEqualBright = v; raw.bayersensor.pixelShiftEqualBrightChannel = v; raw.bayersensor.pixelShiftNonGreenCross = v; - raw.bayersensor.pixelShiftNonGreenCross2 = v; - raw.bayersensor.pixelShiftNonGreenAmaze = v; raw.bayersensor.greenEq = v; raw.bayersensor.linenoise = v; raw.bayersensor.linenoiseDirection = v; @@ -971,37 +954,20 @@ void ParamsEdited::initFrom(const std::vector& raw.bayersensor.dcbEnhance = raw.bayersensor.dcbEnhance && p.raw.bayersensor.dcb_enhance == other.raw.bayersensor.dcb_enhance; //raw.bayersensor.allEnhance = raw.bayersensor.allEnhance && p.raw.bayersensor.all_enhance == other.raw.bayersensor.all_enhance; raw.bayersensor.lmmseIterations = raw.bayersensor.lmmseIterations && p.raw.bayersensor.lmmse_iterations == other.raw.bayersensor.lmmse_iterations; - raw.bayersensor.pixelShiftMotion = raw.bayersensor.pixelShiftMotion && p.raw.bayersensor.pixelShiftMotion == other.raw.bayersensor.pixelShiftMotion; - raw.bayersensor.pixelShiftMotionCorrection = raw.bayersensor.pixelShiftMotionCorrection && p.raw.bayersensor.pixelShiftMotionCorrection == other.raw.bayersensor.pixelShiftMotionCorrection; raw.bayersensor.pixelShiftMotionCorrectionMethod = raw.bayersensor.pixelShiftMotionCorrectionMethod && p.raw.bayersensor.pixelShiftMotionCorrectionMethod == other.raw.bayersensor.pixelShiftMotionCorrectionMethod; - raw.bayersensor.pixelShiftStddevFactorGreen = raw.bayersensor.pixelShiftStddevFactorGreen && p.raw.bayersensor.pixelShiftStddevFactorGreen == other.raw.bayersensor.pixelShiftStddevFactorGreen; - raw.bayersensor.pixelShiftStddevFactorRed = raw.bayersensor.pixelShiftStddevFactorRed && p.raw.bayersensor.pixelShiftStddevFactorRed == other.raw.bayersensor.pixelShiftStddevFactorRed; - raw.bayersensor.pixelShiftStddevFactorBlue = raw.bayersensor.pixelShiftStddevFactorBlue && p.raw.bayersensor.pixelShiftStddevFactorBlue == other.raw.bayersensor.pixelShiftStddevFactorBlue; raw.bayersensor.pixelShiftEperIso = raw.bayersensor.pixelShiftEperIso && p.raw.bayersensor.pixelShiftEperIso == other.raw.bayersensor.pixelShiftEperIso; - raw.bayersensor.pixelShiftNreadIso = raw.bayersensor.pixelShiftNreadIso && p.raw.bayersensor.pixelShiftNreadIso == other.raw.bayersensor.pixelShiftNreadIso; - raw.bayersensor.pixelShiftPrnu = raw.bayersensor.pixelShiftPrnu && p.raw.bayersensor.pixelShiftPrnu == other.raw.bayersensor.pixelShiftPrnu; raw.bayersensor.pixelShiftSigma = raw.bayersensor.pixelShiftSigma && p.raw.bayersensor.pixelShiftSigma == other.raw.bayersensor.pixelShiftSigma; - raw.bayersensor.pixelShiftSum = raw.bayersensor.pixelShiftSum && p.raw.bayersensor.pixelShiftSum == other.raw.bayersensor.pixelShiftSum; - raw.bayersensor.pixelShiftRedBlueWeight = raw.bayersensor.pixelShiftRedBlueWeight && p.raw.bayersensor.pixelShiftRedBlueWeight == other.raw.bayersensor.pixelShiftRedBlueWeight; raw.bayersensor.pixelShiftShowMotion = raw.bayersensor.pixelShiftShowMotion && p.raw.bayersensor.pixelShiftShowMotion == other.raw.bayersensor.pixelShiftShowMotion; raw.bayersensor.pixelShiftShowMotionMaskOnly = raw.bayersensor.pixelShiftShowMotionMaskOnly && p.raw.bayersensor.pixelShiftShowMotionMaskOnly == other.raw.bayersensor.pixelShiftShowMotionMaskOnly; - raw.bayersensor.pixelShiftAutomatic = raw.bayersensor.pixelShiftAutomatic && p.raw.bayersensor.pixelShiftAutomatic == other.raw.bayersensor.pixelShiftAutomatic; - raw.bayersensor.pixelShiftNonGreenHorizontal = raw.bayersensor.pixelShiftNonGreenHorizontal && p.raw.bayersensor.pixelShiftNonGreenHorizontal == other.raw.bayersensor.pixelShiftNonGreenHorizontal; - raw.bayersensor.pixelShiftNonGreenVertical = raw.bayersensor.pixelShiftNonGreenVertical && p.raw.bayersensor.pixelShiftNonGreenVertical == other.raw.bayersensor.pixelShiftNonGreenVertical; raw.bayersensor.pixelShiftHoleFill = raw.bayersensor.pixelShiftHoleFill && p.raw.bayersensor.pixelShiftHoleFill == other.raw.bayersensor.pixelShiftHoleFill; raw.bayersensor.pixelShiftMedian = raw.bayersensor.pixelShiftMedian && p.raw.bayersensor.pixelShiftMedian == other.raw.bayersensor.pixelShiftMedian; - raw.bayersensor.pixelShiftMedian3 = raw.bayersensor.pixelShiftMedian3 && p.raw.bayersensor.pixelShiftMedian3 == other.raw.bayersensor.pixelShiftMedian3; raw.bayersensor.pixelShiftGreen = raw.bayersensor.pixelShiftGreen && p.raw.bayersensor.pixelShiftGreen == other.raw.bayersensor.pixelShiftGreen; raw.bayersensor.pixelShiftBlur = raw.bayersensor.pixelShiftBlur && p.raw.bayersensor.pixelShiftBlur == other.raw.bayersensor.pixelShiftBlur; raw.bayersensor.pixelShiftSmooth = raw.bayersensor.pixelShiftSmooth && p.raw.bayersensor.pixelShiftSmoothFactor == other.raw.bayersensor.pixelShiftSmoothFactor; - raw.bayersensor.pixelShiftExp0 = raw.bayersensor.pixelShiftExp0 && p.raw.bayersensor.pixelShiftExp0 == other.raw.bayersensor.pixelShiftExp0; raw.bayersensor.pixelShiftLmmse = raw.bayersensor.pixelShiftLmmse && p.raw.bayersensor.pixelShiftLmmse == other.raw.bayersensor.pixelShiftLmmse; - raw.bayersensor.pixelShiftOneGreen = raw.bayersensor.pixelShiftOneGreen && p.raw.bayersensor.pixelShiftOneGreen == other.raw.bayersensor.pixelShiftOneGreen; raw.bayersensor.pixelShiftEqualBright = raw.bayersensor.pixelShiftEqualBright && p.raw.bayersensor.pixelShiftEqualBright == other.raw.bayersensor.pixelShiftEqualBright; raw.bayersensor.pixelShiftEqualBrightChannel = raw.bayersensor.pixelShiftEqualBrightChannel && p.raw.bayersensor.pixelShiftEqualBrightChannel == other.raw.bayersensor.pixelShiftEqualBrightChannel; raw.bayersensor.pixelShiftNonGreenCross = raw.bayersensor.pixelShiftNonGreenCross && p.raw.bayersensor.pixelShiftNonGreenCross == other.raw.bayersensor.pixelShiftNonGreenCross; - raw.bayersensor.pixelShiftNonGreenCross2 = raw.bayersensor.pixelShiftNonGreenCross2 && p.raw.bayersensor.pixelShiftNonGreenCross2 == other.raw.bayersensor.pixelShiftNonGreenCross2; - raw.bayersensor.pixelShiftNonGreenAmaze = raw.bayersensor.pixelShiftNonGreenAmaze && p.raw.bayersensor.pixelShiftNonGreenAmaze == other.raw.bayersensor.pixelShiftNonGreenAmaze; raw.bayersensor.greenEq = raw.bayersensor.greenEq && p.raw.bayersensor.greenthresh == other.raw.bayersensor.greenthresh; raw.bayersensor.linenoise = raw.bayersensor.linenoise && p.raw.bayersensor.linenoise == other.raw.bayersensor.linenoise; raw.bayersensor.linenoiseDirection = raw.bayersensor.linenoiseDirection && p.raw.bayersensor.linenoiseDirection == other.raw.bayersensor.linenoiseDirection; @@ -2542,54 +2508,18 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.bayersensor.lmmse_iterations = mods.raw.bayersensor.lmmse_iterations; } - if (raw.bayersensor.pixelShiftMotion) { - toEdit.raw.bayersensor.pixelShiftMotion = mods.raw.bayersensor.pixelShiftMotion; - } - - if (raw.bayersensor.pixelShiftMotionCorrection) { - toEdit.raw.bayersensor.pixelShiftMotionCorrection = mods.raw.bayersensor.pixelShiftMotionCorrection; - } - if (raw.bayersensor.pixelShiftMotionCorrectionMethod) { toEdit.raw.bayersensor.pixelShiftMotionCorrectionMethod = mods.raw.bayersensor.pixelShiftMotionCorrectionMethod; } - if (raw.bayersensor.pixelShiftStddevFactorGreen) { - toEdit.raw.bayersensor.pixelShiftStddevFactorGreen = mods.raw.bayersensor.pixelShiftStddevFactorGreen; - } - - if (raw.bayersensor.pixelShiftStddevFactorRed) { - toEdit.raw.bayersensor.pixelShiftStddevFactorRed = mods.raw.bayersensor.pixelShiftStddevFactorRed; - } - - if (raw.bayersensor.pixelShiftStddevFactorBlue) { - toEdit.raw.bayersensor.pixelShiftStddevFactorBlue = mods.raw.bayersensor.pixelShiftStddevFactorBlue; - } - if (raw.bayersensor.pixelShiftEperIso) { toEdit.raw.bayersensor.pixelShiftEperIso = mods.raw.bayersensor.pixelShiftEperIso; } - if (raw.bayersensor.pixelShiftNreadIso) { - toEdit.raw.bayersensor.pixelShiftNreadIso = mods.raw.bayersensor.pixelShiftNreadIso; - } - - if (raw.bayersensor.pixelShiftPrnu) { - toEdit.raw.bayersensor.pixelShiftPrnu = mods.raw.bayersensor.pixelShiftPrnu; - } - if (raw.bayersensor.pixelShiftSigma) { toEdit.raw.bayersensor.pixelShiftSigma = mods.raw.bayersensor.pixelShiftSigma; } - if (raw.bayersensor.pixelShiftSum) { - toEdit.raw.bayersensor.pixelShiftSum = mods.raw.bayersensor.pixelShiftSum; - } - - if (raw.bayersensor.pixelShiftRedBlueWeight) { - toEdit.raw.bayersensor.pixelShiftRedBlueWeight = mods.raw.bayersensor.pixelShiftRedBlueWeight; - } - if (raw.bayersensor.pixelShiftShowMotion) { toEdit.raw.bayersensor.pixelShiftShowMotion = mods.raw.bayersensor.pixelShiftShowMotion; } @@ -2598,18 +2528,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.bayersensor.pixelShiftShowMotionMaskOnly = mods.raw.bayersensor.pixelShiftShowMotionMaskOnly; } - if (raw.bayersensor.pixelShiftAutomatic) { - toEdit.raw.bayersensor.pixelShiftAutomatic = mods.raw.bayersensor.pixelShiftAutomatic; - } - - if (raw.bayersensor.pixelShiftNonGreenHorizontal) { - toEdit.raw.bayersensor.pixelShiftNonGreenHorizontal = mods.raw.bayersensor.pixelShiftNonGreenHorizontal; - } - - if (raw.bayersensor.pixelShiftNonGreenVertical) { - toEdit.raw.bayersensor.pixelShiftNonGreenVertical = mods.raw.bayersensor.pixelShiftNonGreenVertical; - } - if (raw.bayersensor.pixelShiftHoleFill) { toEdit.raw.bayersensor.pixelShiftHoleFill = mods.raw.bayersensor.pixelShiftHoleFill; } @@ -2618,10 +2536,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.bayersensor.pixelShiftMedian = mods.raw.bayersensor.pixelShiftMedian; } - if (raw.bayersensor.pixelShiftMedian3) { - toEdit.raw.bayersensor.pixelShiftMedian3 = mods.raw.bayersensor.pixelShiftMedian3; - } - if (raw.bayersensor.pixelShiftGreen) { toEdit.raw.bayersensor.pixelShiftGreen = mods.raw.bayersensor.pixelShiftGreen; } @@ -2634,18 +2548,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.bayersensor.pixelShiftSmoothFactor = mods.raw.bayersensor.pixelShiftSmoothFactor; } - if (raw.bayersensor.pixelShiftExp0) { - toEdit.raw.bayersensor.pixelShiftExp0 = mods.raw.bayersensor.pixelShiftExp0; - } - if (raw.bayersensor.pixelShiftLmmse) { toEdit.raw.bayersensor.pixelShiftLmmse = mods.raw.bayersensor.pixelShiftLmmse; } - if (raw.bayersensor.pixelShiftOneGreen) { - toEdit.raw.bayersensor.pixelShiftOneGreen = mods.raw.bayersensor.pixelShiftOneGreen; - } - if (raw.bayersensor.pixelShiftEqualBright) { toEdit.raw.bayersensor.pixelShiftEqualBright = mods.raw.bayersensor.pixelShiftEqualBright; } @@ -2658,14 +2564,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.raw.bayersensor.pixelShiftNonGreenCross = mods.raw.bayersensor.pixelShiftNonGreenCross; } - if (raw.bayersensor.pixelShiftNonGreenCross2) { - toEdit.raw.bayersensor.pixelShiftNonGreenCross2 = mods.raw.bayersensor.pixelShiftNonGreenCross2; - } - - if (raw.bayersensor.pixelShiftNonGreenAmaze) { - toEdit.raw.bayersensor.pixelShiftNonGreenAmaze = mods.raw.bayersensor.pixelShiftNonGreenAmaze; - } - if (raw.bayersensor.greenEq) { toEdit.raw.bayersensor.greenthresh = dontforceSet && options.baBehav[ADDSET_PREPROCESS_GREENEQUIL] ? toEdit.raw.bayersensor.greenthresh + mods.raw.bayersensor.greenthresh : mods.raw.bayersensor.greenthresh; } @@ -3187,9 +3085,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng bool RAWParamsEdited::BayerSensor::isUnchanged() const { return method && imageNum && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq - && pixelShiftMotion && pixelShiftMotionCorrection && pixelShiftMotionCorrectionMethod && pixelShiftStddevFactorGreen && pixelShiftStddevFactorRed && pixelShiftStddevFactorBlue && pixelShiftEperIso - && pixelShiftNreadIso && pixelShiftPrnu && pixelShiftSigma && pixelShiftSum && pixelShiftRedBlueWeight && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly - && pixelShiftAutomatic && pixelShiftNonGreenHorizontal && pixelShiftNonGreenVertical && pixelShiftHoleFill && pixelShiftMedian && pixelShiftMedian3 && pixelShiftNonGreenCross && pixelShiftNonGreenCross2 && pixelShiftNonGreenAmaze && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftExp0 && pixelShiftLmmse && pixelShiftOneGreen && pixelShiftEqualBright && pixelShiftEqualBrightChannel + && pixelShiftMotionCorrectionMethod && pixelShiftEperIso && pixelShiftSigma && pixelShiftShowMotion && pixelShiftShowMotionMaskOnly + && pixelShiftHoleFill && pixelShiftMedian && pixelShiftNonGreenCross && pixelShiftGreen && pixelShiftBlur && pixelShiftSmooth && pixelShiftLmmse && pixelShiftEqualBright && pixelShiftEqualBrightChannel && linenoise && linenoiseDirection && pdafLinesFilter && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 5dcf987cc..949da1106 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -734,37 +734,20 @@ public: bool dcbIterations; bool dcbEnhance; bool lmmseIterations; - bool pixelShiftMotion; - bool pixelShiftMotionCorrection; bool pixelShiftMotionCorrectionMethod; - bool pixelShiftStddevFactorGreen; - bool pixelShiftStddevFactorRed; - bool pixelShiftStddevFactorBlue; bool pixelShiftEperIso; - bool pixelShiftNreadIso; - bool pixelShiftPrnu; bool pixelShiftSigma; - bool pixelShiftSum; - bool pixelShiftRedBlueWeight; bool pixelShiftShowMotion; bool pixelShiftShowMotionMaskOnly; - bool pixelShiftAutomatic; - bool pixelShiftNonGreenHorizontal; - bool pixelShiftNonGreenVertical; bool pixelShiftHoleFill; bool pixelShiftMedian; - bool pixelShiftMedian3; bool pixelShiftGreen; bool pixelShiftBlur; bool pixelShiftSmooth; - bool pixelShiftExp0; bool pixelShiftLmmse; - bool pixelShiftOneGreen; bool pixelShiftEqualBright; bool pixelShiftEqualBrightChannel; bool pixelShiftNonGreenCross; - bool pixelShiftNonGreenCross2; - bool pixelShiftNonGreenAmaze; //bool allEnhance; bool greenEq; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 4828e90dc..c9ed1cd14 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -846,34 +846,18 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param } if (!raw_pixelshift->get_active ()) { - filterPE.raw.bayersensor.pixelShiftAutomatic = falsePE.raw.bayersensor.pixelShiftAutomatic; filterPE.raw.bayersensor.pixelShiftBlur = falsePE.raw.bayersensor.pixelShiftBlur; filterPE.raw.bayersensor.pixelShiftEperIso = falsePE.raw.bayersensor.pixelShiftEperIso; filterPE.raw.bayersensor.pixelShiftEqualBright = falsePE.raw.bayersensor.pixelShiftEqualBright; filterPE.raw.bayersensor.pixelShiftEqualBrightChannel = falsePE.raw.bayersensor.pixelShiftEqualBrightChannel; - filterPE.raw.bayersensor.pixelShiftExp0 = falsePE.raw.bayersensor.pixelShiftExp0; filterPE.raw.bayersensor.pixelShiftGreen = falsePE.raw.bayersensor.pixelShiftGreen; filterPE.raw.bayersensor.pixelShiftHoleFill = falsePE.raw.bayersensor.pixelShiftHoleFill; filterPE.raw.bayersensor.pixelShiftLmmse = falsePE.raw.bayersensor.pixelShiftLmmse; filterPE.raw.bayersensor.pixelShiftMedian = falsePE.raw.bayersensor.pixelShiftMedian; - filterPE.raw.bayersensor.pixelShiftMedian3 = falsePE.raw.bayersensor.pixelShiftMedian3; - filterPE.raw.bayersensor.pixelShiftMotion = falsePE.raw.bayersensor.pixelShiftMotion; - filterPE.raw.bayersensor.pixelShiftMotionCorrection = falsePE.raw.bayersensor.pixelShiftMotionCorrection; filterPE.raw.bayersensor.pixelShiftMotionCorrectionMethod = falsePE.raw.bayersensor.pixelShiftMotionCorrectionMethod; - filterPE.raw.bayersensor.pixelShiftNonGreenAmaze = falsePE.raw.bayersensor.pixelShiftNonGreenAmaze; filterPE.raw.bayersensor.pixelShiftNonGreenCross = falsePE.raw.bayersensor.pixelShiftNonGreenCross; - filterPE.raw.bayersensor.pixelShiftNonGreenCross2 = falsePE.raw.bayersensor.pixelShiftNonGreenCross2; - filterPE.raw.bayersensor.pixelShiftNonGreenHorizontal = falsePE.raw.bayersensor.pixelShiftNonGreenHorizontal; - filterPE.raw.bayersensor.pixelShiftNonGreenVertical = falsePE.raw.bayersensor.pixelShiftNonGreenVertical; - filterPE.raw.bayersensor.pixelShiftNreadIso = falsePE.raw.bayersensor.pixelShiftNreadIso; - filterPE.raw.bayersensor.pixelShiftPrnu = falsePE.raw.bayersensor.pixelShiftPrnu; - filterPE.raw.bayersensor.pixelShiftRedBlueWeight = falsePE.raw.bayersensor.pixelShiftRedBlueWeight; filterPE.raw.bayersensor.pixelShiftSigma = falsePE.raw.bayersensor.pixelShiftSigma; filterPE.raw.bayersensor.pixelShiftSmooth = falsePE.raw.bayersensor.pixelShiftSmooth; - filterPE.raw.bayersensor.pixelShiftStddevFactorBlue = falsePE.raw.bayersensor.pixelShiftStddevFactorBlue; - filterPE.raw.bayersensor.pixelShiftStddevFactorGreen = falsePE.raw.bayersensor.pixelShiftStddevFactorGreen; - filterPE.raw.bayersensor.pixelShiftStddevFactorRed = falsePE.raw.bayersensor.pixelShiftStddevFactorRed; - filterPE.raw.bayersensor.pixelShiftSum = falsePE.raw.bayersensor.pixelShiftSum; filterPE.raw.bayersensor.pixelShiftShowMotion = falsePE.raw.bayersensor.pixelShiftShowMotion; filterPE.raw.bayersensor.pixelShiftShowMotionMaskOnly = falsePE.raw.bayersensor.pixelShiftShowMotionMaskOnly; } diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index e2838c2c0..f3ef28f4a 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -1,11 +1,13 @@ #pragma once // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 331 +#define PPVERSION 332 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 332 2018-18-04 + changed pixelShiftEperIso calculation 331 2018-14-02 changed wavelet.Lmethod to int 330 2018-20-01 diff --git a/tools/win/InnoSetup/WindowsInnoSetup.iss.in b/tools/win/InnoSetup/WindowsInnoSetup.iss.in index 235d64968..6814d9c74 100644 --- a/tools/win/InnoSetup/WindowsInnoSetup.iss.in +++ b/tools/win/InnoSetup/WindowsInnoSetup.iss.in @@ -38,7 +38,7 @@ AppId={#MyAppName}{#MyAppVersion} AppName={#MyAppName} AppVersion={#MyAppVersion} -VersionInfoVersion={#MyAppVersionNumeric} +;VersionInfoVersion={#MyAppVersionNumeric} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL}