diff --git a/src/kdcraw_p.cpp b/src/kdcraw_p.cpp
index d6f5d00..76a7d42 100644
--- a/src/kdcraw_p.cpp
+++ b/src/kdcraw_p.cpp
@@ -1,690 +1,698 @@
/** ===========================================================
* @file
*
* This file is a part of KDE project
*
*
* @date 2008-10-09
* @brief internal private container for KDcraw
*
* @author Copyright (C) 2008-2015 by Gilles Caulier
* caulier dot gilles at gmail dot com
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation;
* either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
#include "kdcraw.h"
#include "kdcraw_p.h"
// Qt includes
#include
#include
// Local includes
#include "libkdcraw_debug.h"
namespace KDcrawIface
{
int callbackForLibRaw(void* data, enum LibRaw_progress p, int iteration, int expected)
{
if (data)
{
KDcraw::Private* const d = static_cast(data);
if (d)
{
return d->progressCallback(p, iteration, expected);
}
}
return 0;
}
// --------------------------------------------------------------------------------------------------
KDcraw::Private::Private(KDcraw* const p)
{
m_progress = 0.0;
m_parent = p;
}
KDcraw::Private::~Private()
{
}
void KDcraw::Private::createPPMHeader(QByteArray& imgData, libraw_processed_image_t* const img)
{
QString header = QString::fromUtf8("P%1\n%2 %3\n%4\n").arg(img->colors == 3 ? QLatin1String("6") : QLatin1String("5"))
.arg(img->width)
.arg(img->height)
.arg((1 << img->bits)-1);
imgData.append(header.toLatin1());
imgData.append(QByteArray((const char*)img->data, (int)img->data_size));
}
int KDcraw::Private::progressCallback(enum LibRaw_progress p, int iteration, int expected)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw progress: " << libraw_strprogress(p) << " pass "
<< iteration << " of " << expected;
// post a little change in progress indicator to show raw processor activity.
setProgress(progressValue()+0.01);
// Clean processing termination by user...
if (m_parent->checkToCancelWaitingData())
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw process terminaison invoked...";
m_parent->m_cancel = true;
m_progress = 0.0;
return 1;
}
// Return 0 to continue processing...
return 0;
}
void KDcraw::Private::setProgress(double value)
{
m_progress = value;
m_parent->setWaitingDataProgress(m_progress);
}
double KDcraw::Private::progressValue() const
{
return m_progress;
}
void KDcraw::Private::fillIndentifyInfo(LibRaw* const raw, DcrawInfoContainer& identify)
{
identify.dateTime.setTime_t(raw->imgdata.other.timestamp);
identify.make = QString::fromUtf8(raw->imgdata.idata.make);
identify.model = QString::fromUtf8(raw->imgdata.idata.model);
identify.owner = QString::fromUtf8(raw->imgdata.other.artist);
identify.DNGVersion = QString::number(raw->imgdata.idata.dng_version);
identify.sensitivity = raw->imgdata.other.iso_speed;
identify.exposureTime = raw->imgdata.other.shutter;
identify.aperture = raw->imgdata.other.aperture;
identify.focalLength = raw->imgdata.other.focal_len;
identify.imageSize = QSize(raw->imgdata.sizes.width, raw->imgdata.sizes.height);
identify.fullSize = QSize(raw->imgdata.sizes.raw_width, raw->imgdata.sizes.raw_height);
identify.outputSize = QSize(raw->imgdata.sizes.iwidth, raw->imgdata.sizes.iheight);
identify.thumbSize = QSize(raw->imgdata.thumbnail.twidth, raw->imgdata.thumbnail.theight);
identify.topMargin = raw->imgdata.sizes.top_margin;
identify.leftMargin = raw->imgdata.sizes.left_margin;
identify.hasIccProfile = raw->imgdata.color.profile ? true : false;
identify.isDecodable = true;
identify.pixelAspectRatio = raw->imgdata.sizes.pixel_aspect;
identify.rawColors = raw->imgdata.idata.colors;
identify.rawImages = raw->imgdata.idata.raw_count;
identify.blackPoint = raw->imgdata.color.black;
for (int ch = 0; ch < 4; ch++)
{
identify.blackPointCh[ch] = raw->imgdata.color.cblack[ch];
}
identify.whitePoint = raw->imgdata.color.maximum;
identify.orientation = (DcrawInfoContainer::ImageOrientation)raw->imgdata.sizes.flip;
memcpy(&identify.cameraColorMatrix1, &raw->imgdata.color.cmatrix, sizeof(raw->imgdata.color.cmatrix));
memcpy(&identify.cameraColorMatrix2, &raw->imgdata.color.rgb_cam, sizeof(raw->imgdata.color.rgb_cam));
memcpy(&identify.cameraXYZMatrix, &raw->imgdata.color.cam_xyz, sizeof(raw->imgdata.color.cam_xyz));
if (raw->imgdata.idata.filters)
{
if (!raw->imgdata.idata.cdesc[3])
{
raw->imgdata.idata.cdesc[3] = 'G';
}
for (int i=0; i < 16; i++)
{
identify.filterPattern.append(QChar::fromLatin1(raw->imgdata.idata.cdesc[raw->COLOR(i >> 1, i & 1)]));
}
identify.colorKeys = QString::fromLatin1(raw->imgdata.idata.cdesc);
}
for(int c = 0 ; c < raw->imgdata.idata.colors ; c++)
{
identify.daylightMult[c] = raw->imgdata.color.pre_mul[c];
}
if (raw->imgdata.color.cam_mul[0] > 0)
{
for(int c = 0 ; c < 4 ; c++)
{
identify.cameraMult[c] = raw->imgdata.color.cam_mul[c];
}
}
}
bool KDcraw::Private::loadFromLibraw(const QString& filePath, QByteArray& imageData,
int& width, int& height, int& rgbmax)
{
m_parent->m_cancel = false;
LibRaw raw;
// Set progress call back function.
raw.set_progress_handler(callbackForLibRaw, this);
QByteArray deadpixelPath = QFile::encodeName(m_parent->m_rawDecodingSettings.deadPixelMap);
QByteArray cameraProfile = QFile::encodeName(m_parent->m_rawDecodingSettings.inputProfile);
QByteArray outputProfile = QFile::encodeName(m_parent->m_rawDecodingSettings.outputProfile);
if (!m_parent->m_rawDecodingSettings.autoBrightness)
{
// Use a fixed white level, ignoring the image histogram.
raw.imgdata.params.no_auto_bright = 1;
}
if (m_parent->m_rawDecodingSettings.sixteenBitsImage)
{
// (-4) 16bit ppm output
raw.imgdata.params.output_bps = 16;
}
if (m_parent->m_rawDecodingSettings.halfSizeColorImage)
{
// (-h) Half-size color image (3x faster than -q).
raw.imgdata.params.half_size = 1;
}
if (m_parent->m_rawDecodingSettings.RGBInterpolate4Colors)
{
// (-f) Interpolate RGB as four colors.
raw.imgdata.params.four_color_rgb = 1;
}
if (m_parent->m_rawDecodingSettings.DontStretchPixels)
{
// (-j) Do not stretch the image to its correct aspect ratio.
raw.imgdata.params.use_fuji_rotate = 1;
}
// (-H) Unclip highlight color.
raw.imgdata.params.highlight = m_parent->m_rawDecodingSettings.unclipColors;
if (m_parent->m_rawDecodingSettings.brightness != 1.0)
{
// (-b) Set Brightness value.
raw.imgdata.params.bright = m_parent->m_rawDecodingSettings.brightness;
}
if (m_parent->m_rawDecodingSettings.enableBlackPoint)
{
// (-k) Set Black Point value.
raw.imgdata.params.user_black = m_parent->m_rawDecodingSettings.blackPoint;
}
if (m_parent->m_rawDecodingSettings.enableWhitePoint)
{
// (-S) Set White Point value (saturation).
raw.imgdata.params.user_sat = m_parent->m_rawDecodingSettings.whitePoint;
}
if (m_parent->m_rawDecodingSettings.medianFilterPasses > 0)
{
// (-m) After interpolation, clean up color artifacts by repeatedly applying a 3x3 median filter to the R-G and B-G channels.
raw.imgdata.params.med_passes = m_parent->m_rawDecodingSettings.medianFilterPasses;
}
if (!m_parent->m_rawDecodingSettings.deadPixelMap.isEmpty())
{
// (-P) Read the dead pixel list from this file.
raw.imgdata.params.bad_pixels = deadpixelPath.data();
}
switch (m_parent->m_rawDecodingSettings.whiteBalance)
{
case RawDecodingSettings::NONE:
{
break;
}
case RawDecodingSettings::CAMERA:
{
// (-w) Use camera white balance, if possible.
raw.imgdata.params.use_camera_wb = 1;
break;
}
case RawDecodingSettings::AUTO:
{
// (-a) Use automatic white balance.
raw.imgdata.params.use_auto_wb = 1;
break;
}
case RawDecodingSettings::CUSTOM:
{
/* Convert between Temperature and RGB.
*/
double T;
double RGB[3];
double xD, yD, X, Y, Z;
DcrawInfoContainer identify;
T = m_parent->m_rawDecodingSettings.customWhiteBalance;
/* Here starts the code picked and adapted from ufraw (0.12.1)
to convert Temperature + green multiplier to RGB multipliers
*/
/* Convert between Temperature and RGB.
* Base on information from http://www.brucelindbloom.com/
* The fit for D-illuminant between 4000K and 12000K are from CIE
* The generalization to 2000K < T < 4000K and the blackbody fits
* are my own and should be taken with a grain of salt.
*/
const double XYZ_to_RGB[3][3] = {
{ 3.24071, -0.969258, 0.0556352 },
{-1.53726, 1.87599, -0.203996 },
{-0.498571, 0.0415557, 1.05707 }
};
// Fit for CIE Daylight illuminant
if (T <= 4000)
{
xD = 0.27475e9/(T*T*T) - 0.98598e6/(T*T) + 1.17444e3/T + 0.145986;
}
else if (T <= 7000)
{
xD = -4.6070e9/(T*T*T) + 2.9678e6/(T*T) + 0.09911e3/T + 0.244063;
}
else
{
xD = -2.0064e9/(T*T*T) + 1.9018e6/(T*T) + 0.24748e3/T + 0.237040;
}
yD = -3*xD*xD + 2.87*xD - 0.275;
X = xD/yD;
Y = 1;
Z = (1-xD-yD)/yD;
RGB[0] = X*XYZ_to_RGB[0][0] + Y*XYZ_to_RGB[1][0] + Z*XYZ_to_RGB[2][0];
RGB[1] = X*XYZ_to_RGB[0][1] + Y*XYZ_to_RGB[1][1] + Z*XYZ_to_RGB[2][1];
RGB[2] = X*XYZ_to_RGB[0][2] + Y*XYZ_to_RGB[1][2] + Z*XYZ_to_RGB[2][2];
/* End of the code picked to ufraw
*/
RGB[1] = RGB[1] / m_parent->m_rawDecodingSettings.customWhiteBalanceGreen;
/* By default, decraw override his default D65 WB
We need to keep it as a basis : if not, colors with some
DSLR will have a high dominant of color that will lead to
a completely wrong WB
*/
if (rawFileIdentify(identify, filePath))
{
RGB[0] = identify.daylightMult[0] / RGB[0];
RGB[1] = identify.daylightMult[1] / RGB[1];
RGB[2] = identify.daylightMult[2] / RGB[2];
}
else
{
RGB[0] = 1.0 / RGB[0];
RGB[1] = 1.0 / RGB[1];
RGB[2] = 1.0 / RGB[2];
qCDebug(LIBKDCRAW_LOG) << "Warning: cannot get daylight multipliers";
}
// (-r) set Raw Color Balance Multipliers.
raw.imgdata.params.user_mul[0] = RGB[0];
raw.imgdata.params.user_mul[1] = RGB[1];
raw.imgdata.params.user_mul[2] = RGB[2];
raw.imgdata.params.user_mul[3] = RGB[1];
break;
}
case RawDecodingSettings::AERA:
{
// (-A) Calculate the white balance by averaging a rectangular area from image.
raw.imgdata.params.greybox[0] = m_parent->m_rawDecodingSettings.whiteBalanceArea.left();
raw.imgdata.params.greybox[1] = m_parent->m_rawDecodingSettings.whiteBalanceArea.top();
raw.imgdata.params.greybox[2] = m_parent->m_rawDecodingSettings.whiteBalanceArea.width();
raw.imgdata.params.greybox[3] = m_parent->m_rawDecodingSettings.whiteBalanceArea.height();
break;
}
}
// (-q) Use an interpolation method.
raw.imgdata.params.user_qual = m_parent->m_rawDecodingSettings.RAWQuality;
switch (m_parent->m_rawDecodingSettings.NRType)
{
case RawDecodingSettings::WAVELETSNR:
{
// (-n) Use wavelets to erase noise while preserving real detail.
raw.imgdata.params.threshold = m_parent->m_rawDecodingSettings.NRThreshold;
break;
}
case RawDecodingSettings::FBDDNR:
{
// (100 - 1000) => (1 - 10) conversion
raw.imgdata.params.fbdd_noiserd = lround(m_parent->m_rawDecodingSettings.NRThreshold / 100.0);
break;
}
+#if !LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 19)
case RawDecodingSettings::LINENR:
{
// (100 - 1000) => (0.001 - 0.02) conversion.
raw.imgdata.params.linenoise = m_parent->m_rawDecodingSettings.NRThreshold * 2.11E-5 + 0.00111111;
raw.imgdata.params.cfaline = true;
break;
}
case RawDecodingSettings::IMPULSENR:
{
// (100 - 1000) => (0.005 - 0.05) conversion.
raw.imgdata.params.lclean = m_parent->m_rawDecodingSettings.NRThreshold * 5E-5;
raw.imgdata.params.cclean = m_parent->m_rawDecodingSettings.NRChroThreshold * 5E-5;
raw.imgdata.params.cfa_clean = true;
break;
}
+#endif
default: // No Noise Reduction
{
raw.imgdata.params.threshold = 0;
raw.imgdata.params.fbdd_noiserd = 0;
+#if !LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 19)
raw.imgdata.params.linenoise = 0;
raw.imgdata.params.cfaline = false;
raw.imgdata.params.lclean = 0;
raw.imgdata.params.cclean = 0;
raw.imgdata.params.cfa_clean = false;
+#endif
break;
}
}
+#if !LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 19)
// Chromatic aberration correction.
raw.imgdata.params.ca_correc = m_parent->m_rawDecodingSettings.enableCACorrection;
raw.imgdata.params.cared = m_parent->m_rawDecodingSettings.caMultiplier[0];
raw.imgdata.params.cablue = m_parent->m_rawDecodingSettings.caMultiplier[1];
+#endif
// Exposure Correction before interpolation.
raw.imgdata.params.exp_correc = m_parent->m_rawDecodingSettings.expoCorrection;
raw.imgdata.params.exp_shift = m_parent->m_rawDecodingSettings.expoCorrectionShift;
raw.imgdata.params.exp_preser = m_parent->m_rawDecodingSettings.expoCorrectionHighlight;
switch (m_parent->m_rawDecodingSettings.inputColorSpace)
{
case RawDecodingSettings::EMBEDDED:
{
// (-p embed) Use input profile from RAW file to define the camera's raw colorspace.
raw.imgdata.params.camera_profile = (char*)"embed";
break;
}
case RawDecodingSettings::CUSTOMINPUTCS:
{
if (!m_parent->m_rawDecodingSettings.inputProfile.isEmpty())
{
// (-p) Use input profile file to define the camera's raw colorspace.
raw.imgdata.params.camera_profile = cameraProfile.data();
}
break;
}
default:
{
// No input profile
break;
}
}
switch (m_parent->m_rawDecodingSettings.outputColorSpace)
{
case RawDecodingSettings::CUSTOMOUTPUTCS:
{
if (!m_parent->m_rawDecodingSettings.outputProfile.isEmpty())
{
// (-o) Use ICC profile file to define the output colorspace.
raw.imgdata.params.output_profile = outputProfile.data();
}
break;
}
default:
{
// (-o) Define the output colorspace.
raw.imgdata.params.output_color = m_parent->m_rawDecodingSettings.outputColorSpace;
break;
}
}
//-- Extended demosaicing settings ----------------------------------------------------------
raw.imgdata.params.dcb_iterations = m_parent->m_rawDecodingSettings.dcbIterations;
raw.imgdata.params.dcb_enhance_fl = m_parent->m_rawDecodingSettings.dcbEnhanceFl;
+#if !LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 19)
raw.imgdata.params.eeci_refine = m_parent->m_rawDecodingSettings.eeciRefine;
raw.imgdata.params.es_med_passes = m_parent->m_rawDecodingSettings.esMedPasses;
+#endif
//-------------------------------------------------------------------------------------------
setProgress(0.1);
qCDebug(LIBKDCRAW_LOG) << filePath;
qCDebug(LIBKDCRAW_LOG) << m_parent->m_rawDecodingSettings;
int ret = raw.open_file((const char*)(QFile::encodeName(filePath)).constData());
if (ret != LIBRAW_SUCCESS)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run open_file: " << libraw_strerror(ret);
raw.recycle();
return false;
}
if (m_parent->m_cancel)
{
raw.recycle();
return false;
}
setProgress(0.2);
ret = raw.unpack();
if (ret != LIBRAW_SUCCESS)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run unpack: " << libraw_strerror(ret);
raw.recycle();
return false;
}
if (m_parent->m_cancel)
{
raw.recycle();
return false;
}
setProgress(0.25);
if (m_parent->m_rawDecodingSettings.fixColorsHighlights)
{
qCDebug(LIBKDCRAW_LOG) << "Applying LibRaw highlights adjustments";
// 1.0 is fallback to default value
raw.imgdata.params.adjust_maximum_thr = 1.0;
}
else
{
qCDebug(LIBKDCRAW_LOG) << "Disabling LibRaw highlights adjustments";
// 0.0 disables this feature
raw.imgdata.params.adjust_maximum_thr = 0.0;
}
ret = raw.dcraw_process();
if (ret != LIBRAW_SUCCESS)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_process: " << libraw_strerror(ret);
raw.recycle();
return false;
}
if (m_parent->m_cancel)
{
raw.recycle();
return false;
}
setProgress(0.3);
libraw_processed_image_t* img = raw.dcraw_make_mem_image(&ret);
if(!img)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_make_mem_image: " << libraw_strerror(ret);
raw.recycle();
return false;
}
if (m_parent->m_cancel)
{
// Clear memory allocation. Introduced with LibRaw 0.11.0
raw.dcraw_clear_mem(img);
raw.recycle();
return false;
}
setProgress(0.35);
width = img->width;
height = img->height;
rgbmax = (1 << img->bits)-1;
if (img->colors == 3)
{
imageData = QByteArray((const char*)img->data, (int)img->data_size);
}
else
{
// img->colors == 1 (Grayscale) : convert to RGB
imageData = QByteArray();
for (int i = 0 ; i < (int)img->data_size ; ++i)
{
for (int j = 0 ; j < 3 ; ++j)
{
imageData.append(img->data[i]);
}
}
}
// Clear memory allocation. Introduced with LibRaw 0.11.0
raw.dcraw_clear_mem(img);
raw.recycle();
if (m_parent->m_cancel)
{
return false;
}
setProgress(0.4);
qCDebug(LIBKDCRAW_LOG) << "LibRaw: data info: width=" << width
<< " height=" << height
<< " rgbmax=" << rgbmax;
return true;
}
bool KDcraw::Private::loadEmbeddedPreview(QByteArray& imgData, LibRaw& raw)
{
int ret = raw.unpack_thumb();
if (ret != LIBRAW_SUCCESS)
{
raw.recycle();
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run unpack_thumb: " << libraw_strerror(ret);
raw.recycle();
return false;
}
libraw_processed_image_t* const thumb = raw.dcraw_make_mem_thumb(&ret);
if(!thumb)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_make_mem_thumb: " << libraw_strerror(ret);
raw.recycle();
return false;
}
if(thumb->type == LIBRAW_IMAGE_BITMAP)
{
createPPMHeader(imgData, thumb);
}
else
{
imgData = QByteArray((const char*)thumb->data, (int)thumb->data_size);
}
// Clear memory allocation. Introduced with LibRaw 0.11.0
raw.dcraw_clear_mem(thumb);
raw.recycle();
if ( imgData.isEmpty() )
{
qCDebug(LIBKDCRAW_LOG) << "Failed to load JPEG thumb from LibRaw!";
return false;
}
return true;
}
bool KDcraw::Private::loadHalfPreview(QImage& image, LibRaw& raw)
{
raw.imgdata.params.use_auto_wb = 1; // Use automatic white balance.
raw.imgdata.params.use_camera_wb = 1; // Use camera white balance, if possible.
raw.imgdata.params.half_size = 1; // Half-size color image (3x faster than -q).
QByteArray imgData;
int ret = raw.unpack();
if (ret != LIBRAW_SUCCESS)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run unpack: " << libraw_strerror(ret);
raw.recycle();
return false;
}
ret = raw.dcraw_process();
if (ret != LIBRAW_SUCCESS)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_process: " << libraw_strerror(ret);
raw.recycle();
return false;
}
libraw_processed_image_t* halfImg = raw.dcraw_make_mem_image(&ret);
if(!halfImg)
{
qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_make_mem_image: " << libraw_strerror(ret);
raw.recycle();
return false;
}
Private::createPPMHeader(imgData, halfImg);
// Clear memory allocation. Introduced with LibRaw 0.11.0
raw.dcraw_clear_mem(halfImg);
raw.recycle();
if ( imgData.isEmpty() )
{
qCDebug(LIBKDCRAW_LOG) << "Failed to load half preview from LibRaw!";
return false;
}
if (!image.loadFromData(imgData))
{
qCDebug(LIBKDCRAW_LOG) << "Failed to load PPM data from LibRaw!";
return false;
}
return true;
}
} // namespace KDcrawIface
diff --git a/src/rawdecodingsettings.h b/src/rawdecodingsettings.h
index 01cc01b..ad7a664 100644
--- a/src/rawdecodingsettings.h
+++ b/src/rawdecodingsettings.h
@@ -1,363 +1,367 @@
/** ===========================================================
* @file
*
* This file is a part of KDE project
*
*
* @date 2006-12-09
* @brief Raw decoding settings
*
* @author Copyright (C) 2006-2015 by Gilles Caulier
* caulier dot gilles at gmail dot com
* @author Copyright (C) 2006-2013 by Marcel Wiesweg
* marcel dot wiesweg at gmx dot de
* @author Copyright (C) 2007-2008 by Guillaume Castagnino
* casta at xwing dot info
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation;
* either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
#ifndef RAW_DECODING_SETTINGS_H
#define RAW_DECODING_SETTINGS_H
// Qt includes
#include
#include
#include
// Local includes
#include "libkdcraw_export.h"
namespace KDcrawIface
{
class LIBKDCRAW_EXPORT RawDecodingSettings
{
public:
/** RAW decoding Interpolation methods
*
- * NOTE: from original dcraw demosaic
- *
* Bilinear: use high-speed but low-quality bilinear
* interpolation (default - for slow computer). In this method,
* the red value of a non-red pixel is computed as the average of
* the adjacent red pixels, and similar for blue and green.
* VNG: use Variable Number of Gradients interpolation.
* This method computes gradients near the pixel of interest and uses
* the lower gradients (representing smoother and more similar parts
* of the image) to make an estimate.
* PPG: use Patterned Pixel Grouping interpolation.
* Pixel Grouping uses assumptions about natural scenery in making estimates.
* It has fewer color artifacts on natural images than the Variable Number of
* Gradients method.
* AHD: use Adaptive Homogeneity-Directed interpolation.
* This method selects the direction of interpolation so as to
* maximize a homogeneity metric, thus typically minimizing color artifacts.
+ * DCB: DCB interpolation (see http://www.linuxphoto.org/html/dcb.html for details)
*
- * NOTE: from GPL2 demosaic pack.
+ * NOTE: from GPL2/GPL3 demosaic packs - will not work with libraw>=0.19
*
- * DCB: DCB interpolation (see http://www.linuxphoto.org/html/dcb.html for details)
* PL_AHD: modified AHD interpolation (see http://sites.google.com/site/demosaicalgorithms/modified-dcraw
* for details).
* AFD: demosaicing through 5 pass median filter from PerfectRaw project.
* VCD: VCD interpolation.
* VCD_AHD: mixed demosaicing between VCD and AHD.
* LMMSE: LMMSE interpolation from PerfectRaw.
- *
- * NOTE: from GPL3 demosaic pack.
- *
* AMAZE: AMaZE interpolation and color aberration removal from RawTherapee project.
+ *
+ * NOTE: for libraw>=0.19 only
+ *
+ * DHT: DHT interpolation.
+ * AAHD: Enhanced Adaptative AHD interpolation.
*/
enum DecodingQuality
{
- // from original dcraw demosaic
BILINEAR = 0,
VNG = 1,
PPG = 2,
AHD = 3,
- // Extended demosaicing method from GPL2 demosaic pack
DCB = 4,
PL_AHD = 5,
AFD = 6,
VCD = 7,
VCD_AHD = 8,
LMMSE = 9,
- // Extended demosaicing methods from GPL3 demosaic pack
- AMAZE = 10
+ AMAZE = 10,
+ DHT = 11,
+ AAHD = 12
};
/** White balances alternatives
* NONE: no white balance used : reverts to standard daylight D65 WB.
* CAMERA: Use the camera embedded WB if available. Reverts to NONE if not.
* AUTO: Averages an auto WB on the entire image.
* CUSTOM: Let use set it's own temperature and green factor (later converted to RGBG factors).
* AERA: Let use an aera from image to average white balance (see whiteBalanceArea for details).
*/
enum WhiteBalance
{
NONE = 0,
CAMERA = 1,
AUTO = 2,
CUSTOM = 3,
AERA = 4
};
/** Noise Reduction method to apply before demosaicing
* NONR: No noise reduction.
* WAVELETSNR: wavelets correction to erase noise while preserving real detail. It's applied after interpolation.
* FBDDNR: Fake Before Demosaicing Denoising noise reduction. It's applied before interpolation.
* LINENR: CFA Line Denoise. It's applied after interpolation.
* IMPULSENR: Impulse Denoise. It's applied after interpolation.
*/
enum NoiseReduction
{
NONR = 0,
WAVELETSNR,
FBDDNR,
LINENR,
IMPULSENR
};
/** Input color profile used to decoded image
* NOINPUTCS: No input color profile.
* EMBEDDED: Use the camera profile embedded in RAW file if exist.
* CUSTOMINPUTCS: Use a custom input color space profile.
*/
enum InputColorSpace
{
NOINPUTCS = 0,
EMBEDDED,
CUSTOMINPUTCS
};
/** Output RGB color space used to decoded image
* RAWCOLOR: No output color profile (Linear RAW).
* SRGB: Use standard sRGB color space.
* ADOBERGB: Use standard Adobe RGB color space.
* WIDEGAMMUT: Use standard RGB Wide Gamut color space.
* PROPHOTO: Use standard RGB Pro Photo color space.
* CUSTOMOUTPUTCS: Use a custom workspace color profile.
*/
enum OutputColorSpace
{
RAWCOLOR = 0,
SRGB,
ADOBERGB,
WIDEGAMMUT,
PROPHOTO,
CUSTOMOUTPUTCS
};
/** Standard constructor with default settings
*/
RawDecodingSettings();
/** Equivalent to the copy constructor
*/
RawDecodingSettings& operator=(const RawDecodingSettings& prm);
/** Compare for equality
*/
bool operator==(const RawDecodingSettings& o) const;
/** Standard destructor
*/
virtual ~RawDecodingSettings();
/** Method to use a settings to optimize time loading, for exemple to compute image histogram
*/
void optimizeTimeLoading();
public:
/** If true, images with overblown channels are processed much more accurate,
* without 'pink clouds' (and blue highlights under tungsteen lamps).
*/
bool fixColorsHighlights;
/** If false, use a fixed white level, ignoring the image histogram.
*/
bool autoBrightness;
/** Turn on RAW file decoding in 16 bits per color per pixel instead 8 bits.
*/
bool sixteenBitsImage;
/** Half-size color image decoding (twice as fast as "enableRAWQuality").
* Turn on this option to reduce time loading to render histogram for example,
* no to render an image to screen.
*/
bool halfSizeColorImage;
/** White balance type to use. See WhiteBalance values for detail
*/
WhiteBalance whiteBalance;
/** The temperature and the green multiplier of the custom white balance
*/
int customWhiteBalance;
double customWhiteBalanceGreen;
/** Turn on RAW file decoding using RGB interpolation as four colors.
*/
bool RGBInterpolate4Colors;
/** For cameras with non-square pixels, do not stretch the image to its
* correct aspect ratio. In any case, this option guarantees that each
* output pixel corresponds to one RAW pixel.
*/
bool DontStretchPixels;
/** Unclip Highlight color level:
* 0 = Clip all highlights to solid white.
* 1 = Leave highlights unclipped in various shades of pink.
* 2 = Blend clipped and unclipped values together for a gradual
* fade to white.
* 3-9 = Reconstruct highlights. Low numbers favor whites; high numbers
* favor colors.
*/
int unclipColors;
/** RAW quality decoding factor value. See DecodingQuality values
* for details.
*/
DecodingQuality RAWQuality;
/** After interpolation, clean up color artifacts by repeatedly applying
* a 3x3 median filter to the R-G and B-G channels.
*/
int medianFilterPasses;
/** Noise reduction method to apply before demosaicing.
*/
NoiseReduction NRType;
/** Noise reduction threshold value. Null value disable NR. Range is between 100 and 1000.
* For IMPULSENR : set the amount of Luminance impulse denoise.
*/
int NRThreshold;
/** Turn on chromatic aberrations correction
+ * @deprecated does not work with libraw>=0.19
*/
bool enableCACorrection;
/** Magnification factor for Red and Blue layers
* - caMultiplier[0] = amount of correction on red-green axis.
* - caMultiplier[1] = amount of correction on blue-yellow axis.
* - Both values set to 0.0 = automatic CA correction.
+ * @deprecated does not work with libraw>=0.19
*/
double caMultiplier[2];
/** Brightness of output image.
*/
double brightness;
/** Turn on the black point setting to decode RAW image.
*/
bool enableBlackPoint;
/** Black Point value of output image.
*/
int blackPoint;
/** Turn on the white point setting to decode RAW image.
*/
bool enableWhitePoint;
/** White Point value of output image.
*/
int whitePoint;
/** The input color profile used to decoded RAW data. See OutputColorProfile
* values for details.
*/
InputColorSpace inputColorSpace;
/** Path to custom input ICC profile to define the camera's raw colorspace.
*/
QString inputProfile;
/** The output color profile used to decoded RAW data. See OutputColorProfile
* values for details.
*/
OutputColorSpace outputColorSpace;
/** Path to custom output ICC profile to define the color workspace.
*/
QString outputProfile;
/** Path to text file including dead pixel list.
*/
QString deadPixelMap;
/** Rectangle used to calculate the white balance by averaging the region of image.
*/
QRect whiteBalanceArea;
//-- Extended demosaicing settings ----------------------------------------------------------
/// For DCB interpolation.
/** Number of DCB median filtering correction passes.
* -1 : disable (default)
* 1-10 : DCB correction passes
*/
int dcbIterations;
/** Turn on the DCB interpolation with enhance interpolated colors.
*/
bool dcbEnhanceFl;
/// For VCD_AHD interpolation.
/** Turn on the EECI refine for VCD Demosaicing.
+ * @deprecated does not work with libraw>=0.19
*/
bool eeciRefine;
/** Use edge-sensitive median filtering for artifact supression after VCD demosaicing.
* 0 : disable (default)
* 1-10 : median filter passes.
+ * @deprecated does not work with libraw>=0.19
*/
int esMedPasses;
/** For IMPULSENR Noise reduction. Set the amount of Chrominance impulse denoise.
- Null value disable NR. Range is between 100 and 1000.
+ * Null value disable NR. Range is between 100 and 1000.
+ * @deprecated does not work with libraw>=0.19
*/
int NRChroThreshold;
/** Turn on the Exposure Correction before interpolation.
*/
bool expoCorrection;
/** Shift of Exposure Correction before interpolation in linear scale.
* Usable range is from 0.25 (darken image 1 stop : -2EV) to 8.0 (lighten ~1.5 photographic stops : +3EV).
*/
double expoCorrectionShift;
/** Amount of highlight preservation for exposure correction before interpolation in E.V.
* Usable range is from 0.0 (linear exposure shift, highlights may blow) to 1.0 (maximum highlights preservation)
* This settings can only take effect if expoCorrectionShift > 1.0.
*/
double expoCorrectionHighlight;
};
//! qDebug() stream operator. Writes settings @a s to the debug output in a nicely formatted way.
LIBKDCRAW_EXPORT QDebug operator<<(QDebug dbg, const RawDecodingSettings& s);
} // namespace KDcrawIface
#endif /* RAW_DECODING_SETTINGS_H */