Added possibility to export profiling reference image without WB to make it possible to generate DNG profiles; also apply transform and scaling on profiling reference image
This commit is contained in:
@@ -1410,6 +1410,7 @@ TP_ICM_NOICM;No ICM: sRGB Output
|
||||
TP_ICM_OUTPUTPROFILE;Output Profile
|
||||
TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling
|
||||
TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile.
|
||||
TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance
|
||||
TP_ICM_TONECURVE;Use DCP's tone curve
|
||||
TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve.
|
||||
TP_ICM_WORKINGPROFILE;Working Profile
|
||||
|
||||
@@ -956,7 +956,7 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &
|
||||
}
|
||||
|
||||
|
||||
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
|
||||
void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) {
|
||||
|
||||
MyMutex::MyLock lock(mProcessing);
|
||||
|
||||
@@ -969,7 +969,6 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
|
||||
Imagefloat* im = new Imagefloat (fW, fH);
|
||||
imgsrc->preprocess( ppar.raw, ppar.lensProf, ppar.coarse );
|
||||
imgsrc->demosaic(ppar.raw );
|
||||
//imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.toneCurve, ppar.icm, ppar.raw);
|
||||
ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
|
||||
if (params.wb.method=="Camera")
|
||||
currWB = imgsrc->getWB ();
|
||||
@@ -988,29 +987,46 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
|
||||
}
|
||||
currWB = autoWB;
|
||||
}
|
||||
params.wb.temperature = currWB.getTemp ();
|
||||
params.wb.green = currWB.getGreen ();
|
||||
if (!apply_wb) {
|
||||
currWB = ColorTemp(); // = no white balance
|
||||
}
|
||||
imgsrc->getImage (currWB, 0, im, pp, ppar.toneCurve, ppar.icm, ppar.raw);
|
||||
imgsrc->convertColorSpace(im, ppar.icm, currWB, params.raw);
|
||||
if (params.crop.enabled) {
|
||||
Imagefloat *tmpim = new Imagefloat (params.crop.w, params.crop.h);
|
||||
int cx = params.crop.x;
|
||||
int cy = params.crop.y;
|
||||
int cw = params.crop.w;
|
||||
int ch = params.crop.h;
|
||||
ImProcFunctions ipf (&ppar, true);
|
||||
if (ipf.needsTransform()) {
|
||||
Imagefloat* trImg = new Imagefloat (fW, fH);
|
||||
ipf.transform (im, trImg, 0, 0, 0, 0, fW, fH, fW, fH, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(),
|
||||
imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), true);
|
||||
delete im;
|
||||
im = trImg;
|
||||
}
|
||||
if (params.crop.enabled) {
|
||||
Imagefloat *tmpim = new Imagefloat (params.crop.w, params.crop.h);
|
||||
int cx = params.crop.x;
|
||||
int cy = params.crop.y;
|
||||
int cw = params.crop.w;
|
||||
int ch = params.crop.h;
|
||||
#pragma omp parallel for
|
||||
for (int i=cy; i<cy+ch; i++) {
|
||||
for (int j=cx; j<cx+cw; j++) {
|
||||
tmpim->r(i-cy, j-cx) = im->r(i, j);
|
||||
tmpim->g(i-cy, j-cx) = im->g(i, j);
|
||||
tmpim->b(i-cy, j-cx) = im->b(i, j);
|
||||
}
|
||||
}
|
||||
delete im;
|
||||
im = tmpim;
|
||||
}
|
||||
for (int i=cy; i<cy+ch; i++) {
|
||||
for (int j=cx; j<cx+cw; j++) {
|
||||
tmpim->r(i-cy, j-cx) = im->r(i, j);
|
||||
tmpim->g(i-cy, j-cx) = im->g(i, j);
|
||||
tmpim->b(i-cy, j-cx) = im->b(i, j);
|
||||
}
|
||||
}
|
||||
delete im;
|
||||
im = tmpim;
|
||||
}
|
||||
Image16* im16 = im->to16();
|
||||
delete im;
|
||||
|
||||
int imw, imh;
|
||||
double tmpScale = ipf.resizeScale(¶ms, fW, fH, imw, imh);
|
||||
if (tmpScale != 1.0) {
|
||||
Image16* tempImage = new Image16 (imw, imh);
|
||||
ipf.resize (im16, tempImage, tmpScale);
|
||||
delete im16;
|
||||
im16 = tempImage;
|
||||
}
|
||||
im16->saveTIFF (fname,16,true);
|
||||
delete im16;
|
||||
//im->saveJPEG (fname, 85);
|
||||
|
||||
@@ -233,7 +233,7 @@ class ImProcCoordinator : public StagedImageProcessor {
|
||||
void setAutoChromaListener (AutoChromaListener* adn) {adnListener = adn; }
|
||||
void setWaveletListener (WaveletListener* awa) {awavListener = awa; }
|
||||
|
||||
void saveInputICCReference (const Glib::ustring& fname);
|
||||
void saveInputICCReference (const Glib::ustring& fname, bool apply_wb);
|
||||
|
||||
InitialImage* getInitialImage () { return imgsrc; }
|
||||
};
|
||||
|
||||
@@ -250,6 +250,7 @@ class ImProcFunctions {
|
||||
void sharpeningcam (CieImage* ncie, float** buffer);
|
||||
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
|
||||
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
|
||||
float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh);
|
||||
void lab2monitorRgb (LabImage* lab, Image8* image);
|
||||
void resize (Image16* src, Image16* dst, float dScale);
|
||||
// void Lanczoslab (LabImage* src, LabImage* dst, float scale);
|
||||
|
||||
@@ -333,6 +333,65 @@ SSEFUNCTION static void Lanczos(const LabImage* src, LabImage* dst, float scale)
|
||||
}
|
||||
}
|
||||
|
||||
float ImProcFunctions::resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh) {
|
||||
imw = fw;
|
||||
imh = fh;
|
||||
if (!params || !params->resize.enabled) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// get the resize parameters
|
||||
int refw, refh;
|
||||
double dScale;
|
||||
if (params->crop.enabled && params->resize.appliesTo == "Cropped area") {
|
||||
// the resize values applies to the crop dimensions
|
||||
refw = params->crop.w;
|
||||
refh = params->crop.h;
|
||||
}
|
||||
else {
|
||||
// the resize values applies to the image dimensions
|
||||
// if a crop exists, it will be resized to the calculated scale
|
||||
refw = fw;
|
||||
refh = fh;
|
||||
}
|
||||
|
||||
switch(params->resize.dataspec) {
|
||||
case (1):
|
||||
// Width
|
||||
dScale = (double)params->resize.width/(double)refw;
|
||||
break;
|
||||
case (2):
|
||||
// Height
|
||||
dScale = (double)params->resize.height/(double)refh;
|
||||
break;
|
||||
case (3):
|
||||
// FitBox
|
||||
if ((double)refw/(double)refh > (double)params->resize.width/(double)params->resize.height)
|
||||
dScale = (double)params->resize.width/(double)refw;
|
||||
else
|
||||
dScale = (double)params->resize.height/(double)refh;
|
||||
break;
|
||||
default:
|
||||
// Scale
|
||||
dScale = params->resize.scale;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fabs(dScale-1.0)<=1e-5) {
|
||||
return 1.0;
|
||||
}
|
||||
if (params->crop.enabled && params->resize.appliesTo == "Full image") {
|
||||
imw = params->crop.w;
|
||||
imh = params->crop.h;
|
||||
}
|
||||
else {
|
||||
imw = refw;
|
||||
imh = refh;
|
||||
}
|
||||
imw = (int)( (double)imw * dScale + 0.5 );
|
||||
imh = (int)( (double)imh * dScale + 0.5 );
|
||||
return (float)dScale;
|
||||
}
|
||||
|
||||
void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale) {
|
||||
#ifdef PROFILE
|
||||
|
||||
@@ -236,10 +236,17 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
|
||||
// compute channel multipliers
|
||||
double r, g, b;
|
||||
float rm, gm, bm;
|
||||
ctemp.getMultipliers (r, g, b);
|
||||
rm = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b;
|
||||
gm = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b;
|
||||
bm = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b;
|
||||
if (ctemp.getTemp() < 0) {
|
||||
// no white balance, ie revert the pre-process white balance to restore original unbalanced raw camera color
|
||||
rm = ri->get_pre_mul(0);
|
||||
gm = ri->get_pre_mul(1);
|
||||
bm = ri->get_pre_mul(2);
|
||||
} else {
|
||||
ctemp.getMultipliers (r, g, b);
|
||||
rm = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b;
|
||||
gm = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b;
|
||||
bm = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b;
|
||||
}
|
||||
|
||||
if (true) {
|
||||
// adjust gain so the maximum raw value of the least scaled channel just hits max
|
||||
|
||||
@@ -368,7 +368,7 @@ namespace rtengine {
|
||||
virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) =0;
|
||||
virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) =0;
|
||||
|
||||
virtual void saveInputICCReference (const Glib::ustring& fname) =0;
|
||||
virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) =0;
|
||||
|
||||
virtual void setProgressListener (ProgressListener* l) =0;
|
||||
virtual void setSizeListener (SizeListener* l) =0;
|
||||
|
||||
@@ -1045,63 +1045,14 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
|
||||
}
|
||||
if (pl) pl->setProgress (0.70);
|
||||
|
||||
if (params.resize.enabled) {
|
||||
|
||||
// get the resize parameters
|
||||
int refw, refh;
|
||||
double tmpScale;
|
||||
if (params.crop.enabled && params.resize.appliesTo == "Cropped area") {
|
||||
// the resize values applies to the crop dimensions
|
||||
refw = cw;
|
||||
refh = ch;
|
||||
}
|
||||
else {
|
||||
// the resize values applies to the image dimensions
|
||||
// if a crop exists, it will be resized to the calculated scale
|
||||
refw = fw;
|
||||
refh = fh;
|
||||
}
|
||||
|
||||
switch(params.resize.dataspec) {
|
||||
case (1):
|
||||
// Width
|
||||
tmpScale = (double)params.resize.width/(double)refw;
|
||||
break;
|
||||
case (2):
|
||||
// Height
|
||||
tmpScale = (double)params.resize.height/(double)refh;
|
||||
break;
|
||||
case (3):
|
||||
// FitBox
|
||||
if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height)
|
||||
tmpScale = (double)params.resize.width/(double)refw;
|
||||
else
|
||||
tmpScale = (double)params.resize.height/(double)refh;
|
||||
break;
|
||||
default:
|
||||
// Scale
|
||||
tmpScale = params.resize.scale;
|
||||
break;
|
||||
}
|
||||
|
||||
int imw, imh;
|
||||
double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh);
|
||||
if (tmpScale != 1.0) {
|
||||
// resize image
|
||||
if (fabs(tmpScale-1.0)>1e-5) {
|
||||
int imw, imh;
|
||||
if (params.crop.enabled && params.resize.appliesTo == "Full image") {
|
||||
imw = cw;
|
||||
imh = ch;
|
||||
}
|
||||
else {
|
||||
imw = refw;
|
||||
imh = refh;
|
||||
}
|
||||
imw = (int)( (double)imw * tmpScale + 0.5 );
|
||||
imh = (int)( (double)imh * tmpScale + 0.5 );
|
||||
Image16* tempImage = new Image16 (imw, imh);
|
||||
ipf.resize (readyImg, tempImage, tmpScale);
|
||||
delete readyImg;
|
||||
readyImg = tempImage;
|
||||
}
|
||||
Image16* tempImage = new Image16 (imw, imh);
|
||||
ipf.resize (readyImg, tempImage, tmpScale);
|
||||
delete readyImg;
|
||||
readyImg = tempImage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -693,6 +693,13 @@ void ICMPanel::saveReferencePressed () {
|
||||
dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL);
|
||||
dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK);
|
||||
|
||||
Gtk::CheckButton applyWB(M("TP_ICM_SAVEREFERENCE_APPLYWB"));
|
||||
applyWB.set_active(true);
|
||||
Gtk::HBox* hbox = Gtk::manage( new Gtk::HBox() );
|
||||
hbox->pack_end(applyWB, Gtk::PACK_SHRINK, 2);
|
||||
Gtk::VBox *vbox = dialog.get_vbox();
|
||||
vbox->pack_end(*hbox, Gtk::PACK_SHRINK, 2);
|
||||
|
||||
Gtk::FileFilter filter_tif;
|
||||
filter_tif.set_name(M("SAVEDLG_TIFFFILTER"));
|
||||
filter_tif.add_pattern("*.tif");
|
||||
@@ -704,6 +711,7 @@ void ICMPanel::saveReferencePressed () {
|
||||
filter_any.add_pattern("*");
|
||||
dialog.add_filter(filter_any);
|
||||
|
||||
dialog.show_all_children();
|
||||
//dialog.set_do_overwrite_confirmation (true);
|
||||
|
||||
bool done = false;
|
||||
@@ -717,7 +725,7 @@ void ICMPanel::saveReferencePressed () {
|
||||
if (ext != "tif" && ext != "tiff")
|
||||
fname += ".tif";
|
||||
if (confirmOverwrite(dialog, fname)) {
|
||||
icmplistener->saveInputICCReference (fname);
|
||||
icmplistener->saveInputICCReference (fname, applyWB.get_active());
|
||||
lastRefFilename = Glib::path_get_basename (fname);
|
||||
done = true;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class ICMPanelListener {
|
||||
|
||||
public:
|
||||
virtual ~ICMPanelListener() {}
|
||||
virtual void saveInputICCReference (Glib::ustring fname) {}
|
||||
virtual void saveInputICCReference (Glib::ustring fname, bool apply_wb) {}
|
||||
};
|
||||
|
||||
class ICMPanel : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel {
|
||||
|
||||
@@ -580,10 +580,10 @@ void ToolPanelCoordinator::cropSelectRequested () {
|
||||
toolBar->setTool (TMCropSelect);
|
||||
}
|
||||
|
||||
void ToolPanelCoordinator::saveInputICCReference (Glib::ustring fname) {
|
||||
void ToolPanelCoordinator::saveInputICCReference (Glib::ustring fname, bool apply_wb) {
|
||||
|
||||
if (ipc)
|
||||
ipc->saveInputICCReference (fname);
|
||||
ipc->saveInputICCReference (fname, apply_wb);
|
||||
}
|
||||
|
||||
int ToolPanelCoordinator::getSpotWBRectSize () {
|
||||
|
||||
@@ -265,7 +265,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
|
||||
void cropSelectRequested ();
|
||||
|
||||
// icmpanellistener interface
|
||||
void saveInputICCReference (Glib::ustring fname);
|
||||
void saveInputICCReference (Glib::ustring fname, bool apply_wb);
|
||||
|
||||
// imageareatoollistener interface
|
||||
void spotWBselected (int x, int y, Thumbnail* thm=NULL);
|
||||
|
||||
Reference in New Issue
Block a user