Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
No build reason found for images:x86_64
openSUSE:12.2:PowerPC
kdegraphics3
better-exif.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File better-exif.patch of Package kdegraphics3
--- kfile-plugins/jpeg/kfile_jpeg.cpp +++ kfile-plugins/jpeg/kfile_jpeg.cpp @@ -19,7 +19,6 @@ * */ - #include <stdlib.h> #include "kfile_jpeg.h" @@ -35,8 +34,11 @@ #include <qdict.h> #include <qvalidator.h> #include <qimage.h> +#include <qwmatrix.h> -#include "exif.h" +#include <exiv2/image.hpp> +#include <exiv2/exif.hpp> +#include <exiv2/tags.hpp> #define EXIFGROUP "Jpeg EXIF Data" @@ -58,98 +60,35 @@ KJpegPlugin::KJpegPlugin(QObject *parent i18n("JPEG Exif") ); KFileMimeTypeInfo::ItemInfo* item; - item = addItemInfo( exifGroup, "Comment", i18n("Comment"), QVariant::String); + item = addItemInfo( exifGroup, "UserComment", i18n("Comment"), QVariant::String); setAttributes( item, - KFileMimeTypeInfo::Modifiable | - KFileMimeTypeInfo::Addable | +// KFileMimeTypeInfo::Modifiable | +// KFileMimeTypeInfo::Addable | KFileMimeTypeInfo::MultiLine ); - item = addItemInfo( exifGroup, "Manufacturer", i18n("Camera Manufacturer"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Model", i18n("Camera Model"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Date/time", i18n("Date/Time"), - QVariant::DateTime ); - - item = addItemInfo( exifGroup, "CreationDate", i18n("Creation Date"), - QVariant::Date ); - - item = addItemInfo( exifGroup, "CreationTime", i18n("Creation Time"), - QVariant::Time ); - item = addItemInfo( exifGroup, "Dimensions", i18n("Dimensions"), QVariant::Size ); setHint( item, KFileMimeTypeInfo::Size ); setUnit( item, KFileMimeTypeInfo::Pixels ); - item = addItemInfo( exifGroup, "Orientation", i18n("Orientation"), - QVariant::Int ); - - item = addItemInfo( exifGroup, "ColorMode", i18n("Color Mode"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Flash used", i18n("Flash Used"), - QVariant::String ); - item = addItemInfo( exifGroup, "Focal length", i18n("Focal Length"), - QVariant::String ); - setUnit( item, KFileMimeTypeInfo::Millimeters ); - - item = addItemInfo( exifGroup, "35mm equivalent", i18n("35mm Equivalent"), - QVariant::Int ); - setUnit( item, KFileMimeTypeInfo::Millimeters ); - - item = addItemInfo( exifGroup, "CCD width", i18n("CCD Width"), - QVariant::String ); - setUnit( item, KFileMimeTypeInfo::Millimeters ); - - item = addItemInfo( exifGroup, "Exposure time", i18n("Exposure Time"), - QVariant::String ); - setHint( item, KFileMimeTypeInfo::Seconds ); - - item = addItemInfo( exifGroup, "Aperture", i18n("Aperture"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Focus dist.", i18n("Focus Dist."), - QVariant::String ); - - item = addItemInfo( exifGroup, "Exposure bias", i18n("Exposure Bias"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Whitebalance", i18n("Whitebalance"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Metering mode", i18n("Metering Mode"), - QVariant::String ); - - item = addItemInfo( exifGroup, "Exposure", i18n("Exposure"), - QVariant::String ); - - item = addItemInfo( exifGroup, "ISO equiv.", i18n("ISO Equiv."), - QVariant::String ); - - item = addItemInfo( exifGroup, "JPEG quality", i18n("JPEG Quality"), - QVariant::String ); - - item = addItemInfo( exifGroup, "User comment", i18n("User Comment"), - QVariant::String ); - setHint(item, KFileMimeTypeInfo::Description); - - item = addItemInfo( exifGroup, "JPEG process", i18n("JPEG Process"), - QVariant::String ); - item = addItemInfo( exifGroup, "Thumbnail", i18n("Thumbnail"), QVariant::Image ); setHint( item, KFileMimeTypeInfo::Thumbnail ); -// ### -// exifGroup.setSupportsVariableKeys(true); + for (const Exiv2::TagInfo* taglist = Exiv2::ExifTags::ifdTagList(); + taglist->tag_ != 0xffff; taglist++) + addItemInfo (exifGroup, taglist->name_, taglist->title_, QVariant::String); + + for (const Exiv2::TagInfo* taglist = Exiv2::ExifTags::exifTagList(); + taglist->tag_ != 0xffff; taglist++) + addItemInfo (exifGroup, taglist->name_, taglist->title_, QVariant::String); + + //exifGroup->setSupportsVariableKeys(true); } QValidator* KJpegPlugin::createValidator(const KFileMetaInfoItem& /*item*/, - QObject */*parent*/, - const char */*name*/ ) const + QObject* /*parent*/, + const char* /*name*/ ) const { // no need to return a validator that validates everything as OK :) // if (item.isEditable()) @@ -161,30 +100,48 @@ QValidator* KJpegPlugin::createValidator bool KJpegPlugin::writeInfo( const KFileMetaInfo& info ) const { QString comment = info[EXIFGROUP].value("Comment").toString(); - QString path = info.path(); kdDebug(7034) << "exif writeInfo: " << info.path() << " \"" << comment << "\"\n"; +#if 0 + try { + Exiv2::Image::AutoPtr image = + Exiv2::ImageFactory::open(QFile::encodeName(info.path()).data()); + image->readMetadata(); + Exiv2::ExifData &exifData = image->exifData(); + + /* + Exiv2 uses a CommentValue for Exif user comments. The format of the + comment string includes an optional charset specification at the beginning: + + [charset=["]Ascii|Jis|Unicode|Undefined["] ]comment + + Undefined is used as a default if the comment doesn't start with a charset + definition. + + Following are a few examples of valid comments. The last one is written to + the file. + */ + exifData["Exif.Photo.UserComment"] + = "charset=\"Unicode\" An Unicode Exif comment added with Exiv2"; + exifData["Exif.Photo.UserComment"] + = "charset=\"Undefined\" An undefined Exif comment added with Exiv2"; + exifData["Exif.Photo.UserComment"] + = "Another undefined Exif comment added with Exiv2"; + exifData["Exif.Photo.UserComment"] + = "charset=Ascii An ASCII Exif comment added with Exiv2"; - /* - Do a strictly safe insertion of the comment: + exifData["Exif.Photo.UserComment"] + = std::string("charset=\"Unicode\" ") + std::string(comment.utf8().data()); - Scan original to verify it's a proper jpeg - Open a unique temporary file in this directory - Write temporary, replacing all COM blocks with this one. - Scan temporary, to verify it's a proper jpeg - Rename original to another unique name - Rename temporary to original - Unlink original - */ - /* - The jpeg standard does not regulate the contents of the COM block. - I'm assuming the best thing to do here is write as unicode utf-8, - which is fully backwards compatible with readers expecting ascii. - Readers expecting a national character set are out of luck... - */ - if( safe_copy_and_modify( QFile::encodeName( path ), comment.utf8() ) ) { - return false; - } + image->writeMetadata(); + } + catch (Exiv2::AnyError& e) + { + return false; + } +#else + return false; +#endif return true; } @@ -194,292 +151,79 @@ bool KJpegPlugin::readInfo( KFileMetaInf if ( path.isEmpty() ) // remote file return false; - QString tag; - ExifData ImageInfo; + std::string tag; - // parse the jpeg file now try { - if ( !ImageInfo.scan(info.path()) ) { - kdDebug(7034) << "Not a JPEG file!\n"; + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(info.path().utf8().data()); + if (!image.get()) return false; - } - } - catch (FatalError& e) { // malformed exif data? - kdDebug(7034) << "Exception caught while parsing Exif data of: " << info.path() << endl; - e.debug_print(); - return false; - } + image->readMetadata(); + Exiv2::ExifData& ImageInfo = image->exifData(); - KFileMetaInfoGroup exifGroup = appendGroup( info, EXIFGROUP ); + KFileMetaInfoGroup exifGroup = appendGroup( info, EXIFGROUP ); - tag = ImageInfo.getComment(); - if ( tag.length() ) { - kdDebug(7034) << "exif inserting Comment: " << tag << "\n"; - appendItem( exifGroup, "Comment", tag ); - } else { - appendItem( exifGroup, "Comment", tag ); // So user can add new comment - } - - tag = ImageInfo.getCameraMake(); - if (tag.length()) - appendItem( exifGroup, "Manufacturer", tag ); - - tag = ImageInfo.getCameraModel(); - if (tag.length()) - appendItem( exifGroup, "Model", tag ); - - tag = ImageInfo.getDateTime(); - if (tag.length()){ - QDateTime dt = parseDateTime( tag.stripWhiteSpace() ); - if ( dt.isValid() ) { - appendItem( exifGroup, "Date/time", dt ); - appendItem( exifGroup, "CreationDate", dt.date() ); - appendItem( exifGroup, "CreationTime", dt.time() ); + tag = image->comment(); + if ( tag.length() ) { + kdDebug(7034) << "exif inserting Comment: " << tag.c_str() << "\n"; + appendItem( exifGroup, "UserComment", QString::fromUtf8(tag.c_str()) ); + } else { + appendItem( exifGroup, "UserComment", QString::null); // So user can add new comment } - } - - appendItem( exifGroup,"Dimensions", QSize( ImageInfo.getWidth(), - ImageInfo.getHeight() ) ); - - if ( ImageInfo.getOrientation() ) - appendItem( exifGroup, "Orientation", ImageInfo.getOrientation() ); - - appendItem( exifGroup, "ColorMode", ImageInfo.getIsColor() ? - i18n("Color") : i18n("Black and white") ); - int flashUsed = ImageInfo.getFlashUsed(); // -1, <set> - if ( flashUsed >= 0 ) { - QString flash = i18n("Flash", "(unknown)"); - switch ( flashUsed ) { - case 0: flash = i18n("Flash", "No"); - break; - case 1: - case 5: - case 7: - flash = i18n("Flash", "Fired"); - break; - case 9: - case 13: - case 15: - flash = i18n( "Flash", "Fill Fired" ); - break; - case 16: - flash = i18n( "Flash", "Off" ); - break; - case 24: - flash = i18n( "Flash", "Auto Off" ); - break; - case 25: - case 29: - case 31: - flash = i18n( "Flash", "Auto Fired" ); - break; - case 32: - flash = i18n( "Flash", "Not Available" ); - break; - default: - break; + for (Exiv2::ExifData::const_iterator i = ImageInfo.begin(); + i != ImageInfo.end(); ++i) { + std::ostringstream str; + str << *i; + QString dt = QString::fromUtf8( str.str().c_str()); + dt = convertDateTime( dt ); // exiv2 doesn't seem to convert to normal date/time, check + appendItem(exifGroup, QString::fromUtf8(i->tagName().c_str()), dt ); } - appendItem( exifGroup, "Flash used", - flash ); - } - - if (ImageInfo.getFocalLength()){ - appendItem( exifGroup, "Focal length", - QString().sprintf("%4.1f", ImageInfo.getFocalLength()) ); - - if (ImageInfo.getCCDWidth()){ - appendItem( exifGroup, "35mm equivalent", - (int)(ImageInfo.getFocalLength()/ImageInfo.getCCDWidth()*35 + 0.5) ); - } - } - if (ImageInfo.getCCDWidth()){ - appendItem( exifGroup, "CCD width", - QString().sprintf("%4.2f", ImageInfo.getCCDWidth()) ); - } - - if (ImageInfo.getExposureTime()){ - tag=QString().sprintf("%6.3f", ImageInfo.getExposureTime()); - float exposureTime = ImageInfo.getExposureTime(); - if (exposureTime > 0 && exposureTime <= 0.5){ - tag+=QString().sprintf(" (1/%d)", (int)(0.5 + 1/exposureTime) ); - } - appendItem( exifGroup, "Exposure time", tag ); - } - - if (ImageInfo.getApertureFNumber()){ - appendItem( exifGroup, "Aperture", - QString().sprintf("f/%3.1f", - (double)ImageInfo.getApertureFNumber())); - } - - if (ImageInfo.getDistance()){ - if (ImageInfo.getDistance() < 0){ - tag=i18n("Infinite"); - }else{ - tag=QString().sprintf("%5.2fm",(double)ImageInfo.getDistance()); + Exiv2::ExifData::const_iterator iw = + ImageInfo.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth")); + if (iw == ImageInfo.end()) + iw = ImageInfo.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension")); + Exiv2::ExifData::const_iterator ih = + ImageInfo.findKey(Exiv2::ExifKey("Exif.Image.ImageLength")); + if (ih == ImageInfo.end()) + ih = ImageInfo.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension")); + + if (iw != ImageInfo.end() && ih != ImageInfo.end()) + appendItem( exifGroup,"Dimensions", QSize( iw->toLong(), ih->toLong())); + + if ( what & KFileMetaInfo::Thumbnail ) { + Exiv2::ExifThumbC thumb(ImageInfo); Exiv2::DataBuf thumbnail = thumb.copy(); + QImage image; + image.loadFromData(thumbnail.pData_, thumbnail.size_); + // if there's no thumbnail in the jpeg, create a thumbnail from the file itself, + // so that orientation is applied correctly (kio_thumbnail doesn't handle it) + if( image.isNull()) + image.load( info.path()); + if( !image.isNull()) { + Exiv2::ExifData::const_iterator ort = ImageInfo.findKey(Exiv2::ExifKey("Exif.Image.Orientation")); + if (ort != ImageInfo.end()) { + QWMatrix m; + QWMatrix flip= QWMatrix(-1,0,0,1,0,0); + switch( ort->toLong()) { // notice intentional fallthroughs + case 2: m = flip; break; + case 4: m = flip; + case 3: m.rotate(180); break; + case 5: m = flip; + case 6: m.rotate(90); break; + case 7: m = flip; + case 8: m.rotate(270); break; + default: break; // should never happen + } + if( !m.isIdentity()) + image = image.xForm( m ); + } + appendItem( exifGroup, "Thumbnail", image ); + } } - appendItem( exifGroup, "Focus dist.", tag ); - } - - if (ImageInfo.getExposureBias()){ - appendItem( exifGroup, "Exposure bias", - QString().sprintf("%4.2f", - (double)ImageInfo.getExposureBias()) ); } - - if (ImageInfo.getWhitebalance() != -1){ - switch(ImageInfo.getWhitebalance()) { - case 0: - tag=i18n("Unknown"); - break; - case 1: - tag=i18n("Daylight"); - break; - case 2: - tag=i18n("Fluorescent"); - break; - case 3: - //tag=i18n("incandescent"); - tag=i18n("Tungsten"); - break; - case 17: - tag=i18n("Standard light A"); - break; - case 18: - tag=i18n("Standard light B"); - break; - case 19: - tag=i18n("Standard light C"); - break; - case 20: - tag=i18n("D55"); - break; - case 21: - tag=i18n("D65"); - break; - case 22: - tag=i18n("D75"); - break; - case 255: - tag=i18n("Other"); - break; - default: - //23 to 254 = reserved - tag=i18n("Unknown"); - } - appendItem( exifGroup, "Whitebalance", tag ); - } - - if (ImageInfo.getMeteringMode() != -1){ - switch(ImageInfo.getMeteringMode()) { - case 0: - tag=i18n("Unknown"); - break; - case 1: - tag=i18n("Average"); - break; - case 2: - tag=i18n("Center weighted average"); - break; - case 3: - tag=i18n("Spot"); - break; - case 4: - tag=i18n("MultiSpot"); - break; - case 5: - tag=i18n("Pattern"); - break; - case 6: - tag=i18n("Partial"); - break; - case 255: - tag=i18n("Other"); - break; - default: - // 7 to 254 = reserved - tag=i18n("Unknown"); - } - appendItem( exifGroup, "Metering mode", tag ); - } - - if (ImageInfo.getExposureProgram()){ - switch(ImageInfo.getExposureProgram()) { - case 0: - tag=i18n("Not defined"); - break; - case 1: - tag=i18n("Manual"); - break; - case 2: - tag=i18n("Normal program"); - break; - case 3: - tag=i18n("Aperture priority"); - break; - case 4: - tag=i18n("Shutter priority"); - break; - case 5: - tag=i18n("Creative program\n(biased toward fast shutter speed)"); - break; - case 6: - tag=i18n("Action program\n(biased toward fast shutter speed)"); - break; - case 7: - tag=i18n("Portrait mode\n(for closeup photos with the background out of focus)"); - break; - case 8: - tag=i18n("Landscape mode\n(for landscape photos with the background in focus)"); - break; - default: - // 9 to 255 = reserved - tag=i18n("Unknown"); - } - appendItem( exifGroup, "Exposure", tag ); - } - - if (ImageInfo.getISOequivalent()){ - appendItem( exifGroup, "ISO equiv.", - QString().sprintf("%2d", - (int)ImageInfo.getISOequivalent()) ); - } - - if (ImageInfo.getCompressionLevel()){ - switch(ImageInfo.getCompressionLevel()) { - case 1: - tag=i18n("Basic"); - break; - case 2: - tag=i18n("Normal"); - break; - case 4: - tag=i18n("Fine"); - break; - default: - tag=i18n("Unknown"); - } - appendItem( exifGroup, "JPEG quality", tag ); - } - - tag = ImageInfo.getUserComment(); - if (tag.length()){ - appendItem( exifGroup, "EXIF comment", tag ); - } - - int a; - for (a=0;;a++){ - if (ProcessTable[a].Tag == ImageInfo.getProcess() || ProcessTable[a].Tag == 0){ - appendItem( exifGroup, "JPEG process", - QString::fromUtf8( ProcessTable[a].Desc) ); - break; - } - } - - if ( what & KFileMetaInfo::Thumbnail && !ImageInfo.isNullThumbnail() ){ - appendItem( exifGroup, "Thumbnail", ImageInfo.getThumbnail() ); + catch (Exiv2::AnyError& e) { + kdDebug(7034) << "Caught Exiv2 exception" << endl; + return false; } return true; @@ -487,11 +231,10 @@ bool KJpegPlugin::readInfo( KFileMetaInf // format of the string is: // YYYY:MM:DD HH:MM:SS -QDateTime KJpegPlugin::parseDateTime( const QString& string ) +QString KJpegPlugin::convertDateTime( const QString& string ) { - QDateTime dt; if ( string.length() != 19 ) - return dt; + return string; QString year = string.left( 4 ); QString month = string.mid( 5, 2 ); @@ -521,11 +264,13 @@ QDateTime KJpegPlugin::parseDateTime( co allOk &= ok; if ( allOk ) { + QDateTime dt; dt.setDate( QDate( y, mo, d ) ); dt.setTime( QTime( h, mi, s ) ); + return KGlobal::locale()->formatDateTime( dt, true, true ); // short format, seconds } - return dt; + return string; } #include "kfile_jpeg.moc" --- kfile-plugins/jpeg/kfile_jpeg.desktop +++ kfile-plugins/jpeg/kfile_jpeg.desktop @@ -60,5 +60,5 @@ Name[zu]=Ulwazi lwe-JPEG EXIF ServiceTypes=KFilePlugin X-KDE-Library=kfile_jpeg MimeType=image/jpeg -PreferredItems=User comment,CreationDate,CreationTime,Dimensions,Exposure time,JPEG quality,Comment +PreferredItems=UserComment,Dimensions,DateTime,DateTimeOriginal,Flash,ExposureTime,Orientation,ApertureValue SupportsThumbnail=true --- kfile-plugins/jpeg/kfile_jpeg.h +++ kfile-plugins/jpeg/kfile_jpeg.h @@ -37,7 +37,7 @@ public: QObject* parent, const char* name) const; private: - QDateTime parseDateTime( const QString& string ); + QString convertDateTime( const QString& string ); }; #endif --- kfile-plugins/jpeg/Makefile.am +++ kfile-plugins/jpeg/Makefile.am @@ -6,13 +6,13 @@ KDE_CXXFLAGS = $(USE_EXCEPTIONS) INCLUDES = $(all_includes) # these are the headers for your project -noinst_HEADERS = kfile_jpeg.h exif.h +noinst_HEADERS = kfile_jpeg.h kde_module_LTLIBRARIES = kfile_jpeg.la -kfile_jpeg_la_SOURCES = kfile_jpeg.cpp exif.cpp kfile_setcomment.cpp +kfile_jpeg_la_SOURCES = kfile_jpeg.cpp kfile_setcomment.cpp kfile_jpeg_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -kfile_jpeg_la_LIBADD = $(LIB_KIO) +kfile_jpeg_la_LIBADD = $(LIB_KIO) -lexiv2 # let automoc handle all of the meta source files (moc) METASOURCES = AUTO
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor