[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