Merge pull request #6806 from Lawrence37/browser-preview-applied-pparams
Enable black level and abstract profile preview in file browser
This commit is contained in:
commit
ec12c170a2
@ -229,7 +229,7 @@ void mappingToCurve(const std::vector<int> &mapping, std::vector<double> &curve)
|
||||
} // 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
|
||||
|
||||
@ -311,7 +311,7 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, St
|
||||
eSensorType sensor_type;
|
||||
double scale;
|
||||
int w = fw / skip, h = fh / skip;
|
||||
const std::unique_ptr<Thumbnail> thumb(Thumbnail::loadFromRaw(getFileName(), sensor_type, w, h, 1, false, observer, false, true));
|
||||
const std::unique_ptr<Thumbnail> thumb(Thumbnail::loadFromRaw(getFileName(), sensor_type, w, h, 1, false, observer, false, &rawParams, true));
|
||||
if (!thumb) {
|
||||
if (settings->verbose) {
|
||||
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
|
||||
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 };
|
||||
}
|
||||
|
@ -1037,7 +1037,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
|
||||
if (params->toneCurve.histmatching) {
|
||||
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) {
|
||||
|
@ -5645,7 +5645,7 @@ double ImProcFunctions::getAutoDistor(const Glib::ustring &fname, int thumb_size
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, sensorType, w_raw, h_raw, 1, 1.0, ColorTemp::DEFAULT_OBSERVER, FALSE);
|
||||
Thumbnail* raw = rtengine::Thumbnail::loadFromRaw(fname, sensorType, w_raw, h_raw, 1, 1.0, ColorTemp::DEFAULT_OBSERVER, FALSE, nullptr);
|
||||
|
||||
if (!raw) {
|
||||
delete thumb;
|
||||
|
@ -186,7 +186,7 @@ public:
|
||||
}
|
||||
void getAutoExpHistogram (LUTu & histogram, int& histcompr) 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;
|
||||
|
||||
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
|
||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <clocale>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
@ -519,7 +599,7 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType
|
||||
#define FISGREEN(filter,row,col) \
|
||||
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1 || !filter)
|
||||
|
||||
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, bool forHistogramMatching)
|
||||
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, const RAWParams *rawParams, bool forHistogramMatching)
|
||||
{
|
||||
RawImage *ri = new RawImage (fname);
|
||||
unsigned int tempImageNum = 0;
|
||||
@ -562,8 +642,15 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens
|
||||
tpp->greenMultiplier = ri->get_pre_mul (1);
|
||||
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];
|
||||
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
|
||||
|
||||
ri->pre_interpolate();
|
||||
@ -1434,6 +1521,50 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT
|
||||
|
||||
ipf.softLight(labView, params.softlight);
|
||||
|
||||
if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE) {
|
||||
const int GW = labView->W;
|
||||
const int GH = labView->H;
|
||||
std::unique_ptr<LabImage> provis;
|
||||
const float pres = 0.01f * params.icm.preser;
|
||||
if (pres > 0.f && params.icm.wprim != ColorManagementParams::Primaries::DEFAULT) {
|
||||
provis.reset(new LabImage(GW, GH));
|
||||
provis->CopyFrom(labView);
|
||||
}
|
||||
|
||||
const std::unique_ptr<Imagefloat> tmpImage1(new Imagefloat(GW, GH));
|
||||
|
||||
ipf.lab2rgb(*labView, *tmpImage1, params.icm.workingProfile);
|
||||
|
||||
const float gamtone = params.icm.workingTRCGamma;
|
||||
const float slotone = params.icm.workingTRCSlope;
|
||||
|
||||
int illum = toUnderlying(params.icm.will);
|
||||
const int prim = toUnderlying(params.icm.wprim);
|
||||
|
||||
Glib::ustring prof = params.icm.workingProfile;
|
||||
|
||||
cmsHTRANSFORM dummy = nullptr;
|
||||
int ill = 0;
|
||||
ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false);
|
||||
ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, illum, prim, dummy, false, true, true);
|
||||
|
||||
ipf.rgb2lab(*tmpImage1, *labView, params.icm.workingProfile);
|
||||
// labView and provis
|
||||
if(provis) {
|
||||
ipf.preserv(labView, provis.get(), GW, GH);
|
||||
}
|
||||
if(params.icm.fbw) {
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (int x = 0; x < GH; x++)
|
||||
for (int y = 0; y < GW; y++) {
|
||||
labView->a[x][y] = 0.f;
|
||||
labView->b[x][y] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (params.colorappearance.enabled) {
|
||||
CurveFactory::curveLightBrightColor (
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
void getDimensions (int& w, int& h, double& scaleFac);
|
||||
|
||||
static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false, bool forHistogramMatching = false);
|
||||
static Thumbnail* loadFromRaw (const Glib::ustring& fname, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, StandardObserver wbObserver, bool rotate, bool forHistogramMatching=false);
|
||||
static Thumbnail* loadFromRaw (const Glib::ustring& fname, 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);
|
||||
|
||||
void getCamWB (double& temp, double& green, StandardObserver observer);
|
||||
|
@ -782,7 +782,7 @@ private:
|
||||
|
||||
if (params.toneCurve.histmatching) {
|
||||
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) {
|
||||
|
@ -615,7 +615,7 @@ void BatchToolPanelCoordinator::optionsChanged ()
|
||||
initSession ();
|
||||
}
|
||||
|
||||
void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt)
|
||||
void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint)
|
||||
{
|
||||
|
||||
if (whoChangedIt != BATCHEDITOR && !blockedUpdate) {
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
void getCamWB (double& temp, double& green, rtengine::StandardObserver observer) override;
|
||||
|
||||
// thumbnaillistener interface
|
||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
|
||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint) override;
|
||||
|
||||
// batchpparamschangelistener interface
|
||||
void beginBatchPParamsChange(int numberOfEntries) override;
|
||||
|
@ -1995,7 +1995,7 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event)
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt)
|
||||
void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint)
|
||||
{
|
||||
|
||||
if (whoChangedIt != EDITOR) {
|
||||
|
@ -119,7 +119,7 @@ public:
|
||||
void clearParamChanges() override;
|
||||
|
||||
// thumbnaillistener interface
|
||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
|
||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint) override;
|
||||
|
||||
// HistoryBeforeLineListener
|
||||
void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) override;
|
||||
|
@ -89,14 +89,19 @@ void FileBrowserEntry::init ()
|
||||
ps = RTImage::createPixbufFromFile ("filetype-ps.png");
|
||||
}
|
||||
|
||||
void FileBrowserEntry::refreshThumbnailImage ()
|
||||
void FileBrowserEntry::refreshThumbnailImage(bool upgradeHint)
|
||||
{
|
||||
|
||||
if (!thumbnail) {
|
||||
return;
|
||||
}
|
||||
|
||||
thumbImageUpdater->add (this, &updatepriority, false, this);
|
||||
thumbImageUpdater->add (this, &updatepriority, upgradeHint, upgradeHint, this);
|
||||
}
|
||||
|
||||
void FileBrowserEntry::refreshThumbnailImage ()
|
||||
{
|
||||
refreshThumbnailImage(false);
|
||||
}
|
||||
|
||||
void FileBrowserEntry::refreshQuickThumbnailImage ()
|
||||
@ -108,7 +113,7 @@ void FileBrowserEntry::refreshQuickThumbnailImage ()
|
||||
|
||||
// Only make a (slow) processed preview if the picture has been edited at all
|
||||
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 ()
|
||||
@ -202,13 +207,13 @@ FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet ()
|
||||
return (static_cast<FileThumbnailButtonSet*>(buttonSet));
|
||||
}
|
||||
|
||||
void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt)
|
||||
void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint)
|
||||
{
|
||||
|
||||
if ( thumbnail->isQuick() ) {
|
||||
refreshQuickThumbnailImage ();
|
||||
} else {
|
||||
refreshThumbnailImage ();
|
||||
refreshThumbnailImage(upgradeHint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ class FileBrowserEntry final : public ThumbBrowserEntryBase,
|
||||
void updateCursor (int x, int y);
|
||||
void drawStraightenGuide (Cairo::RefPtr<Cairo::Context> c);
|
||||
void customBackBufferUpdate (Cairo::RefPtr<Cairo::Context> c) override;
|
||||
void refreshThumbnailImage(bool upgradeHint);
|
||||
|
||||
public:
|
||||
|
||||
@ -98,7 +99,7 @@ public:
|
||||
void getIconSize (int& w, int& h) const override;
|
||||
|
||||
// thumbnaillistener interface
|
||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt) override;
|
||||
void procParamsChanged (Thumbnail* thm, int whoChangedIt, bool upgradeHint) override;
|
||||
// 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); // inside gtk thread
|
||||
|
@ -45,12 +45,13 @@ public:
|
||||
|
||||
struct Job {
|
||||
Job(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade,
|
||||
ThumbImageUpdateListener* listener):
|
||||
bool forceUpgrade, ThumbImageUpdateListener* listener):
|
||||
tbe_(tbe),
|
||||
/*pparams_(pparams),
|
||||
height_(height), */
|
||||
priority_(priority),
|
||||
upgrade_(upgrade),
|
||||
force_upgrade_(forceUpgrade),
|
||||
listener_(listener)
|
||||
{}
|
||||
|
||||
@ -58,6 +59,7 @@ public:
|
||||
tbe_(nullptr),
|
||||
priority_(nullptr),
|
||||
upgrade_(false),
|
||||
force_upgrade_(false),
|
||||
listener_(nullptr)
|
||||
{}
|
||||
|
||||
@ -66,6 +68,7 @@ public:
|
||||
int height_;*/
|
||||
bool* priority_;
|
||||
bool upgrade_;
|
||||
bool force_upgrade_;
|
||||
ThumbImageUpdateListener* listener_;
|
||||
};
|
||||
|
||||
@ -153,8 +156,8 @@ public:
|
||||
Thumbnail* thm = j.tbe_->thumbnail;
|
||||
|
||||
if ( j.upgrade_ ) {
|
||||
if ( thm->isQuick() ) {
|
||||
img = thm->upgradeThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale);
|
||||
if ( thm->isQuick() || j.force_upgrade_ ) {
|
||||
img = thm->upgradeThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale, j.force_upgrade_);
|
||||
}
|
||||
} else {
|
||||
img = thm->processThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale);
|
||||
@ -191,7 +194,7 @@ ThumbImageUpdater::~ThumbImageUpdater() {
|
||||
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?
|
||||
if ( l == nullptr ) {
|
||||
@ -206,7 +209,8 @@ void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upg
|
||||
for ( ; i != impl_->jobs_.end(); ++i ) {
|
||||
if ( i->tbe_ == tbe &&
|
||||
i->listener_ == l &&
|
||||
i->upgrade_ == upgrade ) {
|
||||
i->upgrade_ == upgrade &&
|
||||
i->force_upgrade_ == forceUpgrade) {
|
||||
DEBUG("updating job %s", tbe->shortname.c_str());
|
||||
// we have one, update queue entry, will be picked up by thread when processed
|
||||
/*i->pparams_ = params;
|
||||
@ -218,7 +222,7 @@ void ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upg
|
||||
|
||||
// create a new job and append to queue
|
||||
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());
|
||||
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 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.
|
||||
|
@ -240,7 +240,7 @@ void Thumbnail::_generateThumbnailImage ()
|
||||
|
||||
if ( tpp == nullptr ) {
|
||||
quick = false;
|
||||
tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE);
|
||||
tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw));
|
||||
}
|
||||
|
||||
cfs.sensortype = sensorType;
|
||||
@ -387,7 +387,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu
|
||||
void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt)
|
||||
{
|
||||
for (size_t i = 0; i < listeners.size(); i++) {
|
||||
listeners[i]->procParamsChanged (this, whoChangedIt);
|
||||
listeners[i]->procParamsChanged (this, whoChangedIt, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -490,7 +490,7 @@ void Thumbnail::clearProcParams (int whoClearedIt)
|
||||
} // end of mutex lock
|
||||
|
||||
for (size_t i = 0; i < listeners.size(); i++) {
|
||||
listeners[i]->procParamsChanged (this, whoClearedIt);
|
||||
listeners[i]->procParamsChanged (this, whoClearedIt, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,8 +502,18 @@ bool Thumbnail::hasProcParams () const
|
||||
|
||||
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 =
|
||||
resetToDefault
|
||||
|| blackLevelChanged
|
||||
|| pparams->raw.expos != pp.raw.expos
|
||||
|| pparams->toneCurve != pp.toneCurve
|
||||
|| pparams->locallab != pp.locallab
|
||||
|| pparams->labCurve != pp.labCurve
|
||||
@ -538,6 +548,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh
|
||||
|| pparams->filmNegative != pp.filmNegative
|
||||
|| whoChangedIt == FILEBROWSER
|
||||
|| whoChangedIt == BATCHEDITOR;
|
||||
const bool upgradeHint = blackLevelChanged;
|
||||
|
||||
{
|
||||
MyMutex::MyLock lock(mutex);
|
||||
@ -573,7 +584,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh
|
||||
|
||||
if (needsReprocessing) {
|
||||
for (size_t i = 0; i < listeners.size(); i++) {
|
||||
listeners[i]->procParamsChanged (this, whoChangedIt);
|
||||
listeners[i]->procParamsChanged (this, whoChangedIt, upgradeHint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -747,12 +758,12 @@ rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::Pro
|
||||
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);
|
||||
|
||||
if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL ) {
|
||||
if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL && !forceUpgrade ) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,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
|
||||
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 getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h);
|
||||
void getOriginalSize (int& w, int& h) const;
|
||||
|
@ -24,5 +24,5 @@ class ThumbnailListener
|
||||
{
|
||||
public:
|
||||
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