[Kde-imaging] extragear/libs/kipi-plugins

Gilles Caulier caulier.gilles at free.fr
Mon Sep 18 14:17:10 CEST 2006


SVN commit 585974 by cgilles:

kipi-plugins from trunk : JPEGLossLess plugin : Using Exiv2 library intead libkexif.
CCMAIL: kde-imaging at kde.org

 M  +165 -3    common/exiv2iface/exiv2iface.cpp  
 M  +21 -0     common/exiv2iface/exiv2iface.h  
 M  +4 -2      jpeglossless/Makefile.am  
 M  +66 -63    jpeglossless/jpegtransform.cpp  
 M  +3 -3      jpeglossless/jpegtransform.h  
 M  +1 -1      kipiplugins.kdevelop  


--- trunk/extragear/libs/kipi-plugins/common/exiv2iface/exiv2iface.cpp #585973:585974
@@ -5,6 +5,10 @@
  *
  * Copyright 2006 by Gilles Caulier
  *
+ * NOTE: This class is a simplified version of Digikam::DMetadata
+ *       class from digiKam core. Please contact digiKam team 
+ *       before to change/fix/improve this implementation.
+ *
  * 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;
@@ -56,9 +60,7 @@
 {
 public:
 
-    Exiv2IfacePriv()
-    {
-    }
+    Exiv2IfacePriv(){}
 
     std::string     imageComments;  
 
@@ -516,4 +518,164 @@
     return QDateTime();
 }
 
+Exiv2Iface::ImageOrientation Exiv2Iface::getImageOrientation()
+{
+    if (d->exifMetadata.empty())
+       return ORIENTATION_UNSPECIFIED;
+
+    // Workaround for older Exiv2 versions which do not support
+    // Minolta Makernotes and throw an error for such keys.
+    bool supportMinolta = true;
+    try
+    {
+        Exiv2::ExifKey minoltaKey1("Exif.MinoltaCs7D.Rotation");
+        Exiv2::ExifKey minoltaKey2("Exif.MinoltaCs5D.Rotation");
+    }
+    catch( Exiv2::Error &e )
+    {
+        supportMinolta = false;
+    }
+
+    try
+    {
+        Exiv2::ExifData exifData(d->exifMetadata);
+        Exiv2::ExifData::iterator it;
+        long orientation;
+        ImageOrientation imageOrient = ORIENTATION_NORMAL;
+
+        // Because some camera set a wrong standard exif orientation tag, 
+        // We need to check makernote tags in first!
+
+        // -- Minolta Cameras ----------------------------------
+
+        if (supportMinolta)
+        {
+            Exiv2::ExifKey minoltaKey1("Exif.MinoltaCs7D.Rotation");
+            it = exifData.findKey(minoltaKey1);
+
+            if (it != exifData.end())
+            {
+                orientation = it->toLong();
+                kdDebug() << "Minolta Makernote Orientation: " << orientation << endl;
+                switch(orientation)
+                {
+                    case 76:
+                        imageOrient = ORIENTATION_ROT_90;
+                        break;
+                    case 82:
+                        imageOrient = ORIENTATION_ROT_270;
+                        break;
+                }
+                return imageOrient;
+            }
+
+            Exiv2::ExifKey minoltaKey2("Exif.MinoltaCs5D.Rotation");
+            it = exifData.findKey(minoltaKey2);
+
+            if (it != exifData.end())
+            {
+                orientation = it->toLong();
+                kdDebug() << "Minolta Makernote Orientation: " << orientation << endl;
+                switch(orientation)
+                {
+                    case 76:
+                        imageOrient = ORIENTATION_ROT_90;
+                        break;
+                    case 82:
+                        imageOrient = ORIENTATION_ROT_270;
+                        break;
+                }
+                return imageOrient;
+            }
+        }
+
+        // -- Standard Exif tag --------------------------------
+
+        Exiv2::ExifKey keyStd("Exif.Image.Orientation");
+        it = exifData.findKey(keyStd);
+
+        if (it != exifData.end())
+        {
+            orientation = it->toLong();
+            kdDebug() << "Exif Orientation: " << orientation << endl;
+            return (ImageOrientation)orientation;
+        }
+    }
+    catch( Exiv2::Error &e )
+    {
+        kdDebug() << "Cannot parse Exif Orientation tag using Exiv2 (" 
+                  << QString::fromLocal8Bit(e.what().c_str())
+                  << ")" << endl;
+    }
+
+    return ORIENTATION_UNSPECIFIED;
+}
+
+bool Exiv2Iface::setImageOrientation(ImageOrientation orientation)
+{
+    if (d->exifMetadata.empty())
+       return false;
+
+    // Workaround for older Exiv2 versions which do not support
+    // Minolta Makernotes and throw an error for such keys.
+    bool supportMinolta = true;
+    try
+    {
+        Exiv2::ExifKey minoltaKey1("Exif.MinoltaCs7D.Rotation");
+        Exiv2::ExifKey minoltaKey2("Exif.MinoltaCs5D.Rotation");
+    }
+    catch( Exiv2::Error &e )
+    {
+        supportMinolta = false;
+    }
+
+    try
+    {    
+        if (orientation < ORIENTATION_UNSPECIFIED || orientation > ORIENTATION_ROT_270)
+        {
+            kdDebug() << k_funcinfo << "Exif orientation tag value is not correct!" << endl;
+            return false;
+        }
+        
+        d->exifMetadata["Exif.Image.Orientation"] = (uint16_t)orientation;
+        kdDebug() << "Exif orientation tag set to: " << orientation << endl;
+
+        // -- Minolta Cameras ----------------------------------
+
+        if (supportMinolta)
+        {
+            // Minolta camera store image rotation in Makernote.
+            // We remove these informations to prevent duplicate values. 
+    
+            Exiv2::ExifData::iterator it;
+
+            Exiv2::ExifKey minoltaKey1("Exif.MinoltaCs7D.Rotation");
+            it = d->exifMetadata.findKey(minoltaKey1);
+            if (it != d->exifMetadata.end())
+            {
+                d->exifMetadata.erase(it);
+                kdDebug() << "Removing Exif.MinoltaCs7D.Rotation tag" << endl;
+            }
+        
+            Exiv2::ExifKey minoltaKey2("Exif.MinoltaCs5D.Rotation");
+            it = d->exifMetadata.findKey(minoltaKey2);
+            if (it != d->exifMetadata.end())
+            {
+                d->exifMetadata.erase(it);
+                kdDebug() << "Removing Exif.MinoltaCs5D.Rotation tag" << endl;
+            }
+        }
+
+        return true;
+    }
+    catch( Exiv2::Error &e )
+    {
+        kdDebug() << "Cannot set Exif Orientation tag using Exiv2 (" 
+                  << QString::fromLocal8Bit(e.what().c_str())
+                  << ")" << endl;
+    }        
+    
+    return false;
+}
+
 }  // NameSpace KIPIPlugins
--- trunk/extragear/libs/kipi-plugins/common/exiv2iface/exiv2iface.h #585973:585974
@@ -5,6 +5,10 @@
  *
  * Copyright 2006 by Gilles Caulier
  *
+ * NOTE: This class is a simplified version of Digikam::DMetadata
+ *       class from digiKam core. Please contact digiKam team 
+ *       before to change/fix/improve this implementation.
+ *
  * 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;
@@ -38,6 +42,21 @@
 
 public:
 
+    enum ImageOrientation
+    {
+        ORIENTATION_UNSPECIFIED  = 0, 
+        ORIENTATION_NORMAL       = 1, 
+        ORIENTATION_HFLIP        = 2, 
+        ORIENTATION_ROT_180      = 3, 
+        ORIENTATION_VFLIP        = 4, 
+        ORIENTATION_ROT_90_HFLIP = 5, 
+        ORIENTATION_ROT_90       = 6, 
+        ORIENTATION_ROT_90_VFLIP = 7, 
+        ORIENTATION_ROT_270      = 8
+    };
+
+public:
+
     Exiv2Iface();
     ~Exiv2Iface();
     
@@ -57,7 +76,9 @@
     bool setExifThumbnail(const QImage& thumb);
     bool setExifTagString(const char *exifTagName, const QString& value);
     bool setImagePreview(const QImage& preview);
+    bool setImageOrientation(ImageOrientation orientation);
 
+    Exiv2Iface::ImageOrientation getImageOrientation();
     QDateTime getImageDateTime() const;
 
 private:
--- trunk/extragear/libs/kipi-plugins/jpeglossless/Makefile.am #585973:585974
@@ -1,5 +1,6 @@
 METASOURCES  = AUTO
 INCLUDES     = -I$(top_srcdir)/kipi-plugins/common/include \
+	           -I$(top_srcdir)/kipi-plugins/common/exiv2iface \
 	           $(LIBKIPI_CFLAGS) $(LIBKEXIF_CFLAGS) $(all_includes)
 
 # --enable-final triggers: http://bugs.kde.org/show_bug.cgi?id=126326
@@ -10,13 +11,14 @@
 # Install this plugin in the KDE modules directory
 kde_module_LTLIBRARIES = kipiplugin_jpeglossless.la
 
-kipiplugin_jpeglossless_la_DEPENDENCIES = $(LIBKIPI_LIBS_DEP) $(LIBKEXIF_LIBS_DEP)
+kipiplugin_jpeglossless_la_DEPENDENCIES = $(LIBKIPI_LIBS_DEP) 
 
 kipiplugin_jpeglossless_la_SOURCES = plugin_jpeglossless.cpp jpegtransform.cpp \
 		                             actionthread.cpp utils.cpp transupp.cpp \
 		                             imagerotate.cpp convert2grayscale.cpp imageflip.cpp 
 
-kipiplugin_jpeglossless_la_LIBADD = -ljpeg $(LIBKEXIF_LIBS) $(LIBKIPI_LIBS) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT)
+kipiplugin_jpeglossless_la_LIBADD = $(top_builddir)/kipi-plugins/common/exiv2iface/libexiv2iface.la \
+		                            -ljpeg $(LIBKIPI_LIBS) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT)
 
 
 kipiplugin_jpeglossless_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
--- trunk/extragear/libs/kipi-plugins/jpeglossless/jpegtransform.cpp #585973:585974
@@ -47,13 +47,9 @@
 #include <klocale.h>
 #include <ktempfile.h>
 
-// Lib KExif includes.
-
-#include <libkexif/kexifdata.h>
-#include <libkexif/kexifutils.h>
-
 // Local includes.
 
+#include "pluginsversion.h"
 #include "transupp.h"
 #include "jpegtransform.h"
 
@@ -124,23 +120,21 @@
 
     (void) jpeg_read_header(&srcinfo, true);
 
-    KExifData *exifData = new KExifData;
-    exifData->readFromFile(src);
+    // Get Exif orientation action to do.
+    KIPIPlugins::Exiv2Iface exiv2Iface;
+    exiv2Iface.load(src);
+    getExifAction(exifAction, exiv2Iface.getImageOrientation());
 
-    getExifAction(exifAction, exifData->getImageOrientation());
-
-    delete exifData;
-
     // Compose actions: first exif, then user
     action*=exifAction;
     action*=userAction;
 
-    //Convert action into flip+rotate action
+    // Convert action into flip+rotate action
     convertTransform(action, flip, rotate);
     kdDebug() << "Transforming with option " << flip << " " << rotate <<endl;
     bool twoPass = (flip != JXFORM_NONE);
 
-    //If twoPass is true, we need another file (src -> tempFile -> destGiven)
+    // If twoPass is true, we need another file (src -> tempFile -> destGiven)
     if (twoPass) 
     {
         KTempFile tempFile;
@@ -266,93 +260,102 @@
         fclose(input_file);
         fclose(output_file);
 
-        //unlink temp file
+        // Unlink temp file
         unlink(QFile::encodeName(dest));
     }
 
-    KExifUtils::writeOrientation(destGiven, KExifData::NORMAL);
+    // And set finaly update the metadata to target file.
 
+    QImage img(destGiven);
+    QImage exifThumbnail = img.scale(160, 120, QImage::ScaleMin);
+    exiv2Iface.load(destGiven);
+    exiv2Iface.setImageOrientation(KIPIPlugins::Exiv2Iface::ORIENTATION_NORMAL);
+    exiv2Iface.setImageProgramId(QString("Kipi JPEGLossLess"), QString(kipiplugins_version));
+    exiv2Iface.setImageDimensions(img.size());
+    exiv2Iface.setExifThumbnail(exifThumbnail);
+    exiv2Iface.save(destGiven);
+
     return true;
 }
 
-/*
-   Converts the mathematically correct description
-   into the primitive operations that can be carried out losslessly.
+/** Converts the mathematically correct description
+    into the primitive operations that can be carried out losslessly.
 */
 void convertTransform(Matrix &action, JXFORM_CODE &flip, JXFORM_CODE &rotate) 
 {
-   flip=JXFORM_NONE;
-   rotate=JXFORM_NONE;
-
-   if (action==Matrix::rotate90) 
-   {
-      rotate=JXFORM_ROT_90;
-   }
-   else if (action==Matrix::rotate180) 
-   {
-      rotate=JXFORM_ROT_180;
-   }
-   else if (action==Matrix::rotate270) 
-   {
-      rotate=JXFORM_ROT_270;
-   }
-   else if (action==Matrix::flipHorizontal) 
-   {
-      flip=JXFORM_FLIP_H;
-   }
-   else if (action==Matrix::flipVertical) 
-   {
-      flip=JXFORM_FLIP_V;
-   }
-   else if (action==Matrix::rotate90flipHorizontal) 
-   {
-      //first rotate, then flip!
-      rotate=JXFORM_ROT_90;
-      flip=JXFORM_FLIP_H;
-   }
-   else if (action==Matrix::rotate90flipVertical) 
-   {
-      //first rotate, then flip!
-      rotate=JXFORM_ROT_90;
-      flip=JXFORM_FLIP_V;
-   }
+    flip   = JXFORM_NONE;
+    rotate = JXFORM_NONE;
+    
+    if (action == Matrix::rotate90) 
+    {
+        rotate = JXFORM_ROT_90;
+    }
+    else if (action == Matrix::rotate180) 
+    {
+        rotate = JXFORM_ROT_180;
+    }
+    else if (action == Matrix::rotate270) 
+    {
+        rotate = JXFORM_ROT_270;
+    }
+    else if (action == Matrix::flipHorizontal) 
+    {
+        flip = JXFORM_FLIP_H;
+    }
+    else if (action == Matrix::flipVertical) 
+    {
+        flip = JXFORM_FLIP_V;
+    }
+    else if (action == Matrix::rotate90flipHorizontal) 
+    {
+        //first rotate, then flip!
+        rotate = JXFORM_ROT_90;
+        flip   = JXFORM_FLIP_H;
+    }
+    else if (action == Matrix::rotate90flipVertical) 
+    {
+        //first rotate, then flip!
+        rotate = JXFORM_ROT_90;
+        flip   = JXFORM_FLIP_V;
+    }
 }
 
-void getExifAction(Matrix &action, KExifData::ImageOrientation exifOrientation) 
+void getExifAction(Matrix &action, KIPIPlugins::Exiv2Iface::ImageOrientation exifOrientation) 
 {
     switch (exifOrientation) 
     {
-        case KExifData::NORMAL:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_NORMAL:
             break;
 
-        case KExifData::HFLIP:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_HFLIP:
             action*=Matrix::flipHorizontal;
             break;
 
-        case KExifData::ROT_180:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_ROT_180:
             action*=Matrix::rotate180;
             break;
 
-        case KExifData::VFLIP:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_VFLIP:
             action*=Matrix::flipVertical;
             break;
 
-        case KExifData::ROT_90_HFLIP:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_ROT_90_HFLIP:
             action*=Matrix::rotate90flipHorizontal;
             break;
 
-        case KExifData::ROT_90:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_ROT_90:
             action*=Matrix::rotate90;
             break;
 
-        case KExifData::ROT_90_VFLIP:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_ROT_90_VFLIP:
             action*=Matrix::rotate90flipVertical;
             break;
 
-        case KExifData::ROT_270:
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_ROT_270:
             action*=Matrix::rotate270;
             break;
-        case KExifData::UNSPECIFIED:
+
+        case KIPIPlugins::Exiv2Iface::ORIENTATION_UNSPECIFIED:
             action*=Matrix::none;
             break;
     }
--- trunk/extragear/libs/kipi-plugins/jpeglossless/jpegtransform.h #585973:585974
@@ -28,9 +28,9 @@
 
 #include <qstring.h>
 
-// Lib KExif includes. 
+// Local includes.
 
-#include <libkexif/kexifdata.h>
+#include "exiv2iface.h"
 
 namespace KIPIJPEGLossLessPlugin
 {
@@ -124,7 +124,7 @@
 
 void convertTransform(Matrix &action, JXFORM_CODE &flip, JXFORM_CODE &rotate);
 
-void getExifAction(Matrix &action, KExifData::ImageOrientation exifOrientation);
+void getExifAction(Matrix &action, KIPIPlugins::Exiv2Iface::ImageOrientation exifOrientation);
 
 }  // NameSpace KIPIJPEGLossLessPlugin
 
--- trunk/extragear/libs/kipi-plugins/kipiplugins.kdevelop #585973:585974
@@ -110,7 +110,7 @@
     <run>
       <directoryradio>custom</directoryradio>
       <customdirectory>/</customdirectory>
-      <mainprogram>/opt/kde3/bin/digikam</mainprogram>
+      <mainprogram>/usr/bin/digikam</mainprogram>
       <programargs/>
       <terminal>false</terminal>
       <autocompile>false</autocompile>


More information about the Kde-imaging mailing list