From e12b58cfcf32c62823f1ffbd32291d7997576b0c Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 6 Nov 2019 14:40:05 +0100 Subject: [PATCH 01/18] Decode standard Panasonic DC-S1 and DC-S1R files (pixelshift files are not supported yet), #5204 --- rtengine/camconst.json | 5 ++ rtengine/dcraw.cc | 171 +++++++++++++++++++++++++++++++++++++++++ rtengine/dcraw.h | 15 ++++ 3 files changed, 191 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 3393dec9f..169b0b0b7 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2142,6 +2142,11 @@ Camera constants: } }, + { // Quality B, per ISO info missing + "make_model": [ "Panasonic DC-S1", "Panasonic DC-S1R" ], + "ranges": { "white": 16383 } + }, + { // Quality B, per ISO info missing "make_model": "PENTAX K-x", "dcraw_matrix": [ 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 ], // adobe dcp d65 diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index ae6f60cd1..7278f867f 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2757,6 +2757,10 @@ void CLASS panasonic_load_raw() } } } + } else if (RT_pana_info.encoding == 6) { + panasonicC6_load_raw(); + } else if (RT_pana_info.encoding == 7) { + panasonicC7_load_raw(); } else { for (row=0; row < height; row++) for (col=0; col < raw_width; col++) { @@ -10759,6 +10763,173 @@ void CLASS nikon_14bit_load_raw() free(buf); } +// Code adapted from libraw +/* -*- C++ -*- + * Copyright 2019 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +void CLASS pana_cs6_page_decoder::read_page() +{ + if (!buffer || (maxoffset - lastoffset < 16)) + ; +#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) + pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit + pixelbuffer[1] = + (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & + 0x3fff; + pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; + pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); + pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); + pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); + pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; + pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); + pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); + pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; + pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; + pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); + pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; + pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; +#undef wbuffer + current = 0; + lastoffset += 16; +} + +void CLASS panasonicC6_load_raw() +{ + const int rowstep = 16; + const int blocksperrow = raw_width / 11; + const int rowbytes = blocksperrow * 16; + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC6_load_raw()"); + + for (int row = 0; row < raw_height - rowstep + 1; + row += rowstep) + { + int rowstoread = MIN(rowstep, raw_height - row); + fread (iobuf, rowbytes, rowstoread, ifp); +// if (libraw_internal_data.internal_data.input->read( +// iobuf, rowbytes, rowstoread) != rowstoread) +// throw LIBRAW_EXCEPTION_IO_EOF; + pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread); + for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) + { + unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; + for (int rblock = 0; rblock < blocksperrow; rblock++) + { + page.read_page(); + unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; + unsigned pmul = 0, pixel_base = 0; + for (int pix = 0; pix < 11; pix++) + { + if (pix % 3 == 2) + { + unsigned base = page.nextpixel(); + if (base > 3); +// throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit + // field, but.... + if (base == 3) + base = 4; + pixel_base = 0x200 << base; + pmul = 1 << base; + } + unsigned epixel = page.nextpixel(); + if (oddeven[pix % 2]) + { + epixel *= pmul; + if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) + epixel += nonzero[pix % 2] - pixel_base; + nonzero[pix % 2] = epixel; + } + else + { + oddeven[pix % 2] = epixel; + if (epixel) + nonzero[pix % 2] = epixel; + else + epixel = nonzero[pix % 2]; + } + unsigned spix = epixel - 0xf; + if (spix <= 0xffff) + rowptr[col++] = spix & 0xffff; + else + { + epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); + rowptr[col++] = epixel & 0x3fff; + } + } + } + } + } + free(iobuf); + tiff_bps = RT_pana_info.bpp; +} + +void CLASS panasonicC7_load_raw() +{ + const int rowstep = 16; + int pixperblock = RT_pana_info.bpp == 14 ? 9 : 10; + int rowbytes = raw_width / pixperblock * 16; + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC7_load_raw()"); + for (int row = 0; row < raw_height - rowstep + 1; + row += rowstep) + { + int rowstoread = MIN(rowstep, raw_height - row); + fread (iobuf, rowbytes, rowstoread, ifp); + unsigned char *bytes = iobuf; + for (int crow = 0; crow < rowstoread; crow++) + { + unsigned short *rowptr = &raw_image[(row + crow)]; + for (int col = 0; col < raw_width - pixperblock + 1; + col += pixperblock, bytes += 16) + { + if (RT_pana_info.bpp == 14) + { + rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + rowptr[col + 1] = + (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + rowptr[col + 2] = + (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + rowptr[col + 5] = + (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + rowptr[col + 6] = + (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + else if (RT_pana_info.bpp == + 12) // have not seen in the wild yet + { + rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + } + } + } + free(iobuf); + tiff_bps = RT_pana_info.bpp; +} + //----------------------------------------------------------------------------- /* RT: Delete from here */ diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 5e17b47ab..522cc798d 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -411,6 +411,21 @@ private: unsigned encoding; }; +class pana_cs6_page_decoder +{ + unsigned int pixelbuffer[14], lastoffset, maxoffset; + unsigned char current, *buffer; + public: + pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) + : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) + { + } + void read_page(); // will throw IO error if not enough space in buffer + unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } +}; +void panasonicC6_load_raw(); +void panasonicC7_load_raw(); + void canon_rmf_load_raw(); void panasonic_load_raw(); void olympus_load_raw(); From 70a00d335acf5d3331da6c6c1e959d09ea91f443 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 6 Nov 2019 14:53:50 +0100 Subject: [PATCH 02/18] better white level for panasonic dc-s1 --- rtengine/camconst.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 169b0b0b7..32e8bc628 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2144,7 +2144,7 @@ Camera constants: { // Quality B, per ISO info missing "make_model": [ "Panasonic DC-S1", "Panasonic DC-S1R" ], - "ranges": { "white": 16383 } + "ranges": { "white": 16225 } }, { // Quality B, per ISO info missing From 2da0990433462eda5b099a7b57581012fbf3fdc6 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 6 Nov 2019 23:07:41 +0100 Subject: [PATCH 03/18] make own compilation unit for panasonic decoders --- rtengine/CMakeLists.txt | 1 + rtengine/dcraw.cc | 260 ------------------------------- rtengine/dcraw.h | 12 -- rtengine/panasonic_decoders.cc | 276 +++++++++++++++++++++++++++++++++ 4 files changed, 277 insertions(+), 272 deletions(-) create mode 100644 rtengine/panasonic_decoders.cc diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 07b0d9f84..c37341c8b 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -104,6 +104,7 @@ set(RTENGINESOURCEFILES lj92.c loadinitial.cc myfile.cc + panasonic_decoders.cc pdaflinesfilter.cc PF_correct_RT.cc pipettebuffer.cc diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 7278f867f..b81594dc4 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2688,97 +2688,6 @@ void CLASS canon_rmf_load_raw() maximum = curve[0x3ff]; } -unsigned CLASS pana_bits_t::operator() (int nbits, unsigned *bytes) -{ -/*RT static uchar buf[0x4000]; */ -/*RT static int vbits;*/ - int byte; - - if (!nbits && !bytes) return vbits=0; - if (!vbits) { - fread (buf+load_flags, 1, 0x4000-load_flags, ifp); - fread (buf, 1, load_flags, ifp); - } - if (encoding == 5) { - for (byte = 0; byte < 16; byte++) - { - bytes[byte] = buf[vbits++]; - vbits &= 0x3FFF; - } - return 0; - } else { - vbits = (vbits - nbits) & 0x1ffff; - byte = vbits >> 3 ^ 0x3ff0; - return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); - } -} - -void CLASS panasonic_load_raw() -{ - pana_bits_t pana_bits(ifp,load_flags, RT_pana_info.encoding); - int row, col, i, j, sh=0, pred[2], nonz[2]; - unsigned bytes[16] = {}; - ushort *raw_block_data; - - pana_bits(0, 0); - int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; - if (RT_pana_info.encoding == 5) { - for (row = 0; row < raw_height; row++) - { - raw_block_data = raw_image + row * raw_width; - - for (col = 0; col < raw_width; col += enc_blck_size) { - pana_bits(0, bytes); - - if (RT_pana_info.bpp == 12) { - raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; - raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); - raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; - raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); - raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; - raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); - raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; - raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); - raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; - raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); - } - else if (RT_pana_info.bpp == 14) { - raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); - raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + - ((bytes[3] & 0xF) << 10); - raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + - ((bytes[5] & 3) << 12); - raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); - raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); - raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); - raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); - raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); - raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); - } - } - } - } else if (RT_pana_info.encoding == 6) { - panasonicC6_load_raw(); - } else if (RT_pana_info.encoding == 7) { - panasonicC7_load_raw(); - } else { - for (row=0; row < height; row++) - for (col=0; col < raw_width; col++) { - if ((i = col % 14) == 0) - pred[0] = pred[1] = nonz[0] = nonz[1] = 0; - if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); - if (nonz[i & 1]) { - if ((j = pana_bits(8))) { - if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) - pred[i & 1] &= ~(-1 << sh); - pred[i & 1] += j << sh; - } - } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) - pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); - if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror(); - } - } -} void CLASS olympus_load_raw() { @@ -10763,175 +10672,6 @@ void CLASS nikon_14bit_load_raw() free(buf); } -// Code adapted from libraw -/* -*- C++ -*- - * Copyright 2019 LibRaw LLC (info@libraw.org) - * - LibRaw is free software; you can redistribute it and/or modify - it under the terms of the one of two licenses as you choose: - -1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 - (See file LICENSE.LGPL provided in LibRaw distribution archive for details). - -2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 - (See file LICENSE.CDDL provided in LibRaw distribution archive for details). - - */ - -void CLASS pana_cs6_page_decoder::read_page() -{ - if (!buffer || (maxoffset - lastoffset < 16)) - ; -#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) - pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit - pixelbuffer[1] = - (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & - 0x3fff; - pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; - pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); - pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); - pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); - pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; - pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); - pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); - pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; - pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; - pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); - pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; - pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; -#undef wbuffer - current = 0; - lastoffset += 16; -} - -void CLASS panasonicC6_load_raw() -{ - const int rowstep = 16; - const int blocksperrow = raw_width / 11; - const int rowbytes = blocksperrow * 16; - unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); - merror(iobuf, "panasonicC6_load_raw()"); - - for (int row = 0; row < raw_height - rowstep + 1; - row += rowstep) - { - int rowstoread = MIN(rowstep, raw_height - row); - fread (iobuf, rowbytes, rowstoread, ifp); -// if (libraw_internal_data.internal_data.input->read( -// iobuf, rowbytes, rowstoread) != rowstoread) -// throw LIBRAW_EXCEPTION_IO_EOF; - pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread); - for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) - { - unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; - for (int rblock = 0; rblock < blocksperrow; rblock++) - { - page.read_page(); - unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; - unsigned pmul = 0, pixel_base = 0; - for (int pix = 0; pix < 11; pix++) - { - if (pix % 3 == 2) - { - unsigned base = page.nextpixel(); - if (base > 3); -// throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit - // field, but.... - if (base == 3) - base = 4; - pixel_base = 0x200 << base; - pmul = 1 << base; - } - unsigned epixel = page.nextpixel(); - if (oddeven[pix % 2]) - { - epixel *= pmul; - if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) - epixel += nonzero[pix % 2] - pixel_base; - nonzero[pix % 2] = epixel; - } - else - { - oddeven[pix % 2] = epixel; - if (epixel) - nonzero[pix % 2] = epixel; - else - epixel = nonzero[pix % 2]; - } - unsigned spix = epixel - 0xf; - if (spix <= 0xffff) - rowptr[col++] = spix & 0xffff; - else - { - epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); - rowptr[col++] = epixel & 0x3fff; - } - } - } - } - } - free(iobuf); - tiff_bps = RT_pana_info.bpp; -} - -void CLASS panasonicC7_load_raw() -{ - const int rowstep = 16; - int pixperblock = RT_pana_info.bpp == 14 ? 9 : 10; - int rowbytes = raw_width / pixperblock * 16; - unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); - merror(iobuf, "panasonicC7_load_raw()"); - for (int row = 0; row < raw_height - rowstep + 1; - row += rowstep) - { - int rowstoread = MIN(rowstep, raw_height - row); - fread (iobuf, rowbytes, rowstoread, ifp); - unsigned char *bytes = iobuf; - for (int crow = 0; crow < rowstoread; crow++) - { - unsigned short *rowptr = &raw_image[(row + crow)]; - for (int col = 0; col < raw_width - pixperblock + 1; - col += pixperblock, bytes += 16) - { - if (RT_pana_info.bpp == 14) - { - rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); - rowptr[col + 1] = - (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); - rowptr[col + 2] = - (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); - rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); - rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); - rowptr[col + 5] = - (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); - rowptr[col + 6] = - (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); - rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); - rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); - } - else if (RT_pana_info.bpp == - 12) // have not seen in the wild yet - { - rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; - rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); - rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; - rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); - rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; - rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); - rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; - rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); - rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; - rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); - } - } - } - } - free(iobuf); - tiff_bps = RT_pana_info.bpp; -} - -//----------------------------------------------------------------------------- - /* RT: Delete from here */ /*RT*/#undef SQR /*RT*/#undef MAX diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 522cc798d..3d753d876 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -411,18 +411,6 @@ private: unsigned encoding; }; -class pana_cs6_page_decoder -{ - unsigned int pixelbuffer[14], lastoffset, maxoffset; - unsigned char current, *buffer; - public: - pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) - : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) - { - } - void read_page(); // will throw IO error if not enough space in buffer - unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } -}; void panasonicC6_load_raw(); void panasonicC7_load_raw(); diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc new file mode 100644 index 000000000..8949a0851 --- /dev/null +++ b/rtengine/panasonic_decoders.cc @@ -0,0 +1,276 @@ + +#include "StopWatch.h" +#include +#include "dcraw.h" +// Code adapted from libraw +/* -*- C++ -*- + * Copyright 2019 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + +*/ + + +unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) +{ + int byte; + + if (!nbits && !bytes) { + return vbits=0; + } + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); + fread (buf, 1, load_flags, ifp); + } + if (encoding == 5) { + for (byte = 0; byte < 16; byte++) + { + bytes[byte] = buf[vbits++]; + vbits &= 0x3FFF; + } + return 0; + } else { + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); + } +} + +class pana_cs6_page_decoder +{ + unsigned int pixelbuffer[14], lastoffset, maxoffset; + unsigned char current, *buffer; + public: + pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) + : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) + { + } + void read_page(); // will throw IO error if not enough space in buffer + unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } +}; + +#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) + +void pana_cs6_page_decoder::read_page() +{ + if (!buffer || (maxoffset - lastoffset < 16)) + ; + pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit + pixelbuffer[1] = (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & 0x3fff; + pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; + pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); + pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); + pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); + pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; + pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); + pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); + pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; + pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; + pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); + pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; + pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; + current = 0; + lastoffset += 16; +} +#undef wbuffer + +void DCraw::panasonic_load_raw() +{ +StopWatch Stop1("panasonic_load_raw"); + pana_bits_t pana_bits(ifp,load_flags, RT_pana_info.encoding); + int row, col, i, j, sh=0, pred[2], nonz[2]; + unsigned bytes[16] = {}; + + pana_bits(0, 0); + int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; + if (RT_pana_info.encoding == 5 || RT_pana_info.encoding == 7) { + for (row = 0; row < raw_height; row++) { + ushort* raw_block_data = raw_image + row * raw_width; + + for (col = 0; col < raw_width; col += enc_blck_size) { + pana_bits(0, bytes); + + if (RT_pana_info.bpp == 12) { + raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + else if (RT_pana_info.bpp == 14) { + raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + + ((bytes[3] & 0xF) << 10); + raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + + ((bytes[5] & 3) << 12); + raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + } + } + } else if (RT_pana_info.encoding == 6) { + panasonicC6_load_raw(); + } else if (RT_pana_info.encoding == 7) { + panasonicC7_load_raw(); + } else { + for (row=0; row < height; row++) + for (col=0; col < raw_width; col++) { + if ((i = col % 14) == 0) + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); + if (nonz[i & 1]) { + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) + pred[i & 1] &= ~(-1 << sh); + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + if ((raw_image[(row)*raw_width+(col)] = pred[col & 1]) > 4098 && col < width) derror(); + } + } +} + +void DCraw::panasonicC6_load_raw() +{ + const int rowstep = 16; + const int blocksperrow = raw_width / 11; + const int rowbytes = blocksperrow * 16; + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC6_load_raw()"); + + for (int row = 0; row < raw_height - rowstep + 1; + row += rowstep) + { + int rowstoread = MIN(rowstep, raw_height - row); + fread (iobuf, rowbytes, rowstoread, ifp); +// if (libraw_internal_data.internal_data.input->read( +// iobuf, rowbytes, rowstoread) != rowstoread) +// throw LIBRAW_EXCEPTION_IO_EOF; + pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread); + for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) + { + unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; + for (int rblock = 0; rblock < blocksperrow; rblock++) + { + page.read_page(); + unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; + unsigned pmul = 0, pixel_base = 0; + for (int pix = 0; pix < 11; pix++) + { + if (pix % 3 == 2) + { + unsigned base = page.nextpixel(); + if (base > 3); +// throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit + // field, but.... + if (base == 3) + base = 4; + pixel_base = 0x200 << base; + pmul = 1 << base; + } + unsigned epixel = page.nextpixel(); + if (oddeven[pix % 2]) + { + epixel *= pmul; + if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) + epixel += nonzero[pix % 2] - pixel_base; + nonzero[pix % 2] = epixel; + } + else + { + oddeven[pix % 2] = epixel; + if (epixel) + nonzero[pix % 2] = epixel; + else + epixel = nonzero[pix % 2]; + } + unsigned spix = epixel - 0xf; + if (spix <= 0xffff) + rowptr[col++] = spix & 0xffff; + else + { + epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); + rowptr[col++] = epixel & 0x3fff; + } + } + } + } + } + free(iobuf); + tiff_bps = RT_pana_info.bpp; +} + +void DCraw::panasonicC7_load_raw() +{ + constexpr int rowstep = 16; + const int pixperblock = RT_pana_info.bpp == 14 ? 9 : 10; + const int rowbytes = raw_width / pixperblock * 16; + + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC7_load_raw()"); + for (int row = 0; row < raw_height - rowstep + 1; row += rowstep) { + const int rowstoread = MIN(rowstep, raw_height - row); + fread (iobuf, rowbytes, rowstoread, ifp); + unsigned char *bytes = iobuf; + for (int crow = 0; crow < rowstoread; crow++) { + unsigned short *rowptr = &raw_image[row + crow]; + for (int col = 0; col < raw_width - pixperblock + 1; col += pixperblock, bytes += 16) { + if (RT_pana_info.bpp == 14) { + rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + rowptr[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + rowptr[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + rowptr[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + rowptr[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } else if (RT_pana_info.bpp == 12) { // have not seen in the wild yet + rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + } + } + } + free(iobuf); + tiff_bps = RT_pana_info.bpp; +} + +//----------------------------------------------------------------------------- + +/* RT: Delete from here */ +/*RT*/#undef SQR +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#undef ABS +/*RT*/#undef LIM +/*RT*/#undef ULIM +/*RT*/#undef CLIP +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif From 254d9494de3248d882a6fd3ab52d778fadac83d7 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 6 Nov 2019 23:12:52 +0100 Subject: [PATCH 04/18] cleanup --- rtengine/panasonic_decoders.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc index 8949a0851..709f60ab7 100644 --- a/rtengine/panasonic_decoders.cc +++ b/rtengine/panasonic_decoders.cc @@ -260,17 +260,3 @@ void DCraw::panasonicC7_load_raw() free(iobuf); tiff_bps = RT_pana_info.bpp; } - -//----------------------------------------------------------------------------- - -/* RT: Delete from here */ -/*RT*/#undef SQR -/*RT*/#undef MAX -/*RT*/#undef MIN -/*RT*/#undef ABS -/*RT*/#undef LIM -/*RT*/#undef ULIM -/*RT*/#undef CLIP -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif From bc6280afdf95818501e6b063fc63221257168615 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 7 Nov 2019 15:39:03 +0100 Subject: [PATCH 05/18] Fix decoding of Panasonic Highres files, #5204 --- rtengine/panasonic_decoders.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc index 709f60ab7..5630ae3f2 100644 --- a/rtengine/panasonic_decoders.cc +++ b/rtengine/panasonic_decoders.cc @@ -90,7 +90,7 @@ StopWatch Stop1("panasonic_load_raw"); pana_bits(0, 0); int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; - if (RT_pana_info.encoding == 5 || RT_pana_info.encoding == 7) { + if (RT_pana_info.encoding == 5) { for (row = 0; row < raw_height; row++) { ushort* raw_block_data = raw_image + row * raw_width; @@ -230,7 +230,7 @@ void DCraw::panasonicC7_load_raw() fread (iobuf, rowbytes, rowstoread, ifp); unsigned char *bytes = iobuf; for (int crow = 0; crow < rowstoread; crow++) { - unsigned short *rowptr = &raw_image[row + crow]; + ushort *rowptr = &raw_image[(row + crow) * raw_width]; for (int col = 0; col < raw_width - pixperblock + 1; col += pixperblock, bytes += 16) { if (RT_pana_info.bpp == 14) { rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); From ffa461d3de7d7c7a73619d6c786f5989b06fb3e7 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 7 Nov 2019 18:47:11 +0100 Subject: [PATCH 06/18] Bottleneck when loading Panasonic RW2 files, #5517 --- rtexif/rtexif.cc | 21 +++++++++++---------- rtexif/rtexif.h | 9 +++++++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index b2edc2842..89ff6cd33 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -54,13 +54,13 @@ Interpreter stdInterpreter; //----------------------------------------------------------------------------- TagDirectory::TagDirectory () - : attribs (ifdAttribs), order (HOSTORDER), parent (nullptr) {} + : attribs (ifdAttribs), order (HOSTORDER), parent (nullptr), parseJPEG(true) {} TagDirectory::TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border) - : attribs (ta), order (border), parent (p) {} + : attribs (ta), order (border), parent (p), parseJPEG(true) {} -TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored) - : attribs (ta), order (border), parent (p) +TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored, bool parseJpeg) + : attribs (ta), order (border), parent (p), parseJPEG(parseJpeg) { int numOfTags = get2 (f, order); @@ -980,9 +980,10 @@ Tag::Tag (TagDirectory* p, FILE* f, int base) } } - if (tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras + if (parent->getParseJpeg() && tag == 0x002e) { // location of the embedded preview image in raw files of Panasonic cameras ExifManager eManager(f, nullptr, true); const auto fpos = ftell(f); + if (fpos >= 0) { eManager.parseJPEG(fpos); // try to parse the exif data from the preview image @@ -1239,7 +1240,7 @@ defsubdirs: for (size_t j = 0, i = 0; j < count; j++, i++) { int newpos = base + toInt (j * 4, LONG); fseek (f, newpos, SEEK_SET); - directory[i] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order); + directory[i] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order, true, parent->getParseJpeg()); } // set the terminating NULL @@ -1374,7 +1375,7 @@ bool Tag::parseMakerNote (FILE* f, int base, ByteOrder bom ) value = new unsigned char[12]; fread (value, 1, 12, f); directory = new TagDirectory*[2]; - directory[0] = new TagDirectory (parent, f, base, panasonicAttribs, bom); + directory[0] = new TagDirectory (parent, f, base, panasonicAttribs, bom, true, parent->getParseJpeg()); directory[1] = nullptr; } else { return false; @@ -2777,7 +2778,7 @@ void ExifManager::parseStd (bool skipIgnored) { parse(false, skipIgnored); } -void ExifManager::parse (bool isRaw, bool skipIgnored) +void ExifManager::parse (bool isRaw, bool skipIgnored, bool parseJpeg) { int ifdOffset = IFDOffset; @@ -2806,7 +2807,7 @@ void ExifManager::parse (bool isRaw, bool skipIgnored) fseek (f, rml->exifBase + ifdOffset, SEEK_SET); // first read the IFD directory - TagDirectory* root = new TagDirectory (nullptr, f, rml->exifBase, ifdAttribs, order, skipIgnored); + TagDirectory* root = new TagDirectory (nullptr, f, rml->exifBase, ifdAttribs, order, skipIgnored, parseJpeg); // fix ISO issue with nikon and panasonic cameras Tag* make = root->getTag ("Make"); @@ -3174,7 +3175,7 @@ void ExifManager::parseJPEG (int offset) rml.reset(new rtengine::RawMetaDataLocation(0)); } rml->exifBase = tiffbase; - parse (false); + parse (false, true, false); if (rmlCreated) { rml.reset(); } diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 4c5a6cafe..c37533352 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -119,11 +119,12 @@ protected: const TagAttrib* attribs; // descriptor table to decode the tags ByteOrder order; // byte order TagDirectory* parent; // parent directory (NULL if root) + bool parseJPEG; static Glib::ustring getDumpKey (int tagID, const Glib::ustring &tagName); public: TagDirectory (); - TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored = true); + TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored = true, bool parseJpeg = true); TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border); virtual ~TagDirectory (); @@ -135,6 +136,10 @@ public: { return parent; } + inline bool getParseJpeg() const + { + return parseJPEG; + } TagDirectory* getRoot (); inline int getCount () const { @@ -346,7 +351,7 @@ class ExifManager Tag* saveCIFFMNTag (TagDirectory* root, int len, const char* name); void parseCIFF (int length, TagDirectory* root); - void parse (bool isRaw, bool skipIgnored = true); + void parse (bool isRaw, bool skipIgnored = true, bool parseJpeg = true); public: FILE* f; From 9ac34eb33cb999fd105d5c35286970ce8cb4ec08 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 7 Nov 2019 19:35:02 +0100 Subject: [PATCH 07/18] panasonic decoders: cleanup --- rtengine/panasonic_decoders.cc | 250 ++++++++++++++++++--------------- 1 file changed, 133 insertions(+), 117 deletions(-) diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc index 5630ae3f2..37f586a6b 100644 --- a/rtengine/panasonic_decoders.cc +++ b/rtengine/panasonic_decoders.cc @@ -1,7 +1,23 @@ +/* + * This file is part of RawTherapee. + * + * RawTherapee 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. + * + * RawTherapee 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 RawTherapee. If not, see . +*/ -#include "StopWatch.h" #include #include "dcraw.h" + // Code adapted from libraw /* -*- C++ -*- * Copyright 2019 LibRaw LLC (info@libraw.org) @@ -17,7 +33,6 @@ */ - unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) { int byte; @@ -45,15 +60,18 @@ unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) class pana_cs6_page_decoder { - unsigned int pixelbuffer[14], lastoffset, maxoffset; - unsigned char current, *buffer; - public: - pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) + unsigned int pixelbuffer[14], lastoffset, maxoffset; + unsigned char current, *buffer; +public: + pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) - { - } - void read_page(); // will throw IO error if not enough space in buffer - unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } + { + } + void read_page(); // will throw IO error if not enough space in buffer + unsigned int nextpixel() + { + return current < 14 ? pixelbuffer[current++] : 0; + } }; #define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) @@ -83,44 +101,39 @@ void pana_cs6_page_decoder::read_page() void DCraw::panasonic_load_raw() { -StopWatch Stop1("panasonic_load_raw"); - pana_bits_t pana_bits(ifp,load_flags, RT_pana_info.encoding); - int row, col, i, j, sh=0, pred[2], nonz[2]; - unsigned bytes[16] = {}; - - pana_bits(0, 0); int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; if (RT_pana_info.encoding == 5) { - for (row = 0; row < raw_height; row++) { + pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding); + pana_bits(0, 0); + unsigned bytes[16] = {}; + for (int row = 0; row < raw_height; ++row) { ushort* raw_block_data = raw_image + row * raw_width; - for (col = 0; col < raw_width; col += enc_blck_size) { + for (int col = 0; col < raw_width; col += enc_blck_size) { pana_bits(0, bytes); if (RT_pana_info.bpp == 12) { - raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; - raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); - raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; - raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); - raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; - raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); - raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; - raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); - raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; - raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); } else if (RT_pana_info.bpp == 14) { - raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); - raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + - ((bytes[3] & 0xF) << 10); - raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + - ((bytes[5] & 3) << 12); - raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); - raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); - raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); - raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); - raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); - raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + raw_block_data[col + 1] = (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + raw_block_data[col + 2] = (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + raw_block_data[col + 5] = (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + raw_block_data[col + 6] = (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + raw_block_data[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); } } } @@ -129,92 +142,95 @@ StopWatch Stop1("panasonic_load_raw"); } else if (RT_pana_info.encoding == 7) { panasonicC7_load_raw(); } else { - for (row=0; row < height; row++) - for (col=0; col < raw_width; col++) { - if ((i = col % 14) == 0) - pred[0] = pred[1] = nonz[0] = nonz[1] = 0; - if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); - if (nonz[i & 1]) { - if ((j = pana_bits(8))) { - if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) - pred[i & 1] &= ~(-1 << sh); - pred[i & 1] += j << sh; - } - } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) - pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); - if ((raw_image[(row)*raw_width+(col)] = pred[col & 1]) > 4098 && col < width) derror(); - } + pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding); + pana_bits(0, 0); + int sh = 0, pred[2], nonz[2]; + for (int row = 0; row < height; ++row) { + for (int col = 0; col < raw_width; ++col) { + int i; + if ((i = col % 14) == 0) { + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + } + if (i % 3 == 2) { + sh = 4 >> (3 - pana_bits(2)); + } + if (nonz[i & 1]) { + int j; + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) { + pred[i & 1] &= ~(-1 << sh); + } + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) { + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + } + if ((raw_image[(row)*raw_width+(col)] = pred[col & 1]) > 4098 && col < width) { + derror(); + } + } + } } } void DCraw::panasonicC6_load_raw() { - const int rowstep = 16; - const int blocksperrow = raw_width / 11; - const int rowbytes = blocksperrow * 16; - unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); - merror(iobuf, "panasonicC6_load_raw()"); + constexpr int rowstep = 16; + const int blocksperrow = raw_width / 11; + const int rowbytes = blocksperrow * 16; + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + merror(iobuf, "panasonicC6_load_raw()"); - for (int row = 0; row < raw_height - rowstep + 1; - row += rowstep) - { - int rowstoread = MIN(rowstep, raw_height - row); - fread (iobuf, rowbytes, rowstoread, ifp); -// if (libraw_internal_data.internal_data.input->read( -// iobuf, rowbytes, rowstoread) != rowstoread) -// throw LIBRAW_EXCEPTION_IO_EOF; - pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread); - for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) - { - unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; - for (int rblock = 0; rblock < blocksperrow; rblock++) - { - page.read_page(); - unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; - unsigned pmul = 0, pixel_base = 0; - for (int pix = 0; pix < 11; pix++) - { - if (pix % 3 == 2) - { - unsigned base = page.nextpixel(); - if (base > 3); -// throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit - // field, but.... - if (base == 3) - base = 4; - pixel_base = 0x200 << base; - pmul = 1 << base; - } - unsigned epixel = page.nextpixel(); - if (oddeven[pix % 2]) - { - epixel *= pmul; - if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) - epixel += nonzero[pix % 2] - pixel_base; - nonzero[pix % 2] = epixel; - } - else - { - oddeven[pix % 2] = epixel; - if (epixel) - nonzero[pix % 2] = epixel; - else - epixel = nonzero[pix % 2]; - } - unsigned spix = epixel - 0xf; - if (spix <= 0xffff) - rowptr[col++] = spix & 0xffff; - else - { - epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); - rowptr[col++] = epixel & 0x3fff; - } + for (int row = 0; row < raw_height - rowstep + 1; row += rowstep) { + const int rowstoread = MIN(rowstep, raw_height - row); + fread(iobuf, rowbytes, rowstoread, ifp); + pana_cs6_page_decoder page(iobuf, rowbytes * rowstoread); + for (int crow = 0, col = 0; crow < rowstoread; ++crow, col = 0) { + unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; + for (int rblock = 0; rblock < blocksperrow; rblock++) { + page.read_page(); + unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; + unsigned pmul = 0, pixel_base = 0; + for (int pix = 0; pix < 11; ++pix) { + if (pix % 3 == 2) { + unsigned base = page.nextpixel(); + if (base > 3) { + derror(); + } + if (base == 3) { + base = 4; + } + pixel_base = 0x200 << base; + pmul = 1 << base; + } + unsigned epixel = page.nextpixel(); + if (oddeven[pix % 2]) { + epixel *= pmul; + if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) { + epixel += nonzero[pix % 2] - pixel_base; + } + nonzero[pix % 2] = epixel; + } else { + oddeven[pix % 2] = epixel; + if (epixel) { + nonzero[pix % 2] = epixel; + } else { + epixel = nonzero[pix % 2]; + } + } + const unsigned spix = epixel - 0xf; + if (spix <= 0xffff) { + rowptr[col++] = spix & 0xffff; + } else { + epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); + rowptr[col++] = epixel & 0x3fff; + } + } + } } - } } - } - free(iobuf); - tiff_bps = RT_pana_info.bpp; + free(iobuf); + tiff_bps = RT_pana_info.bpp; } void DCraw::panasonicC7_load_raw() From e5258e6f60ae118d11c04ebcd4f6fbb906623adf Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Fri, 8 Nov 2019 20:22:18 +0100 Subject: [PATCH 08/18] reduce rtgui/inspector.h dependencies --- rtgui/inspector.cc | 1 + rtgui/inspector.h | 1 - rtgui/thumbbrowserbase.cc | 1 + rtgui/thumbbrowserbase.h | 4 +++- rtgui/thumbbrowserentrybase.cc | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index d38239cde..9002cc389 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -25,6 +25,7 @@ #include "pathutils.h" #include "rtscalable.h" #include "../rtengine/previewimage.h" +#include "../rtengine/rt_math.h" InspectorBuffer::InspectorBuffer(const Glib::ustring &imagePath) : currTransform(0), fromRaw(false) { diff --git a/rtgui/inspector.h b/rtgui/inspector.h index bb144834a..8338259bf 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -24,7 +24,6 @@ #include "../rtengine/coord.h" #include "../rtengine/coord2d.h" -#include "../rtengine/rt_math.h" class InspectorBuffer { diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 9832b5730..2774cd206 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -18,6 +18,7 @@ #include +#include "inspector.h" #include "multilangmgr.h" #include "options.h" #include "rtscalable.h" diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index a5c51cf5f..5a55aeeca 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -23,13 +23,15 @@ #include #include "guiutils.h" -#include "inspector.h" #include "options.h" #include "thumbbrowserentrybase.h" /* * Class handling the list of ThumbBrowserEntry objects and their position in it's allocated space */ + +class Inspector; + class ThumbBrowserBase : public Gtk::Grid { diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 12059c72e..3840c8bf9 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -20,6 +20,7 @@ #include "options.h" #include "thumbbrowserbase.h" +#include "../rtengine/rt_math.h" namespace { From 587652283dc520bc66d8803f396647d1a527cad9 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sat, 9 Nov 2019 16:51:54 +0100 Subject: [PATCH 09/18] further reduction of include dependencies, also finalised some classes --- rtengine/pipettebuffer.h | 1 - rtgui/batchqueue.cc | 1 + rtgui/batchqueue.h | 3 ++- rtgui/batchqueuepanel.h | 1 + rtgui/bayerpreprocess.h | 2 +- rtgui/bayerprocess.h | 2 +- rtgui/bayerrawexposure.h | 2 +- rtgui/blackwhite.cc | 2 ++ rtgui/blackwhite.h | 7 ++++--- rtgui/cacorrection.h | 2 +- rtgui/chmixer.h | 2 +- rtgui/coarsepanel.h | 2 +- rtgui/colorappearance.cc | 2 ++ rtgui/colorappearance.h | 7 +++++-- rtgui/colortoning.cc | 2 ++ rtgui/colortoning.h | 10 +++++++--- rtgui/curveeditor.cc | 1 + rtgui/curveeditor.h | 6 +++--- rtgui/curveeditorgroup.cc | 1 + rtgui/curveeditorgroup.h | 2 +- rtgui/darkframe.h | 2 +- rtgui/defringe.cc | 2 ++ rtgui/defringe.h | 8 +++++--- rtgui/dehaze.h | 2 +- rtgui/diagonalcurveeditorsubgroup.cc | 1 + rtgui/dirpyrdenoise.cc | 2 ++ rtgui/dirpyrdenoise.h | 6 ++++-- rtgui/dirpyrequalizer.h | 2 +- rtgui/distortion.h | 2 +- rtgui/editbuffer.h | 7 ++++++- rtgui/editorpanel.cc | 1 + rtgui/editorpanel.h | 3 ++- rtgui/epd.h | 2 +- rtgui/fattaltonemap.h | 2 +- rtgui/filebrowserentry.cc | 2 ++ rtgui/filecatalog.cc | 1 + rtgui/filethumbnailbuttonset.h | 1 - rtgui/filmnegative.h | 3 +-- rtgui/filmsimulation.h | 2 +- rtgui/flatcurveeditorsubgroup.cc | 1 + rtgui/flatfield.h | 2 +- rtgui/gradient.h | 2 +- rtgui/hsvequalizer.cc | 2 ++ rtgui/hsvequalizer.h | 9 ++++++--- rtgui/icmpanel.h | 2 +- rtgui/imageareatoollistener.h | 5 ++--- rtgui/impulsedenoise.h | 2 +- rtgui/labcurve.cc | 2 ++ rtgui/labcurve.h | 8 +++++--- rtgui/labgrid.h | 2 +- rtgui/lensgeom.h | 2 +- rtgui/lensprofile.h | 1 - rtgui/localcontrast.h | 2 +- rtgui/pcvignette.h | 2 +- rtgui/perspective.h | 2 +- rtgui/pparamschangelistener.h | 8 ++++++-- rtgui/preprocess.h | 2 +- rtgui/profilechangelistener.h | 6 +++++- rtgui/prsharpening.h | 2 +- rtgui/rawcacorrection.h | 2 +- rtgui/rawexposure.h | 4 +--- rtgui/retinex.cc | 3 +++ rtgui/retinex.h | 9 +++++++-- rtgui/rgbcurves.cc | 2 ++ rtgui/rgbcurves.h | 8 +++++--- rtgui/rotate.cc | 1 + rtgui/rotate.h | 4 ++-- rtgui/rtwindow.cc | 1 + rtgui/sensorbayer.h | 2 +- rtgui/sensorxtrans.h | 2 +- rtgui/shadowshighlights.h | 2 +- rtgui/sharpenedge.h | 2 +- rtgui/sharpening.h | 2 +- rtgui/sharpenmicro.h | 2 +- rtgui/softlight.h | 2 +- rtgui/thumbbrowserbase.cc | 1 + rtgui/thumbbrowserbase.h | 2 +- rtgui/thumbimageupdater.cc | 1 + rtgui/thumbimageupdater.h | 4 +++- rtgui/tonecurve.cc | 2 ++ rtgui/tonecurve.h | 8 +++++--- rtgui/toolbar.h | 2 +- rtgui/toolpanel.h | 3 --- rtgui/toolpanelcoord.cc | 1 + rtgui/vibrance.cc | 3 +++ rtgui/vibrance.h | 8 +++++--- rtgui/vignetting.h | 2 +- rtgui/wavelet.cc | 2 ++ rtgui/wavelet.h | 9 ++++++--- rtgui/whitebalance.h | 2 +- rtgui/xtransprocess.h | 2 +- rtgui/xtransrawexposure.h | 2 +- 92 files changed, 177 insertions(+), 98 deletions(-) diff --git a/rtengine/pipettebuffer.h b/rtengine/pipettebuffer.h index ef8a5f69a..79b6dd8c5 100644 --- a/rtengine/pipettebuffer.h +++ b/rtengine/pipettebuffer.h @@ -19,7 +19,6 @@ #pragma once #include "array2D.h" -#include "coord.h" #include "iimage.h" class EditDataProvider; diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index acb45c266..afbec9efb 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -31,6 +31,7 @@ #include "cachemanager.h" #include "thumbnail.h" #include "batchqueue.h" +#include "batchqueueentry.h" #include "multilangmgr.h" #include "filecatalog.h" #include "batchqueuebuttonset.h" diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index 9ae615965..f0289faa4 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -21,7 +21,6 @@ #include -#include "batchqueueentry.h" #include "lwbutton.h" #include "lwbuttonset.h" #include "threadutils.h" @@ -30,6 +29,8 @@ #include "../rtengine/rtengine.h" #include "../rtengine/noncopyable.h" +class BatchQueueEntry; + class BatchQueueListener { diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index 590ec2347..7c0a367d4 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -29,6 +29,7 @@ class RTWindow; class FileCatalog; class Thumbnail; + class BatchQueuePanel : public Gtk::VBox, public BatchQueueListener, public FormatChangeListener diff --git a/rtgui/bayerpreprocess.h b/rtgui/bayerpreprocess.h index c07bbcba4..16b469626 100644 --- a/rtgui/bayerpreprocess.h +++ b/rtgui/bayerpreprocess.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class BayerPreProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class BayerPreProcess final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { protected: diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h index 04985dc66..5c7498986 100644 --- a/rtgui/bayerprocess.h +++ b/rtgui/bayerprocess.h @@ -25,7 +25,7 @@ #include "guiutils.h" #include "toolpanel.h" -class BayerProcess : +class BayerProcess final : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, diff --git a/rtgui/bayerrawexposure.h b/rtgui/bayerrawexposure.h index 247bf6ff0..eb18aa0e3 100644 --- a/rtgui/bayerrawexposure.h +++ b/rtgui/bayerrawexposure.h @@ -24,7 +24,7 @@ #include "checkbox.h" #include "toolpanel.h" -class BayerRAWExposure : +class BayerRAWExposure final : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index b3ebea28a..596d99607 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -21,6 +21,8 @@ #include "blackwhite.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "guiutils.h" #include "rtimage.h" #include "options.h" diff --git a/rtgui/blackwhite.h b/rtgui/blackwhite.h index 9f504fd4f..1aed86997 100644 --- a/rtgui/blackwhite.h +++ b/rtgui/blackwhite.h @@ -22,13 +22,14 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" -#include "mycurve.h" #include "toolpanel.h" +class DiagonalCurveEditor; +class CurveEditorGroup; class EditDataProvider; +class FlatCurveEditor; class BlackWhite final : public ToolParamBlock, diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h index 6e1667a00..12d6396eb 100644 --- a/rtgui/cacorrection.h +++ b/rtgui/cacorrection.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class CACorrection : +class CACorrection final: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h index fb028cf14..d80b89cf7 100644 --- a/rtgui/chmixer.h +++ b/rtgui/chmixer.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class ChMixer : +class ChMixer final: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/coarsepanel.h b/rtgui/coarsepanel.h index c028bbcad..b7b4f8cf7 100644 --- a/rtgui/coarsepanel.h +++ b/rtgui/coarsepanel.h @@ -22,7 +22,7 @@ #include "toolpanel.h" -class CoarsePanel : +class CoarsePanel final : public Gtk::HBox, public ToolPanel { diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index 094ffec2f..9a6bee524 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -20,6 +20,8 @@ #include "colorappearance.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "guiutils.h" #include "options.h" #include "rtimage.h" diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index 3d82ee831..170212ffe 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -22,11 +22,14 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" #include "toolpanel.h" +class DiagonalCurveEditor; +class CurveEditorGroup; +class CurveEditor; + class ColorAppearance final : public ToolParamBlock, public AdjusterListener, diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 1a6a9b918..59768a6ce 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -2,6 +2,8 @@ * This file is part of RawTherapee. */ #include "colortoning.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "mycurve.h" #include "rtimage.h" #include "eventmapper.h" diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h index 9c7a54488..f1024f41c 100644 --- a/rtgui/colortoning.h +++ b/rtgui/colortoning.h @@ -7,15 +7,19 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" -#include "labgrid.h" #include "thresholdadjuster.h" #include "toolpanel.h" #include "../rtengine/procparams.h" +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; +class FlatCurveEditor; +class LabGrid; + class ColorToning final : public ToolParamBlock, public FoldableToolPanel, diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc index 2b3c100e0..8dc88473e 100644 --- a/rtgui/curveeditor.cc +++ b/rtgui/curveeditor.cc @@ -21,6 +21,7 @@ #include #include "guiutils.h" #include "multilangmgr.h" +#include "popuptogglebutton.h" #include "../rtengine/LUT.h" #include diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index 535c1a86d..baae8f492 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -20,7 +20,6 @@ #include "coloredbar.h" #include "editcallbacks.h" -#include "popuptogglebutton.h" #include "../rtengine/diagonalcurvetypes.h" #include "../rtengine/flatcurvetypes.h" @@ -29,6 +28,7 @@ class CurveEditorGroup; class CurveEditorSubGroup; +class PopUpToggleButton; /* *********************** Curve Editor *********************** @@ -143,7 +143,7 @@ public: */ -class DiagonalCurveEditor : public CurveEditor +class DiagonalCurveEditor final : public CurveEditor { friend class DiagonalCurveEditorSubGroup; @@ -179,7 +179,7 @@ public: */ -class FlatCurveEditor : public CurveEditor +class FlatCurveEditor final : public CurveEditor { friend class FlatCurveEditorSubGroup; diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 06def0a8e..cad49d331 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -24,6 +24,7 @@ #include "diagonalcurveeditorsubgroup.h" #include "flatcurveeditorsubgroup.h" #include "multilangmgr.h" +#include "popuptogglebutton.h" #include "rtimage.h" #include "options.h" #include "pathutils.h" diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index e3412546f..7a5d3a074 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -41,7 +41,7 @@ class FlatCurveEditorSubGroup; * - to start a new line of curve button, use the 'newLine' method * - if you add more than one curve, you must add a "CurveEditor* ce" parameter to your listener */ -class CurveEditorGroup : public Gtk::Grid, public CurveListener +class CurveEditorGroup final : public Gtk::Grid, public CurveListener { friend class CurveEditor; diff --git a/rtgui/darkframe.h b/rtgui/darkframe.h index 779caf16f..30696e3db 100644 --- a/rtgui/darkframe.h +++ b/rtgui/darkframe.h @@ -41,7 +41,7 @@ public: // add other info here }; -class DarkFrame : +class DarkFrame final: public ToolParamBlock, public FoldableToolPanel { diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc index 7114f9a52..cdec88edc 100644 --- a/rtgui/defringe.cc +++ b/rtgui/defringe.cc @@ -20,6 +20,8 @@ #include #include "defringe.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "options.h" #include "../rtengine/color.h" diff --git a/rtgui/defringe.h b/rtgui/defringe.h index 5dd17b547..ebf1eecd8 100644 --- a/rtgui/defringe.h +++ b/rtgui/defringe.h @@ -22,12 +22,14 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" #include "toolpanel.h" -class Defringe : +class CurveEditorGroup; +class FlatCurveEditor; + +class Defringe final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/dehaze.h b/rtgui/dehaze.h index 6a9d31cd1..79d2e015c 100644 --- a/rtgui/dehaze.h +++ b/rtgui/dehaze.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class Dehaze: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class Dehaze final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { private: Adjuster *strength; diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index cece9be66..eed6c63d3 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -32,6 +32,7 @@ #include "diagonalcurveeditorsubgroup.h" #include "rtimage.h" #include "options.h" +#include "popuptogglebutton.h" #include "../rtengine/curves.h" diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index b429dfc9f..7129542d1 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -21,6 +21,8 @@ #include "dirpyrdenoise.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "editbuffer.h" #include "guiutils.h" #include "options.h" diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index 424104314..c754e705c 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -22,11 +22,13 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" #include "toolpanel.h" +class CurveEditor; +class CurveEditorGroup; +class FlatCurveEditor; class EditDataProvider; class DirPyrDenoise final : diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index ff08f36bc..84924099e 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -25,7 +25,7 @@ #include "thresholdadjuster.h" #include "toolpanel.h" -class DirPyrEqualizer : +class DirPyrEqualizer final : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, diff --git a/rtgui/distortion.h b/rtgui/distortion.h index dab20bbd9..7ef33d73a 100644 --- a/rtgui/distortion.h +++ b/rtgui/distortion.h @@ -24,7 +24,7 @@ #include "lensgeomlistener.h" #include "toolpanel.h" -class Distortion : +class Distortion final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/editbuffer.h b/rtgui/editbuffer.h index 046ab7364..a5cf8d0e4 100644 --- a/rtgui/editbuffer.h +++ b/rtgui/editbuffer.h @@ -19,9 +19,14 @@ #pragma once #include "editid.h" -#include "../rtengine/coord.h" #include +namespace rtengine { + +struct Coord; + +} + class EditDataProvider; class EditSubscriber; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 108b11ea3..87f4a0b94 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -24,6 +24,7 @@ #include "../rtengine/imagesource.h" #include "../rtengine/iccstore.h" #include "batchqueue.h" +#include "batchqueueentry.h" #include "soundman.h" #include "rtimage.h" #include "rtwindow.h" diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index b577b858f..e348222a5 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -21,7 +21,6 @@ #include -#include "batchqueueentry.h" #include "filepanel.h" #include "histogrampanel.h" #include "history.h" @@ -35,7 +34,9 @@ #include "../rtengine/noncopyable.h" #include "../rtengine/rtengine.h" +class BatchQueueEntry; class EditorPanel; +class FilePanel; class MyProgressBar; class Thumbnail; class ToolPanelCoordinator; diff --git a/rtgui/epd.h b/rtgui/epd.h index 410004d89..6a5160623 100644 --- a/rtgui/epd.h +++ b/rtgui/epd.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class EdgePreservingDecompositionUI : +class EdgePreservingDecompositionUI final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/fattaltonemap.h b/rtgui/fattaltonemap.h index 9f788351c..3d36ec7d2 100644 --- a/rtgui/fattaltonemap.h +++ b/rtgui/fattaltonemap.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class FattalToneMapping: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class FattalToneMapping final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { protected: Adjuster *threshold; diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 4d31d625e..9da4044c1 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -21,6 +21,7 @@ #include #include +#include "cropguilistener.h" #include "cursormanager.h" #include "guiutils.h" #include "inspector.h" @@ -28,6 +29,7 @@ #include "threadutils.h" #include "thumbbrowserbase.h" #include "thumbnail.h" +#include "toolbar.h" #include "../rtengine/procparams.h" diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 5e93631e5..a2622e52c 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -36,6 +36,7 @@ #include "renamedlg.h" #include "thumbimageupdater.h" #include "batchqueue.h" +#include "batchqueueentry.h" #include "placesbrowser.h" #include "pathutils.h" #include "thumbnail.h" diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h index 66d5b5f67..868d3b58a 100644 --- a/rtgui/filethumbnailbuttonset.h +++ b/rtgui/filethumbnailbuttonset.h @@ -22,7 +22,6 @@ #include -#include "filebrowserentry.h" #include "lwbuttonset.h" class FileBrowserEntry; diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 85919bef9..bca155ceb 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -26,7 +26,6 @@ #include "editcallbacks.h" #include "guiutils.h" #include "toolpanel.h" -#include "wbprovider.h" class FilmNegProvider { @@ -36,7 +35,7 @@ public: virtual bool getFilmNegativeExponents(rtengine::Coord spotA, rtengine::Coord spotB, std::array& newExps) = 0; }; -class FilmNegative : +class FilmNegative final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/filmsimulation.h b/rtgui/filmsimulation.h index fc9e804e1..cfe7016bb 100644 --- a/rtgui/filmsimulation.h +++ b/rtgui/filmsimulation.h @@ -10,7 +10,7 @@ #include "guiutils.h" #include "toolpanel.h" -class ClutComboBox : +class ClutComboBox final : public MyComboBox { public: diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index b5dc4f726..4e0591ac3 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -33,6 +33,7 @@ #include "flatcurveeditorsubgroup.h" #include "rtimage.h" #include "options.h" +#include "popuptogglebutton.h" #include "../rtengine/curves.h" diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h index 4308e938a..d20a96acd 100644 --- a/rtgui/flatfield.h +++ b/rtgui/flatfield.h @@ -42,7 +42,7 @@ public: // add other info here }; -class FlatField : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener +class FlatField final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::FlatFieldAutoClipListener { protected: diff --git a/rtgui/gradient.h b/rtgui/gradient.h index 834f08670..f2be47ccc 100644 --- a/rtgui/gradient.h +++ b/rtgui/gradient.h @@ -10,7 +10,7 @@ #include "guiutils.h" #include "toolpanel.h" -class Gradient : +class Gradient final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc index b570a23ac..ee3eb90a7 100644 --- a/rtgui/hsvequalizer.cc +++ b/rtgui/hsvequalizer.cc @@ -18,6 +18,8 @@ */ #include "hsvequalizer.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "options.h" #include "../rtengine/color.h" diff --git a/rtgui/hsvequalizer.h b/rtgui/hsvequalizer.h index 7d313cc76..987fd20b2 100644 --- a/rtgui/hsvequalizer.h +++ b/rtgui/hsvequalizer.h @@ -22,12 +22,15 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" #include "toolpanel.h" -class HSVEqualizer : +class CurveEditor; +class CurveEditorGroup; +class FlatCurveEditor; + +class HSVEqualizer final : public ToolParamBlock, public FoldableToolPanel, public CurveListener, diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 5573bacb8..cc46c5d37 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -36,7 +36,7 @@ public: virtual void saveInputICCReference(const Glib::ustring& fname, bool apply_wb) = 0; }; -class ICMPanel : +class ICMPanel final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/imageareatoollistener.h b/rtgui/imageareatoollistener.h index 3c753a5e0..b022aa4b7 100644 --- a/rtgui/imageareatoollistener.h +++ b/rtgui/imageareatoollistener.h @@ -18,10 +18,9 @@ */ #pragma once -#include "cropguilistener.h" -#include "toolbar.h" - +class CropGUIListener; class Thumbnail; +class ToolBar; class ImageAreaToolListener { diff --git a/rtgui/impulsedenoise.h b/rtgui/impulsedenoise.h index e3cfc619a..b8acafcfc 100644 --- a/rtgui/impulsedenoise.h +++ b/rtgui/impulsedenoise.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class ImpulseDenoise : +class ImpulseDenoise final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index bd4b27f14..491b02c4c 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -20,6 +20,8 @@ #include "labcurve.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "options.h" #include "../rtengine/color.h" diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index 46f506d68..e8488a8c6 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -22,13 +22,15 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "toolpanel.h" +class CurveEditorGroup; +class DiagonalCurveEditor; class EditDataProvider; +class FlatCurveEditor; -class LCurve : +class LCurve final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index 227b4cacc..4693c897c 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -43,7 +43,7 @@ #include "toolpanel.h" -class LabGridArea: public Gtk::DrawingArea, public BackBuffer { +class LabGridArea final : public Gtk::DrawingArea, public BackBuffer { private: rtengine::ProcEvent evt; Glib::ustring evtMsg; diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index e3352a506..18b31a619 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -23,7 +23,7 @@ #include "lensgeomlistener.h" #include "toolpanel.h" -class LensGeometry : +class LensGeometry final : public ToolParamBlock, public FoldableToolPanel { diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 7e740e26e..7b5b7343c 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -21,7 +21,6 @@ #include #include "guiutils.h" -#include "lensgeom.h" #include "toolpanel.h" class LensProfilePanel final : diff --git a/rtgui/localcontrast.h b/rtgui/localcontrast.h index b23bac697..d1d25fb3d 100644 --- a/rtgui/localcontrast.h +++ b/rtgui/localcontrast.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class LocalContrast: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class LocalContrast final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { private: Adjuster *radius; diff --git a/rtgui/pcvignette.h b/rtgui/pcvignette.h index da0e02dc6..87915703f 100644 --- a/rtgui/pcvignette.h +++ b/rtgui/pcvignette.h @@ -8,7 +8,7 @@ #include "adjuster.h" #include "toolpanel.h" -class PCVignette : +class PCVignette final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 618ad32cf..0564479de 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class PerspCorrection : +class PerspCorrection final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/pparamschangelistener.h b/rtgui/pparamschangelistener.h index 56ac5f605..e255b9657 100644 --- a/rtgui/pparamschangelistener.h +++ b/rtgui/pparamschangelistener.h @@ -18,10 +18,14 @@ */ #pragma once -#include - struct ParamsEdited; +namespace Glib +{ + +class ustring; + +} namespace rtengine { diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index 3b337a450..d10ff5223 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -24,7 +24,7 @@ #include "guiutils.h" #include "toolpanel.h" -class PreProcess : +class PreProcess final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/profilechangelistener.h b/rtgui/profilechangelistener.h index 58c565393..656566867 100644 --- a/rtgui/profilechangelistener.h +++ b/rtgui/profilechangelistener.h @@ -18,8 +18,12 @@ */ #pragma once -#include +namespace Glib +{ +class ustring; + +} namespace rtengine { diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h index 54f2f8063..9738a5cd4 100644 --- a/rtgui/prsharpening.h +++ b/rtgui/prsharpening.h @@ -24,7 +24,7 @@ #include "thresholdadjuster.h" #include "toolpanel.h" -class PrSharpening : +class PrSharpening final : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, diff --git a/rtgui/rawcacorrection.h b/rtgui/rawcacorrection.h index 60c705b19..3c95602a7 100644 --- a/rtgui/rawcacorrection.h +++ b/rtgui/rawcacorrection.h @@ -24,7 +24,7 @@ #include "checkbox.h" #include "toolpanel.h" -class RAWCACorr : +class RAWCACorr final: public ToolParamBlock, public AdjusterListener, public CheckBoxListener, diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h index 75b3a9330..33c897113 100644 --- a/rtgui/rawexposure.h +++ b/rtgui/rawexposure.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class RAWExposure : +class RAWExposure final: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel @@ -32,8 +32,6 @@ class RAWExposure : protected: Adjuster* PexPos; -private: -// Gtk::CheckButton* PextwoGreen; public: RAWExposure (); diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 33f1c2f6a..c78be375f 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -2,6 +2,9 @@ * This file is part of RawTherapee. */ #include "retinex.h" + +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "mycurve.h" #include "rtimage.h" #include "options.h" diff --git a/rtgui/retinex.h b/rtgui/retinex.h index c82c01d3e..ff524f854 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -7,13 +7,18 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" +#include "curvelistener.h" #include "curveeditorgroup.h" #include "guiutils.h" #include "thresholdadjuster.h" #include "toolpanel.h" -class Retinex : +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; +class FlatCurveEditor; + +class Retinex final : public ToolParamBlock, public FoldableToolPanel, public rtengine::RetinexListener, diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 7af6cab97..d501cf449 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -18,6 +18,8 @@ */ #include "rgbcurves.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "options.h" #include "../rtengine/procparams.h" diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h index b73aa22b7..5ed2ea540 100644 --- a/rtgui/rgbcurves.h +++ b/rtgui/rgbcurves.h @@ -22,11 +22,13 @@ #include "adjuster.h" #include "colorprovider.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "toolpanel.h" -class RGBCurves : +class CurveEditorGroup; +class DiagonalCurveEditor; + +class RGBCurves final : public ToolParamBlock, public FoldableToolPanel, public CurveListener, diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc index 7436186c3..06c53cd4e 100644 --- a/rtgui/rotate.cc +++ b/rtgui/rotate.cc @@ -21,6 +21,7 @@ #include "rotate.h" #include "guiutils.h" +#include "lensgeomlistener.h" #include "rtimage.h" #include "../rtengine/procparams.h" diff --git a/rtgui/rotate.h b/rtgui/rotate.h index 5730fd481..41e10eb4d 100644 --- a/rtgui/rotate.h +++ b/rtgui/rotate.h @@ -21,10 +21,10 @@ #include #include "adjuster.h" -#include "lensgeomlistener.h" #include "toolpanel.h" -class Rotate : +class LensGeomListener; +class Rotate final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index c3d735e8f..ae7072d88 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -29,6 +29,7 @@ #include "whitebalance.h" #include "../rtengine/settings.h" #include "batchqueuepanel.h" +#include "batchqueueentry.h" #include "editorpanel.h" #include "filepanel.h" #include "filmsimulation.h" diff --git a/rtgui/sensorbayer.h b/rtgui/sensorbayer.h index 3d6018181..2401bf760 100644 --- a/rtgui/sensorbayer.h +++ b/rtgui/sensorbayer.h @@ -22,7 +22,7 @@ #include "toolpanel.h" -class SensorBayer : +class SensorBayer final : public ToolParamBlock, public FoldableToolPanel { diff --git a/rtgui/sensorxtrans.h b/rtgui/sensorxtrans.h index c1cacb2f4..eee014f6c 100644 --- a/rtgui/sensorxtrans.h +++ b/rtgui/sensorxtrans.h @@ -22,7 +22,7 @@ #include "toolpanel.h" -class SensorXTrans : +class SensorXTrans final: public ToolParamBlock, public FoldableToolPanel { diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h index 4f3ee7577..7bb0bb01c 100644 --- a/rtgui/shadowshighlights.h +++ b/rtgui/shadowshighlights.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class ShadowsHighlights : +class ShadowsHighlights final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/sharpenedge.h b/rtgui/sharpenedge.h index 46a528153..a813d86e1 100644 --- a/rtgui/sharpenedge.h +++ b/rtgui/sharpenedge.h @@ -28,7 +28,7 @@ #include "adjuster.h" #include "toolpanel.h" -class SharpenEdge : +class SharpenEdge final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index e922e82c7..bd5e6f1b7 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -24,7 +24,7 @@ #include "thresholdadjuster.h" #include "toolpanel.h" -class Sharpening : +class Sharpening final: public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, diff --git a/rtgui/sharpenmicro.h b/rtgui/sharpenmicro.h index 3120e6e7b..23224dd60 100644 --- a/rtgui/sharpenmicro.h +++ b/rtgui/sharpenmicro.h @@ -28,7 +28,7 @@ #include "adjuster.h" #include "toolpanel.h" -class SharpenMicro : +class SharpenMicro final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/softlight.h b/rtgui/softlight.h index a584d3a73..710da4e34 100644 --- a/rtgui/softlight.h +++ b/rtgui/softlight.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class SoftLight: public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +class SoftLight final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { private: Adjuster *strength; diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 2774cd206..c9329cf91 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -23,6 +23,7 @@ #include "options.h" #include "rtscalable.h" #include "thumbbrowserbase.h" +#include "thumbbrowserentrybase.h" #include "../rtengine/rt_math.h" diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index 5a55aeeca..d6bafaf69 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -24,13 +24,13 @@ #include "guiutils.h" #include "options.h" -#include "thumbbrowserentrybase.h" /* * Class handling the list of ThumbBrowserEntry objects and their position in it's allocated space */ class Inspector; +class ThumbBrowserEntryBase; class ThumbBrowserBase : public Gtk::Grid diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index bf230fe63..03606bb3d 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -23,6 +23,7 @@ #include #include "thumbimageupdater.h" +#include "thumbbrowserentrybase.h" #include "guiutils.h" #include "threadutils.h" diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h index cdf65bd62..a2e2ecb19 100644 --- a/rtgui/thumbimageupdater.h +++ b/rtgui/thumbimageupdater.h @@ -20,7 +20,6 @@ #include -#include "thumbbrowserentrybase.h" #include "../rtengine/noncopyable.h" @@ -36,6 +35,9 @@ namespace procparams } } + +class ThumbBrowserEntryBase; + class ThumbImageUpdateListener { public: diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 68f3ee4de..dc9b17fa9 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -23,6 +23,8 @@ #include "tonecurve.h" #include "adjuster.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "eventmapper.h" #include "ppversion.h" #include "options.h" diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index cba810e15..e0482c5da 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -21,14 +21,16 @@ #include #include "adjuster.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "guiutils.h" #include "toolpanel.h" +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; class EditDataProvider; -class ToneCurve : +class ToneCurve final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/toolbar.h b/rtgui/toolbar.h index 9f0a2818b..e6d99f819 100644 --- a/rtgui/toolbar.h +++ b/rtgui/toolbar.h @@ -37,7 +37,7 @@ public: virtual void editModeSwitchedOff() = 0; }; -class ToolBar : public Gtk::HBox +class ToolBar final : public Gtk::HBox { private: std::unique_ptr handimg; diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 627200835..0f002e048 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -41,9 +41,6 @@ class ProcParams; } } -class FoldableToolPanel; -class ToolPanel; - class ToolPanelListener { public: diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index e774e3d39..a636994b2 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -21,6 +21,7 @@ #include "metadatapanel.h" #include "options.h" #include "rtimage.h" + #include "../rtengine/imagesource.h" #include "../rtengine/dfmanager.h" #include "../rtengine/ffmanager.h" diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc index 67052785a..4a9fab3d3 100644 --- a/rtgui/vibrance.cc +++ b/rtgui/vibrance.cc @@ -18,6 +18,9 @@ */ #include "vibrance.h" + +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "options.h" #include "../rtengine/color.h" diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h index 211f631f9..12acc7948 100644 --- a/rtgui/vibrance.h +++ b/rtgui/vibrance.h @@ -21,12 +21,14 @@ #include #include "adjuster.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "thresholdadjuster.h" #include "toolpanel.h" -class Vibrance : +class CurveEditorGroup; +class DiagonalCurveEditor; + +class Vibrance final : public ToolParamBlock, public AdjusterListener, public ThresholdCurveProvider, diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h index 8cc8c498b..be7765094 100644 --- a/rtgui/vignetting.h +++ b/rtgui/vignetting.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class Vignetting : +class Vignetting final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 4fd3a7b8f..3981457e6 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -20,6 +20,8 @@ #include "wavelet.h" #include +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "editcallbacks.h" #include "guiutils.h" #include "rtimage.h" diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 20a0ba4e5..6551b58d4 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -22,15 +22,18 @@ #include #include "adjuster.h" #include "toolpanel.h" -#include "curveeditor.h" -#include "curveeditorgroup.h" +#include "curvelistener.h" #include "thresholdadjuster.h" #include "colorprovider.h" #include "guiutils.h" +class CurveEditor; +class CurveEditorGroup; +class DiagonalCurveEditor; class EditDataProvider; +class FlatCurveEditor; -class Wavelet : +class Wavelet final : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 528c81d17..b4d09f119 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -35,7 +35,7 @@ public: virtual void spotWBRequested(int size) = 0; }; -class WhiteBalance : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoWBListener +class WhiteBalance final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoWBListener { enum WB_LabelType { diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h index b17b56b07..d6cb120e0 100644 --- a/rtgui/xtransprocess.h +++ b/rtgui/xtransprocess.h @@ -25,7 +25,7 @@ #include "guiutils.h" #include "toolpanel.h" -class XTransProcess : +class XTransProcess final : public ToolParamBlock, public AdjusterListener, public CheckBoxListener, diff --git a/rtgui/xtransrawexposure.h b/rtgui/xtransrawexposure.h index 46c418f2f..a8daf6972 100644 --- a/rtgui/xtransrawexposure.h +++ b/rtgui/xtransrawexposure.h @@ -23,7 +23,7 @@ #include "adjuster.h" #include "toolpanel.h" -class XTransRAWExposure : +class XTransRAWExposure final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel From d32c570383fde892d2afa785978a1f7fb4ca2c78 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 10 Nov 2019 16:05:24 +0100 Subject: [PATCH 10/18] Capture sharpening: removed gamma --- rtengine/capturesharpening.cc | 12 +++--- rtengine/color.h | 8 ++-- rtengine/procparams.cc | 5 --- rtengine/procparams.h | 1 - rtgui/batchtoolpanelcoord.cc | 2 +- rtgui/paramsedited.cc | 8 +--- rtgui/paramsedited.h | 1 - rtgui/pdsharpening.cc | 76 +++++++++-------------------------- rtgui/pdsharpening.h | 4 +- 9 files changed, 30 insertions(+), 87 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index f574fa45f..357a8593f 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -543,7 +543,9 @@ BENCHFUN array2D tmpIThr(fullTileSize, fullTileSize); array2D tmpThr(fullTileSize, fullTileSize); array2D lumThr(fullTileSize, fullTileSize); -#pragma omp for schedule(dynamic,2) collapse(2) +#ifdef _OPENMP + #pragma omp for schedule(dynamic,2) collapse(2) +#endif for (int i = border; i < H - border; i+= tileSize) { for(int j = border; j < W - border; j+= tileSize) { const bool endOfCol = (i + tileSize + border) >= H; @@ -754,14 +756,13 @@ BENCHFUN array2D& L = Lbuffer ? *Lbuffer : red; array2D& YOld = YOldbuffer ? * YOldbuffer : green; array2D& YNew = YNewbuffer ? * YNewbuffer : blue; - const float gamma = sharpeningParams.gamma; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) #endif for (int i = 0; i < H; ++i) { Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W); - Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], gamma, W); + Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], W); } if (plistener) { plistener->setProgress(0.1); @@ -784,9 +785,8 @@ BENCHFUN for (int i = 0; i < H; ++i) { int j = 0; #ifdef __SSE2__ - const vfloat gammav = F2V(gamma); for (; j < W - 3; j += 4) { - const vfloat factor = pow_F(vmaxf(LVFU(YNew[i][j]), ZEROV) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); + const vfloat factor = vmaxf(LVFU(YNew[i][j]), ZEROV) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)); STVFU(red[i][j], LVFU(redVals[i][j]) * factor); STVFU(green[i][j], LVFU(greenVals[i][j]) * factor); STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor); @@ -794,7 +794,7 @@ BENCHFUN #endif for (; j < W; ++j) { - const float factor = pow_F(std::max(YNew[i][j], 0.f) / std::max(YOld[i][j], 0.00001f), gamma); + const float factor = std::max(YNew[i][j], 0.f) / std::max(YOld[i][j], 0.00001f); red[i][j] = redVals[i][j] * factor; green[i][j] = greenVals[i][j] * factor; blue[i][j] = blueVals[i][j] * factor; diff --git a/rtengine/color.h b/rtengine/color.h index a89778157..d9c344c27 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -1808,11 +1808,9 @@ public: return (hr); } - static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) { - gamma = 1.f / gamma; + static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, int W) { int i = 0; #ifdef __SSE2__ - const vfloat gammav = F2V(gamma); const vfloat c1v = F2V(0.2627f); const vfloat c2v = F2V(0.6780f); const vfloat c3v = F2V(0.0593f); @@ -1820,7 +1818,7 @@ public: const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV); const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV); const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV); - vfloat yv = pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav); + vfloat yv = c1v * Rv + c2v * Gv + c3v * Bv; STVFU(Y1[i], yv); STVFU(Y2[i], yv); } @@ -1829,7 +1827,7 @@ public: const float r = std::max(R[i], 0.f); const float g = std::max(G[i], 0.f); const float b = std::max(B[i], 0.f); - Y1[i] = Y2[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma); + Y1[i] = Y2[i] = 0.2627f * r + 0.6780f * g + 0.0593f * b; } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index c09da1e84..1492797d6 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1159,7 +1159,6 @@ CaptureSharpeningParams::CaptureSharpeningParams() : autoContrast(true), autoRadius(true), contrast(10.0), - gamma(1.00), deconvradius(0.75), deconvradiusOffset(0.0), deconviter(20) @@ -1171,7 +1170,6 @@ bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) return enabled == other.enabled && contrast == other.contrast - && gamma == other.gamma && autoContrast == other.autoContrast && autoRadius == other.autoRadius && deconvradius == other.deconvradius @@ -3383,7 +3381,6 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->pdsharpening.contrast, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.autoContrast, "PostDemosaicSharpening", "AutoContrast", pdsharpening.autoContrast, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.autoRadius, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, keyFile); - saveToKeyfile(!pedited || pedited->pdsharpening.gamma, "PostDemosaicSharpening", "DeconvGamma", pdsharpening.gamma, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradius, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradiusOffset, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); @@ -4473,8 +4470,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pedited, pdsharpening.autoContrast, pedited->pdsharpening.autoContrast); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); - - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvGamma", pedited, pdsharpening.gamma, pedited->pdsharpening.gamma); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 015b487ff..0473fe272 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -548,7 +548,6 @@ struct CaptureSharpeningParams { bool autoContrast; bool autoRadius; double contrast; - double gamma; double deconvradius; double deconvradiusOffset; int deconviter; diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 8aed3e96f..2824a285c 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -157,7 +157,7 @@ void BatchToolPanelCoordinator::initSession () cacorrection->setAdjusterBehavior (false); sharpening->setAdjusterBehavior (false, false, false, false, false, false, false); prsharpening->setAdjusterBehavior (false, false, false, false, false, false, false); - pdSharpening->setAdjusterBehavior (false, false, false, false); + pdSharpening->setAdjusterBehavior (false, false, false); sharpenEdge->setAdjusterBehavior (false, false); sharpenMicro->setAdjusterBehavior (false, false, false); epd->setAdjusterBehavior (false, false, false, false, false); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 74bf975de..fbee97009 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -169,7 +169,6 @@ void ParamsEdited::set(bool v) pdsharpening.contrast = v; pdsharpening.autoContrast = v; pdsharpening.autoRadius = v; - pdsharpening.gamma = v; pdsharpening.deconvradius = v; pdsharpening.deconvradiusOffset = v; pdsharpening.deconviter = v; @@ -756,7 +755,6 @@ void ParamsEdited::initFrom(const std::vector& pdsharpening.contrast = pdsharpening.contrast && p.pdsharpening.contrast == other.pdsharpening.contrast; pdsharpening.autoContrast = pdsharpening.autoContrast && p.pdsharpening.autoContrast == other.pdsharpening.autoContrast; pdsharpening.autoRadius = pdsharpening.autoRadius && p.pdsharpening.autoRadius == other.pdsharpening.autoRadius; - pdsharpening.gamma = pdsharpening.gamma && p.pdsharpening.gamma == other.pdsharpening.gamma; pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; pdsharpening.deconvradiusOffset = pdsharpening.deconvradiusOffset && p.pdsharpening.deconvradiusOffset == other.pdsharpening.deconvradiusOffset; pdsharpening.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; @@ -1742,10 +1740,6 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.autoRadius = mods.pdsharpening.autoRadius; } - if (pdsharpening.gamma) { - toEdit.pdsharpening.gamma = dontforceSet && options.baBehav[ADDSET_SHARP_GAMMA] ? toEdit.pdsharpening.gamma + mods.pdsharpening.gamma : mods.pdsharpening.gamma; - } - if (pdsharpening.deconvradius) { toEdit.pdsharpening.deconvradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.pdsharpening.deconvradius + mods.pdsharpening.deconvradius : mods.pdsharpening.deconvradius; } @@ -3307,5 +3301,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && autoContrast && autoRadius && gamma && deconvradius && deconvradiusOffset && deconviter; + return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 86bffe48d..6c129040c 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -215,7 +215,6 @@ struct CaptureSharpeningParamsEdited { bool contrast; bool autoContrast; bool autoRadius; - bool gamma; bool deconvradius; bool deconvradiusOffset; bool deconviter; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index d0ccc43a8..ad982b82e 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -37,7 +37,6 @@ PdSharpening::PdSharpening() : { auto m = ProcEventMapper::getInstance(); EvPdShrContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CONTRAST"); - EvPdSharpenGamma = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_GAMMA"); EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); EvPdShrDRadiusOffset = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS_BOOST"); EvPdShrDIterations = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); @@ -57,17 +56,14 @@ PdSharpening::PdSharpening() : pack_start(*hb); Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); - gamma = Gtk::manage(new Adjuster(M("TP_SHARPENING_GAMMA"), 0.5, 6.0, 0.05, 1.00)); dradius = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS"), 0.4, 1.15, 0.01, 0.75)); dradius->addAutoButton(); dradius->setAutoValue(true); dradiusOffset = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS_BOOST"), -0.5, 0.5, 0.01, 0.0)); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 1, 100, 1, 20)); - rld->pack_start(*gamma); rld->pack_start(*dradius); rld->pack_start(*dradiusOffset); rld->pack_start(*diter); - gamma->show(); dradius->show(); dradiusOffset->show(); diter->show(); @@ -76,13 +72,11 @@ PdSharpening::PdSharpening() : dradius->setAdjusterListener(this); dradiusOffset->setAdjusterListener(this); - gamma->setAdjusterListener(this); diter->setAdjusterListener(this); contrast->delay = std::max(contrast->delay, options.adjusterMaxDelay); dradius->delay = std::max(dradius->delay, options.adjusterMaxDelay); dradiusOffset->delay = std::max(dradiusOffset->delay, options.adjusterMaxDelay); - gamma->delay = std::max(gamma->delay, options.adjusterMaxDelay); diter->delay = std::max(diter->delay, options.adjusterMaxDelay); } @@ -101,7 +95,6 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) contrast->setEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); contrast->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoContrast); dradius->setAutoInconsistent(multiImage && !pedited->pdsharpening.autoRadius); - gamma->setEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); dradiusOffset->setEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); @@ -113,7 +106,6 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) contrast->setValue(pp->pdsharpening.contrast); contrast->setAutoValue(pp->pdsharpening.autoContrast); - gamma->setValue(pp->pdsharpening.gamma); dradius->setValue(pp->pdsharpening.deconvradius); dradius->setAutoValue(pp->pdsharpening.autoRadius); dradiusOffset->setValue(pp->pdsharpening.deconvradiusOffset); @@ -130,7 +122,6 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pp->pdsharpening.contrast = contrast->getValue(); pp->pdsharpening.autoContrast = contrast->getAutoValue(); pp->pdsharpening.enabled = getEnabled(); - pp->pdsharpening.gamma = gamma->getValue(); pp->pdsharpening.deconvradius = dradius->getValue(); pp->pdsharpening.autoRadius = dradius->getAutoValue(); pp->pdsharpening.deconvradiusOffset = dradiusOffset->getValue(); @@ -139,7 +130,6 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->pdsharpening.contrast = contrast->getEditedState(); pedited->pdsharpening.autoContrast = !contrast->getAutoInconsistent(); - pedited->pdsharpening.gamma = gamma->getEditedState(); pedited->pdsharpening.deconvradius = dradius->getEditedState(); pedited->pdsharpening.autoRadius = !dradius->getAutoInconsistent(); pedited->pdsharpening.deconvradiusOffset = dradiusOffset->getEditedState(); @@ -152,20 +142,17 @@ void PdSharpening::setDefaults(const ProcParams* defParams, const ParamsEdited* { contrast->setDefault(defParams->pdsharpening.contrast); - gamma->setDefault(defParams->pdsharpening.gamma); dradius->setDefault(defParams->pdsharpening.deconvradius); dradiusOffset->setDefault(defParams->pdsharpening.deconvradiusOffset); diter->setDefault(defParams->pdsharpening.deconviter); if (pedited) { contrast->setDefaultEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); - gamma->setDefaultEditedState(pedited->pdsharpening.gamma ? Edited : UnEdited); dradius->setDefaultEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); dradiusOffset->setDefaultEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setDefaultEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); } else { contrast->setDefaultEditedState(Irrelevant); - gamma->setDefaultEditedState(Irrelevant); dradius->setDefaultEditedState(Irrelevant); dradiusOffset->setDefaultEditedState(Irrelevant); diter->setDefaultEditedState(Irrelevant); @@ -178,7 +165,7 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) Glib::ustring costr; - if (a == gamma || a == dradius || a == dradiusOffset) { + if (a == dradius || a == dradiusOffset) { costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else { costr = Glib::ustring::format((int)a->getValue()); @@ -186,8 +173,6 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) if (a == contrast) { listener->panelChanged(EvPdShrContrast, costr); - } else if (a == gamma) { - listener->panelChanged(EvPdSharpenGamma, costr); } else if (a == dradius) { listener->panelChanged(EvPdShrDRadius, costr); } else if (a == dradiusOffset) { @@ -217,17 +202,15 @@ void PdSharpening::setBatchMode(bool batchMode) ToolPanel::setBatchMode(batchMode); contrast->showEditedCB(); - gamma->showEditedCB(); dradius->showEditedCB(); dradiusOffset->showEditedCB(); diter->showEditedCB(); } -void PdSharpening::setAdjusterBehavior(bool contrastadd, bool gammaadd, bool radiusadd, bool iteradd) +void PdSharpening::setAdjusterBehavior(bool contrastadd, bool radiusadd, bool iteradd) { contrast->setAddMode(contrastadd); - gamma->setAddMode(gammaadd); dradius->setAddMode(radiusadd); dradiusOffset->setAddMode(radiusadd); diter->setAddMode(iteradd); @@ -237,7 +220,6 @@ void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) { contrast->trimValue(pp->pdsharpening.contrast); - gamma->trimValue(pp->pdsharpening.gamma); dradius->trimValue(pp->pdsharpening.deconvradius); dradiusOffset->trimValue(pp->pdsharpening.deconvradiusOffset); diter->trimValue(pp->pdsharpening.deconviter); @@ -271,47 +253,25 @@ void PdSharpening::autoRadiusChanged(double autoRadius) void PdSharpening::adjusterAutoToggled(Adjuster* a, bool newval) { - if (a == contrast) { - if (multiImage) { - if (contrast->getAutoInconsistent()) { - contrast->setAutoInconsistent(false); - contrast->setAutoValue(false); - } else if (lastAutoContrast) { - contrast->setAutoInconsistent(true); - } - - lastAutoContrast = contrast->getAutoValue(); + if (multiImage) { + if (a->getAutoInconsistent()) { + a->setAutoInconsistent(false); + a->setAutoValue(false); + } else if (lastAutoRadius) { + a->setAutoInconsistent(true); } - if (listener) { - if (contrast->getAutoInconsistent()) { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_UNCHANGED")); - } else if (contrast->getAutoValue()) { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvPdShrAutoContrast, M("GENERAL_DISABLED")); - } - } - } else { // must be dradius - if (multiImage) { - if (dradius->getAutoInconsistent()) { - dradius->setAutoInconsistent(false); - dradius->setAutoValue(false); - } else if (lastAutoRadius) { - dradius->setAutoInconsistent(true); - } + (a == contrast ? lastAutoContrast : lastAutoRadius) = a->getAutoValue(); + } - lastAutoRadius = dradius->getAutoValue(); - } - - if (listener) { - if (dradius->getAutoInconsistent()) { - listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_UNCHANGED")); - } else if (dradius->getAutoValue()) { - listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_ENABLED")); - } else { - listener->panelChanged(EvPdShrAutoRadius, M("GENERAL_DISABLED")); - } + if (listener) { + const auto event = (a == contrast ? EvPdShrAutoContrast : EvPdShrAutoRadius); + if (a->getAutoInconsistent()) { + listener->panelChanged(event, M("GENERAL_UNCHANGED")); + } else if (a->getAutoValue()) { + listener->panelChanged(event, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(event, M("GENERAL_DISABLED")); } } } diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index f621fd0a5..61d80503f 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -26,7 +26,6 @@ class PdSharpening final : public ToolParamBlock, public AdjusterListener, publi protected: Adjuster* contrast; - Adjuster* gamma; Adjuster* dradius; Adjuster* dradiusOffset; Adjuster* diter; @@ -36,7 +35,6 @@ protected: rtengine::ProcEvent EvPdShrContrast; rtengine::ProcEvent EvPdShrDRadius; rtengine::ProcEvent EvPdShrDRadiusOffset; - rtengine::ProcEvent EvPdSharpenGamma; rtengine::ProcEvent EvPdShrDIterations; rtengine::ProcEvent EvPdShrAutoContrast; rtengine::ProcEvent EvPdShrAutoRadius; @@ -59,6 +57,6 @@ public: void autoContrastChanged (double autoContrast) override; void autoRadiusChanged (double autoRadius) override; - void setAdjusterBehavior (bool contrastadd, bool gammaadd, bool radiusadd, bool iteradds); + void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool iteradds); void trimValues (rtengine::procparams::ProcParams* pp) override; }; From faa324ebf7e77f066c23c11a5d0e5c6f101d32ba Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Sun, 10 Nov 2019 23:13:15 +0100 Subject: [PATCH 11/18] Panasonic DC-S1 / DC-S1R white levels, #5204 Based on measurements from supplied white frames of the DC-S1, and non-white frame raw files with clipping from various sources on the internet of the DC-S1R. --- rtengine/camconst.json | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 32e8bc628..3463bfcc9 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2142,9 +2142,22 @@ Camera constants: } }, - { // Quality B, per ISO info missing - "make_model": [ "Panasonic DC-S1", "Panasonic DC-S1R" ], - "ranges": { "white": 16225 } + { // Quality B, issue #5204. Missing ISO 50, 64 and 80 and I expect the WL to differ for these ISO values + "make_model": [ "Panasonic DC-S1" ], + "dcraw_matrix": [ 9744, -3905, -779, -4899, 12807, 2324, -798, 1630, 5827 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 11.4 + "ranges": { "white": 16320 } + }, + + { // Quality X, issue #5204. No white frames available. + "make_model": [ "Panasonic DC-S1R" ], + "dcraw_matrix": [ 11822, -5321, -1249, -5958, 15114, 766, -614, 1264, 7043 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 11.4 + "ranges": { + "white": [ + { "iso": 50, "levels": 9500 }, + { "iso": [64, 80], "levels": 11600 }, + { "iso": 100, "levels": 16336 } + ] + } }, { // Quality B, per ISO info missing From af4bf34b6baaef0522e79c4968ebcdff0006fe70 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 11 Nov 2019 15:52:31 +0100 Subject: [PATCH 12/18] Capture sharpening: cleanup --- rtengine/capturesharpening.cc | 126 ++++++++++++++++------------------ 1 file changed, 58 insertions(+), 68 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 357a8593f..b1e1657b4 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -99,33 +99,48 @@ void compute3x3kernel(float sigma, float kernel[3][3]) { } } -inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[3][3]) +inline void initTile(float** dst, const int tileSize) +{ + + // first rows + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < tileSize; ++j) { + dst[i][j] = 1.f; + } + } + + // left and right border + for (int i = 3; i < tileSize - 3; ++i) { + dst[i][0] = dst[i][1] = dst[i][2] = 1.f; + dst[i][tileSize - 3] = dst[i][tileSize - 2] = dst[i][tileSize - 1] = 1.f; + } + + // last rows + for (int i = tileSize - 3 ; i < tileSize; ++i) { + for (int j = 0; j < tileSize; ++j) { + dst[i][j] = 1.f; + } + } +} + +inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[3][3]) { const float c11 = kernel[0][0]; const float c10 = kernel[0][1]; const float c00 = kernel[1][1]; - for (int i = 1; i < H - 1; i++) { - dst[i][0] = 1.f; - for (int j = 1; j < W - 1; j++) { + for (int i = 1; i < tileSize - 1; i++) { + for (int j = 1; j < tileSize - 1; j++) { const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + c00 * src[i][j]; dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } - dst[i][W - 1] = 1.f; - } - // first and last row - for (int j = 0; j < W; ++j) { - dst[0][j] = 1.f; - } - for (int j = 0; j < W; ++j) { - dst[H - 1][j] = 1.f; } } -inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[5][5]) +inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[5][5]) { const float c21 = kernel[0][1]; @@ -134,10 +149,9 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES const float c10 = kernel[1][2]; const float c00 = kernel[2][2]; - for (int i = 2; i < H - 2; ++i) { - dst[i][0] = dst[i][1] = 1.f; + for (int i = 2; i < tileSize - 2; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 2; j < W - 2; ++j) { + for (int j = 2; j < tileSize - 2; ++j) { const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + @@ -146,23 +160,10 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } - dst[i][W - 2] = dst[i][W - 1] = 1.f; - } - - // first and last rows - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } - } - for (int i = H - 2 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } } } -inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int W, const int H, const float kernel[7][7]) +inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** RESTRICT divBuffer, const int tileSize, const float kernel[7][7]) { const float c31 = kernel[0][2]; @@ -174,10 +175,9 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST const float c10 = kernel[2][3]; const float c00 = kernel[3][3]; - for (int i = 3; i < H - 3; ++i) { - dst[i][0] = dst[i][1] = dst[i][2] = 1.f; + for (int i = 3; i < tileSize - 3; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 3; j < W - 3; ++j) { + for (int j = 3; j < tileSize - 3; ++j) { const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + @@ -189,30 +189,17 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f); } - dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f; - } - - // first and last rows - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } - } - for (int i = H - 3 ; i < H; ++i) { - for (int j = 0; j < W; ++j) { - dst[i][j] = 1.f; - } } } -inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[3][3]) +inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[3][3]) { const float c11 = kernel[0][0]; const float c10 = kernel[0][1]; const float c00 = kernel[1][1]; - for (int i = 1; i < H - 1; i++) { - for (int j = 1; j < W - 1; j++) { + for (int i = 1; i < tileSize - 1; i++) { + for (int j = 1; j < tileSize - 1; j++) { const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) + c00 * src[i][j]; @@ -222,7 +209,7 @@ inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int W } -inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[5][5]) +inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[5][5]) { const float c21 = kernel[0][1]; @@ -231,9 +218,9 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int const float c10 = kernel[1][2]; const float c00 = kernel[2][2]; - for (int i = 2; i < H - 2; ++i) { + for (int i = 2; i < tileSize - 2; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 2; j < W - 2; ++j) { + for (int j = 2; j < tileSize - 2; ++j) { const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) + c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) + c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) + @@ -245,7 +232,7 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int } } -inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int W, const int H, const float kernel[7][7]) +inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int tileSize, const float kernel[7][7]) { const float c31 = kernel[0][2]; @@ -257,9 +244,9 @@ inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int W const float c10 = kernel[2][3]; const float c00 = kernel[3][3]; - for (int i = 3; i < H - 3; ++i) { + for (int i = 3; i < tileSize - 3; ++i) { // I tried hand written SSE code but gcc vectorizes better - for (int j = 3; j < W - 3; ++j) { + for (int j = 3; j < tileSize - 3; ++j) { const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) + c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) + c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) + @@ -543,6 +530,7 @@ BENCHFUN array2D tmpIThr(fullTileSize, fullTileSize); array2D tmpThr(fullTileSize, fullTileSize); array2D lumThr(fullTileSize, fullTileSize); + initTile(tmpThr, fullTileSize); #ifdef _OPENMP #pragma omp for schedule(dynamic,2) collapse(2) #endif @@ -570,14 +558,14 @@ BENCHFUN if (is3x3) { for (int k = 0; k < iterations; ++k) { // apply 3x3 gaussian blur and divide luminance by result of gaussian blur - gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel3); - gauss3x3mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel3); + gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel3); + gauss3x3mult(tmpThr, tmpIThr, fullTileSize, kernel3); } } else if (is5x5) { for (int k = 0; k < iterations; ++k) { // apply 5x5 gaussian blur and divide luminance by result of gaussian blur - gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel5); - gauss5x5mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel5); + gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel5); + gauss5x5mult(tmpThr, tmpIThr, fullTileSize, kernel5); } } else { if (sigmaCornerOffset != 0.0) { @@ -586,17 +574,17 @@ BENCHFUN if (sigmaTile >= 0.4f) { float lkernel7[7][7]; compute7x7kernel(static_cast(sigma) + distanceFactor * distance, lkernel7); - for (int k = 0; k < iterations - 1; ++k) { + for (int k = 0; k < iterations; ++k) { // apply 7x7 gaussian blur and divide luminance by result of gaussian blur - gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, lkernel7); - gauss7x7mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, lkernel7); + gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7); + gauss7x7mult(tmpThr, tmpIThr, fullTileSize, lkernel7); } } } else { for (int k = 0; k < iterations; ++k) { // apply 7x7 gaussian blur and divide luminance by result of gaussian blur - gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, fullTileSize, kernel7); - gauss7x7mult(tmpThr, tmpIThr, fullTileSize, fullTileSize, kernel7); + gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel7); + gauss7x7mult(tmpThr, tmpIThr, fullTileSize, kernel7); } } } @@ -643,7 +631,7 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams plistener->setProgress(0.0); } BENCHFUN - const float xyz_rgb[3][3] = { // XYZ from RGB + constexpr float 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 } @@ -659,6 +647,8 @@ BENCHFUN array2D clipMask(W, H); constexpr float clipLimit = 0.95f; + constexpr float maxSigma = 1.15f; + if (getSensorType() == ST_BAYER) { const float whites[2][2] = { {(ri->get_white(FC(0,0)) - c_black[FC(0,0)]) * scale_mul[FC(0,0)] * clipLimit, (ri->get_white(FC(0,1)) - c_black[FC(0,1)]) * scale_mul[FC(0,1)] * clipLimit}, @@ -667,7 +657,7 @@ BENCHFUN buildClipMaskBayer(rawData, W, H, clipMask, whites); const unsigned int fc[2] = {FC(0,0), FC(1,0)}; if (sharpeningParams.autoRadius) { - radius = std::min(calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc), 1.15f); + radius = std::min(calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc), maxSigma); } } else if (getSensorType() == ST_FUJI_XTRANS) { float whites[6][6]; @@ -695,14 +685,14 @@ BENCHFUN } } if (sharpeningParams.autoRadius) { - radius = std::min(calcRadiusXtrans(rawData, W, H, 1000.f, clipVal, i, j), 1.15f); + radius = std::min(calcRadiusXtrans(rawData, W, H, 1000.f, clipVal, i, j), maxSigma); } } else if (ri->get_colors() == 1) { buildClipMaskMono(rawData, W, H, clipMask, (ri->get_white(0) - c_black[0]) * scale_mul[0] * clipLimit); if (sharpeningParams.autoRadius) { const unsigned int fc[2] = {0, 0}; - radius = std::min(calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc), 1.15f); + radius = std::min(calcRadiusBayer(rawData, W, H, 1000.f, clipVal, fc), maxSigma); } } From 174f5e95ff1daa684a034f55961b6244e9acd164 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 12 Nov 2019 00:19:04 +0100 Subject: [PATCH 13/18] Capture sharpening: revome transations related to gamma! --- rtdata/languages/default | 3 --- 1 file changed, 3 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index f21a352f0..f1ed6ed5f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -768,7 +768,6 @@ HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrast threshold -HISTORY_MSG_PDSHARPEN_GAMMA;CS - Gamma HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radius HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost @@ -782,7 +781,6 @@ HISTORY_MSG_RAW_BORDER;Raw border HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold -HISTORY_MSG_SHARPENING_GAMMA;Sharpening - Gamma HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength @@ -2032,7 +2030,6 @@ TP_SHARPENING_BLUR;Blur radius TP_SHARPENING_CONTRAST;Contrast threshold TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Edge tolerance -TP_SHARPENING_GAMMA;Gamma TP_SHARPENING_HALOCONTROL;Halo control TP_SHARPENING_HCAMOUNT;Amount TP_SHARPENING_LABEL;Sharpening From e525f5bec19802b048753c13a3aaa634964ec269 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 12 Nov 2019 14:37:15 +0100 Subject: [PATCH 14/18] Capture sharpening: added range-adjuster to exclude bright areas from sharpening --- rtengine/capturesharpening.cc | 2 +- rtengine/procparams.cc | 6 +++++- rtengine/procparams.h | 1 + rtgui/addsetids.h | 2 +- rtgui/batchtoolpanelcoord.cc | 2 +- rtgui/paramsedited.cc | 8 +++++++- rtgui/paramsedited.h | 1 + rtgui/pdsharpening.cc | 26 +++++++++++++++++++++++++- rtgui/pdsharpening.h | 4 +++- 9 files changed, 45 insertions(+), 7 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index b1e1657b4..82e8abb20 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -646,7 +646,7 @@ BENCHFUN const array2D& blueVals = blueCache ? *blueCache : blue; array2D clipMask(W, H); - constexpr float clipLimit = 0.95f; + const float clipLimit = sharpeningParams.deconvrange / 100.f; constexpr float maxSigma = 1.15f; if (getSensorType() == ST_BAYER) { diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 1492797d6..9714b97e5 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1161,7 +1161,8 @@ CaptureSharpeningParams::CaptureSharpeningParams() : contrast(10.0), deconvradius(0.75), deconvradiusOffset(0.0), - deconviter(20) + deconviter(20), + deconvrange(95) { } @@ -1173,6 +1174,7 @@ bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) && autoContrast == other.autoContrast && autoRadius == other.autoRadius && deconvradius == other.deconvradius + && deconvrange == other.deconvrange && deconvradiusOffset == other.deconvradiusOffset && deconviter == other.deconviter; } @@ -3383,6 +3385,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->pdsharpening.autoRadius, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradius, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradiusOffset, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.deconvrange, "PostDemosaicSharpening", "DeconvRange", pdsharpening.deconvrange, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); // Post resize sharpening @@ -4472,6 +4475,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRange", pedited, pdsharpening.deconvrange, pedited->pdsharpening.deconvrange); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0473fe272..b32f66e4f 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -551,6 +551,7 @@ struct CaptureSharpeningParams { double deconvradius; double deconvradiusOffset; int deconviter; + int deconvrange; CaptureSharpeningParams(); diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 46cf19ed5..b1fd2bfed 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -140,7 +140,7 @@ enum { ADDSET_XTRANS_FALSE_COLOR_SUPPRESSION, ADDSET_SOFTLIGHT_STRENGTH, ADDSET_DEHAZE_STRENGTH, - ADDSET_SHARP_GAMMA, + ADDSET_SHARP_RANGE, ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!! }; diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 2824a285c..8aed3e96f 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -157,7 +157,7 @@ void BatchToolPanelCoordinator::initSession () cacorrection->setAdjusterBehavior (false); sharpening->setAdjusterBehavior (false, false, false, false, false, false, false); prsharpening->setAdjusterBehavior (false, false, false, false, false, false, false); - pdSharpening->setAdjusterBehavior (false, false, false); + pdSharpening->setAdjusterBehavior (false, false, false, false); sharpenEdge->setAdjusterBehavior (false, false); sharpenMicro->setAdjusterBehavior (false, false, false); epd->setAdjusterBehavior (false, false, false, false, false); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index fbee97009..f31adedde 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -172,6 +172,7 @@ void ParamsEdited::set(bool v) pdsharpening.deconvradius = v; pdsharpening.deconvradiusOffset = v; pdsharpening.deconviter = v; + pdsharpening.deconvrange = v; prsharpening.enabled = v; prsharpening.contrast = v; prsharpening.radius = v; @@ -758,6 +759,7 @@ void ParamsEdited::initFrom(const std::vector& pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; pdsharpening.deconvradiusOffset = pdsharpening.deconvradiusOffset && p.pdsharpening.deconvradiusOffset == other.pdsharpening.deconvradiusOffset; pdsharpening.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; + pdsharpening.deconvrange = pdsharpening.deconvrange && p.pdsharpening.deconvrange == other.pdsharpening.deconvrange; prsharpening.enabled = prsharpening.enabled && p.prsharpening.enabled == other.prsharpening.enabled; prsharpening.contrast = prsharpening.contrast && p.prsharpening.contrast == other.prsharpening.contrast; prsharpening.radius = prsharpening.radius && p.prsharpening.radius == other.prsharpening.radius; @@ -1752,6 +1754,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.pdsharpening.deconviter + mods.pdsharpening.deconviter : mods.pdsharpening.deconviter; } + if (pdsharpening.deconvrange) { + toEdit.pdsharpening.deconvrange = dontforceSet && options.baBehav[ADDSET_SHARP_RANGE] ? toEdit.pdsharpening.deconvrange + mods.pdsharpening.deconvrange : mods.pdsharpening.deconvrange; + } + if (prsharpening.enabled) { toEdit.prsharpening.enabled = mods.prsharpening.enabled; } @@ -3301,5 +3307,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter; + return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter && deconvrange; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 6c129040c..1a708329a 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -218,6 +218,7 @@ struct CaptureSharpeningParamsEdited { bool deconvradius; bool deconvradiusOffset; bool deconviter; + bool deconvrange; bool isUnchanged() const; }; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index ad982b82e..02fe56033 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -24,6 +24,7 @@ #include "eventmapper.h" #include "options.h" +#include "rtimage.h" #include "../rtengine/procparams.h" @@ -37,6 +38,7 @@ PdSharpening::PdSharpening() : { auto m = ProcEventMapper::getInstance(); EvPdShrContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CONTRAST"); + EvPdShrRange = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RANGE"); EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); EvPdShrDRadiusOffset = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS_BOOST"); EvPdShrDIterations = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); @@ -53,6 +55,14 @@ PdSharpening::PdSharpening() : pack_start(*contrast); contrast->show(); + Gtk::Image *al = Gtk::manage(new RTImage("circle-black-small.png")); + Gtk::Image *ar = Gtk::manage(new RTImage("circle-white-small.png")); + range = Gtk::manage(new Adjuster(M("TP_SHARPENING_RANGE"), 0, 100, 1, 95, al, ar)); + range->setAdjusterListener(this); + + pack_start(*range); + range->show(); + pack_start(*hb); Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); @@ -73,8 +83,10 @@ PdSharpening::PdSharpening() : dradius->setAdjusterListener(this); dradiusOffset->setAdjusterListener(this); diter->setAdjusterListener(this); + range->setAdjusterListener(this); contrast->delay = std::max(contrast->delay, options.adjusterMaxDelay); + range->delay = std::max(range->delay, options.adjusterMaxDelay); dradius->delay = std::max(dradius->delay, options.adjusterMaxDelay); dradiusOffset->delay = std::max(dradiusOffset->delay, options.adjusterMaxDelay); diter->delay = std::max(diter->delay, options.adjusterMaxDelay); @@ -98,6 +110,7 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); dradiusOffset->setEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); + range->setEditedState(pedited->pdsharpening.deconvrange ? Edited : UnEdited); set_inconsistent(multiImage && !pedited->pdsharpening.enabled); } @@ -110,6 +123,7 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) dradius->setAutoValue(pp->pdsharpening.autoRadius); dradiusOffset->setValue(pp->pdsharpening.deconvradiusOffset); diter->setValue(pp->pdsharpening.deconviter); + range->setValue(pp->pdsharpening.deconvrange); lastAutoContrast = pp->pdsharpening.autoContrast; lastAutoRadius = pp->pdsharpening.autoRadius; @@ -126,6 +140,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pp->pdsharpening.autoRadius = dradius->getAutoValue(); pp->pdsharpening.deconvradiusOffset = dradiusOffset->getValue(); pp->pdsharpening.deconviter =(int)diter->getValue(); + pp->pdsharpening.deconvrange =(int)range->getValue(); if (pedited) { pedited->pdsharpening.contrast = contrast->getEditedState(); @@ -134,6 +149,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pedited->pdsharpening.autoRadius = !dradius->getAutoInconsistent(); pedited->pdsharpening.deconvradiusOffset = dradiusOffset->getEditedState(); pedited->pdsharpening.deconviter = diter->getEditedState(); + pedited->pdsharpening.deconvrange = range->getEditedState(); pedited->pdsharpening.enabled = !get_inconsistent(); } } @@ -145,17 +161,20 @@ void PdSharpening::setDefaults(const ProcParams* defParams, const ParamsEdited* dradius->setDefault(defParams->pdsharpening.deconvradius); dradiusOffset->setDefault(defParams->pdsharpening.deconvradiusOffset); diter->setDefault(defParams->pdsharpening.deconviter); + range->setDefault(defParams->pdsharpening.deconvrange); if (pedited) { contrast->setDefaultEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); dradius->setDefaultEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); dradiusOffset->setDefaultEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setDefaultEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); + range->setDefaultEditedState(pedited->pdsharpening.deconvrange ? Edited : UnEdited); } else { contrast->setDefaultEditedState(Irrelevant); dradius->setDefaultEditedState(Irrelevant); dradiusOffset->setDefaultEditedState(Irrelevant); diter->setDefaultEditedState(Irrelevant); + range->setDefaultEditedState(Irrelevant); } } @@ -179,6 +198,8 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvPdShrDRadiusOffset, costr); } else if (a == diter) { listener->panelChanged(EvPdShrDIterations, costr); + } else if (a == range) { + listener->panelChanged(EvPdShrRange, costr); } } } @@ -205,15 +226,17 @@ void PdSharpening::setBatchMode(bool batchMode) dradius->showEditedCB(); dradiusOffset->showEditedCB(); diter->showEditedCB(); + range->showEditedCB(); } -void PdSharpening::setAdjusterBehavior(bool contrastadd, bool radiusadd, bool iteradd) +void PdSharpening::setAdjusterBehavior(bool contrastadd, bool radiusadd, bool iteradd, bool rangeadd) { contrast->setAddMode(contrastadd); dradius->setAddMode(radiusadd); dradiusOffset->setAddMode(radiusadd); diter->setAddMode(iteradd); + range->setAddMode(rangeadd); } void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) @@ -223,6 +246,7 @@ void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) dradius->trimValue(pp->pdsharpening.deconvradius); dradiusOffset->trimValue(pp->pdsharpening.deconvradiusOffset); diter->trimValue(pp->pdsharpening.deconviter); + range->trimValue(pp->pdsharpening.deconvrange); } void PdSharpening::autoContrastChanged(double autoContrast) diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index 61d80503f..b22e26fab 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -26,6 +26,7 @@ class PdSharpening final : public ToolParamBlock, public AdjusterListener, publi protected: Adjuster* contrast; + Adjuster* range; Adjuster* dradius; Adjuster* dradiusOffset; Adjuster* diter; @@ -33,6 +34,7 @@ protected: bool lastAutoContrast; bool lastAutoRadius; rtengine::ProcEvent EvPdShrContrast; + rtengine::ProcEvent EvPdShrRange; rtengine::ProcEvent EvPdShrDRadius; rtengine::ProcEvent EvPdShrDRadiusOffset; rtengine::ProcEvent EvPdShrDIterations; @@ -57,6 +59,6 @@ public: void autoContrastChanged (double autoContrast) override; void autoRadiusChanged (double autoRadius) override; - void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool iteradds); + void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool iteradd, bool rangeadd); void trimValues (rtengine::procparams::ProcParams* pp) override; }; From 4857566d258ffaaf12e03bf17df4bb90b2e505f0 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Tue, 12 Nov 2019 18:06:55 +0100 Subject: [PATCH 15/18] Capture sharpening: add range label to default file --- rtdata/languages/default | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index f1ed6ed5f..bdc3fc8a0 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -771,6 +771,7 @@ HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrast threshold HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radius HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost +HISTORY_MSG_PDSHARPEN_RANGE;CS - Range HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2037,6 +2038,7 @@ TP_SHARPENING_METHOD;Method TP_SHARPENING_ONLYEDGES;Sharpen only edges TP_SHARPENING_RADIUS;Radius TP_SHARPENING_RADIUS_BOOST;Corner radius boost +TP_SHARPENING_RANGE;Range TP_SHARPENING_RLD;RL Deconvolution TP_SHARPENING_RLD_AMOUNT;Amount TP_SHARPENING_RLD_DAMPING;Damping From a4909dc09e610b02beeddc8f01b329ed1b3711e7 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Tue, 12 Nov 2019 22:49:07 +0100 Subject: [PATCH 16/18] Panasonic DC-S1 white levels update Updated white levels for ISO 50, 64 and 80, based on raw files from issue #5204 --- rtengine/camconst.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 3463bfcc9..f2db455a3 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1,4 +1,5 @@ /* +vim: set syntax=javascript: DO NOT EDIT THIS FILE! @@ -2142,10 +2143,17 @@ Camera constants: } }, - { // Quality B, issue #5204. Missing ISO 50, 64 and 80 and I expect the WL to differ for these ISO values + { // Quality A, issue #5204. "make_model": [ "Panasonic DC-S1" ], "dcraw_matrix": [ 9744, -3905, -779, -4899, 12807, 2324, -798, 1630, 5827 ], // ColorMatrix2 using illuminant D65 from Adobe DNG Converter 11.4 - "ranges": { "white": 16320 } + "ranges": { + "white": [ + { "iso": 50, "levels": 8400 }, // LENR 8000 + { "iso": 64, "levels": 10450 }, // LENR 10000 + { "iso": 80, "levels": 13050 }, // LENR 12400 + { "iso": 100, "levels": 16320 } + ] + } }, { // Quality X, issue #5204. No white frames available. From 3be7016517f2fe5989aa9a35969d5e0e99e47608 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Wed, 13 Nov 2019 21:05:24 +0100 Subject: [PATCH 17/18] Capture sharpening: Remove range adjuster and introduce --- rtdata/languages/default | 4 +-- rtengine/capturesharpening.cc | 66 ++++++++++++++++++++++++++++++----- rtengine/procparams.cc | 8 ++--- rtengine/procparams.h | 2 +- rtgui/addsetids.h | 1 - rtgui/batchtoolpanelcoord.cc | 2 +- rtgui/paramsedited.cc | 10 +++--- rtgui/paramsedited.h | 2 +- rtgui/pdsharpening.cc | 43 ++++++++++------------- rtgui/pdsharpening.h | 16 ++++++--- 10 files changed, 102 insertions(+), 52 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index bdc3fc8a0..da4d5c804 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -767,11 +767,11 @@ HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius +HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrast threshold HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterations HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radius HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost -HISTORY_MSG_PDSHARPEN_RANGE;CS - Range HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter @@ -2033,12 +2033,12 @@ TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Edge tolerance TP_SHARPENING_HALOCONTROL;Halo control TP_SHARPENING_HCAMOUNT;Amount +TP_SHARPENING_ITERCHECK;Auto limit iterations TP_SHARPENING_LABEL;Sharpening TP_SHARPENING_METHOD;Method TP_SHARPENING_ONLYEDGES;Sharpen only edges TP_SHARPENING_RADIUS;Radius TP_SHARPENING_RADIUS_BOOST;Corner radius boost -TP_SHARPENING_RANGE;Range TP_SHARPENING_RLD;RL Deconvolution TP_SHARPENING_RLD_AMOUNT;Amount TP_SHARPENING_RLD_DAMPING;Damping diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 82e8abb20..60f83a652 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -497,7 +497,30 @@ float calcRadiusXtrans(const float * const *rawData, int W, int H, float lowerLi return std::sqrt((1.f / (std::log(1.f / maxRatio))) / -2.f); } -void CaptureDeconvSharpening (float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, rtengine::ProgressListener* plistener, double startVal, double endVal) +bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int border) +{ + bool stopped = false; + for (int ii = border; !stopped && ii < fullTileSize - border; ++ii) { +#ifdef __SSE2__ + for (int jj = border; jj < fullTileSize - border; jj += 4) { + if (_mm_movemask_ps((vfloat)vmaskf_lt(vmul2f(LVFU(tmpIThr[ii][jj])), LVFU(iterCheck[ii - border][jj - border])))) { + stopped = true; + break; + } + } +#else + for (int jj = border; jj < fullTileSize - border; ++jj) { + if (tmpIThr[ii][jj] * xxx < luminance[i + ii - border][j + jj - border] * clipmask[i + ii - border][j + jj - border]) { + stopped = true; + break; + } + } +#endif + } + return stopped; +} + +void CaptureDeconvSharpening (float ** clipmask, float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal) { BENCHFUN const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0); @@ -513,7 +536,7 @@ BENCHFUN compute7x7kernel(sigma, kernel7); } - constexpr int tileSize = 194; + constexpr int tileSize = 32; constexpr int border = 5; constexpr int fullTileSize = tileSize + 2 * border; const float cornerRadius = std::min(1.15f, sigma + sigmaCornerOffset); @@ -522,6 +545,7 @@ BENCHFUN double progress = startVal; const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H); + #ifdef _OPENMP #pragma omp parallel #endif @@ -530,9 +554,10 @@ BENCHFUN array2D tmpIThr(fullTileSize, fullTileSize); array2D tmpThr(fullTileSize, fullTileSize); array2D lumThr(fullTileSize, fullTileSize); + array2D iterCheck(tileSize, tileSize); initTile(tmpThr, fullTileSize); #ifdef _OPENMP - #pragma omp for schedule(dynamic,2) collapse(2) + #pragma omp for schedule(dynamic,16) collapse(2) #endif for (int i = border; i < H - border; i+= tileSize) { for(int j = border; j < W - border; j+= tileSize) { @@ -541,6 +566,11 @@ BENCHFUN // fill tiles if (endOfRow || endOfCol) { // special handling for small tiles at end of row or column + for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) { + for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) { + iterCheck[k][l] = oldLuminance[ii][jj] * clipmask[ii][jj]; + } + } for (int k = 0, ii = endOfCol ? H - fullTileSize : i; k < fullTileSize; ++k, ++ii) { for (int l = 0, jj = endOfRow ? W - fullTileSize : j; l < fullTileSize; ++l, ++jj) { tmpIThr[k][l] = oldLuminance[ii - border][jj - border]; @@ -548,6 +578,11 @@ BENCHFUN } } } else { + for (int ii = 0; ii < tileSize; ++ii) { + for (int jj = 0; jj < tileSize; ++jj) { + iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * clipmask[i + ii][j + jj]; + } + } for (int ii = i; ii < i + fullTileSize; ++ii) { for (int jj = j; jj < j + fullTileSize; ++jj) { tmpIThr[ii - i][jj - j] = oldLuminance[ii - border][jj - border]; @@ -555,17 +590,24 @@ BENCHFUN } } } + bool stopped = false; if (is3x3) { - for (int k = 0; k < iterations; ++k) { + for (int k = 0; k < iterations && !stopped; ++k) { // apply 3x3 gaussian blur and divide luminance by result of gaussian blur gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel3); gauss3x3mult(tmpThr, tmpIThr, fullTileSize, kernel3); + if (checkIterStop) { + stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border); + } } } else if (is5x5) { - for (int k = 0; k < iterations; ++k) { + for (int k = 0; k < iterations && !stopped; ++k) { // apply 5x5 gaussian blur and divide luminance by result of gaussian blur gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel5); gauss5x5mult(tmpThr, tmpIThr, fullTileSize, kernel5); + if (checkIterStop) { + stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border); + } } } else { if (sigmaCornerOffset != 0.0) { @@ -574,17 +616,23 @@ BENCHFUN if (sigmaTile >= 0.4f) { float lkernel7[7][7]; compute7x7kernel(static_cast(sigma) + distanceFactor * distance, lkernel7); - for (int k = 0; k < iterations; ++k) { + for (int k = 0; k < iterations && !stopped; ++k) { // apply 7x7 gaussian blur and divide luminance by result of gaussian blur gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7); gauss7x7mult(tmpThr, tmpIThr, fullTileSize, lkernel7); + if (checkIterStop) { + stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border); + } } } } else { - for (int k = 0; k < iterations; ++k) { + for (int k = 0; k < iterations && !stopped; ++k) { // apply 7x7 gaussian blur and divide luminance by result of gaussian blur gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel7); gauss7x7mult(tmpThr, tmpIThr, fullTileSize, kernel7); + if (checkIterStop) { + stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border); + } } } } @@ -646,7 +694,7 @@ BENCHFUN const array2D& blueVals = blueCache ? *blueCache : blue; array2D clipMask(W, H); - const float clipLimit = sharpeningParams.deconvrange / 100.f; + constexpr float clipLimit = 0.95f; constexpr float maxSigma = 1.15f; if (getSensorType() == ST_BAYER) { @@ -765,7 +813,7 @@ BENCHFUN } conrastThreshold = contrast * 100.f; - CaptureDeconvSharpening(YNew, YOld, blend, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, plistener, 0.2, 0.9); + CaptureDeconvSharpening(clipMask, YNew, YOld, blend, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, sharpeningParams.deconvitercheck, plistener, 0.2, 0.9); if (plistener) { plistener->setProgress(0.9); } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9714b97e5..9483c6a02 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1162,7 +1162,7 @@ CaptureSharpeningParams::CaptureSharpeningParams() : deconvradius(0.75), deconvradiusOffset(0.0), deconviter(20), - deconvrange(95) + deconvitercheck(true) { } @@ -1174,7 +1174,7 @@ bool CaptureSharpeningParams::operator ==(const CaptureSharpeningParams& other) && autoContrast == other.autoContrast && autoRadius == other.autoRadius && deconvradius == other.deconvradius - && deconvrange == other.deconvrange + && deconvitercheck == other.deconvitercheck && deconvradiusOffset == other.deconvradiusOffset && deconviter == other.deconviter; } @@ -3385,7 +3385,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->pdsharpening.autoRadius, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradius, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconvradiusOffset, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, keyFile); - saveToKeyfile(!pedited || pedited->pdsharpening.deconvrange, "PostDemosaicSharpening", "DeconvRange", pdsharpening.deconvrange, keyFile); + saveToKeyfile(!pedited || pedited->pdsharpening.deconvitercheck, "PostDemosaicSharpening", "DeconvIterCheck", pdsharpening.deconvitercheck, keyFile); saveToKeyfile(!pedited || pedited->pdsharpening.deconviter, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, keyFile); // Post resize sharpening @@ -4475,7 +4475,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRange", pedited, pdsharpening.deconvrange, pedited->pdsharpening.deconvrange); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterCheck", pedited, pdsharpening.deconvitercheck, pedited->pdsharpening.deconvitercheck); assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index b32f66e4f..01c54ffc5 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -551,7 +551,7 @@ struct CaptureSharpeningParams { double deconvradius; double deconvradiusOffset; int deconviter; - int deconvrange; + bool deconvitercheck; CaptureSharpeningParams(); diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index b1fd2bfed..05150517f 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -140,7 +140,6 @@ enum { ADDSET_XTRANS_FALSE_COLOR_SUPPRESSION, ADDSET_SOFTLIGHT_STRENGTH, ADDSET_DEHAZE_STRENGTH, - ADDSET_SHARP_RANGE, ADDSET_PARAM_NUM // THIS IS USED AS A DELIMITER!! }; diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 8aed3e96f..2824a285c 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -157,7 +157,7 @@ void BatchToolPanelCoordinator::initSession () cacorrection->setAdjusterBehavior (false); sharpening->setAdjusterBehavior (false, false, false, false, false, false, false); prsharpening->setAdjusterBehavior (false, false, false, false, false, false, false); - pdSharpening->setAdjusterBehavior (false, false, false, false); + pdSharpening->setAdjusterBehavior (false, false, false); sharpenEdge->setAdjusterBehavior (false, false); sharpenMicro->setAdjusterBehavior (false, false, false); epd->setAdjusterBehavior (false, false, false, false, false); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f31adedde..82132008a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -172,7 +172,7 @@ void ParamsEdited::set(bool v) pdsharpening.deconvradius = v; pdsharpening.deconvradiusOffset = v; pdsharpening.deconviter = v; - pdsharpening.deconvrange = v; + pdsharpening.deconvitercheck = v; prsharpening.enabled = v; prsharpening.contrast = v; prsharpening.radius = v; @@ -759,7 +759,7 @@ void ParamsEdited::initFrom(const std::vector& pdsharpening.deconvradius = pdsharpening.deconvradius && p.pdsharpening.deconvradius == other.pdsharpening.deconvradius; pdsharpening.deconvradiusOffset = pdsharpening.deconvradiusOffset && p.pdsharpening.deconvradiusOffset == other.pdsharpening.deconvradiusOffset; pdsharpening.deconviter = pdsharpening.deconviter && p.pdsharpening.deconviter == other.pdsharpening.deconviter; - pdsharpening.deconvrange = pdsharpening.deconvrange && p.pdsharpening.deconvrange == other.pdsharpening.deconvrange; + pdsharpening.deconvitercheck = pdsharpening.deconvitercheck && p.pdsharpening.deconvitercheck == other.pdsharpening.deconvitercheck; prsharpening.enabled = prsharpening.enabled && p.prsharpening.enabled == other.prsharpening.enabled; prsharpening.contrast = prsharpening.contrast && p.prsharpening.contrast == other.prsharpening.contrast; prsharpening.radius = prsharpening.radius && p.prsharpening.radius == other.prsharpening.radius; @@ -1754,8 +1754,8 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.pdsharpening.deconviter = dontforceSet && options.baBehav[ADDSET_SHARP_ITER] ? toEdit.pdsharpening.deconviter + mods.pdsharpening.deconviter : mods.pdsharpening.deconviter; } - if (pdsharpening.deconvrange) { - toEdit.pdsharpening.deconvrange = dontforceSet && options.baBehav[ADDSET_SHARP_RANGE] ? toEdit.pdsharpening.deconvrange + mods.pdsharpening.deconvrange : mods.pdsharpening.deconvrange; + if (pdsharpening.deconvitercheck) { + toEdit.pdsharpening.deconvitercheck = mods.pdsharpening.deconvitercheck; } if (prsharpening.enabled) { @@ -3307,5 +3307,5 @@ bool FilmNegativeParamsEdited::isUnchanged() const bool CaptureSharpeningParamsEdited::isUnchanged() const { - return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter && deconvrange; + return enabled && contrast && autoContrast && autoRadius && deconvradius && deconvradiusOffset && deconviter && deconvitercheck; } \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 1a708329a..01a3e4efe 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -218,7 +218,7 @@ struct CaptureSharpeningParamsEdited { bool deconvradius; bool deconvradiusOffset; bool deconviter; - bool deconvrange; + bool deconvitercheck; bool isUnchanged() const; }; diff --git a/rtgui/pdsharpening.cc b/rtgui/pdsharpening.cc index 02fe56033..4f5416c82 100644 --- a/rtgui/pdsharpening.cc +++ b/rtgui/pdsharpening.cc @@ -38,7 +38,7 @@ PdSharpening::PdSharpening() : { auto m = ProcEventMapper::getInstance(); EvPdShrContrast = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CONTRAST"); - EvPdShrRange = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RANGE"); + EvPdShrCheckIter = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_CHECKITER"); EvPdShrDRadius = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS"); EvPdShrDRadiusOffset = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_RADIUS_BOOST"); EvPdShrDIterations = m->newEvent(CAPTURESHARPEN, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); @@ -55,14 +55,6 @@ PdSharpening::PdSharpening() : pack_start(*contrast); contrast->show(); - Gtk::Image *al = Gtk::manage(new RTImage("circle-black-small.png")); - Gtk::Image *ar = Gtk::manage(new RTImage("circle-white-small.png")); - range = Gtk::manage(new Adjuster(M("TP_SHARPENING_RANGE"), 0, 100, 1, 95, al, ar)); - range->setAdjusterListener(this); - - pack_start(*range); - range->show(); - pack_start(*hb); Gtk::VBox* rld = Gtk::manage(new Gtk::VBox()); @@ -71,22 +63,25 @@ PdSharpening::PdSharpening() : dradius->setAutoValue(true); dradiusOffset = Gtk::manage(new Adjuster(M("TP_SHARPENING_RADIUS_BOOST"), -0.5, 0.5, 0.01, 0.0)); diter = Gtk::manage(new Adjuster(M("TP_SHARPENING_RLD_ITERATIONS"), 1, 100, 1, 20)); + itercheck = Gtk::manage(new CheckBox(M("TP_SHARPENING_ITERCHECK"), multiImage)); + itercheck->setCheckBoxListener(this); + rld->pack_start(*dradius); rld->pack_start(*dradiusOffset); rld->pack_start(*diter); + rld->pack_start(*itercheck); dradius->show(); dradiusOffset->show(); diter->show(); + itercheck->show(); rld->show(); pack_start(*rld); dradius->setAdjusterListener(this); dradiusOffset->setAdjusterListener(this); diter->setAdjusterListener(this); - range->setAdjusterListener(this); contrast->delay = std::max(contrast->delay, options.adjusterMaxDelay); - range->delay = std::max(range->delay, options.adjusterMaxDelay); dradius->delay = std::max(dradius->delay, options.adjusterMaxDelay); dradiusOffset->delay = std::max(dradiusOffset->delay, options.adjusterMaxDelay); diter->delay = std::max(diter->delay, options.adjusterMaxDelay); @@ -110,7 +105,7 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) dradius->setEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); dradiusOffset->setEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); - range->setEditedState(pedited->pdsharpening.deconvrange ? Edited : UnEdited); + itercheck->setEdited(pedited->pdsharpening.deconvitercheck); set_inconsistent(multiImage && !pedited->pdsharpening.enabled); } @@ -123,7 +118,8 @@ void PdSharpening::read(const ProcParams* pp, const ParamsEdited* pedited) dradius->setAutoValue(pp->pdsharpening.autoRadius); dradiusOffset->setValue(pp->pdsharpening.deconvradiusOffset); diter->setValue(pp->pdsharpening.deconviter); - range->setValue(pp->pdsharpening.deconvrange); + itercheck->setValue(pp->pdsharpening.deconvitercheck); + lastAutoContrast = pp->pdsharpening.autoContrast; lastAutoRadius = pp->pdsharpening.autoRadius; @@ -140,7 +136,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pp->pdsharpening.autoRadius = dradius->getAutoValue(); pp->pdsharpening.deconvradiusOffset = dradiusOffset->getValue(); pp->pdsharpening.deconviter =(int)diter->getValue(); - pp->pdsharpening.deconvrange =(int)range->getValue(); + pp->pdsharpening.deconvitercheck = itercheck->getLastActive(); if (pedited) { pedited->pdsharpening.contrast = contrast->getEditedState(); @@ -149,7 +145,7 @@ void PdSharpening::write(ProcParams* pp, ParamsEdited* pedited) pedited->pdsharpening.autoRadius = !dradius->getAutoInconsistent(); pedited->pdsharpening.deconvradiusOffset = dradiusOffset->getEditedState(); pedited->pdsharpening.deconviter = diter->getEditedState(); - pedited->pdsharpening.deconvrange = range->getEditedState(); + pedited->pdsharpening.deconvitercheck = !itercheck->get_inconsistent(); pedited->pdsharpening.enabled = !get_inconsistent(); } } @@ -161,20 +157,24 @@ void PdSharpening::setDefaults(const ProcParams* defParams, const ParamsEdited* dradius->setDefault(defParams->pdsharpening.deconvradius); dradiusOffset->setDefault(defParams->pdsharpening.deconvradiusOffset); diter->setDefault(defParams->pdsharpening.deconviter); - range->setDefault(defParams->pdsharpening.deconvrange); if (pedited) { contrast->setDefaultEditedState(pedited->pdsharpening.contrast ? Edited : UnEdited); dradius->setDefaultEditedState(pedited->pdsharpening.deconvradius ? Edited : UnEdited); dradiusOffset->setDefaultEditedState(pedited->pdsharpening.deconvradiusOffset ? Edited : UnEdited); diter->setDefaultEditedState(pedited->pdsharpening.deconviter ? Edited : UnEdited); - range->setDefaultEditedState(pedited->pdsharpening.deconvrange ? Edited : UnEdited); } else { contrast->setDefaultEditedState(Irrelevant); dradius->setDefaultEditedState(Irrelevant); dradiusOffset->setDefaultEditedState(Irrelevant); diter->setDefaultEditedState(Irrelevant); - range->setDefaultEditedState(Irrelevant); + } +} + +void PdSharpening::checkBoxToggled (CheckBox* c, CheckValue newval) +{ + if (listener) { + listener->panelChanged (EvPdShrCheckIter, itercheck->getLastActive() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); } } @@ -198,8 +198,6 @@ void PdSharpening::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvPdShrDRadiusOffset, costr); } else if (a == diter) { listener->panelChanged(EvPdShrDIterations, costr); - } else if (a == range) { - listener->panelChanged(EvPdShrRange, costr); } } } @@ -226,17 +224,15 @@ void PdSharpening::setBatchMode(bool batchMode) dradius->showEditedCB(); dradiusOffset->showEditedCB(); diter->showEditedCB(); - range->showEditedCB(); } -void PdSharpening::setAdjusterBehavior(bool contrastadd, bool radiusadd, bool iteradd, bool rangeadd) +void PdSharpening::setAdjusterBehavior(bool contrastadd, bool radiusadd, bool iteradd) { contrast->setAddMode(contrastadd); dradius->setAddMode(radiusadd); dradiusOffset->setAddMode(radiusadd); diter->setAddMode(iteradd); - range->setAddMode(rangeadd); } void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) @@ -246,7 +242,6 @@ void PdSharpening::trimValues(rtengine::procparams::ProcParams* pp) dradius->trimValue(pp->pdsharpening.deconvradius); dradiusOffset->trimValue(pp->pdsharpening.deconvradiusOffset); diter->trimValue(pp->pdsharpening.deconviter); - range->trimValue(pp->pdsharpening.deconvrange); } void PdSharpening::autoContrastChanged(double autoContrast) diff --git a/rtgui/pdsharpening.h b/rtgui/pdsharpening.h index b22e26fab..7d971eaee 100644 --- a/rtgui/pdsharpening.h +++ b/rtgui/pdsharpening.h @@ -19,22 +19,29 @@ #pragma once #include "adjuster.h" +#include "checkbox.h" #include "toolpanel.h" -class PdSharpening final : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoContrastListener, public rtengine::AutoRadiusListener +class PdSharpening final : + public ToolParamBlock, + public AdjusterListener, + public FoldableToolPanel, + public rtengine::AutoContrastListener, + public rtengine::AutoRadiusListener, + public CheckBoxListener { protected: Adjuster* contrast; - Adjuster* range; Adjuster* dradius; Adjuster* dradiusOffset; Adjuster* diter; + CheckBox* itercheck; bool lastAutoContrast; bool lastAutoRadius; rtengine::ProcEvent EvPdShrContrast; - rtengine::ProcEvent EvPdShrRange; + rtengine::ProcEvent EvPdShrCheckIter; rtengine::ProcEvent EvPdShrDRadius; rtengine::ProcEvent EvPdShrDRadiusOffset; rtengine::ProcEvent EvPdShrDIterations; @@ -59,6 +66,7 @@ public: void autoContrastChanged (double autoContrast) override; void autoRadiusChanged (double autoRadius) override; - void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool iteradd, bool rangeadd); + void setAdjusterBehavior (bool contrastadd, bool radiusadd, bool iteradd); void trimValues (rtengine::procparams::ProcParams* pp) override; + void checkBoxToggled(CheckBox* c, CheckValue newval) override; }; From c2ed31991bd8faee2882c7f997c5a663e82c5518 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Thu, 14 Nov 2019 11:57:55 +0100 Subject: [PATCH 18/18] Capture sharpening: fix broken non SSE build --- rtengine/capturesharpening.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/rtengine/capturesharpening.cc b/rtengine/capturesharpening.cc index 60f83a652..2866839bf 100644 --- a/rtengine/capturesharpening.cc +++ b/rtengine/capturesharpening.cc @@ -503,14 +503,14 @@ bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int bord for (int ii = border; !stopped && ii < fullTileSize - border; ++ii) { #ifdef __SSE2__ for (int jj = border; jj < fullTileSize - border; jj += 4) { - if (_mm_movemask_ps((vfloat)vmaskf_lt(vmul2f(LVFU(tmpIThr[ii][jj])), LVFU(iterCheck[ii - border][jj - border])))) { + if (_mm_movemask_ps((vfloat)vmaskf_lt(LVFU(tmpIThr[ii][jj]), LVFU(iterCheck[ii - border][jj - border])))) { stopped = true; break; } } #else for (int jj = border; jj < fullTileSize - border; ++jj) { - if (tmpIThr[ii][jj] * xxx < luminance[i + ii - border][j + jj - border] * clipmask[i + ii - border][j + jj - border]) { + if (tmpIThr[ii][jj] < iterCheck[ii - border][jj - border]) { stopped = true; break; } @@ -566,9 +566,11 @@ BENCHFUN // fill tiles if (endOfRow || endOfCol) { // special handling for small tiles at end of row or column - for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) { - for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) { - iterCheck[k][l] = oldLuminance[ii][jj] * clipmask[ii][jj]; + if (checkIterStop) { + for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) { + for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) { + iterCheck[k][l] = oldLuminance[ii][jj] * clipmask[ii][jj] * 0.5f; + } } } for (int k = 0, ii = endOfCol ? H - fullTileSize : i; k < fullTileSize; ++k, ++ii) { @@ -578,9 +580,11 @@ BENCHFUN } } } else { - for (int ii = 0; ii < tileSize; ++ii) { - for (int jj = 0; jj < tileSize; ++jj) { - iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * clipmask[i + ii][j + jj]; + if (checkIterStop) { + for (int ii = 0; ii < tileSize; ++ii) { + for (int jj = 0; jj < tileSize; ++jj) { + iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * clipmask[i + ii][j + jj] * 0.5f; + } } } for (int ii = i; ii < i + fullTileSize; ++ii) {