Show black level adjustments in file browser
File browser thumbnails for raw images start with a minimally-processed images. These images are cached and image adjustments are applied on top. The black level is "baked-into" the cached image. Therefore, to reflect the black level adjustments in the thumbnail, one of two options are required: 1. Cache an image before the black level is applied and process the black level on top of this image. 2. Recreate the base image with the new black level and cache it. The first option yields better performance when the user changes the black level. However, it requires other base adjustments to be applied every time, such as the camera multipliers. The second option requires the base image to be recreated every time the black level is changed. This commit implements the second option. It minimizes code changes, and therefore possible bugs. It does add a performance penalty when the black level changes, but the black level adjustment is rarely used.
This commit is contained in:
parent
b68a6e9581
commit
6787c53c9b
@ -229,7 +229,7 @@ void mappingToCurve(const std::vector<int> &mapping, std::vector<double> &curve)
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, StandardObserver observer, std::vector<double> &outCurve)
|
void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, const procparams::RAWParams &rawParams, StandardObserver observer, std::vector<double> &outCurve)
|
||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, St
|
|||||||
eSensorType sensor_type;
|
eSensorType sensor_type;
|
||||||
double scale;
|
double scale;
|
||||||
int w = fw / skip, h = fh / skip;
|
int w = fw / skip, h = fh / skip;
|
||||||
std::unique_ptr<Thumbnail> thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, observer, false, true));
|
std::unique_ptr<Thumbnail> thumb(Thumbnail::loadFromRaw(getFileName(), rml, sensor_type, w, h, 1, false, observer, false, &rawParams, true));
|
||||||
if (!thumb) {
|
if (!thumb) {
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl;
|
std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl;
|
||||||
|
@ -167,7 +167,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for RAW files, compute a tone curve using histogram matching on the embedded thumbnail
|
// for RAW files, compute a tone curve using histogram matching on the embedded thumbnail
|
||||||
virtual void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, StandardObserver observer, std::vector<double> &outCurve)
|
virtual void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, const procparams::RAWParams &rawParams, StandardObserver observer, std::vector<double> &outCurve)
|
||||||
{
|
{
|
||||||
outCurve = { 0.0 };
|
outCurve = { 0.0 };
|
||||||
}
|
}
|
||||||
|
@ -793,7 +793,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
|||||||
|
|
||||||
if (params->toneCurve.histmatching) {
|
if (params->toneCurve.histmatching) {
|
||||||
if (!params->toneCurve.fromHistMatching) {
|
if (!params->toneCurve.fromHistMatching) {
|
||||||
imgsrc->getAutoMatchedToneCurve(params->icm, params->wb.observer, params->toneCurve.curve);
|
imgsrc->getAutoMatchedToneCurve(params->icm, params->raw, params->wb.observer, params->toneCurve.curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->toneCurve.autoexp) {
|
if (params->toneCurve.autoexp) {
|
||||||
|
@ -5645,7 +5645,7 @@ double ImProcFunctions::getAutoDistor(const Glib::ustring &fname, int thumb_size
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, ri, sensorType, w_raw, h_raw, 1, 1.0, ColorTemp::DEFAULT_OBSERVER, FALSE);
|
Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, ri, sensorType, w_raw, h_raw, 1, 1.0, ColorTemp::DEFAULT_OBSERVER, FALSE, nullptr);
|
||||||
|
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
delete thumb;
|
delete thumb;
|
||||||
|
@ -186,7 +186,7 @@ public:
|
|||||||
}
|
}
|
||||||
void getAutoExpHistogram (LUTu & histogram, int& histcompr) override;
|
void getAutoExpHistogram (LUTu & histogram, int& histcompr) override;
|
||||||
void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) override;
|
void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) override;
|
||||||
void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, StandardObserver observer, std::vector<double> &outCurve) override;
|
void getAutoMatchedToneCurve(const procparams::ColorManagementParams &cp, const procparams::RAWParams &rawParams, StandardObserver observer, std::vector<double> &outCurve) override;
|
||||||
DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) override;
|
DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) override;
|
||||||
|
|
||||||
void convertColorSpace(Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) override;
|
void convertColorSpace(Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) override;
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
@ -65,6 +67,84 @@ bool checkRawImageThumb (const rtengine::RawImage& raw_image)
|
|||||||
return raw_image.get_thumbOffset() + length <= raw_image.get_file()->size;
|
return raw_image.get_thumbOffset() + length <= raw_image.get_file()->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the black level adjustments in the processing parameters.
|
||||||
|
*
|
||||||
|
* @param cblack The original black levels that will be modified.
|
||||||
|
* @param sensorType Sensor type.
|
||||||
|
* @param rawParams Subset of processing parameters for raw data.
|
||||||
|
*/
|
||||||
|
void adjustBlackLevels(float cblack[4], rtengine::eSensorType sensorType, const rtengine::RAWParams *rawParams)
|
||||||
|
{
|
||||||
|
if (!rawParams) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<float, 4> black_adjust{0.f, 0.f, 0.f, 0.f};
|
||||||
|
|
||||||
|
switch (sensorType) {
|
||||||
|
case rtengine::eSensorType::ST_BAYER:
|
||||||
|
case rtengine::eSensorType::ST_FOVEON:
|
||||||
|
black_adjust[0] = static_cast<float>(rawParams->bayersensor.black1); // R
|
||||||
|
black_adjust[1] = static_cast<float>(rawParams->bayersensor.black0); // G1
|
||||||
|
black_adjust[2] = static_cast<float>(rawParams->bayersensor.black2); // B
|
||||||
|
black_adjust[3] = static_cast<float>(rawParams->bayersensor.black3); // G2
|
||||||
|
break;
|
||||||
|
case rtengine::eSensorType::ST_FUJI_XTRANS:
|
||||||
|
black_adjust[0] = static_cast<float>(rawParams->xtranssensor.blackred);
|
||||||
|
black_adjust[1] = static_cast<float>(rawParams->xtranssensor.blackgreen);
|
||||||
|
black_adjust[2] = static_cast<float>(rawParams->xtranssensor.blackblue);
|
||||||
|
black_adjust[3] = static_cast<float>(rawParams->xtranssensor.blackgreen);
|
||||||
|
break;
|
||||||
|
case rtengine::eSensorType::ST_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < black_adjust.size(); i++) {
|
||||||
|
cblack[i] = std::max(0.f, cblack[i] + black_adjust[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the new scale multipliers based on new black levels.
|
||||||
|
*
|
||||||
|
* @param scale_mul The original scale multipliers to be adjusted.
|
||||||
|
* @param pre_mul Pre-multipliers.
|
||||||
|
* @param c_black Updated black levels.
|
||||||
|
* @param isMono Is the image using mono demosaicing?
|
||||||
|
* @param ri Pointer to the raw image.
|
||||||
|
*/
|
||||||
|
void calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const float c_black[4], bool isMono, const rtengine::RawImage *ri)
|
||||||
|
{
|
||||||
|
std::array<float, 4> c_white;
|
||||||
|
|
||||||
|
for (int i = 0; i < c_white.size(); ++i) {
|
||||||
|
c_white[i] = static_cast<float>(ri->get_white(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMono || ri->get_colors() == 1) {
|
||||||
|
for (int c = 0; c < 4; c++) {
|
||||||
|
scale_mul[c] = 65535.f / (c_white[c] - c_black[c]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::array<float, 4> pre_mul;
|
||||||
|
|
||||||
|
for (int c = 0; c < 4; c++) {
|
||||||
|
pre_mul[c] = pre_mul_[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pre_mul[3] == 0) {
|
||||||
|
pre_mul[3] = pre_mul[1]; // G2 == G1
|
||||||
|
}
|
||||||
|
|
||||||
|
float maxpremul = std::max(std::max(std::max(pre_mul[0], pre_mul[1]), pre_mul[2]), pre_mul[3]);
|
||||||
|
|
||||||
|
for (int c = 0; c < 4; c++) {
|
||||||
|
scale_mul[c] = (pre_mul[c] / maxpremul) * 65535.f / (c_white[c] - c_black[c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void scale_colors (rtengine::RawImage *ri, float scale_mul[4], float cblack[4], bool multiThread)
|
void scale_colors (rtengine::RawImage *ri, float scale_mul[4], float cblack[4], bool multiThread)
|
||||||
{
|
{
|
||||||
@ -544,7 +624,7 @@ RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname)
|
|||||||
return rml;
|
return rml;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, bool forHistogramMatching)
|
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, const RAWParams *rawParams, bool forHistogramMatching)
|
||||||
{
|
{
|
||||||
RawImage *ri = new RawImage (fname);
|
RawImage *ri = new RawImage (fname);
|
||||||
unsigned int tempImageNum = 0;
|
unsigned int tempImageNum = 0;
|
||||||
@ -587,8 +667,15 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
|
|||||||
tpp->greenMultiplier = ri->get_pre_mul (1);
|
tpp->greenMultiplier = ri->get_pre_mul (1);
|
||||||
tpp->blueMultiplier = ri->get_pre_mul (2);
|
tpp->blueMultiplier = ri->get_pre_mul (2);
|
||||||
|
|
||||||
|
bool isMono =
|
||||||
|
(ri->getSensorType() == ST_FUJI_XTRANS &&
|
||||||
|
rawParams->xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) ||
|
||||||
|
(ri->getSensorType() == ST_BAYER &&
|
||||||
|
rawParams->bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO));
|
||||||
float pre_mul[4], scale_mul[4], cblack[4];
|
float pre_mul[4], scale_mul[4], cblack[4];
|
||||||
ri->get_colorsCoeff (pre_mul, scale_mul, cblack, false);
|
ri->get_colorsCoeff (pre_mul, scale_mul, cblack, false);
|
||||||
|
adjustBlackLevels(cblack, sensorType, rawParams);
|
||||||
|
calculate_scale_mul(scale_mul, pre_mul, cblack, isMono, ri);
|
||||||
scale_colors (ri, scale_mul, cblack, forHistogramMatching); // enable multithreading when forHistogramMatching is true
|
scale_colors (ri, scale_mul, cblack, forHistogramMatching); // enable multithreading when forHistogramMatching is true
|
||||||
|
|
||||||
ri->pre_interpolate();
|
ri->pre_interpolate();
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
void getDimensions (int& w, int& h, double& scaleFac);
|
void getDimensions (int& w, int& h, double& scaleFac);
|
||||||
|
|
||||||
static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false);
|
static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false);
|
||||||
static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, bool forHistogramMatching = false);
|
static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, const RAWParams *rawParams, bool forHistogramMatching = false);
|
||||||
static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool inspectorMode = false);
|
static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool inspectorMode = false);
|
||||||
static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname);
|
static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname);
|
||||||
|
|
||||||
|
@ -781,7 +781,7 @@ private:
|
|||||||
|
|
||||||
if (params.toneCurve.histmatching) {
|
if (params.toneCurve.histmatching) {
|
||||||
if (!params.toneCurve.fromHistMatching) {
|
if (!params.toneCurve.fromHistMatching) {
|
||||||
imgsrc->getAutoMatchedToneCurve(params.icm, params.wb.observer, params.toneCurve.curve);
|
imgsrc->getAutoMatchedToneCurve(params.icm, params.raw, params.wb.observer, params.toneCurve.curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.toneCurve.autoexp) {
|
if (params.toneCurve.autoexp) {
|
||||||
|
@ -615,7 +615,7 @@ void BatchToolPanelCoordinator::optionsChanged ()
|
|||||||
initSession ();
|
initSession ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt)
|
void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (whoChangedIt != BATCHEDITOR && !blockedUpdate) {
|
if (whoChangedIt != BATCHEDITOR && !blockedUpdate) {
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) override;
|
void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) override;
|
||||||
|
|
||||||
// thumbnaillistener interface
|
// thumbnaillistener interface
|
||||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
|
void procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint) override;
|
||||||
|
|
||||||
// batchpparamschangelistener interface
|
// batchpparamschangelistener interface
|
||||||
void beginBatchPParamsChange(int numberOfEntries) override;
|
void beginBatchPParamsChange(int numberOfEntries) override;
|
||||||
|
@ -1987,7 +1987,7 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt)
|
void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (whoChangedIt != EDITOR) {
|
if (whoChangedIt != EDITOR) {
|
||||||
|
@ -118,7 +118,7 @@ public:
|
|||||||
void clearParamChanges() override;
|
void clearParamChanges() override;
|
||||||
|
|
||||||
// thumbnaillistener interface
|
// thumbnaillistener interface
|
||||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
|
void procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint) override;
|
||||||
|
|
||||||
// HistoryBeforeLineListener
|
// HistoryBeforeLineListener
|
||||||
void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) override;
|
void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) override;
|
||||||
|
@ -90,14 +90,19 @@ FileBrowserEntry::~FileBrowserEntry ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBrowserEntry::refreshThumbnailImage ()
|
void FileBrowserEntry::refreshThumbnailImage(bool upgradeHint)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!thumbnail) {
|
if (!thumbnail) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbImageUpdater->add (this, &updatepriority, false, this);
|
thumbImageUpdater->add (this, &updatepriority, upgradeHint, upgradeHint, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileBrowserEntry::refreshThumbnailImage ()
|
||||||
|
{
|
||||||
|
refreshThumbnailImage(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBrowserEntry::refreshQuickThumbnailImage ()
|
void FileBrowserEntry::refreshQuickThumbnailImage ()
|
||||||
@ -109,7 +114,7 @@ void FileBrowserEntry::refreshQuickThumbnailImage ()
|
|||||||
|
|
||||||
// Only make a (slow) processed preview if the picture has been edited at all
|
// Only make a (slow) processed preview if the picture has been edited at all
|
||||||
bool upgrade_to_processed = (!options.internalThumbIfUntouched || thumbnail->isPParamsValid());
|
bool upgrade_to_processed = (!options.internalThumbIfUntouched || thumbnail->isPParamsValid());
|
||||||
thumbImageUpdater->add(this, &updatepriority, upgrade_to_processed, this);
|
thumbImageUpdater->add(this, &updatepriority, upgrade_to_processed, false, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBrowserEntry::calcThumbnailSize ()
|
void FileBrowserEntry::calcThumbnailSize ()
|
||||||
@ -203,13 +208,13 @@ FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet ()
|
|||||||
return (static_cast<FileThumbnailButtonSet*>(buttonSet));
|
return (static_cast<FileThumbnailButtonSet*>(buttonSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt)
|
void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( thumbnail->isQuick() ) {
|
if ( thumbnail->isQuick() ) {
|
||||||
refreshQuickThumbnailImage ();
|
refreshQuickThumbnailImage ();
|
||||||
} else {
|
} else {
|
||||||
refreshThumbnailImage ();
|
refreshThumbnailImage(upgradeHint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ class FileBrowserEntry final : public ThumbBrowserEntryBase,
|
|||||||
void updateCursor (int x, int y);
|
void updateCursor (int x, int y);
|
||||||
void drawStraightenGuide (Cairo::RefPtr<Cairo::Context> c);
|
void drawStraightenGuide (Cairo::RefPtr<Cairo::Context> c);
|
||||||
void customBackBufferUpdate (Cairo::RefPtr<Cairo::Context> c) override;
|
void customBackBufferUpdate (Cairo::RefPtr<Cairo::Context> c) override;
|
||||||
|
void refreshThumbnailImage(bool upgradeHint);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ public:
|
|||||||
void getIconSize (int& w, int& h) const override;
|
void getIconSize (int& w, int& h) const override;
|
||||||
|
|
||||||
// thumbnaillistener interface
|
// thumbnaillistener interface
|
||||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
|
void procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint) override;
|
||||||
// thumbimageupdatelistener interface
|
// thumbimageupdatelistener interface
|
||||||
void updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams) override;
|
void updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams) override;
|
||||||
void _updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams); // inside gtk thread
|
void _updateImage(rtengine::IImage8* img, double scale, const rtengine::procparams::CropParams& cropParams); // inside gtk thread
|
||||||
|
@ -45,12 +45,13 @@ public:
|
|||||||
|
|
||||||
struct Job {
|
struct Job {
|
||||||
Job(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade,
|
Job(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade,
|
||||||
ThumbImageUpdateListener* listener):
|
bool forceUpgrade, ThumbImageUpdateListener* listener):
|
||||||
tbe_(tbe),
|
tbe_(tbe),
|
||||||
/*pparams_(pparams),
|
/*pparams_(pparams),
|
||||||
height_(height), */
|
height_(height), */
|
||||||
priority_(priority),
|
priority_(priority),
|
||||||
upgrade_(upgrade),
|
upgrade_(upgrade),
|
||||||
|
force_upgrade_(forceUpgrade),
|
||||||
listener_(listener)
|
listener_(listener)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ public:
|
|||||||
tbe_(nullptr),
|
tbe_(nullptr),
|
||||||
priority_(nullptr),
|
priority_(nullptr),
|
||||||
upgrade_(false),
|
upgrade_(false),
|
||||||
|
force_upgrade_(false),
|
||||||
listener_(nullptr)
|
listener_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ public:
|
|||||||
int height_;*/
|
int height_;*/
|
||||||
bool* priority_;
|
bool* priority_;
|
||||||
bool upgrade_;
|
bool upgrade_;
|
||||||
|
bool force_upgrade_;
|
||||||
ThumbImageUpdateListener* listener_;
|
ThumbImageUpdateListener* listener_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,8 +156,8 @@ public:
|
|||||||
Thumbnail* thm = j.tbe_->thumbnail;
|
Thumbnail* thm = j.tbe_->thumbnail;
|
||||||
|
|
||||||
if ( j.upgrade_ ) {
|
if ( j.upgrade_ ) {
|
||||||
if ( thm->isQuick() ) {
|
if ( thm->isQuick() || j.force_upgrade_ ) {
|
||||||
img = thm->upgradeThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale);
|
img = thm->upgradeThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale, j.force_upgrade_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
img = thm->processThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale);
|
img = thm->processThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale);
|
||||||
@ -191,7 +194,7 @@ ThumbImageUpdater::~ThumbImageUpdater() {
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l)
|
void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, bool forceUpgrade, ThumbImageUpdateListener* l)
|
||||||
{
|
{
|
||||||
// nobody listening?
|
// nobody listening?
|
||||||
if ( l == nullptr ) {
|
if ( l == nullptr ) {
|
||||||
@ -206,7 +209,8 @@ void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upg
|
|||||||
for ( ; i != impl_->jobs_.end(); ++i ) {
|
for ( ; i != impl_->jobs_.end(); ++i ) {
|
||||||
if ( i->tbe_ == tbe &&
|
if ( i->tbe_ == tbe &&
|
||||||
i->listener_ == l &&
|
i->listener_ == l &&
|
||||||
i->upgrade_ == upgrade ) {
|
i->upgrade_ == upgrade &&
|
||||||
|
i->force_upgrade_ == forceUpgrade) {
|
||||||
DEBUG("updating job %s", tbe->shortname.c_str());
|
DEBUG("updating job %s", tbe->shortname.c_str());
|
||||||
// we have one, update queue entry, will be picked up by thread when processed
|
// we have one, update queue entry, will be picked up by thread when processed
|
||||||
/*i->pparams_ = params;
|
/*i->pparams_ = params;
|
||||||
@ -218,7 +222,7 @@ void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upg
|
|||||||
|
|
||||||
// create a new job and append to queue
|
// create a new job and append to queue
|
||||||
DEBUG("queueing job %s", tbe->shortname.c_str());
|
DEBUG("queueing job %s", tbe->shortname.c_str());
|
||||||
impl_->jobs_.push_back(Impl::Job(tbe, priority, upgrade, l));
|
impl_->jobs_.push_back(Impl::Job(tbe, priority, upgrade, forceUpgrade, l));
|
||||||
|
|
||||||
DEBUG("adding run request %s", tbe->shortname.c_str());
|
DEBUG("adding run request %s", tbe->shortname.c_str());
|
||||||
impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob));
|
impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob));
|
||||||
|
@ -78,7 +78,7 @@ public:
|
|||||||
* @param priority if \c true then run as soon as possible
|
* @param priority if \c true then run as soon as possible
|
||||||
* @param l listener waiting on update
|
* @param l listener waiting on update
|
||||||
*/
|
*/
|
||||||
void add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l);
|
void add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, bool forceUpgrade, ThumbImageUpdateListener* l);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove jobs associated with listener \c l.
|
* @brief Remove jobs associated with listener \c l.
|
||||||
|
@ -173,7 +173,7 @@ void Thumbnail::_generateThumbnailImage ()
|
|||||||
|
|
||||||
if ( tpp == nullptr ) {
|
if ( tpp == nullptr ) {
|
||||||
quick = false;
|
quick = false;
|
||||||
tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE);
|
tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
cfs.sensortype = sensorType;
|
cfs.sensortype = sensorType;
|
||||||
@ -334,7 +334,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu
|
|||||||
void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt)
|
void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < listeners.size(); i++) {
|
for (size_t i = 0; i < listeners.size(); i++) {
|
||||||
listeners[i]->procParamsChanged (this, whoChangedIt);
|
listeners[i]->procParamsChanged (this, whoChangedIt, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +437,7 @@ void Thumbnail::clearProcParams (int whoClearedIt)
|
|||||||
} // end of mutex lock
|
} // end of mutex lock
|
||||||
|
|
||||||
for (size_t i = 0; i < listeners.size(); i++) {
|
for (size_t i = 0; i < listeners.size(); i++) {
|
||||||
listeners[i]->procParamsChanged (this, whoClearedIt);
|
listeners[i]->procParamsChanged (this, whoClearedIt, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,8 +449,17 @@ bool Thumbnail::hasProcParams () const
|
|||||||
|
|
||||||
void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoChangedIt, bool updateCacheNow, bool resetToDefault)
|
void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoChangedIt, bool updateCacheNow, bool resetToDefault)
|
||||||
{
|
{
|
||||||
|
const bool blackLevelChanged =
|
||||||
|
pparams->raw.bayersensor.black0 != pp.raw.bayersensor.black0
|
||||||
|
|| pparams->raw.bayersensor.black1 != pp.raw.bayersensor.black1
|
||||||
|
|| pparams->raw.bayersensor.black2 != pp.raw.bayersensor.black2
|
||||||
|
|| pparams->raw.bayersensor.black3 != pp.raw.bayersensor.black3
|
||||||
|
|| pparams->raw.xtranssensor.blackred != pp.raw.xtranssensor.blackred
|
||||||
|
|| pparams->raw.xtranssensor.blackgreen != pp.raw.xtranssensor.blackgreen
|
||||||
|
|| pparams->raw.xtranssensor.blackblue != pp.raw.xtranssensor.blackblue;
|
||||||
const bool needsReprocessing =
|
const bool needsReprocessing =
|
||||||
resetToDefault
|
resetToDefault
|
||||||
|
|| blackLevelChanged
|
||||||
|| pparams->toneCurve != pp.toneCurve
|
|| pparams->toneCurve != pp.toneCurve
|
||||||
|| pparams->locallab != pp.locallab
|
|| pparams->locallab != pp.locallab
|
||||||
|| pparams->labCurve != pp.labCurve
|
|| pparams->labCurve != pp.labCurve
|
||||||
@ -485,6 +494,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh
|
|||||||
|| pparams->filmNegative != pp.filmNegative
|
|| pparams->filmNegative != pp.filmNegative
|
||||||
|| whoChangedIt == FILEBROWSER
|
|| whoChangedIt == FILEBROWSER
|
||||||
|| whoChangedIt == BATCHEDITOR;
|
|| whoChangedIt == BATCHEDITOR;
|
||||||
|
const bool upgradeHint = blackLevelChanged;
|
||||||
|
|
||||||
{
|
{
|
||||||
MyMutex::MyLock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
@ -520,7 +530,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh
|
|||||||
|
|
||||||
if (needsReprocessing) {
|
if (needsReprocessing) {
|
||||||
for (size_t i = 0; i < listeners.size(); i++) {
|
for (size_t i = 0; i < listeners.size(); i++) {
|
||||||
listeners[i]->procParamsChanged (this, whoChangedIt);
|
listeners[i]->procParamsChanged (this, whoChangedIt, upgradeHint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -694,12 +704,12 @@ rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::Pro
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale)
|
rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale, bool forceUpgrade)
|
||||||
{
|
{
|
||||||
|
|
||||||
MyMutex::MyLock lock(mutex);
|
MyMutex::MyLock lock(mutex);
|
||||||
|
|
||||||
if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL ) {
|
if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL && !forceUpgrade ) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ public:
|
|||||||
|
|
||||||
// unsigned char* getThumbnailImage (int &w, int &h, int fixwh=1); // fixwh = 0: fix w and calculate h, =1: fix h and calculate w
|
// unsigned char* getThumbnailImage (int &w, int &h, int fixwh=1); // fixwh = 0: fix w and calculate h, =1: fix h and calculate w
|
||||||
rtengine::IImage8* processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale);
|
rtengine::IImage8* processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale);
|
||||||
rtengine::IImage8* upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale);
|
rtengine::IImage8* upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale, bool forceUpgrade);
|
||||||
void getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams = nullptr);
|
void getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams = nullptr);
|
||||||
void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h);
|
void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h);
|
||||||
void getOriginalSize (int& w, int& h) const;
|
void getOriginalSize (int& w, int& h) const;
|
||||||
|
@ -24,5 +24,5 @@ class ThumbnailListener
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ThumbnailListener() = default;
|
virtual ~ThumbnailListener() = default;
|
||||||
virtual void procParamsChanged(Thumbnail* thm, int whoChangedIt) = 0;
|
virtual void procParamsChanged(Thumbnail* thm, int whoChangedIt, bool upgradeHint) = 0;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user