]> git.sesse.net Git - mlt/commitdiff
Use libexif to read exif orientation in images
authorj-b-m <jb@kdenlive.org>
Wed, 28 Jul 2010 22:47:19 +0000 (23:47 +0100)
committerj-b-m <jb@kdenlive.org>
Wed, 28 Jul 2010 22:47:19 +0000 (23:47 +0100)
modified:   src/modules/gtk2/Makefile
modified:   src/modules/gtk2/configure
modified:   src/modules/gtk2/producer_pixbuf.c
modified:   src/modules/qimage/Makefile
modified:   src/modules/qimage/configure
modified:   src/modules/qimage/qimage_wrapper.cpp
deleted:    src/modules/qimage/readexif.h

src/modules/gtk2/Makefile
src/modules/gtk2/configure
src/modules/gtk2/producer_pixbuf.c
src/modules/qimage/Makefile
src/modules/qimage/configure
src/modules/qimage/qimage_wrapper.cpp
src/modules/qimage/readexif.h [deleted file]

index 19ad1d6a47de01870d7d4ab0d10e0af7ed001078..21cf033f2f5e41673cf250cb78d02eea6fa4467a 100644 (file)
@@ -21,6 +21,11 @@ CFLAGS += `pkg-config gdk-pixbuf-2.0 --cflags`
 LDFLAGS += `pkg-config gdk-pixbuf-2.0 --libs`
 endif
 
+ifdef USE_EXIF
+CFLAGS += $(EXIFCXXFLAGS) 
+LDFLAGS += $(EXIFLIBS)
+endif
+
 ifdef MMX_FLAGS
 ifndef ARCH_X86_64
 ASM_OBJS = have_mmx.o scale_line_22_yuv_mmx.o
index 299da4b88facde0949232463e8483b54e39e83f4..a01e40801f38dc85ce8f5c3301bd6e2e855a9364 100755 (executable)
@@ -33,6 +33,29 @@ then
        [ "$disable_pixbuf" = "0" ] && echo "USE_PIXBUF=1" >> config.mak
        [ "$disable_pango" = "0" ] && echo "USE_PANGO=1" >> config.mak
 
+       pkg-config --exists 'libexif'
+       if [ $? -eq 0 ]
+       then
+           echo "Libexif found, enabling auto rotate"
+           echo "#define USE_EXIF" >> config.h
+           echo "USE_EXIF=1" >> config.mak
+           echo EXIFCXXFLAGS=$(pkg-config --cflags libexif ) >> config.mak
+           echo EXIFLIBS=$(pkg-config --libs libexif) >> config.mak
+       elif [ -d "$exif_libdir" -a -d "$exif_includedir" ]
+       then
+               # test if we have a libexif
+               if [ -f "$exif_libdir/exif-data.h" ]
+               then
+                       echo "Libexif found, enabling auto rotate"
+                       echo "#define USE_EXIF" >> config.h
+                       echo "USE_EXIF=1" >> config.mak
+                       echo EXIFCXXFLAGS=-I$exif_includedir >> config.mak
+                        echo EXIFLIBS=-L$exif_libdir lexif >> config.mak
+               else
+                       echo "Libexif not found, disabling exif features (auto rotate)"
+               fi
+       fi
+
        exit 0
 fi
 
index 9ed0055af5a53dabb50f07bd02950c0dae61abae..f7ab325855b946be2cf71906c8b60e193d94037f 100644 (file)
 #include <framework/mlt_cache.h>
 #include <framework/mlt_log.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include "../qimage/readexif.h"
+
+#include "config.h"
+
+#ifdef USE_EXIF
+#include <exif-data.h>
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -283,10 +288,18 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
 
                if ( pixbuf )
                {
+#ifdef USE_EXIF
                        // Read the exif value for this file
                        if ( disable_exif == 0) {
-                               int exif_orientation = check_exif_orientation(mlt_properties_get_value( this->filenames, image_idx ));
-
+                               ExifData *d = exif_data_new_from_file( mlt_properties_get_value( this->filenames, image_idx ) );
+                               ExifEntry *entry;
+                               ExifByteOrder byte_order = exif_data_get_byte_order (d);
+                               int exif_orientation = 0;
+                               /* get orientation and rotate image accordingly if necessary */
+                               if ((entry = exif_content_get_entry (d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION)))
+                               {
+                                       exif_orientation = exif_get_short (entry->data, byte_order);
+                               }
                                if ( exif_orientation > 1 )
                                {
                                        GdkPixbuf *processed;
@@ -324,6 +337,8 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
                                        pixbuf = gdk_pixbuf_rotate_simple( processed, matrix );
                                }
                        }
+#endif
+
                        // Register this pixbuf for destruction and reuse
                        mlt_cache_item_close( pixbuf_cache );
                        mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref );
index 9424db531a82113ca5af317e78b9e218e5a3c1a2..064a0e1dc71558a14fe89e330ac416de0437c3f1 100644 (file)
@@ -10,9 +10,9 @@ TARGET = ../libmltqimage$(LIBSUF)
 OBJS = factory.o producer_qimage.o producer_kdenlivetitle.o
 CPPOBJS = qimage_wrapper.o kdenlivetitle_wrapper.o
 
-CXXFLAGS += $(CFLAGS) $(QTCXXFLAGS) -Wno-deprecated
+CXXFLAGS += $(CFLAGS) $(QTCXXFLAGS) $(EXIFCXXFLAGS) -Wno-deprecated
 
-LDFLAGS += $(QTLIBS)
+LDFLAGS += $(QTLIBS) $(EXIFLIBS)
 LDFLAGS += -lstdc++
 
 ifdef USE_KDE
index 592e246b6fadd63f33c6b014b4b206671217c620..d33c1fefde35babbc6e6c1ba6b4e724a9ddded27 100755 (executable)
@@ -10,6 +10,8 @@ QImage options:
   --qimage-includedir     - Location of QT include directory [/usr/include/qt4 or /usr/include/qt3]
   --kde-libdir            - Location of KDE lib directory [/usr/lib]
   --kde-includedir        - Location of KDE include directory [/usr/include/kde]
+  --exif-libdir           - Location of libexif lib directory [/usr/lib]
+  --exif-includedir       - Location of libexif include directory [/usr/include/libexif]
 
 EOF
 
@@ -61,17 +63,45 @@ else
                        --qimage-includedir=* ) qimage_includedir="${i#--qimage-includedir=}" ;;
                        --kde-libdir=* )        kde_libdir="${i#--kde-libdir=}" ;;
                        --kde-includedir=* )    kde_includedir="${i#--kde-includedir=}" ;;
+                       --exif-libdir=* )       exif_libdir="${i#--exif-libdir=}" ;;
+                       --exif-includedir=* )   exif_includedir="${i#--exif-includedir=}" ;;
                        --force-qt3 )           force_qt3="true" ;;
                esac
        done
 
+       echo > config.h
+       echo > config.mak
+
+       pkg-config --exists 'libexif'
+       if [ $? -eq 0 ]
+       then
+           echo "Libexif found, enabling auto rotate"
+           echo "#define USE_EXIF" >> config.h
+           echo "USE_EXIF=1" >> config.mak
+           echo EXIFCXXFLAGS=$(pkg-config --cflags libexif ) >> config.mak
+           echo EXIFLIBS=$(pkg-config --libs libexif) >> config.mak
+       elif [ -d "$exif_libdir" -a -d "$exif_includedir" ]
+       then
+               # test if we have a libexif
+               if [ -f "$exif_libdir/exif-data.h" ]
+               then
+                       echo "Libexif found, enabling auto rotate"
+                       echo "#define USE_EXIF" >> config.h
+                       echo "USE_EXIF=1" >> config.mak
+                       echo EXIFCXXFLAGS=-I$exif_includedir >> config.mak
+                        echo EXIFLIBS=-L$exif_libdir lexif >> config.mak
+               else
+                       echo "Libexif not found, disabling exif features (auto rotate)"
+               fi
+       fi
+
        pkg-config --exists 'QtGui >= 4'
        if [ $? -eq 0 ] && [ "$force_qt3" = "" ]
        then
                echo "Qt version 4.x detected, will compile Qt4 qimage producer"
                qt4_found=true
-               echo "#define USE_QT4" > config.h
-               echo "USE_QT4=1" > config.mak
+               echo "#define USE_QT4" >> config.h
+               echo "USE_QT4=1" >> config.mak
                echo QTCXXFLAGS=$(pkg-config --cflags QtCore QtGui QtXml QtSvg ) >> config.mak
                echo QTLIBS=$(pkg-config --libs QtCore QtGui QtXml QtSvg) >> config.mak
                
@@ -89,8 +119,6 @@ else
 
                echo "Include directory: " $qimage_includedir
 
-               echo > config.h
-               echo > config.mak
                if [ "$qt4_found" != "" ] && [ "$force_qt3" = "" ]
                then
                        echo "#define USE_QT4" >> config.h
index c16cd57c8e6070e911bdba7ceb9ed309aed141a7..4af012a810ecb922f73a967d0d314120090fe03c 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include "qimage_wrapper.h"
-#include "readexif.h"
 
 #ifdef USE_QT3
 #include <qimage.h>
@@ -43,6 +42,9 @@
 #include <QtCore/QtEndian>
 #endif
 
+#ifdef USE_EXIF
+#include <exif-data.h>
+#endif
 
 #include <cmath>
 
@@ -169,10 +171,18 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
 
                if ( !qimage->isNull( ) )
                {
+#ifdef USE_EXIF
                        // Read the exif value for this file
                        if ( disable_exif == 0) {
-                               int exif_orientation = check_exif_orientation(mlt_properties_get_value( self->filenames, image_idx ));
-
+                               ExifData *d = exif_data_new_from_file( mlt_properties_get_value( self->filenames, image_idx ) );
+                               ExifEntry *entry;
+                               ExifByteOrder byte_order = exif_data_get_byte_order (d);
+                               int exif_orientation = 0;
+                               /* get orientation and rotate image accordingly if necessary */
+                               if ((entry = exif_content_get_entry (d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION)))
+                               {
+                                       exif_orientation = exif_get_short (entry->data, byte_order);
+                               }
                                if ( exif_orientation > 1 )
                                {
                                      // Rotate image according to exif data
@@ -209,7 +219,7 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
                                      qimage = new QImage( processed );
                                }
                        }
-                       
+#endif                 
                        // Store the width/height of the qimage  
                        self->current_width = qimage->width( );
                        self->current_height = qimage->height( );
diff --git a/src/modules/qimage/readexif.h b/src/modules/qimage/readexif.h
deleted file mode 100644 (file)
index 8e1a504..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*\r
- * readexif.h\r
- * \r
- * Slightly modified for use in MLT by Jean-Baptiste Mardelle, 2010\r
- * based on jpegexiforient.c, part of the `jpeg library' by the\r
- * Independent JPEG Group (IJG)).\r
- *\r
- * The Exif orientation value gives the orientation of the camera\r
- * relative to the scene when the image was captured.  The relation\r
- * of the '0th row' and '0th column' to visual position is shown as\r
- * below.\r
- * \r
- *\r
- * Value | 0th Row     | 0th Column\r
- * ------+-------------+-----------\r
- *   1   | top         | left side\r
- *   2   | top         | rigth side\r
- *   3   | bottom      | rigth side\r
- *   4   | bottom      | left side\r
- *   5   | left side   | top\r
- *   6   | right side  | top\r
- *   7   | right side  | bottom\r
- *   8   | left side   | bottom\r
- *\r
- * For convenience, here is what the letter F would look like if it were\r
- * tagged correctly and displayed by a program that ignores the orientation\r
- * tag:\r
- *\r
- *   1        2       3      4         5            6           7          8\r
- *\r
- * 888888  888888      88  88      8888888888  88                  88  8888888888\r
- * 88          88      88  88      88  88      88  88          88  88      88  88\r
- * 8888      8888    8888  8888    88          8888888888  8888888888          88\r
- * 88          88      88  88\r
- * 88          88  888888  888888\r
- *\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-static FILE * myfile;\r
-static unsigned char exif_data[65536L];\r
-\r
-/* Return next input byte, or EOF if no more */\r
-#define NEXTBYTE()  getc(myfile)\r
-\r
-/* Error exit handler */\r
-#define ERREXIT(msg)  (exit(0))\r
-\r
-/* Read one byte, testing for EOF */\r
-static int\r
-read_1_byte (void)\r
-{\r
-  int c;\r
-\r
-  c = NEXTBYTE();\r
-  if (c == EOF)\r
-    ERREXIT("Premature EOF in JPEG file");\r
-  return c;\r
-}\r
-\r
-/* Read 2 bytes, convert to unsigned int */\r
-/* All 2-byte quantities in JPEG markers are MSB first */\r
-static unsigned int\r
-read_2_bytes (void)\r
-{\r
-  int c1, c2;\r
-\r
-  c1 = NEXTBYTE();\r
-  if (c1 == EOF)\r
-    ERREXIT("Premature EOF in JPEG file");\r
-  c2 = NEXTBYTE();\r
-  if (c2 == EOF)\r
-    ERREXIT("Premature EOF in JPEG file");\r
-  return (((unsigned int) c1) << 8) + ((unsigned int) c2);\r
-}\r
-\r
-int check_exif_orientation(char *fname)\r
-{\r
-  int set_flag;\r
-  unsigned int length, i;\r
-  int is_motorola; /* Flag for byte order */\r
-  unsigned int offset, number_of_tags, tagnum;\r
-\r
-    if ((myfile = fopen(fname, "rb")) == NULL) {\r
-       fprintf(stderr, "can't open %s\n", fname);\r
-       return 0;\r
-    }\r
-\r
-  /* Read File head, check for JPEG SOI + Exif APP1 */\r
-  for (i = 0; i < 4; i++)\r
-    exif_data[i] = (unsigned char) read_1_byte();\r
-  if (exif_data[0] != 0xFF ||\r
-      exif_data[1] != 0xD8 ||\r
-      exif_data[2] != 0xFF ||\r
-      exif_data[3] != 0xE1)\r
-    return 0;\r
-  /* Get the marker parameter length count */\r
-  length = read_2_bytes();\r
-  /* Length includes itself, so must be at least 2 */\r
-  /* Following Exif data length must be at least 6 */\r
-  if (length < 8)\r
-    return 0;\r
-  length -= 8;\r
-  /* Read Exif head, check for "Exif" */\r
-  for (i = 0; i < 6; i++)\r
-    exif_data[i] = (unsigned char) read_1_byte();\r
-  if (exif_data[0] != 0x45 ||\r
-      exif_data[1] != 0x78 ||\r
-      exif_data[2] != 0x69 ||\r
-      exif_data[3] != 0x66 ||\r
-      exif_data[4] != 0 ||\r
-      exif_data[5] != 0)\r
-    return 0;\r
-  /* Read Exif body */\r
-  for (i = 0; i < length; i++)\r
-    exif_data[i] = (unsigned char) read_1_byte();\r
-\r
-  if (length < 12) return 0; /* Length of an IFD entry */\r
-\r
-  /* Discover byte order */\r
-  if (exif_data[0] == 0x49 && exif_data[1] == 0x49)\r
-    is_motorola = 0;\r
-  else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D)\r
-    is_motorola = 1;\r
-  else\r
-    return 0;\r
-\r
-  /* Check Tag Mark */\r
-  if (is_motorola) {\r
-    if (exif_data[2] != 0) return 0;\r
-    if (exif_data[3] != 0x2A) return 0;\r
-  } else {\r
-    if (exif_data[3] != 0) return 0;\r
-    if (exif_data[2] != 0x2A) return 0;\r
-  }\r
-\r
-  /* Get first IFD offset (offset to IFD0) */\r
-  if (is_motorola) {\r
-    if (exif_data[4] != 0) return 0;\r
-    if (exif_data[5] != 0) return 0;\r
-    offset = exif_data[6];\r
-    offset <<= 8;\r
-    offset += exif_data[7];\r
-  } else {\r
-    if (exif_data[7] != 0) return 0;\r
-    if (exif_data[6] != 0) return 0;\r
-    offset = exif_data[5];\r
-    offset <<= 8;\r
-    offset += exif_data[4];\r
-  }\r
-  if (offset > length - 2) return 0; /* check end of data segment */\r
-\r
-  /* Get the number of directory entries contained in this IFD */\r
-  if (is_motorola) {\r
-    number_of_tags = exif_data[offset];\r
-    number_of_tags <<= 8;\r
-    number_of_tags += exif_data[offset+1];\r
-  } else {\r
-    number_of_tags = exif_data[offset+1];\r
-    number_of_tags <<= 8;\r
-    number_of_tags += exif_data[offset];\r
-  }\r
-  if (number_of_tags == 0) return 0;\r
-  offset += 2;\r
-\r
-  /* Search for Orientation Tag in IFD0 */\r
-  for (;;) {\r
-    if (offset > length - 12) return 0; /* check end of data segment */\r
-    /* Get Tag number */\r
-    if (is_motorola) {\r
-      tagnum = exif_data[offset];\r
-      tagnum <<= 8;\r
-      tagnum += exif_data[offset+1];\r
-    } else {\r
-      tagnum = exif_data[offset+1];\r
-      tagnum <<= 8;\r
-      tagnum += exif_data[offset];\r
-    }\r
-    if (tagnum == 0x0112) break; /* found Orientation Tag */\r
-    if (--number_of_tags == 0) return 0;\r
-    offset += 12;\r
-  }\r
-  /* Get the Orientation value */\r
-    if (is_motorola) {\r
-      if (exif_data[offset+8] != 0) return 0;\r
-      set_flag = exif_data[offset+9];\r
-    } else {\r
-      if (exif_data[offset+9] != 0) return 0;\r
-      set_flag = exif_data[offset+8];\r
-    }\r
-    if (set_flag > 8) return 0;\r
-    return set_flag;\r
-}\r
-\r