diff --git a/core/dplugins/dimg/raw/dimgrawloader.cpp b/core/dplugins/dimg/raw/dimgrawloader.cpp index e02b786e85..064ed70152 100644 --- a/core/dplugins/dimg/raw/dimgrawloader.cpp +++ b/core/dplugins/dimg/raw/dimgrawloader.cpp @@ -1,355 +1,362 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2005-11-01 * Description : A digital camera RAW files loader for DImg * * Copyright (C) 2005-2019 by Gilles Caulier * Copyright (C) 2005-2012 by Marcel Wiesweg * * 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 "dimgrawloader.h" // C++ includes #include // Qt includes #include // Local includes #include "digikam_debug.h" #include "dimgloaderobserver.h" #include "digikam_globals.h" namespace DigikamRAWDImgPlugin { DImgRAWLoader::DImgRAWLoader(DImg* const image, const DRawDecoding& rawDecodingSettings) : DImgLoader(image), m_observer(nullptr), m_filter(nullptr) { m_decoderSettings = rawDecodingSettings.rawPrm; - m_filter = new RawProcessingFilter(this); + m_filter = new RawProcessingFilter(this); m_filter->setSettings(rawDecodingSettings); } +DImgRAWLoader::~DImgRAWLoader() +{ +} + bool DImgRAWLoader::load(const QString& filePath, DImgLoaderObserver* const observer) { m_observer = observer; readMetadata(filePath); DRawInfo dcrawIdentify; if (!DRawDecoder::rawFileIdentify(dcrawIdentify, filePath)) { return false; } if (m_loadFlags & LoadImageData) { int width, height, rgbmax; QByteArray data; // NOTE: Here, we don't check a possible embedded work-space color profile using // the method checkExifWorkingColorSpace() like with JPEG, PNG, and TIFF loaders, // because RAW file are always in linear mode. if (m_decoderSettings.outputColorSpace == DRawDecoderSettings::CUSTOMOUTPUTCS) { if (m_decoderSettings.outputProfile == IccProfile::sRGB().filePath()) { m_decoderSettings.outputColorSpace = DRawDecoderSettings::SRGB; } else if (m_decoderSettings.outputProfile == IccProfile::adobeRGB().filePath()) { m_decoderSettings.outputColorSpace = DRawDecoderSettings::ADOBERGB; } else if (m_decoderSettings.outputProfile == IccProfile::wideGamutRGB().filePath()) { m_decoderSettings.outputColorSpace = DRawDecoderSettings::WIDEGAMMUT; } else if (m_decoderSettings.outputProfile == IccProfile::proPhotoRGB().filePath()) { m_decoderSettings.outputColorSpace = DRawDecoderSettings::PROPHOTO; } else { // Specifying a custom output is broken somewhere. We use the extremely // wide gamut pro photo profile for 16bit (sRGB for 8bit) and convert afterwards. m_filter->setOutputProfile(IccProfile(m_decoderSettings.outputProfile)); if (m_decoderSettings.sixteenBitsImage) { m_decoderSettings.outputColorSpace = DRawDecoderSettings::PROPHOTO; } else { m_decoderSettings.outputColorSpace = DRawDecoderSettings::SRGB; } } } if (!DRawDecoder::decodeRAWImage(filePath, m_decoderSettings, data, width, height, rgbmax)) { loadingFailed(); return false; } if (!loadedFromRawData(data, width, height, rgbmax, observer)) { loadingFailed(); return false; } } else { imageWidth() = dcrawIdentify.imageSize.width(); imageHeight() = dcrawIdentify.imageSize.height(); } imageSetAttribute(QLatin1String("format"), QLatin1String("RAW")); imageSetAttribute(QLatin1String("originalColorModel"), DImg::COLORMODELRAW); imageSetAttribute(QLatin1String("originalBitDepth"), 16); imageSetAttribute(QLatin1String("originalSize"), dcrawIdentify.imageSize); return true; } bool DImgRAWLoader::checkToCancelWaitingData() { return (m_observer ? !m_observer->continueQuery(m_image) : false); } void DImgRAWLoader::setWaitingDataProgress(double value) { if (m_observer) { m_observer->progressInfo(m_image, value); } } -bool DImgRAWLoader::loadedFromRawData(const QByteArray& data, int width, int height, int rgbmax, - DImgLoaderObserver* const observer) +bool DImgRAWLoader::loadedFromRawData(const QByteArray& data, + int width, + int height, + int rgbmax, + DImgLoaderObserver* const observer) { int checkpoint = 0; if (m_decoderSettings.sixteenBitsImage) // 16 bits image { - uchar* image = new_failureTolerant(width, height, 8); + uchar* const image = new_failureTolerant(width, height, 8); if (!image) { qCWarning(DIGIKAM_DIMG_LOG_RAW) << "Failed to allocate memory for loading raw file"; return false; } unsigned short* dst = reinterpret_cast(image); uchar* src = (uchar*)data.data(); float fac = 65535.0 / rgbmax; checkpoint = 0; - for (int h = 0; h < height; ++h) + for (int h = 0 ; h < height ; ++h) { if (observer && h == checkpoint) { checkpoint += granularity(observer, height, 1.0); if (!observer->continueQuery(m_image)) { delete [] image; return false; } observer->progressInfo(m_image, 0.7 + 0.2 * (((float)h) / ((float)height))); } - for (int w = 0; w < width; ++w) + for (int w = 0 ; w < width ; ++w) { if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) // Intel { dst[0] = (unsigned short)((src[5] * 256 + src[4]) * fac); // Blue dst[1] = (unsigned short)((src[3] * 256 + src[2]) * fac); // Green dst[2] = (unsigned short)((src[1] * 256 + src[0]) * fac); // Red } else { dst[0] = (unsigned short)((src[4] * 256 + src[5]) * fac); // Blue dst[1] = (unsigned short)((src[2] * 256 + src[3]) * fac); // Green dst[2] = (unsigned short)((src[0] * 256 + src[1]) * fac); // Red } dst[3] = 0xFFFF; dst += 4; src += 6; } } // ---------------------------------------------------------- imageData() = (uchar*)image; } else // 8 bits image { - uchar* image = new_failureTolerant(width, height, 4); + uchar* const image = new_failureTolerant(width, height, 4); if (!image) { qCWarning(DIGIKAM_DIMG_LOG_RAW) << "Failed to allocate memory for loading raw file"; return false; } uchar* dst = image; uchar* src = (uchar*)data.data(); checkpoint = 0; - for (int h = 0; h < height; ++h) + for (int h = 0 ; h < height ; ++h) { if (observer && h == checkpoint) { checkpoint += granularity(observer, height, 1.0); if (!observer->continueQuery(m_image)) { delete [] image; return false; } observer->progressInfo(m_image, 0.7 + 0.2 * (((float)h) / ((float)height))); } - for (int w = 0; w < width; ++w) + for (int w = 0 ; w < width ; ++w) { // No need to adapt RGB components accordingly with rgbmax value because Raw engine // always return rgbmax to 255 in 8 bits/color/pixels. dst[0] = src[2]; // Blue dst[1] = src[1]; // Green dst[2] = src[0]; // Red dst[3] = 0xFF; // Alpha dst += 4; src += 3; } } // NOTE: if Color Management is not used here, output color space is in sRGB* color space. // Gamma and White balance are previously adjusted by Raw engine in 8 bits color depth. imageData() = image; } //---------------------------------------------------------- // Assign the right color-space profile. switch (m_decoderSettings.outputColorSpace) { case DRawDecoderSettings::SRGB: { imageSetIccProfile(IccProfile::sRGB()); break; } case DRawDecoderSettings::ADOBERGB: { imageSetIccProfile(IccProfile::adobeRGB()); break; } case DRawDecoderSettings::WIDEGAMMUT: { imageSetIccProfile(IccProfile::wideGamutRGB()); break; } case DRawDecoderSettings::PROPHOTO: { imageSetIccProfile(IccProfile::proPhotoRGB()); break; } case DRawDecoderSettings::CUSTOMOUTPUTCS: { imageSetIccProfile(IccProfile(m_decoderSettings.outputProfile)); break; } case DRawDecoderSettings::RAWCOLOR: { // No icc color-space profile to assign in RAW color mode. imageSetAttribute(QLatin1String("uncalibratedColor"), true); break; } } //---------------------------------------------------------- FilterAction action = m_filter->filterAction(); m_image->addFilterAction(action); imageWidth() = width; imageHeight() = height; imageSetAttribute(QLatin1String("rawDecodingSettings"), QVariant::fromValue(m_filter->settings())); imageSetAttribute(QLatin1String("rawDecodingFilterAction"), QVariant::fromValue(action)); // other attributes are set above return true; } void DImgRAWLoader::postProcess(DImgLoaderObserver* const observer) { if (m_filter->settings().postProcessingSettingsIsDirty()) { m_filter->setObserver(observer, 90, 100); m_filter->setupFilter(*m_image); m_filter->startFilterDirectly(); } } FilterAction DImgRAWLoader::filterAction() const { return m_filter->filterAction(); } bool DImgRAWLoader::save(const QString& /*filePath*/, DImgLoaderObserver* const /*observer=0*/) { // NOTE: RAW files are always Read only. return false; } bool DImgRAWLoader::hasAlpha() const { return false; } bool DImgRAWLoader::isReadOnly() const { return true; } bool DImgRAWLoader::sixteenBit() const { return m_decoderSettings.sixteenBitsImage; } } // namespace DigikamRAWDImgPlugin diff --git a/core/dplugins/dimg/raw/dimgrawloader.h b/core/dplugins/dimg/raw/dimgrawloader.h index 2d3a8e99cb..bafbf001ba 100644 --- a/core/dplugins/dimg/raw/dimgrawloader.h +++ b/core/dplugins/dimg/raw/dimgrawloader.h @@ -1,78 +1,82 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2005-11-01 * Description : A digital camera RAW files loader for DImg * framework using an external dcraw instance. * * Copyright (C) 2005-2019 by Gilles Caulier * Copyright (C) 2005-2012 by Marcel Wiesweg * * 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 DIGIKAM_DIMG_RAW_LOADER_H #define DIGIKAM_DIMG_RAW_LOADER_H // Local includes #include "dimg.h" #include "drawdecoder.h" #include "dimgloader.h" #include "drawdecoding.h" #include "digikam_export.h" #include "rawprocessingfilter.h" using namespace Digikam; namespace DigikamRAWDImgPlugin { class DIGIKAM_EXPORT DImgRAWLoader : public DRawDecoder, public DImgLoader { Q_OBJECT public: explicit DImgRAWLoader(DImg* const image, const DRawDecoding& rawDecodingSettings = DRawDecoding()); + ~DImgRAWLoader(); bool load(const QString& filePath, DImgLoaderObserver* const observer = nullptr) override; bool save(const QString& /*filePath*/, DImgLoaderObserver* const /*observer=0*/) override; bool hasAlpha() const override; bool isReadOnly() const override; bool sixteenBit() const override; void postProcess(DImgLoaderObserver* const observer); FilterAction filterAction() const; private: - bool loadedFromRawData(const QByteArray& data, int width, int height, int rgbmax, + bool loadedFromRawData(const QByteArray& data, + int width, + int height, + int rgbmax, DImgLoaderObserver* const observer); bool checkToCancelWaitingData() override; void setWaitingDataProgress(double value) override; private: DImgLoaderObserver* m_observer; RawProcessingFilter* m_filter; }; } // namespace DigikamRAWDImgPlugin #endif // DIGIKAM_DIMG_RAW_LOADER_H