[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: extragear/graphics/gwenview
From: Aurélien Gâteau <aurelien.gateau () free ! fr>
Date: 2006-11-01 22:32:22
Message-ID: 1162420342.943355.21279.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 601062 by gateau:
Use Exiv2 instead of libexif to handle JPEG info. Avoid crashes with some JPEG
images.
BUG: 136112
M +1 -0 NEWS
M +19 -7 configure.in.in
M +1 -1 gvcore/Makefile.am
M +5 -5 imageutils/Makefile.am
D imageutils/jpeg-data.c
D imageutils/jpeg-data.h
D imageutils/jpeg-marker.c
D imageutils/jpeg-marker.h
M +47 -118 imageutils/jpegcontent.cpp
M +1 -1 imageutils/jpegcontent.h
--- trunk/extragear/graphics/gwenview/NEWS #601061:601062
@@ -10,6 +10,7 @@
shown in the title bar and it was causing the mainwindow to be enlarged if
the name was very long (Bug 127004)
- Show the "rotate left" button in KParts.
+ - Use Exiv2 instead of libexif to fix troubles with some JPEG (Bug 136112).
2006.09.16 - v1.4.0
- Fixes:
--- trunk/extragear/graphics/gwenview/configure.in.in #601061:601062
@@ -94,7 +94,9 @@
GV_ASM_DEFS="$gv_asm_defs"
AC_SUBST(GV_ASM_DEFS)
+#
# libmng check (for gvmngformattype.*)
+#
LIBMNG=
KDE_CHECK_HEADER(libmng.h,
[
@@ -109,14 +111,10 @@
AC_WARN([Can't find libmng.h, Gwenview won't be compiled with MNG support])
fi
-PKG_CHECK_MODULES(LIBEXIF, libexif >= 0.5.12, ,
- AC_MSG_WARN([libexif >= 0.5.12 not found. Please install it.])
- DO_NOT_COMPILE="gwenview $DO_NOT_COMPILE"
- )
-AC_SUBST(LIBEXIF_LIBS)
-AC_SUBST(LIBEXIF_CFLAGS)
-
+#
+# libxcursor
+#
KDE_CHECK_HEADERS(X11/Xcursor/Xcursor.h,
[KDE_CHECK_LIB(Xcursor, XcursorXcFileLoadImages, [
GV_LIB_XCURSOR=-lXcursor
@@ -127,3 +125,17 @@
if test -z "$GV_LIB_XCURSOR"; then
AC_WARN([Can't find Xcursor.h, Gwenview won't be compiled with X cursor \
support]) fi
+
+
+#
+# libexiv2
+#
+KDE_CHECK_HEADERS(exiv2/image.hpp, have_exiv2=yes, have_exiv2=no)
+
+if test "$have_exiv2" = "yes"; then
+ LIB_EXIV2="-lexiv2"
+ AC_SUBST(LIB_EXIV2)
+else
+ AC_MSG_WARN([You are missing libexiv2, which is required to compile Gwenview])
+ DO_NOT_COMPILE="$DO_NOT_COMPILE gwenview"
+fi
--- trunk/extragear/graphics/gwenview/gvcore/Makefile.am #601061:601062
@@ -7,7 +7,7 @@
libgwenviewcore_la_LIBADD = \
$(LIB_KFILE) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_KDEPRINT) $(LIB_QT) \
$(LIBJPEG) $(LIBPNG) $(LIBMNG) $(GV_LIB_XCURSOR) \
- $(LIBEXIF_LIBS) -lkmediaplayer ../imageutils/libgvimageutils.la \
+ -lkmediaplayer ../imageutils/libgvimageutils.la \
../tsthread/libtsthread.la
libgwenviewcore_la_METASOURCES = AUTO
--- trunk/extragear/graphics/gwenview/imageutils/Makefile.am #601061:601062
@@ -4,6 +4,8 @@
-DQT_CLEAN_NAMESPACE
AM_CCASFLAGS = -I$(srcdir) $(GV_ASM_DEFS)
+CXXFLAGS = -fexceptions
+
noinst_LTLIBRARIES = libgvimageutils.la
libgvimageutils_la_SOURCES = \
@@ -12,10 +14,10 @@
scale.cpp \
transupp.c \
asm_scale.S \
- jpeg-data.c \
- jpeg-marker.c \
croppedqimage.cpp
+libgvimageutils_la_LIBADD = $(LIB_KDECORE) $(LIBQT) $(LIBJPEG) $(LIB_EXIV2)
+
noinst_HEADERS = \
orientation.h \
imageutils.h \
@@ -30,7 +32,5 @@
check_PROGRAMS = testjpegcontent
testjpegcontent_SOURCES = testjpegcontent.cpp
-testjpegcontent_LDADD = \
- $(LIB_KFILE) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_KDEPRINT) $(LIB_QT) \
- $(LIBJPEG) $(LIBEXIF_LIBS) libgvimageutils.la
+testjpegcontent_LDADD = $(LIB_KFILE) libgvimageutils.la
testjpegcontent_LDFLAGS = $(all_libraries)
--- trunk/extragear/graphics/gwenview/imageutils/jpegcontent.cpp #601061:601062
@@ -38,15 +38,13 @@
// KDE
#include <kdebug.h>
-// Exif
-#include "exif-data.h"
-#include "exif-ifd.h"
-#include "exif-utils.h"
+// Exiv2
+#include <exiv2/exif.hpp>
+#include <exiv2/image.hpp>
// Local
#include "imageutils/imageutils.h"
#include "imageutils/jpegcontent.h"
-#include "imageutils/jpeg-data.h"
#include "imageutils/jpegerrormanager.h"
namespace ImageUtils {
@@ -145,16 +143,12 @@
QByteArray mRawData;
QSize mSize;
QString mComment;
- bool mPendingChanges;
+ bool mPendingTransformation;
QWMatrix mTransformMatrix;
- ExifData* mExifData;
- ExifEntry* mOrientationEntry;
- ExifByteOrder mByteOrder;
+ Exiv2::ExifData mExifData;
Private() {
- mPendingChanges = false;
- mExifData=0;
- mOrientationEntry=0;
+ mPendingTransformation = false;
}
void setupInmemSource(j_decompress_ptr cinfo) {
@@ -187,7 +181,7 @@
dest->mOutput=outputData;
}
- bool readJPEGInfo() {
+ bool readSize() {
struct jpeg_decompress_struct srcinfo;
jpeg_saved_marker_ptr mark;
@@ -215,15 +209,6 @@
}
mSize=QSize(srcinfo.image_width, srcinfo.image_height);
- // Read the comment, if any
- mComment=QString::null;
- for (mark = srcinfo.marker_list; mark; mark = mark->next) {
- if (mark->marker == JPEG_COM) {
- mComment=QString::fromUtf8((const char*)(mark->data), mark->data_length);
- break;
- }
- }
-
jpeg_destroy_decompress(&srcinfo);
return true;
}
@@ -241,9 +226,6 @@
JPEGContent::~JPEGContent() {
- if (d->mExifData) {
- exif_data_unref(d->mExifData);
- }
delete d;
}
@@ -259,12 +241,8 @@
bool JPEGContent::loadFromData(const QByteArray& data) {
- d->mPendingChanges = false;
+ d->mPendingTransformation = false;
d->mTransformMatrix.reset();
- if (d->mExifData) {
- exif_data_unref(d->mExifData);
- d->mExifData=0;
- }
d->mRawData = data;
if (d->mRawData.size()==0) {
@@ -272,19 +250,20 @@
return false;
}
- if (!d->readJPEGInfo()) return false;
+ if (!d->readSize()) return false;
- d->mExifData = exif_data_new_from_data((unsigned char*)data.data(), data.size());
- if (!d->mExifData) {
- kdError() << "Could not load exif data\n";
+ Exiv2::Image::AutoPtr image;
+ try {
+ image = Exiv2::ImageFactory::open((unsigned char*)data.data(), data.size());
+ } catch (Exiv2::Error&) {
+ kdError() << "Could not load image with Exiv2\n";
return false;
}
- d->mByteOrder = exif_data_get_byte_order(d->mExifData);
-
- d->mOrientationEntry =
- exif_content_get_entry(d->mExifData->ifd[EXIF_IFD_0],
- EXIF_TAG_ORIENTATION);
+ image->readMetadata();
+ d->mExifData = image->exifData();
+ d->mComment = QString::fromUtf8( image->comment().c_str() );
+
// Adjust the size according to the orientation
switch (orientation()) {
case TRANSPOSE:
@@ -302,21 +281,23 @@
Orientation JPEGContent::orientation() const {
- if (!d->mOrientationEntry) {
+ Exiv2::ExifKey key("Exif.Image.Orientation");
+ Exiv2::ExifData::iterator it = d->mExifData.findKey(key);
+ if (it == d->mExifData.end()) {
return NOT_AVAILABLE;
}
- short value=exif_get_short(d->mOrientationEntry->data, d->mByteOrder);
- if (value<NORMAL || value>ROT_270) return NOT_AVAILABLE;
- return Orientation(value);
+ return Orientation( it->toLong() );
}
void JPEGContent::resetOrientation() {
- if (!d->mOrientationEntry) {
+ Exiv2::ExifKey key("Exif.Image.Orientation");
+ Exiv2::ExifData::iterator it = d->mExifData.findKey(key);
+ if (it == d->mExifData.end()) {
return;
}
- exif_set_short(d->mOrientationEntry->data, d->mByteOrder,
- short(ImageUtils::NORMAL));
+
+ *it = uint16_t(ImageUtils::NORMAL);
}
@@ -331,43 +312,10 @@
void JPEGContent::setComment(const QString& comment) {
- d->mPendingChanges = true;
d->mComment = comment;
}
-
-// This code is inspired by jpegtools.c from fbida
-static void doSetComment(struct jpeg_decompress_struct *src, const QString& comment) \
{
- jpeg_saved_marker_ptr mark;
- int size;
-
- /* find or create comment marker */
- for (mark = src->marker_list;; mark = mark->next) {
- if (mark->marker == JPEG_COM)
- break;
- if (NULL == mark->next) {
- mark->next = (jpeg_marker_struct*)
- src->mem->alloc_large((j_common_ptr)src,JPOOL_IMAGE,
- sizeof(*mark));
- mark = mark->next;
- memset(mark,0,sizeof(*mark));
- mark->marker = JPEG_COM;
- break;
- }
- }
-
- /* update comment marker */
- QCString utf8=comment.utf8();
- size = utf8.length();
- mark->data = (JOCTET*)
- src->mem->alloc_large((j_common_ptr)src,JPOOL_IMAGE,size);
- mark->original_length = size;
- mark->data_length = size;
- memcpy(mark->data, utf8, size);
-}
-
-
static QWMatrix createRotMatrix(int angle) {
QWMatrix matrix;
matrix.rotate(angle);
@@ -419,7 +367,7 @@
void JPEGContent::transform(Orientation orientation) {
if (orientation != NOT_AVAILABLE && orientation != NORMAL) {
- d->mPendingChanges = true;
+ d->mPendingTransformation = true;
OrientationInfoList::ConstIterator it(orientationInfoList().begin()), \
end(orientationInfoList().end()); for (; it!=end; ++it) {
if ( (*it).orientation == orientation ) {
@@ -465,7 +413,7 @@
}
-void JPEGContent::applyPendingChanges() {
+void JPEGContent::applyPendingTransformation() {
if (d->mRawData.size()==0) {
kdError() << "No data loaded\n";
return;
@@ -505,8 +453,6 @@
(void) jpeg_read_header(&srcinfo, TRUE);
- doSetComment(&srcinfo, d->mComment);
-
// Init transformation
jpeg_transform_info transformoption;
transformoption.transform = findJxform(d->mTransformMatrix);
@@ -556,24 +502,19 @@
QImage JPEGContent::thumbnail() const {
QImage image;
- if( d->mExifData && d->mExifData->data ) {
- image.loadFromData( d->mExifData->data, d->mExifData->size, "JPEG" );
+ if (!d->mExifData.empty()) {
+ Exiv2::DataBuf thumbnail = d->mExifData.copyThumbnail();
+ image.loadFromData(thumbnail.pData_, thumbnail.size_);
}
return image;
}
void JPEGContent::setThumbnail(const QImage& thumbnail) {
- if( !d->mExifData) {
+ if (d->mExifData.empty()) {
return;
}
- if(d->mExifData->data) {
- free(d->mExifData->data);
- d->mExifData->data=0;
- }
- d->mExifData->size=0;
-
QByteArray array;
QBuffer buffer(array);
buffer.open(IO_WriteOnly);
@@ -584,13 +525,7 @@
return;
}
- d->mExifData->size=array.size();
- d->mExifData->data=(unsigned char*)malloc(d->mExifData->size);
- if (!d->mExifData->data) {
- kdError() << "Could not allocate memory for thumbnail\n";
- return;
- }
- memcpy(d->mExifData->data, array.data(), array.size());
+ d->mExifData.setJpegThumbnail((unsigned char*)array.data(), array.size());
}
@@ -611,29 +546,23 @@
return false;
}
- if (d->mPendingChanges) {
- applyPendingChanges();
- d->mPendingChanges = false;
+ if (d->mPendingTransformation) {
+ applyPendingTransformation();
+ d->mPendingTransformation = false;
}
- if (d->mExifData) {
- // Store Exif info
- JPEGData* jpegData=jpeg_data_new_from_data((unsigned char*)d->mRawData.data(), \
d->mRawData.size());
- if (!jpegData) {
- kdError() << "Could not create jpegData object\n";
- return false;
- }
-
- jpeg_data_set_exif_data(jpegData, d->mExifData);
- unsigned char* dest=0L;
- unsigned int destSize=0;
- jpeg_data_save_data(jpegData, &dest, &destSize);
- jpeg_data_unref(jpegData);
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open((unsigned \
char*)d->mRawData.data(), d->mRawData.size());
- // Update mRawData
- d->mRawData.assign((char*)dest, destSize);
- }
+ // Store Exif info
+ image->setExifData(d->mExifData);
+ image->setComment(d->mComment.utf8().data());
+ image->writeMetadata();
+ // Update mRawData
+ Exiv2::BasicIo& io = image->io();
+ d->mRawData.resize(io.size());
+ io.read((unsigned char*)d->mRawData.data(), io.size());
+
QDataStream stream(file);
stream.writeRawBytes(d->mRawData.data(), d->mRawData.size());
--- trunk/extragear/graphics/gwenview/imageutils/jpegcontent.h #601061:601062
@@ -65,7 +65,7 @@
JPEGContent(const JPEGContent&);
void operator=(const JPEGContent&);
- void applyPendingChanges();
+ void applyPendingTransformation();
};
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic