diff options
Diffstat (limited to 'kfile-plugins/exr')
-rw-r--r-- | kfile-plugins/exr/Makefile.am | 25 | ||||
-rw-r--r-- | kfile-plugins/exr/configure.in.in | 14 | ||||
-rw-r--r-- | kfile-plugins/exr/kfile_exr.cpp | 393 | ||||
-rw-r--r-- | kfile-plugins/exr/kfile_exr.desktop | 57 | ||||
-rw-r--r-- | kfile-plugins/exr/kfile_exr.h | 39 |
5 files changed, 528 insertions, 0 deletions
diff --git a/kfile-plugins/exr/Makefile.am b/kfile-plugins/exr/Makefile.am new file mode 100644 index 00000000..f337359c --- /dev/null +++ b/kfile-plugins/exr/Makefile.am @@ -0,0 +1,25 @@ +## Makefile.am for EXR file meta info plugin + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +# set the include path for X, qt and KDE +INCLUDES = -Drestrict= $(all_includes) $(EXR_FLAGS) +# INCLUDES = $(all_includes) $(EXR_FLAGS) + +# these are the headers for your project +noinst_HEADERS = kfile_exr.h + +kde_module_LTLIBRARIES = kfile_exr.la + +kfile_exr_la_SOURCES = kfile_exr.cpp +kfile_exr_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kfile_exr_la_LIBADD = $(LIB_KIO) $(LIB_EXR) + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: + $(XGETTEXT) *.cpp -o $(podir)/kfile_exr.pot + +services_DATA = kfile_exr.desktop +servicesdir = $(kde_servicesdir) diff --git a/kfile-plugins/exr/configure.in.in b/kfile-plugins/exr/configure.in.in new file mode 100644 index 00000000..2a9ff5e5 --- /dev/null +++ b/kfile-plugins/exr/configure.in.in @@ -0,0 +1,14 @@ +AC_ARG_WITH([openexr], + [AC_HELP_STRING([--with-openexr], + [Enable support for OpenEXR @<:@default=check@:>@])], + [], with_openexr=check) + +if test "x$with_openexr" != xno; then + KDE_FIND_LIBEXR + + if test "x$with_openexr" != xcheck && test -z "$LIB_EXR"; then + AC_MSG_ERROR([--with-openexr was given, but test for OpenEXR failed]) + fi +fi + +AM_CONDITIONAL(include_EXR_MODULES, test -n "$LIB_EXR") diff --git a/kfile-plugins/exr/kfile_exr.cpp b/kfile-plugins/exr/kfile_exr.cpp new file mode 100644 index 00000000..2e995fc6 --- /dev/null +++ b/kfile-plugins/exr/kfile_exr.cpp @@ -0,0 +1,393 @@ +// -*- C++;indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*- +/* This file is part of the KDE project + * Copyright (C) 2003 <[email protected]> + * + * 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 version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $Id$ + */ + +#include <ImfStandardAttributes.h> +#include <ImathBox.h> +#include <ImfInputFile.h> +#include <ImfBoxAttribute.h> +#include <ImfChannelListAttribute.h> +#include <ImfCompressionAttribute.h> +#include <ImfFloatAttribute.h> +#include <ImfIntAttribute.h> +#include <ImfLineOrderAttribute.h> +#include <ImfStringAttribute.h> +#include <ImfVecAttribute.h> +#include <ImfPreviewImage.h> +#include <ImfVersion.h> +#include <ImfCRgbaFile.h> + +#include <iostream> + +#include <stdlib.h> +#include <string> + +#include <kurl.h> +#include <kprocess.h> +#include <klocale.h> +#include <kgenericfactory.h> +#include <kdebug.h> + +#include <qcstring.h> +#include <qfile.h> +#include <qdatetime.h> +#include <qdict.h> +#include <qvalidator.h> +#include <qimage.h> + + +#include "kfile_exr.h" +using namespace Imf; + +typedef KGenericFactory<KExrPlugin> ExrFactory; + +K_EXPORT_COMPONENT_FACTORY(kfile_exr, ExrFactory("kfile_exr")) + +KExrPlugin::KExrPlugin(QObject *parent, const char *name, + const QStringList &args) + : KFilePlugin(parent, name, args) +{ + // set up our mime type + KFileMimeTypeInfo* info = addMimeTypeInfo( "image/x-exr" ); + + KFileMimeTypeInfo::GroupInfo* group = 0; + KFileMimeTypeInfo::ItemInfo* item; + + // info group + group = addGroupInfo( info, "Info", i18n("Information") ); + addItemInfo( group, "Version", i18n("Format Version"), QVariant::Int ); + addItemInfo( group, "Tiled image", i18n("Tiled Image"), QVariant::String ); + item = addItemInfo( group, "Dimensions", i18n("Dimensions"), QVariant::Size ); + setHint( item, KFileMimeTypeInfo::Size ); + setUnit( item, KFileMimeTypeInfo::Pixels ); + item = addItemInfo( group, "ThumbnailDimensions", + i18n("Thumbnail Dimensions"), QVariant::Size ); + setHint( item, KFileMimeTypeInfo::Size ); + setUnit( item, KFileMimeTypeInfo::Pixels ); + addItemInfo( group, "Comment", i18n("Comment"), QVariant::String ); + item = addItemInfo( group, "Thumbnail", i18n("Thumbnail"), QVariant::Image ); + setHint( item, KFileMimeTypeInfo::Thumbnail ); + + // standard attributes group + group = addGroupInfo( info, "Standard", i18n("Standard Attributes") ); + addItemInfo( group, "Owner", i18n("Owner"), QVariant::String ); + addItemInfo( group, "Comments", i18n("Comments"), QVariant::String ); + addItemInfo( group, "Capture Date", i18n("Capture Date"), QVariant::String ); + item = addItemInfo( group, "UTC Offset", i18n("UTC Offset"), QVariant::String ); + item = addItemInfo( group, "Exposure time", i18n("Exposure Time"), QVariant::Double); + setUnit( item, KFileMimeTypeInfo::Seconds ); + item = addItemInfo( group, "Focus", i18n("Focus"), QVariant::Double); + setSuffix( item, i18n("Metres", "m") ); + item = addItemInfo( group, "X Density", i18n("X Density"), QVariant::Double); + setSuffix( item, i18n("Pixels Per Inch", " ppi") ); + item = addItemInfo( group, "White luminance", i18n("White Luminance"), QVariant::Double); + setSuffix( item, i18n("Candelas per square metre", " Nits") ); + addItemInfo( group, "Longitude", i18n("Longitude"), QVariant::String ); + addItemInfo( group, "Latitude", i18n("Latitude"), QVariant::String ); + item = addItemInfo( group, "Altitude", i18n("Altitude"), QVariant::String ); + setSuffix( item, i18n("Metres", "m") ); + addItemInfo( group, "ISO speed", i18n("ISO Speed"), QVariant::Double ); + addItemInfo( group, "Aperture", i18n("Aperture"), QVariant::Double ); + + // channel group + group = addGroupInfo( info, "Channel", i18n("Channels") ); + addItemInfo( group, "A", i18n("A"), QVariant::String ); + addItemInfo( group, "R", i18n("R"), QVariant::String ); + addItemInfo( group, "G", i18n("G"), QVariant::String ); + addItemInfo( group, "B", i18n("B"), QVariant::String ); + addItemInfo( group, "Z", i18n("Z"), QVariant::String ); + addItemInfo( group, "NX", i18n("NX"), QVariant::String ); + addItemInfo( group, "NY", i18n("NY"), QVariant::String ); + addItemInfo( group, "NZ", i18n("NZ"), QVariant::String ); + addItemInfo( group, "R", i18n("R"), QVariant::String ); + addItemInfo( group, "U", i18n("U"), QVariant::String ); + addItemInfo( group, "V", i18n("V"), QVariant::String ); + addItemInfo( group, "materialID", i18n("materialID"), QVariant::String ); + addItemInfo( group, "objectID", i18n("objectID"), QVariant::String ); + addItemInfo( group, "renderID", i18n("renderID"), QVariant::String ); + addItemInfo( group, "pixelCover", i18n("pixelCover"), QVariant::String ); + addItemInfo( group, "velX", i18n("velX"), QVariant::String ); + addItemInfo( group, "velY", i18n("velY"), QVariant::String ); + addItemInfo( group, "packedRGBA", i18n("packedRGBA"), QVariant::String ); + + + // technical group + group = addGroupInfo( info, "Technical", i18n("Technical Details") ); + addItemInfo( group, "Compression", i18n("Compression"), QVariant::String ); + addItemInfo( group, "Line Order", i18n("Line Order"), QVariant::String ); + + // 3dsMax group + // This supports a special plugin for 3D Studio Max + group = addGroupInfo( info, "3dsMax", i18n("3dsMax Details") ); + addItemInfo( group, "Local time", i18n("Local Time"), QVariant::String ); + addItemInfo( group, "System time", i18n("System Time"), QVariant::String ); + addItemInfo( group, "Plugin version", i18n("Plugin Version"), QVariant::String ); + addItemInfo( group, "EXR version", i18n("EXR Version"), QVariant::String ); + addItemInfo( group, "Computer name", i18n("Computer Name"), QVariant::String ); +} + +QCString doType( PixelType pt ) +{ + switch (pt) + { + case UINT: + return QCString("32-bit unsigned integer"); + break; + case HALF: + return QCString("16-bit floating-point"); + break; + case FLOAT: + return QCString("32-bit floating-point"); + break; + default: + return QCString(); + break; + } +} + +bool KExrPlugin::readInfo( KFileMetaInfo& info, uint what) +{ + try + { + InputFile in ( info.path().ascii() ); + const Header &h = in.header(); + + KFileMetaInfoGroup infogroup = appendGroup(info, "Info"); + KFileMetaInfoGroup stdgroup = appendGroup(info, "Standard"); + KFileMetaInfoGroup channelgroup = appendGroup(info, "Channel"); + KFileMetaInfoGroup techgroup = appendGroup(info, "Technical"); + KFileMetaInfoGroup threedsmaxgroup = appendGroup(info, "3dsMax"); + + appendItem( infogroup, "Version", getVersion(in.version()) ); + if (isTiled(in.version())) { + appendItem( infogroup, "Tiled image", "yes" ); + } else { + appendItem( infogroup, "Tiled image", "no" ); + } + + Imath::Box2i dw = h.dataWindow(); + appendItem( infogroup, "Dimensions", QSize( (dw.max.x - dw.min.x + 1 ), + (dw.max.y - dw.min.y + 1 ) ) ); + + if ( h.hasPreviewImage() ) { + const PreviewImage &preview = in.header().previewImage(); + appendItem( infogroup, "ThumbnailDimensions", QSize(preview.width(), preview.height()) ); + QImage qpreview(preview.width(), preview.height(), 32, 0, QImage::BigEndian); + for ( unsigned int y=0; y < preview.height(); y++ ) { + for ( unsigned int x=0; x < preview.width(); x++ ) { + const PreviewRgba &q = preview.pixels()[x+(y*preview.width())]; + qpreview.setPixel( x, y, qRgba(q.r, q.g, q.b, q.a) ); + } + } + appendItem( infogroup, "Thumbnail", qpreview); + } + + const StringAttribute *commentSA = h.findTypedAttribute <StringAttribute> ("comment"); + if (commentSA) { + std::string commentString = commentSA->value(); + QString qcommentString(commentString.data()); + qcommentString.setLength(commentString.size()); + appendItem( infogroup, "Comment", qcommentString ); + } + + // Standard Attributes we are interested in and can + // meaningfully represent. + if ( hasComments(h) ) { + std::string commentsString = comments(h); + QString qcommentsString(commentsString.data()); + qcommentsString.setLength(commentsString.size()); + appendItem( stdgroup, "Comments", qcommentsString ); + } + if ( hasOwner(h) ) { + std::string ownerString = owner(h); + QString qownerString(ownerString.data()); + qownerString.setLength(ownerString.size()); + appendItem( stdgroup, "Owner", qownerString ); + } + if ( hasCapDate(h) ) { + std::string capDateString = capDate(h); + QString qcapDateString(capDateString.data()); + qcapDateString.setLength(capDateString.size()); + appendItem( stdgroup, "Capture Date", qcapDateString ); + } + // This define was introduced in EXR 1.6.0 +#ifndef IMF_B44_COMPRESSION + // This is the 1.4 and earlier version + if ( hasutcOffset(h) ) { +#else + // This is the 1.6.0 and later version + if ( hasUtcOffset(h) ) { +#endif + QString UTCOffset; + if (utcOffset(h)>0.0) { + UTCOffset.append(QString("%1").arg(utcOffset(h)/3600, 0, 'f', 1)); + UTCOffset.append(" hours behind UTC"); + } else { + UTCOffset.append(QString("%1").arg(-1.0*utcOffset(h)/3600, 0, 'f', 1)); + UTCOffset.append(" hours ahead of UTC"); + } + appendItem( stdgroup, "UTC Offset", UTCOffset); + } + if ( hasExpTime(h) ) { + double exposureTime = expTime(h); + appendItem( stdgroup, "Exposure time", exposureTime ); + } + if ( hasFocus(h) ) { + double focusDistance = focus(h); + appendItem( stdgroup, "Focus", focusDistance ); + } + if ( hasXDensity(h) ) { + double XDensity = xDensity(h); + appendItem( stdgroup, "X Density", XDensity ); + } + if ( hasWhiteLuminance(h) ) { + double WhiteLuminance = whiteLuminance(h); + appendItem( stdgroup, "White luminance", WhiteLuminance ); + } + if ( hasLongitude(h) ) { + QString Longitude; + if (longitude(h)<0.0) { + Longitude.append(QString("%1").arg(-1.0*longitude(h),0,'f',3)); + Longitude.append(" deg West"); + } else { + Longitude.append(QString("%1").arg(longitude(h),0,'f',3)); + Longitude.append(" deg East"); + } + appendItem( stdgroup, "Longitude", Longitude); + } + if ( hasLatitude(h) ) { + QString Latitude; + if (latitude(h)<0.0) { + Latitude.append(QString("%1").arg(-1.0*latitude(h),0,'f',3)); + Latitude.append(" deg South"); + } else { + Latitude.append(QString("%1").arg(latitude(h),0,'f',3)); + Latitude.append(" deg North"); + } + appendItem( stdgroup, "Latitude", Latitude ); + } + if ( hasAltitude(h) ) { + double Altitude = altitude(h); + appendItem( stdgroup, "Altitude", QString("%1").arg(Altitude,0,'f',1) ); + } + if ( hasIsoSpeed(h) ) { + double IsoSpeed = isoSpeed(h); + appendItem( stdgroup, "ISO speed", IsoSpeed ); + } + if ( hasAperture(h) ) { + double Aperture = aperture(h); + appendItem( stdgroup, "Aperture", Aperture ); + } + + for (Header::ConstIterator i = h.begin(); i != h.end(); ++i) { + const Attribute *a = &i.attribute(); + + if (const CompressionAttribute *ta = dynamic_cast <const CompressionAttribute *> (a)) { + switch ( ta->value() ) + { + case NO_COMPRESSION: + appendItem( techgroup, "Compression", i18n("No compression")); + break; + case RLE_COMPRESSION: + appendItem( techgroup, "Compression", i18n("Run Length Encoding")); + break; + case ZIPS_COMPRESSION: + appendItem( techgroup, "Compression", i18n("zip, individual scanlines")); + break; + case ZIP_COMPRESSION: + appendItem( techgroup, "Compression", i18n("zip, multi-scanline blocks")); + break; + case PIZ_COMPRESSION: + appendItem( techgroup, "Compression", i18n("piz compression")); + break; + default: + break; + } + } else if (const LineOrderAttribute *ta = dynamic_cast <const LineOrderAttribute *> (a)) { + switch (ta->value()) + { + case INCREASING_Y: + appendItem( techgroup, "Line Order", i18n("increasing Y")); + break; + case DECREASING_Y: + appendItem( techgroup, "Line Order", i18n("decreasing Y")); + break; + default: + break; + }; + } else if (const ChannelListAttribute *ta = dynamic_cast <const ChannelListAttribute *> (a)) { + + for (ChannelList::ConstIterator i = ta->value().begin(); i != ta->value().end(); ++i) + { + appendItem( channelgroup, i.name(), doType(i.channel().type) ); + } + } + } + + // This section deals with some special case stuff for a 3D Studio Max + // plugin from Splutterfish. The weird construction is an + // attempt to to deal with class conversion. C++ string handling + // without Qt is a pain... + const StringAttribute *ver3DSM = h.findTypedAttribute <StringAttribute> ("version3dsMax"); + if (ver3DSM) { + std::string ver3DSMstring = ver3DSM->value(); + QString qver3DSMstring(ver3DSMstring.data()); + qver3DSMstring.setLength(ver3DSMstring.size()); + appendItem( threedsmaxgroup, "Plugin version", qver3DSMstring ); + } + const StringAttribute *verEXR = h.findTypedAttribute <StringAttribute> ("versionEXR"); + if (verEXR) { + std::string verEXRstring = verEXR->value(); + QString qverEXRstring(verEXRstring.data()); + qverEXRstring.setLength(verEXRstring.size()); + appendItem( threedsmaxgroup, "EXR version", QString( verEXRstring.data() ) ); + } + const StringAttribute *localTime = h.findTypedAttribute <StringAttribute> ("localTime"); + if (localTime) { + std::string localTimeString = localTime->value(); + QString qlocalTimeString(localTimeString.data()); + qlocalTimeString.setLength(localTimeString.size()); + appendItem( threedsmaxgroup, "Local time", qlocalTimeString ); + } + const StringAttribute *systemTime = h.findTypedAttribute <StringAttribute> ("systemTime"); + if (systemTime) { + std::string systemTimeString = systemTime->value(); + QString qsystemTimeString(systemTimeString.data()); + qsystemTimeString.setLength(systemTimeString.size()); + appendItem( threedsmaxgroup, "System time", qsystemTimeString ); + } + const StringAttribute *computerName = h.findTypedAttribute <StringAttribute> ("computerName"); + if (computerName) { + std::string computerNameString = computerName->value(); + QString qcomputerNameString(computerNameString.data()); + qcomputerNameString.setLength(computerNameString.size()); + appendItem( threedsmaxgroup, "Computer name", qcomputerNameString ); + } + + return true; + } + catch (const std::exception &e) + { + kdDebug(0) << e.what() << endl; + return false; + } +} + +#include "kfile_exr.moc" diff --git a/kfile-plugins/exr/kfile_exr.desktop b/kfile-plugins/exr/kfile_exr.desktop new file mode 100644 index 00000000..b1b3a583 --- /dev/null +++ b/kfile-plugins/exr/kfile_exr.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Type=Service +Name=EXR Info +Name[br]=Titouroù EXR +Name[ca]=Informació EXR +Name[cs]=EXR info +Name[cy]=Gwybodaeth EXR +Name[da]=EXR-Info +Name[de]=EXR-Info +Name[el]=Πληροφορίες EXR +Name[eo]=EXR-informo +Name[es]=Info EXR +Name[et]=EXR info +Name[fa]=اطلاعات EXR +Name[fi]=EXR-tiedot +Name[fr]=Informations EXR +Name[ga]=Eolas faoi EXR +Name[gl]=Inf. EXR +Name[he]=מידע EXR +Name[hu]=EXR-jellemzők +Name[is]=EXR upplýsingar +Name[it]=Informazioni EXR +Name[ja]=EXR 情報 +Name[kk]=EXR мәліметі +Name[km]=ព័ត៌មាន EXR +Name[lt]=EXR informacija +Name[ms]=Maklumat EXR +Name[nds]=EXR-Info +Name[ne]=EXR सूचना +Name[nl]=EXR-info +Name[nn]=EXR-info +Name[pa]=EXR ਜਾਣਕਾਰੀ +Name[pl]=Informacja EXR +Name[pt]=Informação do EXR +Name[pt_BR]=Informação sobre EXR +Name[ro]=Informaţii EXR +Name[ru]=Информация о EXR +Name[se]=EXR-dieđut +Name[sl]=Podatki o EXR +Name[sr]=EXR информације +Name[sr@Latn]=EXR informacije +Name[sv]=EXR-information +Name[ta]=EXR தகவல் +Name[tg]=Иттилоот оиди EXR +Name[th]=ข้อมูลแฟ้ม EXR +Name[tr]=EXR Bilgisi +Name[uk]=Інформація по EXR +Name[uz]=EXR haqida maʼlumot +Name[uz@cyrillic]=EXR ҳақида маълумот +Name[zh_CN]=EXR 信息 +Name[zh_HK]=EXR 資訊 +Name[zh_TW]=EXR 資訊 +ServiceTypes=KFilePlugin +X-KDE-Library=kfile_exr +MimeType=image/x-exr +PreferredGroups=Info,Standard,Channels,Technical,3dsMax +PreferredItems=Dimensions,Thumbnail,ThumbnailDimensions,Version,Comments,Owner,Latitude,Longitude,Altitude,Capture Date,UTC Offset diff --git a/kfile-plugins/exr/kfile_exr.h b/kfile-plugins/exr/kfile_exr.h new file mode 100644 index 00000000..cb795ba5 --- /dev/null +++ b/kfile-plugins/exr/kfile_exr.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + * Copyright (C) 2003 <[email protected]> + * + * 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 version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $Id$ + */ + +#ifndef __KFILE_EXR_H__ +#define __KFILE_EXR_H__ + +#include <kfilemetainfo.h> +#include <kurl.h> + +class QStringList; + +class KExrPlugin: public KFilePlugin +{ + Q_OBJECT + +public: + KExrPlugin( QObject *parent, const char *name, const QStringList& preferredItems ); + + virtual bool readInfo( KFileMetaInfo& info, uint ); +}; + +#endif |