Add inverse to shapemethod - fixed crash retinex inverse

This commit is contained in:
Desmis 2018-01-03 16:47:54 +01:00
parent 63073b470d
commit 7a714e5093
17 changed files with 3583 additions and 3503 deletions

View File

@ -1812,6 +1812,7 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b,
#endif
int i = 0;
#ifdef __SSE2__
for (; i < width - 3; i += 4) {
const vfloat rv = LVFU(R[i]);
const vfloat gv = LVFU(G[i]);
@ -1821,6 +1822,7 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b,
const vfloat zv = F2V(wp[2][0]) * rv + F2V(wp[2][1]) * gv + F2V(wp[2][2]) * bv;
vmask maxMask = vmaskf_gt(vmaxf(xv, vmaxf(yv, zv)), maxvalfv);
if (_mm_movemask_ps((vfloat)maxMask)) {
// take slower code path for all 4 pixels if one of the values is > MAXVALF. Still faster than non SSE2 version
for (int k = 0; k < 4; ++k) {
@ -1845,7 +1847,9 @@ void Color::RGB2Lab(float *R, float *G, float *B, float *L, float *a, float *b,
STVFU(b[i], c200v * (fy - fz));
}
}
#endif
for (; i < width; ++i) {
const float rv = R[i];
const float gv = G[i];

View File

@ -1037,7 +1037,8 @@ inline void StandardToneCurve::Apply (float& r, float& g, float& b) const
inline void StandardToneCurve::BatchApply(
const size_t start, const size_t end,
float *r, float *g, float *b) const {
float *r, float *g, float *b) const
{
assert(lutToneCurve);
assert(lutToneCurve.getClip() & LUT_CLIP_BELOW);
assert(lutToneCurve.getClip() & LUT_CLIP_ABOVE);
@ -1048,6 +1049,7 @@ inline void StandardToneCurve::BatchApply(
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.
@ -1059,6 +1061,7 @@ inline void StandardToneCurve::BatchApply(
break;
#endif
}
r[i] = lutToneCurve[r[i]];
g[i] = lutToneCurve[g[i]];
b[i] = lutToneCurve[b[i]];
@ -1066,6 +1069,7 @@ inline void StandardToneCurve::BatchApply(
}
#if defined( __SSE2__ ) && defined( __x86_64__ )
for (; i + 3 < end; i += 4) {
__m128 r_val = LVF(r[i]);
__m128 g_val = LVF(g[i]);
@ -1081,6 +1085,7 @@ inline void StandardToneCurve::BatchApply(
g[i] = lutToneCurve[g[i]];
b[i] = lutToneCurve[b[i]];
}
#endif
}
@ -1200,6 +1205,7 @@ inline void SatAndValueBlendingToneCurve::Apply (float& r, float& g, float& b) c
Color::rgb2hsv(r, g, b, h, s, v);
float dV;
if (newLum > lum) {
// Linearly targeting Value = 1 and Saturation = 0
float coef = (newLum - lum) / (65535.f - lum);
@ -1210,6 +1216,7 @@ inline void SatAndValueBlendingToneCurve::Apply (float& r, float& g, float& b) c
float coef = (newLum - lum) / lum ;
dV = v * coef;
}
Color::hsv2rgb(h, s, v + dV, r, g, b);
}

View File

@ -80,17 +80,21 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
lens.clear();
tag = newFrameRootDir->findTag("Make");
if (!tag) {
newFrameRootDir = rootDir;
tag = newFrameRootDir->findTag("Make");
if (!tag) {
// For some raw files (like Canon's CR2 files), the metadata are contained in the first root directory
newFrameRootDir = firstRootDir;
tag = newFrameRootDir->findTag("Make");
}
}
if (tag) {
make = tag->valueToString();
// Same dcraw treatment
for (const auto& corp : {
"Canon",
@ -123,6 +127,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
}
tag = newFrameRootDir->findTagUpward("Model");
if (tag) {
model = tag->valueToString();
}
@ -157,18 +162,21 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
}
tag = newFrameRootDir->findTagUpward("Orientation");
if (tag) {
orientation = tag->valueToString();
}
tag = newFrameRootDir->findTagUpward("MakerNote");
rtexif::TagDirectory* mnote = nullptr;
if (tag) {
mnote = tag->getDirectory();
}
rtexif::TagDirectory* exif = nullptr;
tag = newFrameRootDir->findTagUpward("Exif");
if (tag) {
exif = tag->getDirectory();
}
@ -403,13 +411,16 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
// ISO at max value supported, check manufacturer specific
if (iso_speed == 65535 || iso_speed == 0) {
rtexif::Tag* baseIsoTag = mnote->getTag("ISO");
if (baseIsoTag) {
std::string isoData = baseIsoTag->valueToString();
if (isoData.size() > 1) {
iso_speed = stoi(isoData);
}
}
}
if (mnote->getTag("LensType")) {
lens = mnote->getTag("LensType")->valueToString();
}
@ -448,8 +459,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
if (panalens.find("LUMIX") != Glib::ustring::npos) {
lens = "Panasonic " + panalens;
}
else {
} else {
lens = panalens;
}
}
@ -465,6 +475,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
}
rtexif::Tag* t = newFrameRootDir->getTag(0x83BB);
if (t) {
iptc = iptc_data_new_from_data((unsigned char*)t->getValue(), (unsigned)t->getValueSize());
}
@ -482,6 +493,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
if (mnote && (!make.compare(0, 6, "PENTAX") || (!make.compare(0, 5, "RICOH") && !model.compare(0, 6, "PENTAX")))) {
const rtexif::Tag* const hdr = mnote->findTag("HDR");
if (hdr) {
if (hdr->toInt() > 0 && hdr->toInt(2) > 0) {
isHDR = true;
@ -491,10 +503,12 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
}
} else {
const rtexif::Tag* const dm = mnote->findTag("DriveMode");
if (dm) {
char buffer[60];
dm->toString(buffer, 3);
buffer[3] = 0;
if (!strcmp(buffer, "HDR")) {
isHDR = true;
#if PRINT_HDR_PS_DETECTION
@ -506,6 +520,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
if (!isHDR) {
const rtexif::Tag* const q = mnote->findTag("Quality");
if (q && q->toInt() == 7) {
isPixelShift = true;
#if PRINT_HDR_PS_DETECTION
@ -542,6 +557,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
samplesperpixel = spp->toInt();
photometric = pi->toInt();
if (photometric == PHOTOMETRIC_LOGLUV) {
if (!c) {
compression = COMPRESSION_NONE;
@ -599,6 +615,7 @@ FrameData::FrameData (rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory*
sampleFormat = IIOSF_UNSIGNED_CHAR;
} else if (bitspersample <= 16) {
sampleFormat = IIOSF_UNSIGNED_SHORT;
if (mnote && (!make.compare(0, 4, "SONY")) && bitspersample >= 12 && samplesperpixel == 4) {
isPixelShift = true;
#if PRINT_HDR_PS_DETECTION
@ -821,12 +838,15 @@ rtexif::TagDirectory* FramesData::getFrameExifData (unsigned int frame) const
rtexif::TagDirectory* FramesData::getBestExifData(ImageSource *imgSource, procparams::RAWParams *rawParams) const
{
rtexif::TagDirectory *td = nullptr;
if (frames.empty()) {
return nullptr;
}
if (imgSource && rawParams) {
eSensorType sensorType = imgSource->getSensorType();
unsigned int imgNum = 0;
if (sensorType == ST_BAYER) {
imgNum = rtengine::LIM<unsigned int>(rawParams->bayersensor.imageNum, 0, frames.size() - 1);
/*
@ -840,12 +860,14 @@ rtexif::TagDirectory* FramesData::getBestExifData (ImageSource *imgSource, procp
td = getFrameExifData(imgNum);
rtexif::Tag* makeTag;
if (td && (makeTag = td->findTag("Make", true))) {
td = makeTag->getParent();
} else {
td = getRootExifData(0);
}
}
return td;
}
@ -1092,6 +1114,7 @@ FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataL
frames.push_back(fd);
}
for (auto currRoot : roots) {
rtexif::Tag* t = currRoot->getTag(0x83BB);
@ -1101,6 +1124,7 @@ FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataL
}
}
}
fclose(f);
}
} else if (hasJpegExtension(fname)) {
@ -1108,16 +1132,20 @@ FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataL
if (f) {
rtexif::ExifManager exifManager(f, std::move(rml), true);
if (exifManager.f) {
exifManager.parseJPEG();
roots = exifManager.roots;
for (auto currFrame : exifManager.frames) {
FrameData* fd = new FrameData(currFrame, currFrame->getRoot(), roots.at(0));
frames.push_back(fd);
}
rewind(exifManager.f); // Not sure this is necessary
iptc = iptc_data_new_from_jpeg_file(exifManager.f);
}
fclose(f);
}
} else if (hasTiffExtension(fname)) {
@ -1135,6 +1163,7 @@ FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataL
frames.push_back(fd);
}
for (auto currRoot : roots) {
rtexif::Tag* t = currRoot->getTag(0x83BB);
@ -1143,6 +1172,7 @@ FramesData::FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataL
break;
}
}
fclose(f);
}
}

View File

@ -48,11 +48,13 @@
#undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
namespace {
namespace
{
using namespace rtengine;
// begin of helper function for rgbProc()
void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize) {
void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize)
{
#ifdef __SSE2__
vfloat cr = F2V(0.299f);
@ -63,6 +65,7 @@ void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j += 4, tj += 4) {
vfloat rv = LVF(rtemp[ti * tileSize + tj]);
@ -76,7 +79,9 @@ void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float
STVF(gtemp[ti * tileSize + tj], gv * tonefactorv);
STVF(btemp[ti * tileSize + tj], bv * tonefactorv);
}
#endif
for (; j < tW; j++, tj++) {
float r = rtemp[ti * tileSize + tj];
@ -93,7 +98,8 @@ void shadowToneCurve(const LUTf &shtonecurve, float *rtemp, float *gtemp, float
}
}
void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, float exp_scale, float comp, float hlrange) {
void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, float exp_scale, float comp, float hlrange)
{
#ifdef __SSE2__
vfloat threev = F2V(3.f);
@ -103,6 +109,7 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j += 4, tj += 4) {
vfloat rv = LVF(rtemp[ti * tileSize + tj]);
@ -112,6 +119,7 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
//TODO: proper treatment of out-of-gamut colors
//float tonefactor = hltonecurve[(0.299f*r+0.587f*g+0.114f*b)];
vmask maxMask = vmaskf_ge(vmaxf(rv, vmaxf(gv, bv)), maxvalfv);
if (_mm_movemask_ps((vfloat)maxMask)) {
for (int k = 0; k < 4; ++k) {
float r = rtemp[ti * tileSize + tj + k];
@ -134,7 +142,9 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
STVF(btemp[ti * tileSize + tj], bv * tonefactorv);
}
}
#endif
for (; j < tW; j++, tj++) {
float r = rtemp[ti * tileSize + tj];
@ -155,19 +165,23 @@ void highlightToneCurve(const LUTf &hltonecurve, float *rtemp, float *gtemp, flo
}
}
void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize) {
void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize)
{
// this is a hack to avoid the blue=>black bug (Issue 2141)
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j += 4, tj += 4) {
vfloat rv = LVF(rtemp[ti * tileSize + tj]);
vfloat gv = LVF(gtemp[ti * tileSize + tj]);
vmask zeromask = vorm(vmaskf_eq(rv, ZEROV), vmaskf_eq(gv, ZEROV));
if (_mm_movemask_ps((vfloat)zeromask)) {
for (int k = 0; k < 4; ++k) {
float r = rtemp[ti * tileSize + tj + k];
float g = gtemp[ti * tileSize + tj + k];
if (r == 0.0f || g == 0.0f) {
float b = btemp[ti * tileSize + tj + k];
float h, s, v;
@ -178,7 +192,9 @@ void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH,
}
}
}
#endif
for (; j < tW; j++, tj++) {
float r = rtemp[ti * tileSize + tj];
float g = gtemp[ti * tileSize + tj];
@ -194,7 +210,8 @@ void proPhotoBlue(float *rtemp, float *gtemp, float *btemp, int istart, int tH,
}
}
void customToneCurve(const ToneCurve &customToneCurve, ToneCurveParams::TcMode curveMode, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, PerceptualToneCurveState ptcApplyState) {
void customToneCurve(const ToneCurve &customToneCurve, ToneCurveParams::TcMode curveMode, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize, PerceptualToneCurveState ptcApplyState)
{
if (curveMode == ToneCurveParams::TcMode::STD) { // Standard
for (int i = istart, ti = 0; i < tH; i++, ti++) {
@ -256,7 +273,8 @@ void customToneCurve(const ToneCurve &customToneCurve, ToneCurveParams::TcMode c
}
}
void fillEditFloat(float *editIFloatTmpR, float *editIFloatTmpG, float *editIFloatTmpB, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize) {
void fillEditFloat(float *editIFloatTmpR, float *editIFloatTmpG, float *editIFloatTmpB, float *rtemp, float *gtemp, float *btemp, int istart, int tH, int jstart, int tW, int tileSize)
{
for (int i = istart, ti = 0; i < tH; i++, ti++) {
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
editIFloatTmpR[ti * tileSize + tj] = Color::gamma2curve[rtemp[ti * tileSize + tj]] / 65535.f;
@ -3790,13 +3808,16 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
for (int i = istart, ti = 0; i < tH; i++, ti++) {
int j = jstart, tj = 0;
#ifdef __SSE2__
for (; j < tW - 3; j += 4, tj += 4) {
//brightness/contrast
STVF(rtemp[ti * TS + tj], tonecurve(LVF(rtemp[ti * TS + tj])));
STVF(gtemp[ti * TS + tj], tonecurve(LVF(gtemp[ti * TS + tj])));
STVF(btemp[ti * TS + tj], tonecurve(LVF(btemp[ti * TS + tj])));
}
#endif
for (; j < tW; j++, tj++) {
//brightness/contrast
rtemp[ti * TS + tj] = tonecurve[rtemp[ti * TS + tj]];
@ -4543,6 +4564,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
}
}
}
// ready, fill lab
for (int i = istart, ti = 0; i < tH; i++, ti++) {
Color::RGB2Lab(&rtemp[ti * TS], &gtemp[ti * TS], &btemp[ti * TS], &(lab->L[i][jstart]), &(lab->a[i][jstart]), &(lab->b[i][jstart]), toxyz, tW - jstart);

View File

@ -3987,7 +3987,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, LabImage
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -4493,7 +4493,7 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -5057,7 +5057,7 @@ void ImProcFunctions::InverseContrast_Local(float ave, struct local_contra & lco
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -5365,7 +5365,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueplus, c
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -7607,7 +7607,7 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, La
if (lp.shapmet == 0) {
calcTransition(lox, loy, ach, lp, zone, localFactor);
} else if (lp.shapmet == 1) {
calcTransition(lox, loy, ach, lp, zone, localFactor);//rect not good
calcTransitionrect(lox, loy, ach, lp, zone, localFactor);//rect not good
}
// calcTransition(lox, loy, ach, lp, zone, localFactor);
@ -12023,7 +12023,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
tmpl = new LabImage(Wd, Hd);
} /* else {
} else {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
@ -12039,7 +12039,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
}
*/
float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax;
ImProcFunctions::MSRLocal(orig, tmpl->L, orig1, Wd, Hd, params->locallab, sk, locRETgainCcurve, 0, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
#ifdef _OPENMP
@ -12093,7 +12093,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
orig1[ir][jr] = sqrt(SQR(bufreti->a[ir][jr]) + SQR(bufreti->b[ir][jr]));
}
} /* else {
} else {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
@ -12105,7 +12105,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
orig1[ir][jr] = sqrt(SQR(transformed->a[ir][jr]) + SQR(transformed->b[ir][jr]));
}
}
*/
ImProcFunctions::MSRLocal(orig, tmpl->L, orig1, Wd, Hd, params->locallab, sk, locRETgainCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);
if (!lp.invret && call <= 3) {
@ -12146,7 +12146,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
// printf ("minch=%2.2f maxch=%2.2f", minch, maxch);
} /* else {
} else {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16)
@ -12163,7 +12163,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
}
}
*/
if (!lp.invret) {

View File

@ -405,10 +405,10 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
if (scale == scal - 1)
{
gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], buffer);
} else { // reuse result of last iteration
// out was modified in last iteration => restore it
if ((((mapmet == 2 && scale > 1) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1)
} else // reuse result of last iteration
{
// out was modified in last iteration => restore it
if ((((mapmet == 2 && scale > 1) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1) {
#ifdef _OPENMP
#pragma omp for
#endif
@ -422,6 +422,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e
gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer);
}
if ((((mapmet == 2 && scale > 2) || mapmet == 3 || mapmet == 4) || (mapmet > 0 && mapcontlutili)) && it == 1 && scale > 0)
{
// out will be modified => store it for use in next iteration. We even don't need a new buffer because 'buffer' is free after gaussianBlur :)
@ -908,10 +909,10 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
if (scale == scal - 1)
{
gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], buffer);
} else { // reuse result of last iteration
// out was modified in last iteration => restore it
if (((mapmet == 4)) && it == 1)
} else // reuse result of last iteration
{
// out was modified in last iteration => restore it
if (((mapmet == 4)) && it == 1) {
#ifdef _OPENMP
#pragma omp for
@ -926,6 +927,7 @@ void ImProcFunctions::MSRLocal (float** luminance, float** templ, const float* c
gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer);
}
if ((mapmet == 4) && it == 1 && scale > 0)
{
// out will be modified => store it for use in next iteration. We even don't need a new buffer because 'buffer' is free after gaussianBlur :)

View File

@ -5389,6 +5389,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
if (keyFile.has_group("MetaData")) {
int mode = int(MetaDataParams::TUNNEL);
assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode);
if (mode >= int(MetaDataParams::TUNNEL) && mode <= int(MetaDataParams::STRIP)) {
metadata.mode = static_cast<MetaDataParams::Mode>(mode);
}

View File

@ -101,6 +101,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
for (int c = 0; c < 4; c++) {
cblack_[c] = this->get_cblack(c);
}
for (int c = 0; c < 4; c++) {
cblack_[FC(c / 2, c % 2)] = this->get_cblack(6 + c / 2 % this->get_cblack(4) * this->get_cblack(5) + c % 2 % this->get_cblack(5));
pre_mul_[c] = this->get_pre_mul(c);
@ -116,6 +117,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
if (!data) { // this happens only for thumbnail creation when get_cam_mul(0) == -1
compress_image(0, false);
}
memset(dsum, 0, sizeof dsum);
if (this->isBayer()) {
@ -315,8 +317,7 @@ skip_block:
if (sum[0] && sum[1] && sum[2] && sum[3])
for (int c = 0; c < 4; c++) {
pre_mul_[c] = (float) sum[c + 4] / sum[c];
}
else if (this->get_cam_mul(0) && this->get_cam_mul(2)) {
} else if (this->get_cam_mul(0) && this->get_cam_mul(2)) {
pre_mul_[0] = this->get_cam_mul(0);
pre_mul_[1] = this->get_cam_mul(1);
pre_mul_[2] = this->get_cam_mul(2);
@ -517,6 +518,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
if (cc && cc->has_rawCrop()) {
int lm, tm, w, h;
cc->get_rawCrop(lm, tm, w, h);
if (isXtrans()) {
shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6));
} else {
@ -524,6 +526,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
filters = (filters << 4) | (filters >> 28); // left rotate filters by 4 bits
}
}
left_margin = lm;
top_margin = tm;
@ -627,8 +630,7 @@ int RawImage::loadRaw (bool loadData, unsigned int imageNum, bool closeFile, Pro
if (isXtrans())
for (int c = 0; c < 4; c++) {
black_c4[c] = cblack[6];
}
else
} else
// RT constants not set, bring in the DCRAW single channel black constant
for (int c = 0; c < 4; c++) {
@ -750,6 +752,7 @@ float** RawImage::compress_image(int frameNum, bool freeImage)
height -= top_margin;
width -= left_margin;
}
#pragma omp parallel for
for (int row = 0; row < height; row++)
@ -764,6 +767,7 @@ float** RawImage::compress_image(int frameNum, bool freeImage)
free(image); // we don't need this anymore
image = nullptr;
}
return data;
}

View File

@ -124,7 +124,10 @@ public:
float** compress_image(int frameNum, bool freeImage = true); // revert to compressed pixels format and release image data
float** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column
unsigned prefilters; // original filters saved ( used for 4 color processing )
unsigned int getFrameCount() const { return is_raw; }
unsigned int getFrameCount() const
{
return is_raw;
}
protected:
Glib::ustring filename; // complete filename
int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif

View File

@ -468,6 +468,7 @@ RawImageSource::RawImageSource ()
camProfile = nullptr;
embProfile = nullptr;
rgbSourceModified = false;
for (int i = 0; i < 4; ++i) {
psRedBrightness[i] = psGreenBrightness[i] = psBlueBrightness[i] = 1.f;
}
@ -1864,6 +1865,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
// Correct vignetting of lens profile
if (!hasFlatField && lensProf.useVign) {
std::unique_ptr<LensCorrection> pmap;
if (lensProf.useLensfun()) {
pmap = LFDatabase::findModifier(lensProf, idata, W, H, coarse, -1);
} else {
@ -1876,6 +1878,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
if (pmap) {
LensCorrection &map = *pmap;
if (ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) {
if (numFrames == 4) {
for (int i = 0; i < 4; ++i) {
@ -1987,6 +1990,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
plistener->setProgressStr("CA Auto Correction...");
plistener->setProgress(0.0);
}
if (numFrames == 4) {
for (int i = 0; i < 4; ++i) {
CA_correct_RT(raw.ca_autocorrect, raw.cared, raw.cablue, 8.0, *rawDataFrames[i]);
@ -2492,8 +2496,7 @@ void RawImageSource::retinex(const ColorManagementParams& cmp, const RetinexPara
int pos = LBuffer[i][j];
hist16RETThr[pos]++; //histogram in Curve
}
}
else
} else
for (int j = 0; j < W - 2 * border; j++) {
LBuffer[i][j] = temp[i][j];
}
@ -4767,12 +4770,10 @@ void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LU
if (ri->getSensorType() == ST_BAYER) // since there are twice as many greens, correct for it
for (int i = 0; i < 256; i++) {
histGreenRaw[i] >>= 1;
}
else if (ri->getSensorType() == ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it
} else if (ri->getSensorType() == ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it
for (int i = 0; i < 256; i++) {
histGreenRaw[i] = (histGreenRaw[i] * 2) / 5;
}
else if (ri->get_colors() == 1) { // monochrome sensor => set all histograms equal
} else if (ri->get_colors() == 1) { // monochrome sensor => set all histograms equal
histGreenRaw += histRedRaw;
histBlueRaw += histRedRaw;
}

View File

@ -204,11 +204,15 @@ public:
static void HLRecovery_blend(float* rin, float* gin, float* bin, int width, float maxval, float* hlmax);
static void init();
static void cleanup();
void setCurrentFrame(unsigned int frameNum) {
void setCurrentFrame(unsigned int frameNum)
{
currFrame = std::min(numFrames - 1, frameNum);
ri = riFrames[currFrame];
}
int getFrameCount() {return numFrames;}
int getFrameCount()
{
return numFrames;
}
protected:
typedef unsigned short ushort;

View File

@ -2472,10 +2472,12 @@ private:
// and may contain subframe depending on initial raw's hierarchy
readyImg->setMetadata(ii->getMetaData()->getRootExifData());
break;
case MetaDataParams::EDIT:
// ask for the correct frame number, but may contain subframe depending on initial raw's hierarchy
readyImg->setMetadata(ii->getMetaData()->getBestExifData(imgsrc, &params.raw), params.exif, params.iptc);
break;
default: // case MetaDataParams::STRIP
// nothing to do
break;

View File

@ -400,7 +400,7 @@ Locallab::Locallab():
ctboxshape->pack_start(*labmshape, Gtk::PACK_SHRINK, 4);
ctboxshape->set_tooltip_markup(M("TP_LOCALLAB_SHAPE_TOOLTIP"));
//ctboxshape->set_tooltip_markup(M("TP_LOCALLAB_SHAPE_TOOLTIP"));
ctboxEx->pack_start(*labmEx, Gtk::PACK_SHRINK, 4);
ctboxEx->set_tooltip_markup(M("TP_LOCALLAB_EXCLUTYPE_TOOLTIP"));