capture sharpening: do not trigger demosaic when changing adjusters

This commit is contained in:
Ingo Weyrich 2019-08-28 18:03:31 +02:00
parent ada08b3b71
commit ba8c3d15bf
6 changed files with 128 additions and 30 deletions

View File

@ -83,7 +83,7 @@ public:
virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {}; virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {};
virtual void filmNegativeProcess (const procparams::FilmNegativeParams &params) {}; virtual void filmNegativeProcess (const procparams::FilmNegativeParams &params) {};
virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array<float, 3>& newExps) { return false; }; virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array<float, 3>& newExps) { return false; };
virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) {}; virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) {};
virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {};
virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {};
virtual void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI) {}; virtual void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI) {};

View File

@ -332,26 +332,31 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
} }
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicAutoContrast : params->raw.xtranssensor.dualDemosaicAutoContrast; bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicAutoContrast : params->raw.xtranssensor.dualDemosaicAutoContrast;
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast; double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast;
imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic imgsrc->demosaic(rp, autoContrast, contrastThreshold, params->pdsharpening.enabled);
if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) { if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) {
bayerAutoContrastListener->autoContrastChanged(contrastThreshold); bayerAutoContrastListener->autoContrastChanged(contrastThreshold);
} else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) { } else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) {
xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0); xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0);
} }
if (params->pdsharpening.enabled) {
double pdSharpencontrastThreshold = params->pdsharpening.contrast;
imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold);
if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) {
pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold);
}
}
// if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag // if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag
todo |= M_INIT; todo |= M_INIT;
}
if ((todo & M_INIT) && params->pdsharpening.enabled) {
double pdSharpencontrastThreshold = params->pdsharpening.contrast;
imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold);
if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) {
pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold);
}
}
if ((todo & M_RAW)
|| (!highDetailRawComputed && highDetailNeeded)
|| (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified())
|| (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) {
if (highDetailNeeded) { if (highDetailNeeded) {
highDetailRawComputed = true; highDetailRawComputed = true;
} else { } else {

View File

@ -45,6 +45,7 @@
#include <omp.h> #include <omp.h>
#endif #endif
#include "opthelper.h" #include "opthelper.h"
#include "../rtgui/multilangmgr.h"
#define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) #define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val )
#undef CLIPD #undef CLIPD
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) #define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
@ -457,6 +458,9 @@ RawImageSource::RawImageSource ()
, green(0, 0) , green(0, 0)
, red(0, 0) , red(0, 0)
, blue(0, 0) , blue(0, 0)
, greenCache(nullptr)
, redCache(nullptr)
, blueCache(nullptr)
, rawDirty(true) , rawDirty(true)
, histMatchingParams(new procparams::ColorManagementParams) , histMatchingParams(new procparams::ColorManagementParams)
{ {
@ -474,6 +478,9 @@ RawImageSource::~RawImageSource ()
{ {
delete idata; delete idata;
delete redCache;
delete greenCache;
delete blueCache;
for(size_t i = 0; i < numFrames; ++i) { for(size_t i = 0; i < numFrames; ++i) {
delete riFrames[i]; delete riFrames[i];
@ -1524,7 +1531,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold) void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache)
{ {
MyTime t1, t2; MyTime t1, t2;
t1.set(); t1.set();
@ -1595,7 +1602,49 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
rgbSourceModified = false; rgbSourceModified = false;
if (cache) {
if (!redCache) {
redCache = new array2D<float>(W, H);
greenCache = new array2D<float>(W, H);
blueCache = new array2D<float>(W, H);
}
#ifdef _OPENMP
#pragma omp parallel sections
#endif
{
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
(*redCache)[i][j] = red[i][j];
}
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
(*greenCache)[i][j] = green[i][j];
}
}
#ifdef _OPENMP
#pragma omp section
#endif
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
(*blueCache)[i][j] = blue[i][j];
}
}
}
} else {
delete redCache;
redCache = nullptr;
delete greenCache;
greenCache = nullptr;
delete blueCache;
blueCache = nullptr;
}
if( settings->verbose ) { if( settings->verbose ) {
if (getSensorType() == ST_BAYER) { if (getSensorType() == ST_BAYER) {
printf("Demosaicing Bayer data: %s - %d usec\n", raw.bayersensor.method.c_str(), t2.etime(t1)); printf("Demosaicing Bayer data: %s - %d usec\n", raw.bayersensor.method.c_str(), t2.etime(t1));
@ -4954,6 +5003,12 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int
void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) { void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) {
BENCHFUN BENCHFUN
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(0.0);
}
const float xyz_rgb[3][3] = { // XYZ from RGB const float xyz_rgb[3][3] = { // XYZ from RGB
{ 0.412453, 0.357580, 0.180423 }, { 0.412453, 0.357580, 0.180423 },
{ 0.212671, 0.715160, 0.072169 }, { 0.212671, 0.715160, 0.072169 },
@ -4962,6 +5017,10 @@ BENCHFUN
float contrast = conrastThreshold / 100.f; float contrast = conrastThreshold / 100.f;
array2D<float>& redVals = redCache ? *redCache : red;
array2D<float>& greenVals = greenCache ? *greenCache : green;
array2D<float>& blueVals = blueCache ? *blueCache : blue;
if (showMask) { if (showMask) {
StopWatch Stop1("Show mask"); StopWatch Stop1("Show mask");
array2D<float>& L = blue; // blue will be overridden anyway => we can use its buffer to store L array2D<float>& L = blue; // blue will be overridden anyway => we can use its buffer to store L
@ -4970,10 +5029,18 @@ BENCHFUN
#endif #endif
for (int i = 0; i < H; ++i) { for (int i = 0; i < H; ++i) {
Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W);
}
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(0.1);
} }
array2D<float>& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask array2D<float>& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask
buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast);
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(0.2);
}
conrastThreshold = contrast * 100.f; conrastThreshold = contrast * 100.f;
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
@ -4983,6 +5050,10 @@ BENCHFUN
red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f; red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f;
} }
} }
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(1.0);
}
return; return;
} }
@ -4995,12 +5066,20 @@ BENCHFUN
#pragma omp parallel for schedule(dynamic, 16) #pragma omp parallel for schedule(dynamic, 16)
#endif #endif
for (int i = 0; i < H; ++i) { for (int i = 0; i < H; ++i) {
Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W); Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W);
Color::RGB2Y(red[i], green[i], blue[i], YOld[i], YNew[i], sharpeningParams.gamma, W); Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W);
}
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(0.1);
} }
// calculate contrast based blend factors to reduce sharpening in regions with low contrast // calculate contrast based blend factors to reduce sharpening in regions with low contrast
JaggedArray<float> blend(W, H); JaggedArray<float> blend(W, H);
buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast); buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast);
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(0.2);
}
conrastThreshold = contrast * 100.f; conrastThreshold = contrast * 100.f;
Stop1.stop(); Stop1.stop();
@ -5008,6 +5087,10 @@ BENCHFUN
ProcParams dummy; ProcParams dummy;
ImProcFunctions ipf(&dummy); ImProcFunctions ipf(&dummy);
ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0); ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0);
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(0.9);
}
StopWatch Stop2("Y2RGB"); StopWatch Stop2("Y2RGB");
const float gamma = sharpeningParams.gamma; const float gamma = sharpeningParams.gamma;
#ifdef _OPENMP #ifdef _OPENMP
@ -5019,20 +5102,24 @@ BENCHFUN
const vfloat gammav = F2V(gamma); const vfloat gammav = F2V(gamma);
for (; j < W - 3; j += 4) { for (; j < W - 3; j += 4) {
const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav); const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav);
STVFU(red[i][j], LVFU(red[i][j]) * factor); STVFU(red[i][j], LVFU(redVals[i][j]) * factor);
STVFU(green[i][j], LVFU(green[i][j]) * factor); STVFU(green[i][j], LVFU(greenVals[i][j]) * factor);
STVFU(blue[i][j], LVFU(blue[i][j]) * factor); STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor);
} }
#endif #endif
for (; j < W; ++j) { for (; j < W; ++j) {
const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma); const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma);
red[i][j] *= factor; red[i][j] = redVals[i][j] * factor;
green[i][j] *= factor; green[i][j] = greenVals[i][j] * factor;
blue[i][j] *= factor; blue[i][j] = blueVals[i][j] * factor;
} }
} }
Stop2.stop(); Stop2.stop();
if (plistener) {
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
plistener->setProgress(1.0);
}
} }
void RawImageSource::cleanup () void RawImageSource::cleanup ()

View File

@ -88,6 +88,12 @@ protected:
array2D<float> red; array2D<float> red;
// the interpolated blue plane: // the interpolated blue plane:
array2D<float> blue; array2D<float> blue;
// the interpolated green plane:
array2D<float>* greenCache;
// the interpolated red plane:
array2D<float>* redCache;
// the interpolated blue plane:
array2D<float>* blueCache;
bool rawDirty; bool rawDirty;
float psRedBrightness[4]; float psRedBrightness[4];
float psGreenBrightness[4]; float psGreenBrightness[4];
@ -117,7 +123,7 @@ public:
void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override; void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override;
void filmNegativeProcess (const procparams::FilmNegativeParams &params) override; void filmNegativeProcess (const procparams::FilmNegativeParams &params) override;
bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams &currentParams, std::array<float, 3>& newExps) override; bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams &currentParams, std::array<float, 3>& newExps) override;
void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) override; void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) override;
void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override; void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override;
void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override; void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override;
void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI) override; void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI) override;

View File

@ -220,7 +220,7 @@ private:
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast; bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast;
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast; double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast;
imgsrc->demosaic (params.raw, autoContrast, contrastThreshold); imgsrc->demosaic (params.raw, autoContrast, contrastThreshold, params.pdsharpening.enabled && pl);
if (params.pdsharpening.enabled) { if (params.pdsharpening.enabled) {
imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast); imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast);
} }

View File

@ -30,11 +30,11 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS
{ {
auto m = ProcEventMapper::getInstance(); auto m = ProcEventMapper::getInstance();
EvPdShrContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_CONTRAST"); EvPdShrContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_CONTRAST");
EvPdSharpenGamma = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_GAMMA"); EvPdSharpenGamma = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_GAMMA");
EvPdShrDRadius = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_RADIUS"); EvPdShrDRadius = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_RADIUS");
EvPdShrDIterations = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ITERATIONS"); EvPdShrDIterations = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_ITERATIONS");
EvPdShrAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST"); EvPdShrAutoContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST");
Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
hb->show(); hb->show();