Version: (using KDE KDE 3.4.1) Installed from: Solaris Packages while converting raw images to jpeg or whatever, is it possible to copy exif data from the raw image to the target (if output format supports storing exif data)
This is can be done using Exiv2 library. future version 0.9.2 will support a lot of TIFF/EP file formats used by major RAW files (NEF, CR2, etc.) Gilles Caulier
SVN commit 583806 by cgilles: kipi-plugins from trunk : Raw Converter : complete rewrite raw converter core ! - Removing old external sub program to invoque dcraw instance. - Using multithreaded implementation based on JPEGLossLess plugin core. - New dcraw interface to invoque dcraw binary program directly using a separate thread. - New dcraw settings widget common to batch and single version of converter. - The new implementation always give RAW file thumbnails in batch converter dialog. - New save target file settings widget common to batch and single version of converter. - New option to convert raw file based on last dcraw version avaialble (8.38) and similar than digiKam dcraw setup : * quality decoding (Bilinear, AHD, VND). * Interpolation as 4 colors. * Use super CCD sensor. * Auto Color balance. * Camera whithe balance. * Noise reduction settings. * Highlight clipping (solid white, Unclip, Recontruct using level) * Brighness adjustements. - Removing obsolete dcraw options comming from dcraw v. 8.xx : red/blue adjustments. - Code simplification and optimisations about compression level with TIFF output files. - Fresh screenshot: http://digikam3rdparty.free.fr/Screenshots/newkipirawconverter.png NOTES : - The code have been tested with the last dcraw release from today. Please take a care if you use an with old version. - The code is in beta. Please take a care. TODO : - Metadata preservation using Exiv2 library. - Embedding sRGB ICC color profile in JPEG/PNG/TIFF files. - More output color space, like Adobe, and WideGamut. - dcraw version detection. - Fix dcraw decoding canceling to stop dcraw imediatly (actually the implementation wait until the current raw file decoding is done). - Fix the dcraw interface class to use bach and single converter plugin at the same time. CCMAIL: kde-imaging@kde.org BUG: 128394 CCBUGS: 107905 M +4 -12 Makefile.am A actions.h [License: GPL] A actionthread.cpp [License: GPL] A actionthread.h [License: GPL] M +323 -348 batchdialog.cpp M +30 -73 batchdialog.h M +3 -2 clistviewitem.h D dcrawprocess.cpp A dcrawsettingswidget.cpp [License: GPL] A dcrawsettingswidget.h [License: GPL] A dcrawutils.cpp [POSSIBLY UNSAFE: popen,scanf] [License: GPL] A dcrawutils.h [License: GPL] D kipidcrawclient.1 A mtqueue.h [License: GPL] D processcontroller.cpp D processcontroller.h A savesettingswidget.cpp [License: GPL] A savesettingswidget.h [License: GPL] M +261 -220 singledialog.cpp M +29 -36 singledialog.h
SVN commit 583913 by cgilles: kipi-plugins from trunk : Raw Converter : - Store icc color space profile used to decode RAW data into target image (JPEG, PNG, TIFF) - 4 icc color profile files (comming from krita repository) are available : SRGB, ADOBERGB, WIDEGAMUT, PROPHOTO Actually, the implementation only use SRGB color space CCBUGS: 107905 M +3 -2 Makefile.am M +78 -2 dcrawutils.cpp M +20 -4 dcrawutils.h A profiles (directory) A profiles/Makefile.am AM profiles/adobergb.icm AM profiles/prophoto.icm AM profiles/srgb.icm AM profiles/widegamut.icm --- trunk/extragear/libs/kipi-plugins/rawconverter/Makefile.am #583912:583913 @@ -1,14 +1,15 @@ INCLUDES = -I$(top_srcdir)/kipi-plugins/common/include \ $(LIBKIPI_CFLAGS) $(all_includes) METASOURCES = AUTO +SUBDIRS = profiles # Install this plugin in the KDE modules directory kde_module_LTLIBRARIES = kipiplugin_rawconverter.la kipiplugin_rawconverter_la_DEPENDENCIES = $(LIBKIPI_LIBS_DEP) # Srcs for the plugin kipiplugin_rawconverter_la_SOURCES = plugin_rawconverter.cpp dcrawutils.cpp savesettingswidget.cpp \ - batchdialog.cpp actionthread.cpp dcrawsettingswidget.cpp \ - singledialog.cpp previewwidget.cpp + batchdialog.cpp actionthread.cpp dcrawsettingswidget.cpp \ + singledialog.cpp previewwidget.cpp iccjpeg.c # Libs needed by the plugin kipiplugin_rawconverter_la_LIBADD = -ljpeg -lpng $(LIB_TIFF) $(LIBKIPI_LIBS) $(LIB_KIO) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawutils.cpp #583912:583913 @@ -38,6 +38,7 @@ #include <tiffio.h> #include <tiffvers.h> #include <png.h> +#include "iccjpeg.h" } // Qt Includes. @@ -50,6 +51,7 @@ #include <kdebug.h> #include <klocale.h> #include <kprocess.h> +#include <kstandarddirs.h> // KIPI include files @@ -355,6 +357,7 @@ pclose( f ); + QByteArray ICCColorProfile = getICCProfilFromFile(rawDecodingSettings.outputColorSpace); QString soft = QString("Kipi Raw Converter v.%1").arg(kipi_version); QFileInfo fi(filePath); destPath = fi.dirPath(true) + QString("/") + ".kipi-rawconverter-tmp-" @@ -380,7 +383,8 @@ int row_stride; JSAMPROW row_pointer[1]; - + + // Init JPEG compressor. cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, f); @@ -395,8 +399,13 @@ cinfo.comp_info[0].v_samp_factor = 1; jpeg_set_quality(&cinfo, 100, true); jpeg_start_compress(&cinfo, true); + + // Write ICC color profil. + if (!ICCColorProfile.isEmpty()) + write_icc_profile (&cinfo, (JOCTET *)ICCColorProfile.data(), ICCColorProfile.size()); + + // Write image data row_stride = cinfo.image_width * 3; - while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = imgData + (cinfo.next_scanline * row_stride); @@ -435,6 +444,14 @@ png_set_sBIT(png_ptr, info_ptr, &sig_bit); png_set_compression_level(png_ptr, 9); + // Write ICC profil. + if (!ICCColorProfile.isEmpty()) + { + png_set_iCCP(png_ptr, info_ptr, "icc", PNG_COMPRESSION_TYPE_BASE, + ICCColorProfile.data(), ICCColorProfile.size()); + } + + QString libpngver(PNG_HEADER_VERSION_STRING); libpngver.replace('\n', ' '); soft.append(QString(" (%1)").arg(libpngver)); @@ -503,6 +520,16 @@ soft.append(QString(" ( %1 )").arg(libtiffver)); TIFFSetField(tif, TIFFTAG_SOFTWARE, (const char*)soft.ascii()); + // Write ICC profil. + if (!ICCColorProfile.isEmpty()) + { +#if defined(TIFFTAG_ICCPROFILE) + TIFFSetField(tif, TIFFTAG_ICCPROFILE, (uint32)ICCColorProfile.size(), + (uchar *)ICCColorProfile.data()); +#endif + } + + // Write image data for (y = 0; y < height; y++) { data = imgData + (y * width * 3); @@ -541,4 +568,53 @@ return true; } +QByteArray DcrawUtils::getICCProfilFromFile(RawDecodingSettings::OutputColorSpace colorSpace) +{ + QString filePath; + KGlobal::dirs()->addResourceType("profiles", KGlobal::dirs()->kde_default("data") + "kipiplugin_rawconverter/profiles"); + + switch(colorSpace) + { + case RawDecodingSettings::SRGB: + { + filePath = KGlobal::dirs()->findResourceDir("profiles", "srgb.icm"); + filePath.append("srgb.icm"); + break; + } + case RawDecodingSettings::ADOBERGB: + { + filePath = KGlobal::dirs()->findResourceDir("profiles", "adobergb.icm"); + filePath.append("adobergb.icm"); + break; + } + case RawDecodingSettings::WIDEGAMMUT: + { + filePath = KGlobal::dirs()->findResourceDir("profiles", "widegamut.icm"); + filePath.append("widegamut.icm"); + break; + } + case RawDecodingSettings::PROPHOTO: + { + filePath = KGlobal::dirs()->findResourceDir("profiles", "prophoto.icm"); + filePath.append("prophoto.icm"); + break; + } + default: + break; + } + + if ( filePath.isEmpty() ) + return QByteArray(); + + QFile file(filePath); + if ( !file.open(IO_ReadOnly) ) + return QByteArray(); + + QByteArray data(file.size()); + QDataStream stream( &file ); + stream.readRawBytes(data.data(), data.size()); + file.close(); + return data; +} + } // namespace KIPIRawConverterPlugin --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawutils.h #583912:583913 @@ -23,6 +23,7 @@ // Qt Includes. +#include <qcstring.h> #include <qstring.h> #include <qimage.h> @@ -49,6 +50,15 @@ PNG }; + enum OutputColorSpace + { + RAWCOLOR = 0, + SRGB, + ADOBERGB, + WIDEGAMMUT, + PROPHOTO + }; + RawDecodingSettings() { enableNoiseReduction = false; @@ -59,6 +69,7 @@ RAWQuality = BILINEAR; outputFileFormat = PNG; + outputColorSpace = SRGB; RGBInterpolate4Colors = false; SuperCCDsecondarySensor = false; @@ -94,10 +105,10 @@ 0 = Clip all highlights to solid white. 1 = Leave highlights unclipped in various shades of pink. 2-9 = Reconstruct highlights. Low numbers favor whites; high numbers favor colors.*/ - int unclipColors; + int unclipColors; - /** RAW quality decoding factor value. */ - int RAWQuality; + /** RAW quality decoding factor value. See DecodingQuality values for details. */ + DecodingQuality RAWQuality; /** RAW file decoding using bilateral filter to reduce noise. This is '-B sigma_domain sigma_range' dcraw option to smooth noise while preserving edges. sigma_domain is in units of pixels, while @@ -114,7 +125,10 @@ float brightness; /** The file format used to convert RAW data. See OutputFormat values for details. */ - int outputFileFormat; + OutputFormat outputFileFormat; + + /** The output color space used to decoded RAW data. See OutputColorSpace values for details. */ + OutputColorSpace outputColorSpace; }; class DcrawUtils @@ -140,6 +154,8 @@ static bool decodeRAWImage(const QString& filePath, QString& destPath, RawDecodingSettings rawDecodingSettings); + static QByteArray getICCProfilFromFile(RawDecodingSettings::OutputColorSpace colorSpace); + }; } // namespace KIPIRawConverterPlugin ** trunk/extragear/libs/kipi-plugins/rawconverter/profiles/adobergb.icm #property svn:mime-type + application/octet-stream ** trunk/extragear/libs/kipi-plugins/rawconverter/profiles/prophoto.icm #property svn:mime-type + application/octet-stream ** trunk/extragear/libs/kipi-plugins/rawconverter/profiles/srgb.icm #property svn:mime-type + application/octet-stream ** trunk/extragear/libs/kipi-plugins/rawconverter/profiles/widegamut.icm #property svn:mime-type + application/octet-stream
SVN commit 583928 by cgilles: kipi-plugins from trunk : Raw Converter : new option to set the output color space to use during RAW image data decoding : SRGB, ADOBERGB, WIDEGAMUT, PROPHOTO CCBUGS: 107905 M +7 -1 batchdialog.cpp M +28 -0 dcrawsettingswidget.cpp M +2 -0 dcrawsettingswidget.h M +6 -0 dcrawutils.cpp M +8 -1 singledialog.cpp --- trunk/extragear/libs/kipi-plugins/rawconverter/batchdialog.cpp #583927:583928 @@ -243,7 +243,11 @@ m_saveSettingsBox->setConflictRule( (SaveSettingsWidget::ConflictRule)config.readNumEntry("Conflict", (int)(SaveSettingsWidget::OVERWRITE))); - + + m_decodingSettingsBox->setOutputColorSpace( + (RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space", + (int)(RawDecodingSettings::SRGB))); + resize(configDialogSize(config, QString("Batch Raw Converter Dialog"))); } @@ -262,6 +266,7 @@ config.writeEntry("Sigma Domain", m_decodingSettingsBox->sigmaDomain()); config.writeEntry("Sigma Range", m_decodingSettingsBox->sigmaRange()); config.writeEntry("Decoding Quality", (int)m_decodingSettingsBox->quality()); + config.writeEntry("Output Color Space", (int)m_decodingSettingsBox->outputColorSpace()); config.writeEntry("Output Format", (int)m_saveSettingsBox->fileFormat()); config.writeEntry("Conflict", (int)m_saveSettingsBox->conflictRule()); @@ -315,6 +320,7 @@ rawDecodingSettings.NRSigmaRange = m_decodingSettingsBox->sigmaRange(); rawDecodingSettings.RAWQuality = m_decodingSettingsBox->quality(); rawDecodingSettings.outputFileFormat = m_saveSettingsBox->fileFormat(); + rawDecodingSettings.outputColorSpace = m_decodingSettingsBox->outputColorSpace(); m_thread->setRawDecodingSettings(rawDecodingSettings); processOne(); --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawsettingswidget.cpp #583927:583928 @@ -64,6 +64,8 @@ unclipColorComboBox = 0; reconstructLabel = 0; reconstructSpinBox = 0; + outputColorSpaceLabel = 0; + outputColorSpaceComboBox = 0; } QLabel *brightnessLabel; @@ -72,9 +74,11 @@ QLabel *NRSigmaDomainlabel; QLabel *unclipColorLabel; QLabel *reconstructLabel; + QLabel *outputColorSpaceLabel; QComboBox *RAWQualityComboBox; QComboBox *unclipColorComboBox; + QComboBox *outputColorSpaceComboBox; QCheckBox *cameraWBCheckBox; QCheckBox *fourColorCheckBox; @@ -237,6 +241,20 @@ // --------------------------------------------------------------- + d->outputColorSpaceLabel = new QLabel(i18n("Color space:"), this); + d->outputColorSpaceComboBox = new QComboBox( false, this ); + d->outputColorSpaceComboBox->insertItem( i18n("Raw (linear)"), 0 ); + d->outputColorSpaceComboBox->insertItem( i18n("sRGB"), 1 ); + d->outputColorSpaceComboBox->insertItem( i18n("Adobe RGB"), 2 ); + d->outputColorSpaceComboBox->insertItem( i18n("Wide Gamut"), 3 ); + d->outputColorSpaceComboBox->insertItem( i18n("Pro-Photo"), 4 ); + QWhatsThis::add( d->outputColorSpaceComboBox, i18n("<p><b>Color space</b><p>" + "Select here the output color space used to decode RAW data.<p>")); + settingsBoxLayout->addMultiCellWidget(d->outputColorSpaceLabel, 11, 11, 0, 0); + settingsBoxLayout->addMultiCellWidget(d->outputColorSpaceComboBox, 11, 11, 1, 1); + + // --------------------------------------------------------------- + connect(d->unclipColorComboBox, SIGNAL(activated(int)), this, SLOT(slotUnclipColorActivated(int))); @@ -333,6 +351,11 @@ } } +RawDecodingSettings::OutputColorSpace DcrawSettingsWidget::outputColorSpace() +{ + return (RawDecodingSettings::OutputColorSpace)(d->outputColorSpaceComboBox->currentItem()); +} + bool DcrawSettingsWidget::useNoiseReduction() { return d->enableNoiseReduction->isChecked(); @@ -413,6 +436,11 @@ } } +void DcrawSettingsWidget::setOutputColorSpace(RawDecodingSettings::OutputColorSpace c) +{ + d->outputColorSpaceComboBox->setCurrentItem((int)c); +} + void DcrawSettingsWidget::setNoiseReduction(bool b) { d->enableNoiseReduction->setChecked(b); --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawsettingswidget.h #583927:583928 @@ -53,6 +53,7 @@ double sigmaDomain(); double sigmaRange(); RawDecodingSettings::DecodingQuality quality(); + RawDecodingSettings::OutputColorSpace outputColorSpace(); void setCameraWB(bool b); void setAutoColorBalance(bool b); @@ -64,6 +65,7 @@ void setSigmaDomain(double b); void setSigmaRange(double b); void setQuality(RawDecodingSettings::DecodingQuality q); + void setOutputColorSpace(RawDecodingSettings::OutputColorSpace c); private slots: --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawutils.cpp #583927:583928 @@ -272,6 +272,7 @@ // -b : Change the output brightness. // -q : Use simple bilinear interpolation for quick results // -B : Use bilateral filter to smooth noise while preserving edges. + // -o : Select the output colorspace used to decode RAW data. command = "dcraw"; command += " -c "; @@ -315,6 +316,11 @@ command += NRSigmaRange.setNum(rawDecodingSettings.NRSigmaRange); command += " "; } + + command += "-o "; + QCString colorSpace; + command += colorSpace.setNum(rawDecodingSettings.outputColorSpace); + command += " "; command += QFile::encodeName( KProcess::quote( filePath ) ); --- trunk/extragear/libs/kipi-plugins/rawconverter/singledialog.cpp #583927:583928 @@ -238,6 +238,10 @@ (SaveSettingsWidget::ConflictRule)config.readNumEntry("Conflict", (int)(SaveSettingsWidget::OVERWRITE))); + m_decodingSettingsBox->setOutputColorSpace( + (RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space", + (int)(RawDecodingSettings::SRGB))); + resize(configDialogSize(config, QString("Single Raw Converter Dialog"))); } @@ -256,6 +260,7 @@ config.writeEntry("Sigma Domain", m_decodingSettingsBox->sigmaDomain()); config.writeEntry("Sigma Range", m_decodingSettingsBox->sigmaRange()); config.writeEntry("Decoding Quality", (int)m_decodingSettingsBox->quality()); + config.writeEntry("Output Color Space", (int)m_decodingSettingsBox->outputColorSpace()); config.writeEntry("Output Format", (int)m_saveSettingsBox->fileFormat()); config.writeEntry("Conflict", (int)m_saveSettingsBox->conflictRule()); @@ -282,6 +287,7 @@ rawDecodingSettings.NRSigmaDomain = m_decodingSettingsBox->sigmaDomain(); rawDecodingSettings.NRSigmaRange = m_decodingSettingsBox->sigmaRange(); rawDecodingSettings.RAWQuality = m_decodingSettingsBox->quality(); + rawDecodingSettings.outputColorSpace = m_decodingSettingsBox->outputColorSpace(); m_thread->setRawDecodingSettings(rawDecodingSettings); @@ -306,7 +312,8 @@ rawDecodingSettings.NRSigmaRange = m_decodingSettingsBox->sigmaRange(); rawDecodingSettings.RAWQuality = m_decodingSettingsBox->quality(); rawDecodingSettings.outputFileFormat = m_saveSettingsBox->fileFormat(); - + rawDecodingSettings.outputColorSpace = m_decodingSettingsBox->outputColorSpace(); + m_thread->setRawDecodingSettings(rawDecodingSettings); KURL::List oneFile;
SVN commit 584176 by cgilles: kipi-plugins from trunk : Raw Converter : dcraw version detection at startup. Code come from digiKam project CCMAIL: kde-imaging@kde.org CCBUGS: 107905, 128394 M +1 -1 Makefile.am A dcrawbinary.cpp [License: GPL] A dcrawbinary.h [License: GPL] M +31 -18 plugin_rawconverter.cpp --- trunk/extragear/libs/kipi-plugins/rawconverter/Makefile.am #584175:584176 @@ -12,7 +12,7 @@ # Srcs for the plugin kipiplugin_rawconverter_la_SOURCES = plugin_rawconverter.cpp dcrawiface.cpp savesettingswidget.cpp \ batchdialog.cpp actionthread.cpp dcrawsettingswidget.cpp \ - singledialog.cpp previewwidget.cpp iccjpeg.c + singledialog.cpp previewwidget.cpp iccjpeg.c dcrawbinary.cpp # Libs needed by the plugin kipiplugin_rawconverter_la_LIBADD = -ljpeg -lpng $(LIB_TIFF) $(LIBKIPI_LIBS) $(LIB_KIO) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) --- trunk/extragear/libs/kipi-plugins/rawconverter/plugin_rawconverter.cpp #584175:584176 @@ -53,6 +53,7 @@ // Local includes. #include "rawfiles.h" +#include "dcrawbinary.h" #include "singledialog.h" #include "batchdialog.h" #include "plugin_rawconverter.h" @@ -123,30 +124,42 @@ bool Plugin_RawConverter::checkBinaries() { - QProcess process; + KIPIRawConverterPlugin::DcrawBinary dcrawBinary; - process.clearArguments(); - process.addArgument("kipidcrawclient"); - - if (!process.start()) + if (!dcrawBinary.isAvailable()) { - KMessageBox::error(kapp->activeWindow(), i18n("Failed to start raw converter client.\n" - "Please check your installation.")); + KMessageBox::information( + kapp->activeWindow(), + i18n("<qt><p>Unable to find the dcraw executable:<br> " + "This program is required by this plugin to support raw file decoding. " + "Please install dcraw as a package from your distributor " + "or <a href=\"%1\">download the source</a>.</p>" + "<p>Note: at least, dcraw version %2 is required by this plugin.</p></qt>") + .arg("http://www.cybercom.net/~dcoffin/dcraw") + .arg(dcrawBinary.minimalVersion()), + QString::null, + QString::null, + KMessageBox::Notify | KMessageBox::AllowLink); return false; } - process.clearArguments(); - process.addArgument("dcraw"); - - if (!process.start()) + if (!dcrawBinary.versionIsRight()) { - KMessageBox::error(kapp->activeWindow(), - i18n("<qt><p>Unable to find the dcraw executable:<br> " - "This program is required to process Raw file formats conversion. " - "Please install dcraw as a package from your distributor " - "or <a href=\"%2\">download the source</a>.</p></qt>") - .arg("http://www.cybercom.net/~dcoffin/dcraw/")); - + KMessageBox::information( + kapp->activeWindow(), + i18n("<qt><p>dcraw executable isn't up to date:<br> " + "The version %1 of dcraw have been found on your computer. " + "This version is too old to run properlly with this plugin. " + "Please update dcraw as a package from your distributor " + "or <a href=\"%2\">download the source</a>.</p>" + "<p>Note: at least, dcraw version %3 is required by this " + "plugin</p></qt>") + .arg(dcrawBinary.version()) + .arg("http://www.cybercom.net/~dcoffin/dcraw") + .arg(dcrawBinary.minimalVersion()), + QString::null, + QString::null, + KMessageBox::Notify | KMessageBox::AllowLink); return false; }
SVN commit 584185 by cgilles: kipi-plugins from trunk : Raw Converter : print dcraw version detected at startup to the header of RAW decoding settings area. CCMAIL: kde-imaging@kde.org CCBUGS: 107905, 128394 M +2 -2 batchdialog.cpp M +1 -1 batchdialog.h M +4 -2 dcrawsettingswidget.cpp M +1 -1 dcrawsettingswidget.h M +10 -6 plugin_rawconverter.cpp M +1 -1 plugin_rawconverter.h M +2 -2 singledialog.cpp M +1 -1 singledialog.h --- trunk/extragear/libs/kipi-plugins/rawconverter/batchdialog.cpp #584184:584185 @@ -74,7 +74,7 @@ namespace KIPIRawConverterPlugin { -BatchDialog::BatchDialog(QWidget* /*parent*/) +BatchDialog::BatchDialog(QWidget* /*parent*/, const QString& dcrawVersion) : KDialogBase(0, 0, false, i18n("Raw Images Batch Converter"), Help|User1|User2|Close, Close, true, i18n("Con&vert"), i18n("&Abort")) @@ -125,7 +125,7 @@ // --------------------------------------------------------------- - m_decodingSettingsBox = new DcrawSettingsWidget(m_page); + m_decodingSettingsBox = new DcrawSettingsWidget(m_page, dcrawVersion); m_saveSettingsBox = new SaveSettingsWidget(m_page); mainLayout->addMultiCellWidget(m_decodingSettingsBox, 1, 1, 1, 1); --- trunk/extragear/libs/kipi-plugins/rawconverter/batchdialog.h #584184:584185 @@ -55,7 +55,7 @@ public: - BatchDialog(QWidget *parent); + BatchDialog(QWidget *parent, const QString& dcrawVersion); ~BatchDialog(); void addItems(const QStringList& itemList); --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawsettingswidget.cpp #584184:584185 @@ -93,8 +93,10 @@ KDoubleNumInput *NRSigmaRange; }; -DcrawSettingsWidget::DcrawSettingsWidget(QWidget *parent) - : QGroupBox(0, Qt::Vertical, i18n("RAW Decoding Settings"), parent) +DcrawSettingsWidget::DcrawSettingsWidget(QWidget *parent, const QString& dcrawVersion) + : QGroupBox(0, Qt::Vertical, + i18n("RAW Decoding Settings (dcraw %1)").arg(dcrawVersion), + parent) { d = new DcrawSettingsWidgetPriv; QGridLayout* settingsBoxLayout = new QGridLayout(layout(), 10, 1, KDialog::spacingHint()); --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawsettingswidget.h #584184:584185 @@ -40,7 +40,7 @@ public: - DcrawSettingsWidget(QWidget *parent); + DcrawSettingsWidget(QWidget *parent, const QString& dcrawVersion); ~DcrawSettingsWidget(); bool useCameraWB(); --- trunk/extragear/libs/kipi-plugins/rawconverter/plugin_rawconverter.cpp #584184:584185 @@ -122,9 +122,10 @@ return false; } -bool Plugin_RawConverter::checkBinaries() +bool Plugin_RawConverter::checkBinaries(QString &dcrawVersion) { KIPIRawConverterPlugin::DcrawBinary dcrawBinary; + dcrawVersion = dcrawBinary.version(); if (!dcrawBinary.isAvailable()) { @@ -154,7 +155,7 @@ "or <a href=\"%2\">download the source</a>.</p>" "<p>Note: at least, dcraw version %3 is required by this " "plugin</p></qt>") - .arg(dcrawBinary.version()) + .arg(dcrawVersion) .arg("http://www.cybercom.net/~dcoffin/dcraw") .arg(dcrawBinary.minimalVersion()), QString::null, @@ -182,7 +183,8 @@ if ( !images.isValid() ) return; - if (!checkBinaries()) + QString dcrawVersion; + if (!checkBinaries(dcrawVersion)) return; if (!isRAWFile(images.images()[0].path())) @@ -193,7 +195,8 @@ } KIPIRawConverterPlugin::SingleDialog *converter = - new KIPIRawConverterPlugin::SingleDialog(images.images()[0].path(), kapp->activeWindow()); + new KIPIRawConverterPlugin::SingleDialog(images.images()[0].path(), + kapp->activeWindow(), dcrawVersion); converter->show(); } @@ -214,11 +217,12 @@ if ( !images.isValid() ) return; - if (!checkBinaries()) + QString dcrawVersion; + if (!checkBinaries(dcrawVersion)) return; KIPIRawConverterPlugin::BatchDialog *converter = - new KIPIRawConverterPlugin::BatchDialog(kapp->activeWindow()); + new KIPIRawConverterPlugin::BatchDialog(kapp->activeWindow(), dcrawVersion); KURL::List urls = images.images(); QStringList files; --- trunk/extragear/libs/kipi-plugins/rawconverter/plugin_rawconverter.h #584184:584185 @@ -46,7 +46,7 @@ private: - bool checkBinaries(); + bool checkBinaries(QString &dcrawVersion); bool isRAWFile(const QString& filePath); private slots: --- trunk/extragear/libs/kipi-plugins/rawconverter/singledialog.cpp #584184:584185 @@ -65,7 +65,7 @@ namespace KIPIRawConverterPlugin { -SingleDialog::SingleDialog(const QString& file, QWidget *parent) +SingleDialog::SingleDialog(const QString& file, QWidget *parent, const QString& dcrawVersion) : KDialogBase(parent, 0, false, i18n("Raw Image Converter"), Help|User1|User2|User3|Close, Close, true, i18n("&Preview"), i18n("Con&vert"), i18n("&Abort")) @@ -115,7 +115,7 @@ // --------------------------------------------------------------- - m_decodingSettingsBox = new DcrawSettingsWidget(page); + m_decodingSettingsBox = new DcrawSettingsWidget(page, dcrawVersion); m_saveSettingsBox = new SaveSettingsWidget(page); mainLayout->addMultiCellWidget(m_decodingSettingsBox, 1, 1, 1, 1); --- trunk/extragear/libs/kipi-plugins/rawconverter/singledialog.h #584184:584185 @@ -49,7 +49,7 @@ public: - SingleDialog(const QString& file, QWidget *parent); + SingleDialog(const QString& file, QWidget *parent, const QString& dcrawVersion); ~SingleDialog(); protected:
SVN commit 584218 by cgilles: kipi-plugins from trunk : Raw Converter : add 'Default' button to set all settings to default values. CCMAIL: kde-imaging@kde.org CCBUGS: 107905, 128394 M +11 -5 batchdialog.cpp M +1 -0 batchdialog.h M +15 -0 dcrawsettingswidget.cpp M +2 -0 dcrawsettingswidget.h M +6 -0 savesettingswidget.cpp M +2 -0 savesettingswidget.h M +11 -5 singledialog.cpp M +4 -3 singledialog.h --- trunk/extragear/libs/kipi-plugins/rawconverter/batchdialog.cpp #584217:584218 @@ -76,7 +76,7 @@ BatchDialog::BatchDialog(QWidget* /*parent*/, const QString& dcrawVersion) : KDialogBase(0, 0, false, i18n("Raw Images Batch Converter"), - Help|User1|User2|Close, Close, true, + Help|Default|User1|User2|Close, Close, true, i18n("Con&vert"), i18n("&Abort")) { m_currentConvertItem = 0; @@ -214,6 +214,12 @@ KDialogBase::slotClose(); } +void BatchDialog::slotDefault() +{ + m_decodingSettingsBox->setDefaultSettings(); + m_saveSettingsBox->setDefaultSettings(); +} + void BatchDialog::readSettings() { KConfig config("kipirc"); @@ -233,6 +239,10 @@ (RawDecodingSettings::DecodingQuality)config.readNumEntry("Decoding Quality", (int)(RawDecodingSettings::BILINEAR))); + m_decodingSettingsBox->setOutputColorSpace( + (RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space", + (int)(RawDecodingSettings::SRGB))); + m_saveSettingsBox->setFileFormat( (RawDecodingSettings::OutputFormat)config.readNumEntry("Output Format", (int)(RawDecodingSettings::PNG))); @@ -241,10 +251,6 @@ (SaveSettingsWidget::ConflictRule)config.readNumEntry("Conflict", (int)(SaveSettingsWidget::OVERWRITE))); - m_decodingSettingsBox->setOutputColorSpace( - (RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space", - (int)(RawDecodingSettings::SRGB))); - resize(configDialogSize(config, QString("Batch Raw Converter Dialog"))); } --- trunk/extragear/libs/kipi-plugins/rawconverter/batchdialog.h #584217:584218 @@ -79,6 +79,7 @@ private slots: + void slotDefault(); void slotClose(); void slotHelp(); void slotUser1(); --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawsettingswidget.cpp #584217:584218 @@ -285,6 +285,21 @@ delete d; } +void DcrawSettingsWidget::setDefaultSettings() +{ + setCameraWB(true); + setAutoColorBalance(true); + setFourColor(false); + setUnclipColor(0); + setSecondarySensor(false); + setNoiseReduction(false); + setBrightness(1.0); + setSigmaDomain(2.0); + setSigmaRange(4.0); + setQuality(RawDecodingSettings::BILINEAR); + setOutputColorSpace(RawDecodingSettings::SRGB); +} + void DcrawSettingsWidget::slotUnclipColorActivated(int v) { if (v == 2) // Reconstruct Highlight method --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawsettingswidget.h #584217:584218 @@ -67,6 +67,8 @@ void setQuality(RawDecodingSettings::DecodingQuality q); void setOutputColorSpace(RawDecodingSettings::OutputColorSpace c); + void setDefaultSettings(); + private slots: void slotUnclipColorActivated(int); --- trunk/extragear/libs/kipi-plugins/rawconverter/savesettingswidget.cpp #584217:584218 @@ -121,6 +121,12 @@ delete d; } +void SaveSettingsWidget::setDefaultSettings() +{ + setFileFormat(RawDecodingSettings::PNG); + setConflictRule(SaveSettingsWidget::OVERWRITE); +} + RawDecodingSettings::OutputFormat SaveSettingsWidget::fileFormat() { return(RawDecodingSettings::OutputFormat)(d->formatComboBox->currentItem()); --- trunk/extragear/libs/kipi-plugins/rawconverter/savesettingswidget.h #584217:584218 @@ -57,6 +57,8 @@ void setFileFormat(RawDecodingSettings::OutputFormat f); void setConflictRule(ConflictRule r); + void setDefaultSettings(); + signals: void signalSaveFormatChanged(); --- trunk/extragear/libs/kipi-plugins/rawconverter/singledialog.cpp #584217:584218 @@ -67,7 +67,7 @@ SingleDialog::SingleDialog(const QString& file, QWidget *parent, const QString& dcrawVersion) : KDialogBase(parent, 0, false, i18n("Raw Image Converter"), - Help|User1|User2|User3|Close, Close, true, + Help|Default|User1|User2|User3|Close, Close, true, i18n("&Preview"), i18n("Con&vert"), i18n("&Abort")) { m_inputFile = file; @@ -208,6 +208,12 @@ KDialogBase::slotClose(); } +void SingleDialog::slotDefault() +{ + m_decodingSettingsBox->setDefaultSettings(); + m_saveSettingsBox->setDefaultSettings(); +} + void SingleDialog::readSettings() { KConfig config("kipirc"); @@ -227,6 +233,10 @@ (RawDecodingSettings::DecodingQuality)config.readNumEntry("Decoding Quality", (int)(RawDecodingSettings::BILINEAR))); + m_decodingSettingsBox->setOutputColorSpace( + (RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space", + (int)(RawDecodingSettings::SRGB))); + m_saveSettingsBox->setFileFormat( (RawDecodingSettings::OutputFormat)config.readNumEntry("Output Format", (int)(RawDecodingSettings::PNG))); @@ -235,10 +245,6 @@ (SaveSettingsWidget::ConflictRule)config.readNumEntry("Conflict", (int)(SaveSettingsWidget::OVERWRITE))); - m_decodingSettingsBox->setOutputColorSpace( - (RawDecodingSettings::OutputColorSpace)config.readNumEntry("Output Color Space", - (int)(RawDecodingSettings::SRGB))); - resize(configDialogSize(config, QString("Single Raw Converter Dialog"))); } --- trunk/extragear/libs/kipi-plugins/rawconverter/singledialog.h #584217:584218 @@ -75,13 +75,14 @@ void processingFailed(const QString&); private slots: - + + void slotDefault(); + void slotClose(); void slotHelp(); void slotUser1(); void slotUser2(); void slotUser3(); - void slotClose(); - + void slotIdentify(); void slotPreviewBlinkTimerDone();
SVN commit 584591 by cgilles: kipi-plugins from trunk : Raw Converter : full cancelable (when you want) dcraw instance during RAW image data decoding. The code use now a KProcess instance instead a simple non-cancelable popen() call. The implementation is inspired from digiKam RAW image loader CCBUGS: 107905, 128394 M +1 -1 dcrawbinary.h M +357 -166 dcrawiface.cpp M +35 -12 dcrawiface.h M +7 -1 rawdecodingsettings.h M +2 -2 singledialog.cpp
SVN commit 584763 by cgilles: kipi-plugins from trunk : Raw Converter : Exif/makernotes/iptc/gps metadata restoration after RAW image decoding. - Add Exiv2 depency. I recommend to use the current implementation of Exiv2 from svn (Exiv2 0.11 will be release in a near future) - Add a new Exiv2 interface class based on some part of digiKam core. This class will be will be moved later to the common plugins folder to remplace libkexif depency everywhere. I need to polish and improve the code before. - Actually, 2 output file formats are fully supported to store metadata : JPEG and PNG. Note PNG Exif/Iptc storing use ImageMagick raw profile stored in compressed text chunk. Tiff file format will be added when Exiv2 library will support Tiff write io (normally later 0.11 release) To all digiKam users : after to have converted Raw files using this plugin, you will have the pleasure to see all metadata into target files using Metadata side bar (:=))) CCMAIL: kde-imaging@kde.org BUG : 107905 CCBUGS: 128394 M +0 -1 Makefile.am M +7 -0 configure.in.bot M +17 -0 configure.in.in M +6 -1 kipiplugins.kdevelop M +4 -2 rawconverter/Makefile.am M +201 -1 rawconverter/dcrawiface.cpp M +15 -0 rawconverter/dcrawiface.h A rawconverter/exiv2iface.cpp [License: GPL] A rawconverter/exiv2iface.h [License: GPL] --- trunk/extragear/libs/kipi-plugins/Makefile.am #584762:584763 @@ -25,7 +25,6 @@ TIMEADJUSTDIR = $(timeadjustdir) endif - if compile_ACQUIREIMAGES ACQUIREIMAGESDIR = acquireimages endif --- trunk/extragear/libs/kipi-plugins/configure.in.bot #584762:584763 @@ -58,3 +58,10 @@ echo "" all_tests=bad fi + +if test "x$have_exiv2" != "xyes"; then + echo "" + echo "You're missing Exiv2 library. The rawconverter plugin will not be compiled." + echo "" + all_tests=bad +fi --- trunk/extragear/libs/kipi-plugins/configure.in.in #584762:584763 @@ -168,6 +168,23 @@ AM_CONDITIONAL(compile_HTMLEXPORT, test -n "${XSLT_CONFIG}") +#------------------------------------------------------------------ +# Check for Exiv2 library +#------------------------------------------------------------------ + +have_exiv2='no' +AC_PATH_PROG(EXIV2_CONFIG,exiv2-config) +KDE_CHECK_HEADER(exiv2/exif.hpp, have_exiv2=yes, have_exiv2=no) + +if test "x$have_exiv2" != "xyes"; then + AC_WARN([Exiv2 library is require for the rawconvert plugin.]) +else + LIB_EXIV2="-lexiv2" + AC_SUBST(LIB_EXIV2) +fi + +AM_CONDITIONAL(compile_RAWCONVERTER, test -n "${EXIV2_CONFIG}") + # ---------------------------------------------------------- # # Slideshow plugin tests --- trunk/extragear/libs/kipi-plugins/kipiplugins.kdevelop #584762:584763 @@ -110,7 +110,7 @@ <run> <directoryradio>custom</directoryradio> <customdirectory>/</customdirectory> - <mainprogram>/usr/bin/digikam</mainprogram> + <mainprogram>/opt/kde3/bin/digikam</mainprogram> <programargs/> <terminal>false</terminal> <autocompile>false</autocompile> @@ -167,6 +167,11 @@ <inlineGet>true</inlineGet> <inlineSet>true</inlineSet> </creategettersetter> + <qt> + <used>false</used> + <version>3</version> + <root>/usr/lib/qt3</root> + </qt> </kdevcppsupport> <kdevcvsservice> <recursivewhenupdate>true</recursivewhenupdate> --- trunk/extragear/libs/kipi-plugins/rawconverter/Makefile.am #584762:584763 @@ -1,5 +1,6 @@ METASOURCES = AUTO SUBDIRS = profiles +KDE_CXXFLAGS = $(USE_EXCEPTIONS) INCLUDES = -I$(top_srcdir)/kipi-plugins/common/include \ $(LIBKIPI_CFLAGS) $(all_includes) @@ -12,10 +13,11 @@ # Srcs for the plugin kipiplugin_rawconverter_la_SOURCES = plugin_rawconverter.cpp dcrawiface.cpp savesettingswidget.cpp \ batchdialog.cpp actionthread.cpp dcrawsettingswidget.cpp \ - singledialog.cpp previewwidget.cpp iccjpeg.c dcrawbinary.cpp + singledialog.cpp previewwidget.cpp iccjpeg.c dcrawbinary.cpp \ + exiv2iface.cpp # Libs needed by the plugin -kipiplugin_rawconverter_la_LIBADD = -ljpeg -lpng $(LIB_TIFF) $(LIBKIPI_LIBS) $(LIB_KIO) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) +kipiplugin_rawconverter_la_LIBADD = -ljpeg -lpng $(LIB_TIFF) $(LIBKIPI_LIBS) $(LIB_KIO) $(LIB_EXIV2) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) # LD flags for the plugin kipiplugin_rawconverter_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawiface.cpp #584762:584763 @@ -38,7 +38,6 @@ #include <jpeglib.h> #include <tiffio.h> #include <tiffvers.h> -#include <png.h> #include "iccjpeg.h" } @@ -63,6 +62,7 @@ #include "pluginsversion.h" #include "rawfiles.h" +#include "exiv2iface.h" #include "dcrawbinary.h" #include "dcrawiface.h" #include "dcrawiface.moc" @@ -468,6 +468,12 @@ jpeg_finish_compress(&cinfo); fclose(f); + + // Metadata restoration. + Exiv2Iface exiv2Ifave; + exiv2Ifave.load(filePath); + exiv2Ifave.setImageProgramId(QString("Kipi Raw Converter"), QString(kipiplugins_version)); + exiv2Ifave.save(destPath); break; } case RawDecodingSettings::PNG: @@ -515,6 +521,23 @@ text.compression = PNG_TEXT_COMPRESSION_zTXt; png_set_text(png_ptr, info_ptr, &(text), 1); + // Metadata restoration. + Exiv2Iface exiv2Ifave; + exiv2Ifave.load(filePath); + exiv2Ifave.setImageProgramId(QString("Kipi Raw Converter"), QString(kipiplugins_version)); + + // Store Exif data. + QByteArray ba = exiv2Ifave.getExif(); + const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + QByteArray profile = QByteArray(ba.size() + sizeof(ExifHeader)); + memcpy(profile.data(), ExifHeader, sizeof(ExifHeader)); + memcpy(profile.data()+sizeof(ExifHeader), ba.data(), ba.size()); + writeRawProfile(png_ptr, info_ptr, "exif", profile.data(), (png_uint_32) profile.size()); + + // Store Iptc data. + QByteArray ba2 = exiv2Ifave.getIptc(); + writeRawProfile(png_ptr, info_ptr, "iptc", ba2.data(), (png_uint_32) ba2.size()); + png_write_info(png_ptr, info_ptr); png_set_shift(png_ptr, &sig_bit); png_set_packing(png_ptr); @@ -570,6 +593,21 @@ w = TIFFScanlineSize(tif); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0)); + + // Metadata restoration. + Exiv2Iface exiv2Ifave; + exiv2Ifave.load(filePath); + exiv2Ifave.setImageProgramId(QString("Kipi Raw Converter"), QString(kipiplugins_version)); + + // Store Exif data. + // TODO + + // Store Iptc data. + QByteArray ba2 = exiv2Ifave.getIptc(true); +#if defined(TIFFTAG_PHOTOSHOP) + TIFFSetField (tif, TIFFTAG_PHOTOSHOP, (uint32)ba2.size(), (uchar *)ba2.data()); +#endif + QString libtiffver(TIFFLIB_VERSION_STR); libtiffver.replace('\n', ' '); soft.append(QString(" ( %1 )").arg(libtiffver)); @@ -841,4 +879,166 @@ kdDebug() << "Dcraw StdErr: " << message << endl; } +void DcrawIface::writeRawProfile(png_struct *ping, png_info *ping_info, char *profile_type, + char *profile_data, png_uint_32 length) +{ + png_textp text; + + register long i; + + uchar *sp; + + png_charp dp; + + png_uint_32 allocated_length, description_length; + + const uchar hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + + kdDebug() << "Writing Raw profile: type=" << profile_type << ", length=" << length << endl; + + text = (png_textp) png_malloc(ping, (png_uint_32) sizeof(png_text)); + description_length = strlen((const char *) profile_type); + allocated_length = (png_uint_32) (length*2 + (length >> 5) + 20 + description_length); + + text[0].text = (png_charp) png_malloc(ping, allocated_length); + text[0].key = (png_charp) png_malloc(ping, (png_uint_32) 80); + text[0].key[0] = '\0'; + + concatenateString(text[0].key, "Raw profile type ", 4096); + concatenateString(text[0].key, (const char *) profile_type, 62); + + sp = (uchar*)profile_data; + dp = text[0].text; + *dp++='\n'; + + copyString(dp, (const char *) profile_type, allocated_length); + + dp += description_length; + *dp++='\n'; + + formatString(dp, allocated_length-strlen(text[0].text), "%8lu ", length); + + dp += 8; + + for (i=0; i < (long) length; i++) + { + if (i%36 == 0) + *dp++='\n'; + + *(dp++)=(char) hex[((*sp >> 4) & 0x0f)]; + *(dp++)=(char) hex[((*sp++ ) & 0x0f)]; + } + + *dp++='\n'; + *dp='\0'; + text[0].text_length = (png_size_t) (dp-text[0].text); + text[0].compression = -1; + + if (text[0].text_length <= allocated_length) + png_set_text(ping, ping_info,text, 1); + + png_free(ping, text[0].text); + png_free(ping, text[0].key); + png_free(ping, text); +} + +size_t DcrawIface::concatenateString(char *destination, const char *source, const size_t length) +{ + register char *q; + + register const char *p; + + register size_t i; + + size_t count; + + if ( !destination || !source || length == 0 ) + return 0; + + p = source; + q = destination; + i = length; + + while ((i-- != 0) && (*q != '\0')) + q++; + + count = (size_t) (q-destination); + i = length-count; + + if (i == 0) + return(count+strlen(p)); + + while (*p != '\0') + { + if (i != 1) + { + *q++=(*p); + i--; + } + p++; + } + + *q='\0'; + + return(count+(p-source)); +} + +size_t DcrawIface::copyString(char *destination, const char *source, const size_t length) +{ + register char *q; + + register const char *p; + + register size_t i; + + if ( !destination || !source || length == 0 ) + return 0; + + p = source; + q = destination; + i = length; + + if ((i != 0) && (--i != 0)) + { + do + { + if ((*q++=(*p++)) == '\0') + break; + } + while (--i != 0); + } + + if (i == 0) + { + if (length != 0) + *q='\0'; + + while (*p++ != '\0'); + } + + return((size_t) (p-source-1)); +} + +long DcrawIface::formatString(char *string, const size_t length, const char *format,...) +{ + long n; + + va_list operands; + + va_start(operands,format); + n = (long) formatStringList(string, length, format, operands); + va_end(operands); + return(n); +} + +long DcrawIface::formatStringList(char *string, const size_t length, const char *format, va_list operands) +{ + int n = vsnprintf(string, length, format, operands); + + if (n < 0) + string[length-1] = '\0'; + + return((long) n); +} + } // namespace KIPIRawConverterPlugin --- trunk/extragear/libs/kipi-plugins/rawconverter/dcrawiface.h #584762:584763 @@ -22,6 +22,13 @@ #ifndef DCRAWIFACE_H #define DCRAWIFACE_H +// C Ansi includes. + +extern "C" +{ +#include <png.h> +} + // Qt Includes. #include <qstring.h> @@ -87,6 +94,14 @@ virtual void customEvent(QCustomEvent *); + void writeRawProfile(png_struct *ping, png_info *ping_info, char *profile_type, + char *profile_data, png_uint_32 length); + + size_t concatenateString(char *destination, const char *source, const size_t length); + size_t copyString(char *destination, const char *source, const size_t length); + long formatString(char *string, const size_t length, const char *format,...); + long formatStringList(char *string, const size_t length, const char *format, va_list operands); + private slots: void slotProcessExited(KProcess *);