[Digikam-devel] extragear/graphics/digikam/libs [POSSIBLY UNSAFE]
Gilles Caulier
caulier.gilles at kdemail.net
Mon Feb 5 16:01:06 GMT 2007
SVN commit 630507 by cgilles:
digikam from trunk : new DcrawIface method to extract usual photo informations with RAW files (X3F, ORF, etc...) unsupported by Exiv2 library, using the dcraw indentify method.
CCMAIL: digikam-devel at kde.org
M +103 -0 dcraw/dcrawiface.cpp [POSSIBLY UNSAFE: popen]
M +3 -0 dcraw/dcrawiface.h
AM dcraw/dcrawinfocontainer.h [License: GPL]
M +13 -7 dimg/loaders/dimgloader.cpp
M +5 -5 dimg/loaders/dimgloader.h
M +2 -2 dimg/loaders/rawloader.cpp
M +1 -0 dmetadata/Makefile.am
M +57 -1 dmetadata/dmetadata.cpp
M +6 -0 dmetadata/dmetadata.h
--- trunk/extragear/graphics/digikam/libs/dcraw/dcrawiface.cpp #630506:630507
@@ -161,4 +161,107 @@
return false;
}
+bool DcrawIface::rawFileIdentify(DcrawInfoContainer& identify, const QString& path)
+{
+ FILE *f=NULL;
+ QByteArray txtData;
+ const int MAX_IPC_SIZE = (1024*32);
+ char buffer[MAX_IPC_SIZE];
+ QFile file;
+ Q_LONG len;
+ QCString command;
+
+ QFileInfo fileInfo(path);
+ QString rawFilesExt(raw_file_extentions);
+ QString ext = fileInfo.extension(false).upper();
+
+ if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.upper().contains(ext))
+ return false;
+
+ // Try to get camera maker/model using dcraw with options:
+ // -c : write to stdout
+ // -i : identify files without decoding them.
+ // -v : verbose mode.
+
+ command = DcrawBinary::instance()->path();
+ command += " -c -i -v ";
+ command += QFile::encodeName( KProcess::quote( path ) );
+ DDebug() << "Running RAW decoding command " << command << endl;
+
+ f = popen( command.data(), "r" );
+
+ if ( f == NULL )
+ {
+ identify = DcrawInfoContainer();
+ return false;
+ }
+
+ file.open( IO_ReadOnly, f );
+
+ while ((len = file.readBlock(buffer, MAX_IPC_SIZE)) != 0)
+ {
+ if ( len == -1 )
+ {
+ identify = DcrawInfoContainer();
+ return false;
+ }
+ else
+ {
+ int oldSize = txtData.size();
+ txtData.resize( txtData.size() + len );
+ memcpy(txtData.data()+oldSize, buffer, len);
+ }
+ }
+
+ file.close();
+ pclose( f );
+ QString dcrawInfo(txtData);
+
+ if ( dcrawInfo.isEmpty() )
+ {
+ identify = DcrawInfoContainer();
+ return false;
+ }
+
+ // Extract Time Stamp.
+ QString timeStampHeader("Timestamp: ");
+ QString timeStamp = dcrawInfo.section('\n', 2, 2);
+ timeStamp.remove(0, timeStampHeader.length());
+ identify.dateTime = QDateTime::fromString(timeStamp);
+
+ // Extract Camera Model.
+ QString cameraHeader("Camera: ");
+ QString camera = dcrawInfo.section('\n', 3, 3);
+ camera.remove(0, cameraHeader.length());
+ identify.model = camera;
+
+ // Extract ISO Speed.
+ QString isoSpeedHeader("ISO speed: ");
+ QString isoSpeed = dcrawInfo.section('\n', 4, 4);
+ isoSpeed.remove(0, isoSpeedHeader.length());
+ identify.sensitivity = isoSpeed.toLong();
+
+ // Extract Shutter Speed.
+ QString shutterSpeedHeader("Shutter: 1/");
+ QString shutterSpeed = dcrawInfo.section('\n', 5, 5);
+ shutterSpeed.remove(0, shutterSpeedHeader.length());
+ shutterSpeed.remove(shutterSpeed.length()-4, 4); // remove " sec" at end of string.
+ identify.exposureTime = shutterSpeed.toFloat();
+
+ // Extract Aperture.
+ QString apertureHeader("Aperture: f/");
+ QString aperture = dcrawInfo.section('\n', 6, 6);
+ aperture.remove(0, apertureHeader.length());
+ identify.aperture = aperture.toFloat();
+
+ // Extract Focal Length.
+ QString focalLengthHeader("Focal Length: ");
+ QString focalLength = dcrawInfo.section('\n', 7, 7);
+ focalLength.remove(0, focalLengthHeader.length());
+ focalLength.remove(focalLength.length()-3, 3); // remove " mm" at end of string.
+ identify.focalLength = focalLength.toFloat();
+
+ return true;
+}
+
} // namespace Digikam
--- trunk/extragear/graphics/digikam/libs/dcraw/dcrawiface.h #630506:630507
@@ -25,6 +25,7 @@
// Local Includes.
+#include "dcrawinfocontainer.h"
#include "digikam_export.h"
namespace Digikam
@@ -32,10 +33,12 @@
class DIGIKAM_EXPORT DcrawIface
{
+
public:
static bool loadDcrawPreview(QImage& image, const QString& path);
+ static bool rawFileIdentify(DcrawInfoContainer& identify, const QString& path);
};
} // namespace Digikam
** trunk/extragear/graphics/digikam/libs/dcraw/dcrawinfocontainer.h #property svn:eol-style
+ native
--- trunk/extragear/graphics/digikam/libs/dimg/loaders/dimgloader.cpp #630506:630507
@@ -1,10 +1,11 @@
/* ============================================================
- * Author: Renchi Raju <renchi at pooh.tam.uiuc.edu>
- * Date : 2005-06-14
- * Description : DImg image loader interface
+ * Authors: Renchi Raju <renchi at pooh.tam.uiuc.edu>
+ * Gilles Caulier <caulier dot gilles at kdemail dot net>
+ * Date : 2005-06-14
+ * Description : DImg image loader interface
*
* Copyright 2005 by Renchi Raju, Gilles Caulier
- * Copyright 2006 by Gilles Caulier
+ * Copyright 2006-2007 by Gilles Caulier
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -119,12 +120,15 @@
m_image->setEmbeddedText(key, text);
}
-void DImgLoader::readMetadata(const QString& filePath, DImg::FORMAT /*ff*/)
+bool DImgLoader::readMetadata(const QString& filePath, DImg::FORMAT /*ff*/)
{
QMap<int, QByteArray>& imageMetadata = imageMetaData();
imageMetadata.clear();
DMetadata metaDataFromFile(filePath);
+ if (!metaDataFromFile.load(filePath))
+ return false;
+
// Do not insert null data into metaData map:
// Even if byte array is null, if there is a key in the map, it will
// be interpreted as "There was data, so write it again to the file".
@@ -134,15 +138,17 @@
imageMetadata.insert(DImg::EXIF, metaDataFromFile.getExif());
if (!metaDataFromFile.getIptc().isNull())
imageMetadata.insert(DImg::IPTC, metaDataFromFile.getIptc());
+
+ return true;
}
-void DImgLoader::saveMetadata(const QString& filePath)
+bool DImgLoader::saveMetadata(const QString& filePath)
{
DMetadata metaDataToFile(filePath);
metaDataToFile.setComments(m_image->getComments());
metaDataToFile.setExif(m_image->getExif());
metaDataToFile.setIptc(m_image->getIptc());
- metaDataToFile.applyChanges();
+ return metaDataToFile.applyChanges();
}
bool DImgLoader::checkExifWorkingColorSpace()
--- trunk/extragear/graphics/digikam/libs/dimg/loaders/dimgloader.h #630506:630507
@@ -1,11 +1,11 @@
/* ============================================================
- * Author: Renchi Raju <renchi at pooh.tam.uiuc.edu>
+ * Authors: Renchi Raju <renchi at pooh.tam.uiuc.edu>
* Gilles Caulier <caulier dot gilles at kdemail dot net>
- * Date : 2005-06-14
+ * Date : 2005-06-14
* Description : DImg image loader interface
*
* Copyright 2005 by Renchi Raju, Gilles Caulier
- * Copyright 2006 by Gilles Caulier
+ * Copyright 2006-2007 by Gilles Caulier
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
@@ -75,8 +75,8 @@
QString imageGetEmbbededText(const QString& key);
void imageSetEmbbededText(const QString& key, const QString& text);
- virtual void readMetadata(const QString& filePath, DImg::FORMAT ff);
- virtual void saveMetadata(const QString& filePath);
+ virtual bool readMetadata(const QString& filePath, DImg::FORMAT ff);
+ virtual bool saveMetadata(const QString& filePath);
virtual int granularity(DImgLoaderObserver *observer, int total, float progressSlice = 1.0);
bool checkExifWorkingColorSpace();
--- trunk/extragear/graphics/digikam/libs/dimg/loaders/rawloader.cpp #630506:630507
@@ -80,12 +80,12 @@
bool RAWLoader::load(const QString& filePath, DImgLoaderObserver *observer)
{
readMetadata(filePath, DImg::RAW);
-
+
// NOTE: Here, we don't check a possible embeded work-space color profile using
// the method checkExifWorkingColorSpace() like with JPEG, PNG, and TIFF loaders,
// because RAW file are always in linear mode.
- return ( loadFromDcraw(filePath, observer) );
+ return(loadFromDcraw(filePath, observer));
}
bool RAWLoader::loadFromDcraw(const QString& filePath, DImgLoaderObserver *observer)
--- trunk/extragear/graphics/digikam/libs/dmetadata/Makefile.am #630506:630507
@@ -9,6 +9,7 @@
libdmetadata_la_LIBADD = $(LIBKEXIV2_LIBS)
INCLUDES = -I$(top_srcdir)/digikam/libs/dimg \
+ -I$(top_srcdir)/digikam/libs/dcraw \
-I$(top_srcdir)/digikam/digikam \
$(all_includes)
--- trunk/extragear/graphics/digikam/libs/dmetadata/dmetadata.cpp #630506:630507
@@ -23,6 +23,7 @@
#include "version.h"
#include "ddebug.h"
+#include "dcrawiface.h"
#include "dmetadata.h"
namespace Digikam
@@ -34,14 +35,69 @@
}
DMetadata::DMetadata(const QString& filePath)
- : KExiv2Iface::KExiv2(filePath)
+ : KExiv2Iface::KExiv2()
{
+ load(filePath);
}
DMetadata::~DMetadata()
{
}
+bool DMetadata::load(const QString& filePath)
+{
+ // In first, we trying to get metadata using Exiv2,
+ // else we will use dcraw to extract minimal informations.
+
+ if (!KExiv2::load(filePath))
+ {
+ if (!loadUsingDcraw(filePath))
+ return false;
+ }
+
+ return true;
+}
+
+bool DMetadata::loadUsingDcraw(const QString& filePath)
+{
+ DcrawInfoContainer identify;
+ if (DcrawIface::rawFileIdentify(identify, filePath))
+ {
+ long int num=1, den=1;
+
+ if (!identify.model.isNull())
+ setExifTagString("Exif.Image.Model", identify.model.latin1(), false);
+
+ if (identify.sensitivity != -1)
+ setExifTagLong("Exif.Photo.ISOSpeedRatings", identify.sensitivity, false);
+
+ if (identify.dateTime.isValid())
+ setImageDateTime(identify.dateTime, false);
+
+ if (identify.exposureTime != -1.0)
+ {
+ convertToRational(1/identify.exposureTime, &num, &den, 8);
+ setExifTagRational("Exif.Photo.ExposureTime", num, den, false);
+ }
+
+ if (identify.aperture != -1.0)
+ {
+ convertToRational(identify.aperture, &num, &den, 8);
+ setExifTagRational("Exif.Photo.ApertureValue", num, den, false);
+ }
+
+ if (identify.focalLength != -1.0)
+ {
+ convertToRational(identify.focalLength, &num, &den, 8);
+ setExifTagRational("Exif.Photo.FocalLength", num, den, false);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
QString DMetadata::getImageComment() const
{
if (getFilePath().isEmpty())
--- trunk/extragear/graphics/digikam/libs/dmetadata/dmetadata.h #630506:630507
@@ -47,6 +47,12 @@
DMetadata();
DMetadata(const QString& filePath);
~DMetadata();
+
+ /** Re-implemented from libKexiv2 to use dcraw identify method if Exiv2 way failed. */
+ bool load(const QString& filePath);
+
+ /** Try to extract metadata using dcraw identify method */
+ bool loadUsingDcraw(const QString& filePath);
/** Metadata manipulation methods */
More information about the Digikam-devel
mailing list