diff --git a/CMakeLists.txt b/CMakeLists.txt index 72c6a510b..c1141caa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -516,7 +516,7 @@ if(WIN32) endif() if(UNIX) - install(FILES rawtherapee.appdata.xml DESTINATION "${APPDATADIR}") + install(FILES com.rawtherapee.RawTherapee.appdata.xml DESTINATION "${APPDATADIR}") endif() # check whether the used version of lensfun has lfDatabase::LoadDirectory diff --git a/rawtherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml similarity index 90% rename from rawtherapee.appdata.xml rename to com.rawtherapee.RawTherapee.appdata.xml index 6a15e723a..0dace6772 100644 --- a/rawtherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -1,6 +1,6 @@ - - rawtherapee.desktop + + com.rawtherapee.RawTherapee RawTherapee An advanced raw photo development program Program pro konverzi a zpracování digitálních raw fotografií @@ -33,6 +33,14 @@ http://rawpedia.rawtherapee.com/ http://rawtherapee.com/ https://discuss.pixls.us/t/localization-how-to-translate-rawtherapee-and-rawpedia/2594 + rawtherapee.desktop + + + + + rawtherapee + rawtherapee-cli + HDR DNG of a misty morning in the countryside diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue-GTK3-20_.css index 33017626a..73cc9c58b 100644 --- a/rtdata/themes/TooWaBlue-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue-GTK3-20_.css @@ -2,7 +2,7 @@ This file is part of RawTherapee. Copyright (c) 2016-2018 TooWaBoo - Version 3.00 + Version 3.02 RawTherapee is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -957,10 +957,9 @@ window.csd:not(.fullscreen) #MainNotebook > header.top { padding-right: 0.25em; } -#RightNotebook > stack > :nth-child(1) > * > box, -#RightNotebook > stack > :nth-child(4) > * > box { - padding: 0.5em; - border: 0.083333333333333333em solid @bg-entry-border; +#RightNotebook > stack > scrolledwindow > viewport { + padding: 0 0.5em; + border: 0.083333333333333333em solid @bg-dark-grey; } #PrefNotebook > header { @@ -1061,7 +1060,7 @@ window.csd:not(.fullscreen) #MainNotebook > header.top { min-width: 0; padding: 0; } -#FileBrowserQueryToolbar { +#FileBrowserQueryToolbar > viewport > box { margin: 0 0 0.416666666666666666em 0; min-height: 0; min-width: 0; @@ -1646,7 +1645,7 @@ messagedialog .dialog-action-area button:not(:only-child):nth-child(2) { min-width: 1.666666666666666666em;/*x*/ margin: 0; border-radius: 0 0.2em 0.2em 0; - box-shadow: inset 0 0.1em rgba(0, 0, 0, 0.1), inset -0.1em -0.1em rgba(230, 230, 230, 0.09); + box-shadow: inset 0 0.1em rgba(0, 0, 0, 0.1), inset -0.1em -0.1em rgba(230, 230, 230, 0.07); border: 0.083333333333333333em solid @bg-entry-border; background-color: @bg-scale-entry; padding: 0; @@ -1866,19 +1865,17 @@ spinbutton { min-height: 1.666666666666666666em;/*x*/ min-width: 0; border-radius: 0.2em; - box-shadow: inset 0.1em 0.1em rgba(0, 0, 0, 0.1), inset -0.1em -0.1em rgba(230, 230, 230, 0.09); + box-shadow: inset 0.1em 0.1em rgba(0, 0, 0, 0.1), inset -0.1em -0.1em rgba(230, 230, 230, 0.07); border: 0.083333333333333333em solid @bg-entry-border; background-color: @bg-scale-entry; } #FileBrowserQueryToolbar entry, #FileBrowserIconToolbar entry { - min-height: 1.666666666666666666em;/*x*/ - min-width: 0; margin: 0; border-right: none; border-top-right-radius: 0; border-bottom-right-radius: 0; - box-shadow: inset 0.1em 0.1em rgba(0, 0, 0, 0.1), inset 0 -0.1em rgba(230, 230, 230, 0.09); + box-shadow: inset 0.1em 0.1em rgba(0, 0, 0, 0.1), inset 0 -0.1em rgba(230, 230, 230, 0.07); } #FileBrowserIconToolbar box > entry { diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 55acf8307..d609c7aed 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2244,9 +2244,8 @@ Camera constants: "make_model": "Sigma SD14", "dcraw_matrix": [ 16411,-4764,-2383,8110,2603,-645,3135,3878,1984 ], // experimental inverted icc wp12 - build with BL=15 //"dcraw_matrix": [ 13804,-4156,-1896,6917,1909,-431,2768,2989,1741 ], // experimental inverted icc wp10 - build with BL=15 - "ranges": { "black": 0, "white": 16383 }, // peripheral black stripes give BL around 37 - "raw_crop": [ 0, 0, -0, -0 ] - //"raw_crop": [ 18, 12, 2652, 1768 ] + "ranges": { "black": 15, "white": 7000 }, + "raw_crop": [ 18, 12, 2652, 1768 ] }, { // Quality C, correction for frame width diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index af5d38c6c..c4118dd19 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -2672,43 +2672,92 @@ void CLASS canon_rmf_load_raw() maximum = curve[0x3ff]; } -unsigned CLASS pana_bits_t::operator() (int nbits) +unsigned CLASS pana_bits_t::operator() (int nbits, unsigned *bytes) { /*RT static uchar buf[0x4000]; */ /*RT static int vbits;*/ int byte; - if (!nbits) return vbits=0; + if (!nbits && !bytes) return vbits=0; if (!vbits) { fread (buf+load_flags, 1, 0x4000-load_flags, ifp); fread (buf, 1, load_flags, ifp); } - vbits = (vbits - nbits) & 0x1ffff; - byte = vbits >> 3 ^ 0x3ff0; - return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); + 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); + 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); - 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(); + 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 { + 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() @@ -6081,6 +6130,7 @@ int CLASS parse_tiff_ifd (int base) unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; struct jhead jh; /*RT*/ IMFILE *sfp; +/*RT*/ int pana_raw = 0; if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; @@ -6096,10 +6146,16 @@ int CLASS parse_tiff_ifd (int base) while (entries--) { tiff_get (base, &tag, &type, &len, &save); switch (tag) { + case 1: if (len == 4) pana_raw = get4(); break; case 5: width = get2(); break; case 6: height = get2(); break; case 7: width += get2(); break; case 9: if ((i = get2())) filters = i; break; + case 10: + if (pana_raw && len == 1 && type == 3) { + RT_pana_info.bpp = get2(); + } + break; case 17: case 18: if (type == 3 && len == 1) cam_mul[(tag-17)*2] = get2() / 256.0; @@ -6119,6 +6175,12 @@ int CLASS parse_tiff_ifd (int base) fseek (ifp, 12, SEEK_CUR); FORC3 cam_mul[c] = get2(); break; + case 45: + if (pana_raw && len == 1 && type == 3) + { + RT_pana_info.encoding = get2(); + } + break; case 46: if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; thumb_offset = ftell(ifp) - 2; diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 96d778815..ea43d2176 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -159,6 +159,13 @@ protected: std::string RT_software; double RT_baseline_exposure; + struct PanasonicRW2Info { + ushort bpp; + ushort encoding; + PanasonicRW2Info(): bpp(0), encoding(0) {} + }; + PanasonicRW2Info RT_pana_info; + float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; int histogram[4][0x2000]; @@ -395,13 +402,15 @@ void nokia_load_raw(); class pana_bits_t{ public: - pana_bits_t(IMFILE *i, unsigned &u): ifp(i), load_flags(u), vbits(0) {} - unsigned operator()(int nbits); + pana_bits_t(IMFILE *i, unsigned &u, unsigned enc): + ifp(i), load_flags(u), vbits(0), encoding(enc) {} + unsigned operator()(int nbits, unsigned *bytes=nullptr); private: IMFILE *ifp; unsigned &load_flags; uchar buf[0x4000]; int vbits; + unsigned encoding; }; void canon_rmf_load_raw(); diff --git a/rtengine/guidedfilter.cc b/rtengine/guidedfilter.cc index 790245b20..e64ef4e3e 100644 --- a/rtengine/guidedfilter.cc +++ b/rtengine/guidedfilter.cc @@ -78,6 +78,7 @@ int calculate_subsampling(int w, int h, int r) void guidedFilter(const array2D &guide, const array2D &src, array2D &dst, int r, float epsilon, bool multithread, int subsampling) { + const int W = src.width(); const int H = src.height(); @@ -135,16 +136,6 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 const array2D &p = src; array2D &q = dst; - AlignedBuffer blur_buf(I.width() * I.height()); - const auto f_mean = - [&](array2D &d, array2D &s, int rad) -> void - { - rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); - float **src = s; - float **dst = d; - boxblur(src, dst, blur_buf.data, rad, rad, s.width(), s.height()); - }; - const auto f_subsample = [=](array2D &d, const array2D &s) -> void { @@ -153,8 +144,18 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 const auto f_upsample = f_subsample; - const int w = W / subsampling; - const int h = H / subsampling; + const size_t w = W / subsampling; + const size_t h = H / subsampling; + + AlignedBuffer blur_buf(w * h); + const auto f_mean = + [&](array2D &d, array2D &s, int rad) -> void + { + rad = LIM(rad, 0, (min(s.width(), s.height()) - 1) / 2 - 1); + float **src = s; + float **dst = d; + boxblur(src, dst, blur_buf.data, rad, rad, s.width(), s.height()); + }; array2D I1(w, h); array2D p1(w, h); @@ -203,6 +204,9 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 apply(SUBMUL, b, a, meanI, meanp); DEBUG_DUMP(b); + meanI.free(); // frees w * h * 4 byte + meanp.free(); // frees w * h * 4 byte + array2D &meana = a; f_mean(meana, a, r1); DEBUG_DUMP(meana); @@ -211,11 +215,13 @@ void guidedFilter(const array2D &guide, const array2D &src, array2 f_mean(meanb, b, r1); DEBUG_DUMP(meanb); + blur_buf.resize(0); // frees w * h * 4 byte + array2D meanA(W, H); f_upsample(meanA, meana); DEBUG_DUMP(meanA); - array2D meanB(W, H); + array2D &meanB = q; f_upsample(meanB, meanb); DEBUG_DUMP(meanB);