merge with dev

This commit is contained in:
Desmis 2019-03-11 10:08:54 +01:00
commit 040e900c02
19 changed files with 322 additions and 125 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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) {

View File

@ -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
{

View File

@ -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);
}

View File

@ -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)) {

View File

@ -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], &gtemp[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)

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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));

View File

@ -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;

View File

@ -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));

View File

@ -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;