merge with dev
This commit is contained in:
commit
040e900c02
@ -1225,6 +1225,12 @@ PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing pr
|
||||
PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries
|
||||
PREFERENCES_CACHEOPTS;Cache Options
|
||||
PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height
|
||||
PREFERENCES_CHUNKSIZES;Tiles per thread
|
||||
PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic
|
||||
PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction
|
||||
PREFERENCES_CHUNKSIZE_RAW_RCD;RCD demosaic
|
||||
PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic
|
||||
PREFERENCES_CHUNKSIZE_RGB;RGB processing
|
||||
PREFERENCES_CLIPPINGIND;Clipping Indication
|
||||
PREFERENCES_CLUTSCACHE;HaldCLUT Cache
|
||||
PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs
|
||||
@ -1341,6 +1347,8 @@ PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list.
|
||||
PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list.
|
||||
PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list.
|
||||
PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list.
|
||||
PREFERENCES_PERFORMANCE_MEASURE;Measure
|
||||
PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console
|
||||
PREFERENCES_PERFORMANCE_THREADS;Threads
|
||||
PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximum number of threads for Noise Reduction and Wavelet Levels (0 = Automatic)
|
||||
PREFERENCES_PREVDEMO;Preview Demosaic Method
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "rt_math.h"
|
||||
#include "gauss.h"
|
||||
#include "median.h"
|
||||
//#define BENCHMARK
|
||||
#include "StopWatch.h"
|
||||
namespace {
|
||||
|
||||
@ -121,10 +120,19 @@ float* RawImageSource::CA_correct_RT(
|
||||
bool fitParamsIn,
|
||||
bool fitParamsOut,
|
||||
float* buffer,
|
||||
bool freeBuffer
|
||||
bool freeBuffer,
|
||||
size_t chunkSize,
|
||||
bool measure
|
||||
)
|
||||
{
|
||||
BENCHFUN
|
||||
|
||||
std::unique_ptr<StopWatch> stop;
|
||||
|
||||
if (measure) {
|
||||
std::cout << "CA correcting " << W << "x" << H << " image with " << chunkSize << " tiles per thread" << std::endl;
|
||||
stop.reset(new StopWatch("CA correction"));
|
||||
}
|
||||
|
||||
// multithreaded and vectorized by Ingo Weyrich
|
||||
constexpr int ts = 128;
|
||||
constexpr int tsh = ts / 2;
|
||||
@ -279,7 +287,7 @@ float* RawImageSource::CA_correct_RT(
|
||||
float blockdenomthr[2][2] = {};
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for collapse(2) schedule(dynamic) nowait
|
||||
#pragma omp for collapse(2) schedule(dynamic, chunkSize) nowait
|
||||
#endif
|
||||
for (int top = -border ; top < height; top += ts - border2) {
|
||||
for (int left = -border; left < width - (W & 1); left += ts - border2) {
|
||||
@ -821,7 +829,7 @@ float* RawImageSource::CA_correct_RT(
|
||||
//green interpolated to optical sample points for R/B
|
||||
float* gshift = (float (*)) (data + 2 * sizeof(float) * ts * ts + sizeof(float) * ts * tsh + 4 * 64); // there is no overlap in buffer usage => share
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic) collapse(2)
|
||||
#pragma omp for schedule(dynamic, chunkSize) collapse(2)
|
||||
#endif
|
||||
for (int top = -border; top < height; top += ts - border2) {
|
||||
for (int left = -border; left < width - (W & 1); left += ts - border2) {
|
||||
|
@ -38,9 +38,15 @@
|
||||
namespace rtengine
|
||||
{
|
||||
|
||||
void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue)
|
||||
void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, size_t chunkSize, bool measure)
|
||||
{
|
||||
BENCHFUN
|
||||
|
||||
std::unique_ptr<StopWatch> stop;
|
||||
|
||||
if (measure) {
|
||||
std::cout << "Demosaicing " << W << "x" << H << " image using AMaZE with " << chunkSize << " Tiles per Thread" << std::endl;
|
||||
stop.reset(new StopWatch("amaze demosaic"));
|
||||
}
|
||||
|
||||
volatile double progress = 0.0;
|
||||
|
||||
@ -176,7 +182,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c
|
||||
// Main algorithm: Tile loop
|
||||
// use collapse(2) to collapse the 2 loops to one large loop, so there is better scaling
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic) collapse(2) nowait
|
||||
#pragma omp for schedule(dynamic, chunkSize) collapse(2) nowait
|
||||
#endif
|
||||
|
||||
for (int top = winy - 16; top < winy + height; top += ts - 32) {
|
||||
|
@ -1279,9 +1279,14 @@ class AdobeToneCurve : public ToneCurve
|
||||
{
|
||||
private:
|
||||
void RGBTone(float& r, float& g, float& b) const; // helper for tone curve
|
||||
|
||||
#ifdef __SSE2__
|
||||
void RGBTone(vfloat& r, vfloat& g, vfloat& b) const; // helper for tone curve
|
||||
#endif
|
||||
public:
|
||||
void Apply(float& r, float& g, float& b) const;
|
||||
void BatchApply(
|
||||
const size_t start, const size_t end,
|
||||
float *r, float *g, float *b) const;
|
||||
};
|
||||
|
||||
class SatAndValueBlendingToneCurve : public ToneCurve
|
||||
@ -1419,7 +1424,7 @@ inline void AdobeToneCurve::Apply(float& ir, float& ig, float& ib) const
|
||||
RGBTone(b, r, g); // Case 2: b > r >= g
|
||||
} else if (b > g) {
|
||||
RGBTone(r, b, g); // Case 3: r >= b > g
|
||||
} else { // Case 4: r >= g == b
|
||||
} else { // Case 4: r == g == b
|
||||
r = lutToneCurve[r];
|
||||
g = lutToneCurve[g];
|
||||
b = g;
|
||||
@ -1437,15 +1442,88 @@ inline void AdobeToneCurve::Apply(float& ir, float& ig, float& ib) const
|
||||
setUnlessOOG(ir, ig, ib, r, g, b);
|
||||
}
|
||||
|
||||
inline void AdobeToneCurve::RGBTone(float& r, float& g, float& b) const
|
||||
{
|
||||
float rold = r, gold = g, bold = b;
|
||||
inline void AdobeToneCurve::BatchApply(
|
||||
const size_t start, const size_t end,
|
||||
float *r, float *g, float *b) const {
|
||||
assert (lutToneCurve);
|
||||
assert (lutToneCurve.getClip() & LUT_CLIP_BELOW);
|
||||
assert (lutToneCurve.getClip() & LUT_CLIP_ABOVE);
|
||||
|
||||
r = lutToneCurve[rold];
|
||||
b = lutToneCurve[bold];
|
||||
g = b + ((r - b) * (gold - bold) / (rold - bold));
|
||||
// All pointers must have the same alignment for SSE usage. In the loop body below,
|
||||
// we will only check `r`, assuming that the same result would hold for `g` and `b`.
|
||||
assert (reinterpret_cast<uintptr_t>(r) % 16 == reinterpret_cast<uintptr_t>(g) % 16);
|
||||
assert (reinterpret_cast<uintptr_t>(g) % 16 == reinterpret_cast<uintptr_t>(b) % 16);
|
||||
|
||||
size_t i = start;
|
||||
while (true) {
|
||||
if (i >= end) {
|
||||
// If we get to the end before getting to an aligned address, just return.
|
||||
// (Or, for non-SSE mode, if we get to the end.)
|
||||
return;
|
||||
#ifdef __SSE2__
|
||||
} else if (reinterpret_cast<uintptr_t>(&r[i]) % 16 == 0) {
|
||||
// Otherwise, we get to the first aligned address; go to the SSE part.
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
Apply(r[i], g[i], b[i]);
|
||||
i++;
|
||||
}
|
||||
#ifdef __SSE2__
|
||||
const vfloat upperv = F2V(MAXVALF);
|
||||
for (; i + 3 < end; i += 4) {
|
||||
|
||||
vfloat rc = vclampf(LVF(r[i]), ZEROV, upperv);
|
||||
vfloat gc = vclampf(LVF(g[i]), ZEROV, upperv);
|
||||
vfloat bc = vclampf(LVF(b[i]), ZEROV, upperv);
|
||||
|
||||
vfloat minval = vminf(vminf(rc, gc), bc);
|
||||
vfloat maxval = vmaxf(vmaxf(rc, gc), bc);
|
||||
vfloat medval = vmaxf(vminf(rc, gc), vminf(bc, vmaxf(rc, gc)));
|
||||
|
||||
const vfloat minvalold = minval;
|
||||
const vfloat maxvalold = maxval;
|
||||
|
||||
RGBTone(maxval, medval, minval);
|
||||
|
||||
const vfloat nr = vself(vmaskf_eq(rc, maxvalold), maxval, vself(vmaskf_eq(rc, minvalold), minval, medval));
|
||||
const vfloat ng = vself(vmaskf_eq(gc, maxvalold), maxval, vself(vmaskf_eq(gc, minvalold), minval, medval));
|
||||
const vfloat nb = vself(vmaskf_eq(bc, maxvalold), maxval, vself(vmaskf_eq(bc, minvalold), minval, medval));
|
||||
|
||||
rc = LVF(r[i]);
|
||||
gc = LVF(g[i]);
|
||||
bc = LVF(b[i]);
|
||||
setUnlessOOG(rc, gc, bc, nr, ng, nb);
|
||||
STVF(r[i], rc);
|
||||
STVF(g[i], gc);
|
||||
STVF(b[i], bc);
|
||||
}
|
||||
// Remainder in non-SSE.
|
||||
for (; i < end; ++i) {
|
||||
Apply(r[i], g[i], b[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void AdobeToneCurve::RGBTone (float& maxval, float& medval, float& minval) const
|
||||
{
|
||||
float minvalold = minval, medvalold = medval, maxvalold = maxval;
|
||||
|
||||
maxval = lutToneCurve[maxvalold];
|
||||
minval = lutToneCurve[minvalold];
|
||||
medval = minval + ((maxval - minval) * (medvalold - minvalold) / (maxvalold - minvalold));
|
||||
}
|
||||
#ifdef __SSE2__
|
||||
inline void AdobeToneCurve::RGBTone (vfloat& maxval, vfloat& medval, vfloat& minval) const
|
||||
{
|
||||
const vfloat minvalold = minval, maxvalold = maxval;
|
||||
|
||||
maxval = lutToneCurve[maxvalold];
|
||||
minval = lutToneCurve[minvalold];
|
||||
medval = minval + ((maxval - minval) * (medval - minvalold) / (maxvalold - minvalold));
|
||||
medval = vself(vmaskf_eq(minvalold, maxvalold), minval, medval);
|
||||
}
|
||||
#endif
|
||||
// Modifying the Luminance channel only
|
||||
inline void LuminanceToneCurve::Apply(float &ir, float &ig, float &ib) const
|
||||
{
|
||||
|
@ -44,17 +44,17 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi
|
||||
// contrast == 0.0 means only first demosaicer will be used
|
||||
if(isBayer) {
|
||||
if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) {
|
||||
amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue);
|
||||
amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) ) {
|
||||
dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance);
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4) ) {
|
||||
rcd_demosaic();
|
||||
rcd_demosaic(options.chunkSizeRCD, options.measure);
|
||||
}
|
||||
} else {
|
||||
if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) ) {
|
||||
xtrans_interpolate (3, true);
|
||||
xtrans_interpolate (3, true, options.chunkSizeXT, options.measure);
|
||||
} else {
|
||||
xtrans_interpolate (1, false);
|
||||
xtrans_interpolate (1, false, options.chunkSizeXT, options.measure);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,17 +70,17 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi
|
||||
vng4_demosaic(rawData, redTmp, greenTmp, blueTmp);
|
||||
|
||||
if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) {
|
||||
amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue);
|
||||
amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) ) {
|
||||
dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance);
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4) ) {
|
||||
rcd_demosaic();
|
||||
rcd_demosaic(options.chunkSizeRCD, options.measure);
|
||||
}
|
||||
} else {
|
||||
if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) ) {
|
||||
xtrans_interpolate (3, true);
|
||||
xtrans_interpolate (3, true, options.chunkSizeXT, options.measure);
|
||||
} else {
|
||||
xtrans_interpolate (1, false);
|
||||
xtrans_interpolate (1, false, options.chunkSizeXT, options.measure);
|
||||
}
|
||||
fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp);
|
||||
}
|
||||
|
@ -379,6 +379,11 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
||||
}
|
||||
}
|
||||
}
|
||||
// If MakeNotes are vague, fall back to Exif LensMake and LensModel if set
|
||||
// https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#LensType
|
||||
if (lens == "Manual Lens No CPU") {
|
||||
lens_from_make_and_model();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,8 +456,6 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
||||
found = true;
|
||||
lens = "Canon " + ldata;
|
||||
}
|
||||
} else {
|
||||
found = lens_from_make_and_model();
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,6 +470,10 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
lens_from_make_and_model();
|
||||
}
|
||||
} else if (!make.compare(0, 6, "PENTAX") || (!make.compare(0, 5, "RICOH") && !model.compare(0, 6, "PENTAX"))) {
|
||||
// ISO at max value supported, check manufacturer specific
|
||||
if (iso_speed == 65535 || iso_speed == 0) {
|
||||
@ -483,8 +490,9 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
||||
|
||||
if (mnote->getTag("LensType")) {
|
||||
lens = mnote->getTag ("LensType")->valueToString();
|
||||
if (!mnote->getTag("LensType")->toInt()) {
|
||||
// try to find something better than "M-42 or No Lens"
|
||||
// If MakeNotes are vague, fall back to Exif LensMake and LensModel if set
|
||||
// https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html#LensType
|
||||
if (lens == "M-42 or No Lens" || lens == "K or M Lens" || lens == "A Series Lens" || lens == "Sigma") {
|
||||
lens_from_make_and_model();
|
||||
}
|
||||
} else {
|
||||
@ -510,6 +518,9 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
||||
} else if (mnote && (!make.compare(0, 4, "SONY") || !make.compare(0, 6, "KONICA"))) {
|
||||
if (mnote->getTag("LensID")) {
|
||||
lens = mnote->getTag("LensID")->valueToString();
|
||||
if (lens == "Unknown") {
|
||||
lens_from_make_and_model();
|
||||
}
|
||||
}
|
||||
} else if (!make.compare(0, 7, "OLYMPUS")) {
|
||||
if (mnote->getTag("Equipment")) {
|
||||
@ -519,6 +530,9 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
|
||||
lens = eq->getTag("LensType")->valueToString();
|
||||
}
|
||||
}
|
||||
if (lens == "Unknown") {
|
||||
lens_from_make_and_model();
|
||||
}
|
||||
} else if (mnote && !make.compare(0, 9, "Panasonic")) {
|
||||
if (mnote->getTag("LensType")) {
|
||||
std::string panalens = mnote->getTag("LensType")->valueToString();
|
||||
@ -1302,37 +1316,33 @@ FramesData::FramesData(const Glib::ustring& fname, std::unique_ptr<RawMetaDataLo
|
||||
FILE* f = g_fopen(fname.c_str(), "rb");
|
||||
|
||||
if (f) {
|
||||
const bool has_rml_exif_base = rml->exifBase >= 0;
|
||||
rtexif::ExifManager exifManager(f, std::move(rml), firstFrameOnly);
|
||||
|
||||
if (has_rml_exif_base) {
|
||||
if (exifManager.f && exifManager.rml) {
|
||||
if (exifManager.rml->exifBase >= 0) {
|
||||
exifManager.parseRaw();
|
||||
|
||||
} else if (exifManager.rml->ciffBase >= 0) {
|
||||
exifManager.parseCIFF();
|
||||
}
|
||||
}
|
||||
|
||||
// copying roots
|
||||
roots = exifManager.roots;
|
||||
|
||||
// creating FrameData
|
||||
for (auto currFrame : exifManager.frames) {
|
||||
frames.push_back(std::unique_ptr<FrameData>(new FrameData(currFrame, currFrame->getRoot(), roots.at(0))));
|
||||
}
|
||||
|
||||
for (auto currRoot : roots) {
|
||||
rtexif::Tag* t = currRoot->getTag(0x83BB);
|
||||
|
||||
if (t && !iptc) {
|
||||
iptc = iptc_data_new_from_data((unsigned char*)t->getValue(), (unsigned)t->getValueSize());
|
||||
break;
|
||||
}
|
||||
if (exifManager.f && exifManager.rml) {
|
||||
if (exifManager.rml->exifBase >= 0) {
|
||||
exifManager.parseRaw ();
|
||||
} else if (exifManager.rml->ciffBase >= 0) {
|
||||
exifManager.parseCIFF ();
|
||||
}
|
||||
}
|
||||
|
||||
// copying roots
|
||||
roots = exifManager.roots;
|
||||
|
||||
// creating FrameData
|
||||
for (auto currFrame : exifManager.frames) {
|
||||
frames.push_back(std::unique_ptr<FrameData>(new FrameData(currFrame, currFrame->getRoot(), roots.at(0))));
|
||||
}
|
||||
|
||||
for (auto currRoot : roots) {
|
||||
rtexif::Tag* t = currRoot->getTag(0x83BB);
|
||||
|
||||
if (t && !iptc) {
|
||||
iptc = iptc_data_new_from_data ((unsigned char*)t->getValue (), (unsigned)t->getValueSize ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
} else if (hasJpegExtension(fname)) {
|
||||
|
@ -225,9 +225,7 @@ void customToneCurve(const ToneCurve &customToneCurve, ToneCurveParams::TcMode c
|
||||
const AdobeToneCurve& userToneCurve = static_cast<const AdobeToneCurve&>(customToneCurve);
|
||||
|
||||
for (int i = istart, ti = 0; i < tH; i++, ti++) {
|
||||
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
|
||||
userToneCurve.Apply(rtemp[ti * tileSize + tj], gtemp[ti * tileSize + tj], btemp[ti * tileSize + tj]);
|
||||
}
|
||||
userToneCurve.BatchApply(0, tW - jstart, &rtemp[ti * tileSize], >emp[ti * tileSize], &btemp[ti * tileSize]);
|
||||
}
|
||||
} else if (curveMode == ToneCurveParams::TcMode::SATANDVALBLENDING) { // apply the curve on the saturation and value channels
|
||||
const SatAndValueBlendingToneCurve& userToneCurve = static_cast<const SatAndValueBlendingToneCurve&>(customToneCurve);
|
||||
@ -2086,17 +2084,24 @@ filmlike_clip(float *r, float *g, float *b)
|
||||
|
||||
void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
||||
int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve,
|
||||
const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve)
|
||||
const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize, bool measure)
|
||||
{
|
||||
rgbProc(working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, asIn, histToneCurve);
|
||||
rgbProc (working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, asIn, histToneCurve, chunkSize, measure);
|
||||
}
|
||||
|
||||
// Process RGB image and convert to LAB space
|
||||
void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
||||
int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve,
|
||||
const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve)
|
||||
const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize, bool measure)
|
||||
{
|
||||
BENCHFUN
|
||||
|
||||
std::unique_ptr<StopWatch> stop;
|
||||
|
||||
if (measure) {
|
||||
std::cout << "rgb processing " << working->getWidth() << "x" << working->getHeight() << " image with " << chunkSize << " tiles per thread" << std::endl;
|
||||
stop.reset(new StopWatch("rgb processing"));
|
||||
}
|
||||
|
||||
Imagefloat *tmpImage = nullptr;
|
||||
|
||||
Imagefloat* editImgFloat = nullptr;
|
||||
@ -2465,7 +2470,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic) collapse(2)
|
||||
#pragma omp for schedule(dynamic, chunkSize) collapse(2)
|
||||
#endif
|
||||
|
||||
for (int ii = 0; ii < working->getHeight(); ii += TS)
|
||||
|
@ -217,11 +217,11 @@ public:
|
||||
void updateColorProfiles(const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck);
|
||||
void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
||||
int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
|
||||
const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve);
|
||||
const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize = 1, bool measure = false);
|
||||
void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
||||
int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
|
||||
const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob,
|
||||
double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve);
|
||||
double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize = 1, bool measure = false);
|
||||
void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, LUTf & clToningcurve, LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]);
|
||||
void toning2col(float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect);
|
||||
void toningsmh(float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect);
|
||||
|
@ -299,7 +299,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA
|
||||
{
|
||||
BENCHFUN
|
||||
if(numFrames != 4) { // fallback for non pixelshift files
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue);
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ BENCHFUN
|
||||
} else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) {
|
||||
dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.dualDemosaicContrast, true);
|
||||
} else {
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[0]), red, green, blue);
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[0]), red, green, blue, options.chunkSizeAMAZE, options.measure);
|
||||
}
|
||||
multi_array2D<float, 3> redTmp(winw, winh);
|
||||
multi_array2D<float, 3> greenTmp(winw, winh);
|
||||
@ -340,7 +340,7 @@ BENCHFUN
|
||||
} else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) {
|
||||
dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], bayerParams.dualDemosaicContrast, true);
|
||||
} else {
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i]);
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], options.chunkSizeAMAZE, options.measure);
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,7 +369,7 @@ BENCHFUN
|
||||
rawParamsTmp.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4);
|
||||
dual_demosaic_RT (true, rawParamsTmp, winw, winh, rawData, red, green, blue, bayerParams.dualDemosaicContrast, true);
|
||||
} else {
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue);
|
||||
amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2043,13 +2043,13 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens
|
||||
|
||||
if (numFrames == 4) {
|
||||
double fitParams[64];
|
||||
float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false);
|
||||
float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA, options.measure);
|
||||
for(int i = 1; i < 3; ++i) {
|
||||
CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false);
|
||||
CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA, options.measure);
|
||||
}
|
||||
CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true);
|
||||
CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA, options.measure);
|
||||
} else {
|
||||
CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, rawData, nullptr, false, false, nullptr, true);
|
||||
CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, rawData, nullptr, false, false, nullptr, true, options.chunkSizeCA, options.measure);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2090,7 +2090,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AHD)) {
|
||||
ahd_demosaic();
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE)) {
|
||||
amaze_demosaic_RT(0, 0, W, H, rawData, red, green, blue);
|
||||
amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4)
|
||||
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4)
|
||||
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4)) {
|
||||
@ -2115,7 +2115,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)) {
|
||||
nodemosaic(true);
|
||||
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCD)) {
|
||||
rcd_demosaic();
|
||||
rcd_demosaic(options.chunkSizeRCD, options.measure);
|
||||
} else {
|
||||
nodemosaic(false);
|
||||
}
|
||||
@ -2123,9 +2123,9 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
|
||||
if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST)) {
|
||||
fast_xtrans_interpolate(rawData, red, green, blue);
|
||||
} else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::ONE_PASS)) {
|
||||
xtrans_interpolate(1, false);
|
||||
xtrans_interpolate(1, false, options.chunkSizeXT, options.measure);
|
||||
} else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::THREE_PASS)) {
|
||||
xtrans_interpolate(3, true);
|
||||
xtrans_interpolate(3, true, options.chunkSizeXT, options.measure);
|
||||
} else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) || raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::TWO_PASS)) {
|
||||
if (!autoContrast) {
|
||||
double threshold = raw.xtranssensor.dualDemosaicContrast;
|
||||
|
@ -249,7 +249,9 @@ protected:
|
||||
bool fitParamsIn,
|
||||
bool fitParamsOut,
|
||||
float* buffer,
|
||||
bool freeBuffer
|
||||
bool freeBuffer,
|
||||
size_t chunkSize = 1,
|
||||
bool measure = false
|
||||
);
|
||||
void ddct8x8s(int isgn, float a[8][8]);
|
||||
|
||||
@ -271,12 +273,12 @@ protected:
|
||||
void jdl_interpolate_omp();
|
||||
void igv_interpolate(int winw, int winh);
|
||||
void lmmse_interpolate_omp(int winw, int winh, array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, int iterations);
|
||||
void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);//Emil's code for AMaZE
|
||||
void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, size_t chunkSize = 1, bool measure = false);//Emil's code for AMaZE
|
||||
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false);
|
||||
void fast_demosaic();//Emil's code for fast demosaicing
|
||||
void dcb_demosaic(int iterations, bool dcb_enhance);
|
||||
void ahd_demosaic();
|
||||
void rcd_demosaic();
|
||||
void rcd_demosaic(size_t chunkSize = 1, bool measure = false);
|
||||
void border_interpolate(unsigned int border, float (*image)[4], unsigned int start = 0, unsigned int end = 0);
|
||||
void border_interpolate2(int winw, int winh, int lborders, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border);
|
||||
@ -295,7 +297,7 @@ protected:
|
||||
void dcb_color_full(float (*image)[3], int x0, int y0, float (*chroma)[2]);
|
||||
void cielab(const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]);
|
||||
void xtransborder_interpolate (int border, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void xtrans_interpolate(const int passes, const bool useCieLab);
|
||||
void xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize = 1, bool measure = false);
|
||||
void fast_xtrans_interpolate (const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void pixelshift(int winx, int winy, int winw, int winh, const RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection);
|
||||
void hflip (Imagefloat* im);
|
||||
|
@ -39,9 +39,14 @@ namespace rtengine
|
||||
* Licensed under the GNU GPL version 3
|
||||
*/
|
||||
// Tiled version by Ingo Weyrich (heckflosse67@gmx.de)
|
||||
void RawImageSource::rcd_demosaic()
|
||||
void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure)
|
||||
{
|
||||
BENCHFUN
|
||||
std::unique_ptr<StopWatch> stop;
|
||||
|
||||
if (measure) {
|
||||
std::cout << "Demosaicing " << W << "x" << H << " image using rcd with " << chunkSize << " tiles per thread" << std::endl;
|
||||
stop.reset(new StopWatch("rcd demosaic"));
|
||||
}
|
||||
|
||||
volatile double progress = 0.0;
|
||||
|
||||
@ -72,7 +77,7 @@ void RawImageSource::rcd_demosaic()
|
||||
float *lpf = PQ_Dir; // reuse buffer, they don't overlap in usage
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for schedule(dynamic) collapse(2) nowait
|
||||
#pragma omp for schedule(dynamic, chunkSize) collapse(2) nowait
|
||||
#endif
|
||||
for(int tr = 0; tr < numTh; ++tr) {
|
||||
for(int tc = 0; tc < numTw; ++tc) {
|
||||
|
@ -998,7 +998,7 @@ private:
|
||||
|
||||
LUTu histToneCurve;
|
||||
|
||||
ipf.rgbProc(baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve);
|
||||
ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve, options.chunkSizeRGB, options.measure);
|
||||
|
||||
if (settings->verbose) {
|
||||
printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob);
|
||||
|
@ -43,6 +43,7 @@ void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b
|
||||
|
||||
if (!rgb) {
|
||||
if(!cbrtinit) {
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < 0x14000; i++) {
|
||||
double r = i / 65535.0;
|
||||
cbrt[i] = r > Color::eps ? std::cbrt(r) : (Color::kappa * r + 16.0) / 116.0;
|
||||
@ -173,9 +174,16 @@ void RawImageSource::xtransborder_interpolate (int border, array2D<float> &red,
|
||||
*/
|
||||
// override CLIP function to test unclipped output
|
||||
#define CLIP(x) (x)
|
||||
void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab)
|
||||
void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize, bool measure)
|
||||
{
|
||||
BENCHFUN
|
||||
|
||||
std::unique_ptr<StopWatch> stop;
|
||||
|
||||
if (measure) {
|
||||
std::cout << passes << "-pass Xtrans Demosaicing " << W << "x" << H << " image with " << chunkSize << " tiles per thread" << std::endl;
|
||||
stop.reset(new StopWatch("xtrans demosaic"));
|
||||
}
|
||||
|
||||
constexpr int ts = 114; /* Tile Size */
|
||||
constexpr int tsh = ts / 2; /* half of Tile Size */
|
||||
|
||||
@ -296,7 +304,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab)
|
||||
uint8_t (*homosummax)[ts] = (uint8_t (*)[ts]) homo[ndir - 1]; // we can reuse the homo-buffer because they are not used together
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for collapse(2) schedule(dynamic) nowait
|
||||
#pragma omp for collapse(2) schedule(dynamic, chunkSize) nowait
|
||||
#endif
|
||||
|
||||
for (int top = 3; top < height - 19; top += ts - 16)
|
||||
|
@ -2116,6 +2116,7 @@ void ExifManager::parseCIFF ()
|
||||
}
|
||||
parseCIFF (rml->ciffLength, root);
|
||||
root->sort ();
|
||||
parse(true);
|
||||
}
|
||||
|
||||
Tag* ExifManager::saveCIFFMNTag (TagDirectory* root, int len, const char* name)
|
||||
|
@ -453,7 +453,12 @@ void Options::setDefaults()
|
||||
maxInspectorBuffers = 2; // a rather conservative value for low specced systems...
|
||||
inspectorDelay = 0;
|
||||
serializeTiffRead = true;
|
||||
|
||||
measure = false;
|
||||
chunkSizeAMAZE = 2;
|
||||
chunkSizeCA = 2;
|
||||
chunkSizeRCD = 2;
|
||||
chunkSizeRGB = 2;
|
||||
chunkSizeXT = 2;
|
||||
FileBrowserToolbarSingleRow = false;
|
||||
hideTPVScrollbar = false;
|
||||
whiteBalanceSpotSize = 8;
|
||||
@ -1108,6 +1113,30 @@ void Options::readFromFile(Glib::ustring fname)
|
||||
serializeTiffRead = keyFile.get_boolean("Performance", "SerializeTiffRead");
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "Measure")) {
|
||||
measure = keyFile.get_boolean("Performance", "Measure");
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "ChunkSizeAMAZE")) {
|
||||
chunkSizeAMAZE = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeAMAZE")));
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "ChunkSizeCA")) {
|
||||
chunkSizeCA = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeCA")));
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "ChunkSizeRCD")) {
|
||||
chunkSizeRCD = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeRCD")));
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "ChunkSizeRGB")) {
|
||||
chunkSizeRGB = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeRGB")));
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "ChunkSizeXT")) {
|
||||
chunkSizeXT = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeXT")));
|
||||
}
|
||||
|
||||
if (keyFile.has_key("Performance", "ThumbnailInspectorMode")) {
|
||||
rtSettings.thumbnail_inspector_mode = static_cast<rtengine::Settings::ThumbnailInspectorMode>(keyFile.get_integer("Performance", "ThumbnailInspectorMode"));
|
||||
}
|
||||
@ -1999,6 +2028,12 @@ void Options::saveToFile(Glib::ustring fname)
|
||||
keyFile.set_integer("Performance", "InspectorDelay", inspectorDelay);
|
||||
keyFile.set_integer("Performance", "PreviewDemosaicFromSidecar", prevdemo);
|
||||
keyFile.set_boolean("Performance", "SerializeTiffRead", serializeTiffRead);
|
||||
keyFile.set_integer("Performance", "Measure", measure);
|
||||
keyFile.set_integer("Performance", "ChunkSizeAMAZE", chunkSizeAMAZE);
|
||||
keyFile.set_integer("Performance", "ChunkSizeRCD", chunkSizeRCD);
|
||||
keyFile.set_integer("Performance", "ChunkSizeRGB", chunkSizeRGB);
|
||||
keyFile.set_integer("Performance", "ChunkSizeXT", chunkSizeXT);
|
||||
keyFile.set_integer("Performance", "ChunkSizeCA", chunkSizeCA);
|
||||
keyFile.set_integer("Performance", "ThumbnailInspectorMode", int(rtSettings.thumbnail_inspector_mode));
|
||||
|
||||
|
||||
|
@ -314,7 +314,12 @@ public:
|
||||
bool filledProfile; // Used as reminder for the ProfilePanel "mode"
|
||||
prevdemo_t prevdemo; // Demosaicing method used for the <100% preview
|
||||
bool serializeTiffRead;
|
||||
|
||||
bool measure;
|
||||
size_t chunkSizeAMAZE;
|
||||
size_t chunkSizeCA;
|
||||
size_t chunkSizeRCD;
|
||||
size_t chunkSizeRGB;
|
||||
size_t chunkSizeXT;
|
||||
bool menuGroupRank;
|
||||
bool menuGroupLabel;
|
||||
bool menuGroupFileOperations;
|
||||
|
@ -31,6 +31,25 @@
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
void placeSpinBox(Gtk::Container* where, Gtk::SpinButton* &spin, const std::string &labelText, int digits, int inc0, int inc1, int maxLength, int range0, int range1, const std::string &toolTip = "") {
|
||||
Gtk::HBox* HB = Gtk::manage ( new Gtk::HBox () );
|
||||
HB->set_spacing (4);
|
||||
if (!toolTip.empty()) {
|
||||
HB->set_tooltip_text (M (toolTip));
|
||||
}
|
||||
Gtk::Label* label = Gtk::manage ( new Gtk::Label (M (labelText) + ":", Gtk::ALIGN_START));
|
||||
spin = Gtk::manage ( new Gtk::SpinButton () );
|
||||
spin->set_digits (digits);
|
||||
spin->set_increments (inc0, inc1);
|
||||
spin->set_max_length (maxLength); // Will this be sufficient? :)
|
||||
spin->set_range (range0, range1);
|
||||
HB->pack_start (*label, Gtk::PACK_SHRINK, 0);
|
||||
HB->pack_end (*spin, Gtk::PACK_SHRINK, 0);
|
||||
where->add(*HB);
|
||||
}
|
||||
}
|
||||
|
||||
extern Options options;
|
||||
extern Glib::ustring argv0;
|
||||
Glib::RefPtr<Gtk::CssProvider> themecss;
|
||||
@ -652,38 +671,36 @@ Gtk::Widget* Preferences::getPerformancePanel()
|
||||
vbPerformance->pack_start (*ftiffserialize, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
Gtk::Frame* fclut = Gtk::manage(new Gtk::Frame(M("PREFERENCES_CLUTSCACHE")));
|
||||
Gtk::HBox* clutCacheSizeHB = Gtk::manage(new Gtk::HBox());
|
||||
clutCacheSizeHB->set_spacing(4);
|
||||
Gtk::Label* CLUTLl = Gtk::manage(new Gtk::Label(M("PREFERENCES_CLUTSCACHE_LABEL") + ":", Gtk::ALIGN_START));
|
||||
clutCacheSizeSB = Gtk::manage(new Gtk::SpinButton());
|
||||
clutCacheSizeSB->set_digits(0);
|
||||
clutCacheSizeSB->set_increments(1, 5);
|
||||
clutCacheSizeSB->set_max_length(2); // Will this be sufficient? :)
|
||||
#ifdef _OPENMP
|
||||
clutCacheSizeSB->set_range(1, 3 * omp_get_num_procs());
|
||||
placeSpinBox(fclut, clutCacheSizeSB, "PREFERENCES_CLUTSCACHE_LABEL", 0, 1, 5, 2, 1, 3 * omp_get_num_procs());
|
||||
#else
|
||||
clutCacheSizeSB->set_range(1, 12);
|
||||
placeSpinBox(fclut, clutCacheSizeSB, "PREFERENCES_CLUTSCACHE_LABEL", 0, 1, 5, 2, 1, 12);
|
||||
#endif
|
||||
clutCacheSizeHB->pack_start(*CLUTLl, Gtk::PACK_SHRINK, 0);
|
||||
clutCacheSizeHB->pack_end(*clutCacheSizeSB, Gtk::PACK_SHRINK, 0);
|
||||
fclut->add(*clutCacheSizeHB);
|
||||
vbPerformance->pack_start (*fclut, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
Gtk::Frame* finspect = Gtk::manage(new Gtk::Frame(M("PREFERENCES_INSPECT_LABEL")));
|
||||
Gtk::HBox* maxIBuffersHB = Gtk::manage(new Gtk::HBox());
|
||||
maxIBuffersHB->set_spacing(4);
|
||||
maxIBuffersHB->set_tooltip_text(M("PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP"));
|
||||
Gtk::Label* maxIBufferLbl = Gtk::manage(new Gtk::Label(M("PREFERENCES_INSPECT_MAXBUFFERS_LABEL") + ":", Gtk::ALIGN_START));
|
||||
maxInspectorBuffersSB = Gtk::manage(new Gtk::SpinButton());
|
||||
maxInspectorBuffersSB->set_digits(0);
|
||||
maxInspectorBuffersSB->set_increments(1, 5);
|
||||
maxInspectorBuffersSB->set_max_length(2);
|
||||
maxInspectorBuffersSB->set_range(1, 12); // ... we have to set a limit, 12 seem to be enough even for systems with tons of RAM
|
||||
maxIBuffersHB->pack_start(*maxIBufferLbl, Gtk::PACK_SHRINK, 0);
|
||||
maxIBuffersHB->pack_end(*maxInspectorBuffersSB, Gtk::PACK_SHRINK, 0);
|
||||
Gtk::Frame* fchunksize = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_CHUNKSIZES")) );
|
||||
Gtk::VBox* chunkSizeVB = Gtk::manage ( new Gtk::VBox () );
|
||||
|
||||
Gtk::HBox* measureHB = Gtk::manage ( new Gtk::HBox () );
|
||||
measureHB->set_spacing (4);
|
||||
measureCB = Gtk::manage ( new Gtk::CheckButton (M ("PREFERENCES_PERFORMANCE_MEASURE")) );
|
||||
measureCB->set_tooltip_text (M ("PREFERENCES_PERFORMANCE_MEASURE_HINT"));
|
||||
measureHB->pack_start(*measureCB, Gtk::PACK_SHRINK, 0);
|
||||
chunkSizeVB->add(*measureHB);
|
||||
|
||||
placeSpinBox(chunkSizeVB, chunkSizeAMSB, "PREFERENCES_CHUNKSIZE_RAW_AMAZE", 0, 1, 5, 2, 1, 16);
|
||||
placeSpinBox(chunkSizeVB, chunkSizeCASB, "PREFERENCES_CHUNKSIZE_RAW_CA", 0, 1, 5, 2, 1, 16);
|
||||
placeSpinBox(chunkSizeVB, chunkSizeRCDSB, "PREFERENCES_CHUNKSIZE_RAW_RCD", 0, 1, 5, 2, 1, 16);
|
||||
placeSpinBox(chunkSizeVB, chunkSizeRGBSB, "PREFERENCES_CHUNKSIZE_RGB", 0, 1, 5, 2, 1, 16);
|
||||
placeSpinBox(chunkSizeVB, chunkSizeXTSB, "PREFERENCES_CHUNKSIZE_RAW_XT", 0, 1, 5, 2, 1, 16);
|
||||
|
||||
fchunksize->add (*chunkSizeVB);
|
||||
|
||||
vbPerformance->pack_start (*fchunksize, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
Gtk::Frame* finspect = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_INSPECT_LABEL")) );
|
||||
Gtk::VBox *inspectorvb = Gtk::manage(new Gtk::VBox());
|
||||
inspectorvb->add(*maxIBuffersHB);
|
||||
placeSpinBox(inspectorvb, maxInspectorBuffersSB, "PREFERENCES_INSPECT_MAXBUFFERS_LABEL", 0, 1, 5, 2, 1, 12, "PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP");
|
||||
|
||||
Gtk::HBox *insphb = Gtk::manage(new Gtk::HBox());
|
||||
thumbnailInspectorMode = Gtk::manage(new Gtk::ComboBoxText());
|
||||
@ -699,24 +716,15 @@ Gtk::Widget* Preferences::getPerformancePanel()
|
||||
Gtk::Frame* threadsFrame = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_PERFORMANCE_THREADS")) );
|
||||
Gtk::VBox* threadsVBox = Gtk::manage ( new Gtk::VBox (Gtk::PACK_SHRINK, 4) );
|
||||
|
||||
Gtk::HBox* threadsHBox = Gtk::manage (new Gtk::HBox (Gtk::PACK_SHRINK, 4));
|
||||
Gtk::Label* threadsLbl = Gtk::manage ( new Gtk::Label (M ("PREFERENCES_PERFORMANCE_THREADS_LABEL") + ":", Gtk::ALIGN_START));
|
||||
threadsSpinBtn = Gtk::manage ( new Gtk::SpinButton () );
|
||||
threadsSpinBtn->set_digits (0);
|
||||
threadsSpinBtn->set_increments (1, 5);
|
||||
threadsSpinBtn->set_max_length (2); // Will this be sufficient? :)
|
||||
#ifdef _OPENMP
|
||||
int maxThreadNumber = omp_get_max_threads();
|
||||
#else
|
||||
int maxThreadNumber = 10;
|
||||
#endif
|
||||
|
||||
threadsSpinBtn->set_range (0, maxThreadNumber);
|
||||
|
||||
threadsHBox->pack_start (*threadsLbl, Gtk::PACK_SHRINK, 2);
|
||||
threadsHBox->pack_end (*threadsSpinBtn, Gtk::PACK_SHRINK, 2);
|
||||
placeSpinBox(threadsVBox, threadsSpinBtn, "PREFERENCES_PERFORMANCE_THREADS_LABEL", 0, 1, 5, 2, 0, maxThreadNumber);
|
||||
|
||||
threadsVBox->pack_start (*threadsHBox, Gtk::PACK_SHRINK);
|
||||
threadsFrame->add (*threadsVBox);
|
||||
|
||||
vbPerformance->pack_start (*threadsFrame, Gtk::PACK_SHRINK, 4);
|
||||
@ -1785,6 +1793,12 @@ void Preferences::storePreferences()
|
||||
|
||||
moptions.rgbDenoiseThreadLimit = threadsSpinBtn->get_value_as_int();
|
||||
moptions.clutCacheSize = clutCacheSizeSB->get_value_as_int();
|
||||
moptions.measure = measureCB->get_active();
|
||||
moptions.chunkSizeAMAZE = chunkSizeAMSB->get_value_as_int();
|
||||
moptions.chunkSizeCA = chunkSizeCASB->get_value_as_int();
|
||||
moptions.chunkSizeRCD = chunkSizeRCDSB->get_value_as_int();
|
||||
moptions.chunkSizeRGB = chunkSizeRGBSB->get_value_as_int();
|
||||
moptions.chunkSizeXT = chunkSizeXTSB->get_value_as_int();
|
||||
moptions.maxInspectorBuffers = maxInspectorBuffersSB->get_value_as_int();
|
||||
moptions.rtSettings.thumbnail_inspector_mode = static_cast<rtengine::Settings::ThumbnailInspectorMode>(thumbnailInspectorMode->get_active_row_number());
|
||||
|
||||
@ -1988,6 +2002,12 @@ void Preferences::fillPreferences()
|
||||
|
||||
threadsSpinBtn->set_value (moptions.rgbDenoiseThreadLimit);
|
||||
clutCacheSizeSB->set_value (moptions.clutCacheSize);
|
||||
measureCB->set_active (moptions.measure);
|
||||
chunkSizeAMSB->set_value (moptions.chunkSizeAMAZE);
|
||||
chunkSizeCASB->set_value (moptions.chunkSizeCA);
|
||||
chunkSizeRGBSB->set_value (moptions.chunkSizeRGB);
|
||||
chunkSizeRCDSB->set_value (moptions.chunkSizeRCD);
|
||||
chunkSizeXTSB->set_value (moptions.chunkSizeXT);
|
||||
maxInspectorBuffersSB->set_value (moptions.maxInspectorBuffers);
|
||||
thumbnailInspectorMode->set_active(int(moptions.rtSettings.thumbnail_inspector_mode));
|
||||
|
||||
|
@ -161,6 +161,12 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener
|
||||
|
||||
Gtk::SpinButton* threadsSpinBtn;
|
||||
Gtk::SpinButton* clutCacheSizeSB;
|
||||
Gtk::CheckButton* measureCB;
|
||||
Gtk::SpinButton* chunkSizeAMSB;
|
||||
Gtk::SpinButton* chunkSizeCASB;
|
||||
Gtk::SpinButton* chunkSizeRCDSB;
|
||||
Gtk::SpinButton* chunkSizeRGBSB;
|
||||
Gtk::SpinButton* chunkSizeXTSB;
|
||||
Gtk::SpinButton* maxInspectorBuffersSB;
|
||||
Gtk::ComboBoxText *thumbnailInspectorMode;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user