Bug 119946 - thumbnails not correctly rotated according to exif information
Summary: thumbnails not correctly rotated according to exif information
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Metadata-Orientation (show other bugs)
Version: 0.8.0
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-11 23:58 UTC by Christian Krause
Modified: 2017-08-12 10:39 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In: 0.9.0
Sentry Crash Report:


Attachments
patch which solves the problem (5.19 KB, patch)
2006-02-23 05:42 UTC, Christian Krause
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Krause 2006-01-11 23:58:41 UTC
Version:           0.8.0 (using KDE KDE 3.5.0)
Installed from:    Compiled From Sources
OS:                Linux

I have pictures with different orientation settings:
a) top-left: ok
b) left-bottom: ok
c) bottom-right: not ok

Images with orientation settings a) and b) are correctly displayed in the image editor/image view and as thumbnails. This means, that e.g. images of type b) are correctly rotated by 90 degree.

The pictures of type c) (180 degrees rotated) are correctly displayed in the image editor/image view, but the thumbnails are _not_ rotated.

Because the rotation even of the thumbnails works fine with images which are 90 degrees rotated, I assume that my digikam configuration is correct.


Configuration of digikam:
Embedded info:
- "Save image info..." is not set
- "rotate images/thumbs according to exif" is set
- "set exif orient. tag to normal after rotate" is not set
Comment 1 Tom Albers 2006-02-04 20:39:24 UTC
As far as i can see there should be debug output when you run digiKam from the konsole. Can you provide the output?
Comment 2 Christian Krause 2006-02-22 04:32:19 UTC
Hi,

sorry for the late answer:

Unfortunately there is no debug output when runnig digikam from the console:

chkr:~> digikam 
Link points to "/tmp/ksocket-chkr"
Link points to "/tmp/kde-chkr"
kbuildsycoca running...
Reusing existing ksycoca
chkr:~>

Do you have any idea, how I can reproduce the output.

Nevetheless, can you reproduce the probloem?
Comment 3 Christian Krause 2006-02-22 05:20:52 UTC
FYI: the problem is still in 0.8.1 
Unfortunately this bugzilla doesn't allow me to change the version information...
Comment 4 Christian Krause 2006-02-23 05:40:52 UTC
I've done a small debug session and found the source of the problem:
In the file digikam-0.8.1/digikam/kioslave/exiforientation_p.h is additional implementation to read the orientation exif tag. This function returns "NORMAL" as orientation for my picture although all other exif tools reports correctly a 180 degrees rotated picture. Additional the code of this file looks a little bit ugly. It seems to be a quick hack to get the orientation flag. No constants, mostly direct numbers and hex values are used. This comments supports my feeling:

// this code is not perfect, but the probability
// that the sequence below is not
// the Orientation tag is very small.

An additional comment indicates, that this code is only temporary and there should a transition to libkexif later.

If I change the code to use libkexif directly, the orientation is correctly recognized. I think it is not worth to find the problem in this old code - a transistion to libkexif is IMHO the best solution.

I'll attach a small patch which solves the problem. My code creates a KExifData object on the stack so this should be thread safe. If creating an object for every picture is too expensive, then it's up to the KDE and C++ gurus to find a better solution.

Nevertheless, this patch works perfectly for me and I hope my patch find its way (or something similiar) to KDE's CVS, SVN or whatever... :-)

Thank you very much in advance.
Comment 5 Christian Krause 2006-02-23 05:42:32 UTC
Created attachment 14819 [details]
patch which solves the problem
Comment 6 caulier.gilles 2006-02-23 07:43:17 UTC
OK, thanks for your patch.

This patch must be applied to 'stable' branch (0.8.x) in svn not 'trunk' branch (0.9.0) because Exiv2 library will be used at all instead libkexif...

Gilles
Comment 7 caulier.gilles 2006-03-06 09:15:14 UTC
SVN commit 516186 by cgilles:

digikam from trunk : Fix Exif auto-rotate thumbnails method in kioslave to use libKexif instead embedded implementation.

TODO : fix this implementation to use Exiv2 instead libkexif in the future.

CCMAIL: digikam-devel@kde.org

CCBUGS: 119946


 M  +8 -3      digikamthumbnail.cpp  
 D             exiforientation_p.h  


--- trunk/extragear/graphics/digikam/kioslave/digikamthumbnail.cpp #516185:516186
@@ -51,11 +51,14 @@
 #include <kprocess.h>
 #include <kio/thumbcreator.h>
 
+// Lib KExif includes.
+
+#include <libkexif/kexifdata.h>
+
 // Local includes
 
 #include "dcraw_parse.h"
 #include "dimg.h"
-#include "exiforientation_p.h"
 #include "digikamthumbnail.h"
 #include "digikam_export.h"
 
@@ -83,8 +86,10 @@
     // Rotate thumbnail based on EXIF rotate tag
     QWMatrix matrix;
 
-    KExifData::ImageOrientation orientation
-        = getExifOrientation(filePath);
+    KExifData ke;
+    ke.readFromFile(filePath);
+    KExifData::ImageOrientation orientation = ke.getImageOrientation();
+    kdDebug() << "Image Orientation: " << (KExifData::ImageOrientation)orientation << endl;
 
     bool doXform = (orientation != KExifData::NORMAL &&
                     orientation != KExifData::UNSPECIFIED);
Comment 8 caulier.gilles 2006-03-06 09:18:32 UTC
SVN commit 516187 by cgilles:

digikam from stable : Fix Exif auto-rotate thumbnails method in kioslave to use libKexif instead embedded implementation.

CCMAIL: digikam-devel@kde.org

CCBUGS: 119946


 M  +8 -3      digikamthumbnail.cpp  
 D             exiforientation_p.h  


--- branches/stable/extragear/graphics/digikam/kioslave/digikamthumbnail.cpp #516186:516187
@@ -55,6 +55,10 @@
 #include <kprocess.h>
 #include <kio/thumbcreator.h>
 
+// Lib KExif includes.
+
+#include <libkexif/kexifdata.h>
+
 // C Ansi includes.
 
 extern "C"
@@ -75,7 +79,6 @@
 // Local includes
 
 #include "dcraw_parse.h"
-#include "exiforientation_p.h"
 #include "digikamthumbnail.h"
 
 #define X_DISPLAY_MISSING 1
@@ -88,8 +91,10 @@
     // Rotate thumbnail based on EXIF rotate tag
     QWMatrix matrix;
 
-    KExifData::ImageOrientation orientation
-        = getExifOrientation(filePath);
+    KExifData ke;
+    ke.readFromFile(filePath);
+    KExifData::ImageOrientation orientation = ke.getImageOrientation();
+    kdDebug() << "Image Orientation: " << (KExifData::ImageOrientation)orientation << endl;
 
     bool doXform = (orientation != KExifData::NORMAL &&
                     orientation != KExifData::UNSPECIFIED);
Comment 9 caulier.gilles 2006-03-06 09:19:53 UTC
Auto-rotate Thumbnails creation using Exif tag tested with my large collection of jpeg image. Work fine now. This file can be closed.

Gilles Caulier
Comment 10 caulier.gilles 2006-05-27 12:48:14 UTC
SVN commit 545326 by cgilles:

digikam from stable: always use thumbnails generated by digiKam kio slave, not kde thumbnails generator.
CCBUGS: 119946, 123742

 M  +14 -10    digikamthumbnail.cpp  


--- branches/stable/extragear/graphics/digikam/kioslave/digikamthumbnail.cpp #545325:545326
@@ -21,6 +21,8 @@
  * ============================================================ */
 
 #define XMD_H
+#define PNG_BYTES_TO_CHECK 4
+#define DigiKamFingerPrint "Digikam Thumbnail Generator"
 
 // Qt Includes.
 
@@ -139,8 +141,6 @@
        thumb = thumb.xForm( matrix );
 }
 
-#define PNG_BYTES_TO_CHECK 4
-
 static QImage loadPNG(const QString& path)
 {
     png_uint_32         w32, h32;
@@ -264,9 +264,8 @@
     }
 
     int sizeOfUint = sizeof(unsigned int);
-    for (i = 0; i < h; i++)
-        lines[i] = ((unsigned char *)(qimage.bits())) +
-                   (i * w * sizeOfUint);
+    for (i = 0 ; i < h ; i++)
+        lines[i] = ((unsigned char *)(qimage.bits())) + (i * w * sizeOfUint);
 
     png_read_image(png_ptr, lines);
     free(lines);
@@ -274,7 +273,8 @@
     png_textp text_ptr;
     int num_text=0;
     png_get_text(png_ptr,info_ptr,&text_ptr,&num_text);
-    while (num_text--) {
+    while (num_text--) 
+    {
         qimage.setText(text_ptr->key,0,text_ptr->text);
         text_ptr++;
     }
@@ -288,7 +288,7 @@
 }
 
 kio_digikamthumbnailProtocol::kio_digikamthumbnailProtocol(int argc, char** argv) 
-    : SlaveBase("kio_digikamthumbnail", argv[2], argv[3])
+                            : SlaveBase("kio_digikamthumbnail", argv[2], argv[3])
 {
     argc_ = argc;
     argv_ = argv;
@@ -331,11 +331,15 @@
         error(KIO::ERR_INTERNAL, i18n("File does not exist"));
         return;
     }
+
+    // NOTE: if thumbnail have not been generated by digiKam (konqueror for example),
+    //       force to recompute it, else we use it.
     
     img = loadPNG(thumbPath);
     if (!img.isNull())
     {
-        if (img.text("Thumb::MTime") == QString::number(st.st_mtime))
+        if (img.text("Thumb::MTime") == QString::number(st.st_mtime) &&
+            img.text("Software")     == QString(DigiKamFingerPrint))
             regenerate = false;
     }
 
@@ -382,9 +386,9 @@
         if (exif)
             exifRotate(url.path(), img);            
 
-        img.setText(QString("Thumb::URI").latin1(), 0, uri);
+        img.setText(QString("Thumb::URI").latin1(),   0, uri);
         img.setText(QString("Thumb::MTime").latin1(), 0, QString::number(st.st_mtime));
-        img.setText(QString("Software").latin1(), 0, QString("Digikam Thumbnail Generator"));
+        img.setText(QString("Software").latin1(),     0, QString(DigiKamFingerPrint));
 
         KTempFile temp(thumbPath + "-digikam-", ".png");
         if (temp.status() == 0)
Comment 11 caulier.gilles 2006-05-27 12:49:36 UTC
SVN commit 545328 by cgilles:

digikam from trunk: always use thumbnails generated by digiKam kio slave, not kde thumbnails generator.
CCBUGS: 119946, 123742

 M  +10 -6     digikamthumbnail.cpp  


--- trunk/extragear/graphics/digikam/kioslave/digikamthumbnail.cpp #545327:545328
@@ -22,6 +22,7 @@
 
 #define XMD_H
 #define PNG_BYTES_TO_CHECK 4
+#define DigiKamFingerPrint "Digikam Thumbnail Generator"
 
 // C++ includes.
 
@@ -273,9 +274,8 @@
     }
 
     int sizeOfUint = sizeof(unsigned int);
-    for (i = 0; i < h; i++)
-        lines[i] = ((unsigned char *)(qimage.bits())) +
-                   (i * w * sizeOfUint);
+    for (i = 0 ; i < h ; i++)
+        lines[i] = ((unsigned char *)(qimage.bits())) + (i * w * sizeOfUint);
 
     png_read_image(png_ptr, lines);
     free(lines);
@@ -341,10 +341,14 @@
         return;
     }
 
+    // NOTE: if thumbnail have not been generated by digiKam (konqueror for example),
+    //       force to recompute it, else we use it.
+
     img = loadPNG(thumbPath);
     if (!img.isNull())
     {
-        if (img.text("Thumb::MTime") == QString::number(st.st_mtime))
+        if (img.text("Thumb::MTime") == QString::number(st.st_mtime) &&
+            img.text("Software")     == QString(DigiKamFingerPrint))
             regenerate = false;
     }
 
@@ -387,9 +391,9 @@
         if (exif)
             exifRotate(url.path(), img);
 
-        img.setText(QString("Thumb::URI").latin1(), 0, uri);
+        img.setText(QString("Thumb::URI").latin1(),   0, uri);
         img.setText(QString("Thumb::MTime").latin1(), 0, QString::number(st.st_mtime));
-        img.setText(QString("Software").latin1(), 0, QString("Digikam Thumbnail Generator"));
+        img.setText(QString("Software").latin1(),     0, QString(DigiKamFingerPrint));
 
         KTempFile temp(thumbPath + "-digikam-", ".png");
         if (temp.status() == 0)