Skip to content

Commit

Permalink
Adds support for the various raw photo formats as decoded by dcraw. A…
Browse files Browse the repository at this point in the history
…s dcraw

is only distributed as a binary, this actually creates a Qt plugin for
mythgallery that runs dcraw externally.

There are likely to be some RAW photo extensions that dcraw supports that got
missed by the original author, and will need to be added.

Also, I decided to leave the icc-profile as a configure-time setting for the
moment as there's a push to be redoing all settings soon anyways, and we might
as well redo it then.

Original patch from Chad Parry <spam@chad.parry.org>
Closes #7745



git-svn-id: http://svn.mythtv.org/svn/trunk@25667 7dbf422c-18fa-0310-86e9-fd20926502f2
  • Loading branch information
Beirdo committed Aug 15, 2010
1 parent 423c950 commit 3a4a359
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 1 deletion.
59 changes: 59 additions & 0 deletions mythplugins/configure
Expand Up @@ -117,6 +117,7 @@ fftw
sdl
exif
newexif
dcraw
"

enable $PLUGIN_LIST $CONFIG_LIST
Expand Down Expand Up @@ -162,6 +163,8 @@ MythGallery related options:
--enable-mythgallery build the mythgallery plugin [$gallery]
--enable-exif enable reading of EXIF headers [$exif]
--enable-new-exif use libexif > version 0.6.9 [$newexif]
--enable-dcraw use dcraw to view raw photos [$dcraw]
--icc-profile=PROFILE ICC profile for dcraw decoding [$icc]
MythGame related options:
--enable-mythgame build the mythgame plugin [$game]
Expand Down Expand Up @@ -247,6 +250,12 @@ for opt do
;;
--disable-new-exif) disable newexif
;;
--enable-dcraw) dcraw="yes"
;;
--disable-dcraw) dcraw="no"
;;
--icc-profile=*) icc=`echo $opt | cut -d '=' -f 2`
;;
--enable-all)
enable $PLUGIN_LIST $CONFIG_LIST
;;
Expand Down Expand Up @@ -453,6 +462,27 @@ if ! disabled weather; then
check_pl_lib "SOAP::Lite" || disable_weather "SOAP::Lite"
fi

if test "$dcraw" != "no" ; then
dcraw="no"
if test x`which dcraw` != x ; then
dcraw="yes"
fi
fi

if test x"$icc" != x ; then
# Assume relative paths are for files in the standard icc directory.
case "$icc" in
/*)
;;
*) icc=/usr/share/color/icc/$icc
;;
esac
# Verify the presence of the file.
if test ! -f "$icc" ; then
icc=""
fi
fi

if test "$music" != "no" ; then
vorbis="no"
if has_header ogg/ogg.h && has_header vorbis/vorbisenc.h && has_header vorbis/vorbisfile.h && has_header vorbis/codec.h && has_library libogg && has_library libvorbisfile && has_library libvorbisenc && has_library libvorbis ; then
Expand Down Expand Up @@ -659,6 +689,10 @@ if test "$gallery" = "yes" ; then
echo " Automatically generated by configure - do not modify" >> ./mythgallery/mythgallery/config.h
echo "*/" >> ./mythgallery/mythgallery/config.h

echo "#" > ./mythgallery/config.pro
echo "# Automatically generated by configure - modify only under penalty of death" >> ./mythgallery/config.pro
echo "#" >> ./mythgallery/config.pro

echo "#" > ./mythgallery/mythgallery/config.pro
echo "# Automatically generated by configure - modify only under penalty of death" >> ./mythgallery/mythgallery/config.pro
echo "#" >> ./mythgallery/mythgallery/config.pro
Expand Down Expand Up @@ -702,6 +736,31 @@ if test "$gallery" = "yes" ; then
if test "$exif" = "no" ; then
echo " EXIF support will not be included in MythGallery"
fi

if test "$dcraw" = "yes" ; then
echo " Dcraw support will be included in MythGallery"
echo "SUBDIRS += dcrawplugin" >> ./mythgallery/config.pro
echo "#define DCRAW_SUPPORT 1" >> ./mythgallery/mythgallery/config.h
echo "LIBS += -L../dcrawplugin -ldcrawplugin" >> ./mythgallery/mythgallery/config.pro
echo "TARGETDEPS += ../dcrawplugin/libdcrawplugin.a" >> ./mythgallery/mythgallery/config.pro

echo "/*" > ./mythgallery/dcrawplugin/config.h
echo " Automatically generated by configure - do not modify" >> ./mythgallery/dcrawplugin/config.h
echo "*/" >> ./mythgallery/dcrawplugin/config.h

if test x"$icc" != x ; then
echo " ICC profile $icc"
# Quote C escape characters.
quoted_icc=`echo "$icc" | sed 's/\\([\\\\"?]\\)/\\\\\\1/g;\$!{s/\$/\\\\/}'`
echo "#define ICC_PROFILE \"$quoted_icc\"" >> ./mythgallery/dcrawplugin/config.h
fi

fi

if test "$dcraw" = "no" ; then
echo " Dcraw support will not be included in MythGallery"
fi

fi

###########################################################
Expand Down
52 changes: 52 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawformats.cpp
@@ -0,0 +1,52 @@
#include "dcrawformats.h"

#include <QSet>
#include <QString>

namespace {

QSet<QString> composeFormats()
{
QSet<QString> formats;
formats << "arw" << "ARW";
formats << "bay" << "BAY";
formats << "bmq" << "BMQ";
formats << "cr2" << "CR2";
formats << "crw" << "CRW";
formats << "cs1" << "CS1";
formats << "dc2" << "DC2";
formats << "dcr" << "DCR";
formats << "dng" << "DNG";
formats << "fff" << "FFF";
formats << "k25" << "K25";
formats << "kdc" << "KDC";
formats << "mos" << "MOS";
formats << "mrw" << "MRW";
formats << "nef" << "NEF";
formats << "orf" << "ORF";
formats << "pef" << "PEF";
formats << "raf" << "RAF";
formats << "raw" << "RAW";
formats << "rdc" << "RDC";
formats << "srf" << "SRF";
formats << "x3f" << "X3F";
return formats;
}

} // anonymous namespace

QSet<QString> DcrawFormats::getFormats()
{
static QSet<QString> formats(composeFormats());
return formats;
}

QStringList DcrawFormats::getFilters()
{
QSet<QString> formats(getFormats());
QStringList filters;
for (QSet<QString>::const_iterator i(formats.begin()); i != formats.end(); ++i)
filters << ("*." + *i);
return filters;
}

15 changes: 15 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawformats.h
@@ -0,0 +1,15 @@

#include <QSet>
#include <QString>
#include <QStringList>

class DcrawFormats
{

public:

static QSet<QString> getFormats();
static QStringList getFilters();

};

90 changes: 90 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawhandler.cpp
@@ -0,0 +1,90 @@
#include "dcrawhandler.h"

#include "config.h"

#include <cstddef>

#include <QByteArray>
#include <QFile>
#include <QImage>
#include <QIODevice>
#include <QProcess>
#include <QString>

namespace
{

bool getPath(QIODevice *device, QString &path)
{
QFile *file = qobject_cast<QFile *>(device);
if (!file)
return false;
path = file->fileName();
return true;
}

} // anonymous namespace

bool DcrawHandler::canRead() const
{
QString path;
bool isFile = getPath(device(), path);
if (!isFile)
// It would still be possible to process this file,
// but piping the image data to dcraw would be
// difficult. This code path wouldn't be exercised in
// MythGallery anyway. So for simplicity we give up.
return false;

QProcess process(NULL);
QString program = "dcraw";
QStringList arguments;
arguments << "-i" << path;
process.start(program, arguments, QIODevice::NotOpen);

bool finished = process.waitForFinished();
if (!finished)
return false;
if (process.exitStatus() != QProcess::NormalExit)
return false;
bool success = (process.exitCode() == 0);
return success;
}

bool DcrawHandler::read(QImage *image)
{
QString path;
bool isFile = getPath(device(), path);
if (!isFile)
// It would still be possible to process this file,
// but piping the image data to dcraw would be
// difficult. This code path wouldn't be exercised in
// MythGallery anyway. So for simplicity we give up.
return false;

QProcess process(NULL);
QString program = "dcraw";
QStringList arguments;
arguments << "-c" << "-w" << "-W";
#ifdef ICC_PROFILE
arguments << "-p" << ICC_PROFILE;
#endif // ICC_PROFILE
arguments << path;
process.start(program, arguments, QIODevice::ReadOnly);

bool finished = process.waitForFinished();
if (!finished)
return false;
if (process.exitStatus() != QProcess::NormalExit)
return false;
if (process.exitCode() != 0)
return false;

QByteArray buffer = process.readAll();
if (buffer.isEmpty())
return false;

bool loaded = image->loadFromData(buffer, "PPM");
return loaded;
}

13 changes: 13 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawhandler.h
@@ -0,0 +1,13 @@
#include <QImage>
#include <QImageIOHandler>

class DcrawHandler : public QImageIOHandler
{

public:

bool canRead() const;
bool read(QImage *image);

};

42 changes: 42 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawplugin.cpp
@@ -0,0 +1,42 @@
#include "dcrawplugin.h"

#include "dcrawformats.h"
#include "dcrawhandler.h"

#include <QByteArray>
#include <QImageIOHandler>
#include <QImageIOPlugin>
#include <QIODevice>
#include <QStringList>

QStringList DcrawPlugin::keys() const
{
return QStringList(DcrawFormats::getFormats().toList());
}

QImageIOPlugin::Capabilities DcrawPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{
if (DcrawFormats::getFormats().contains(format))
return CanRead;

if (format.isEmpty())
{
DcrawHandler handler;
handler.setDevice(device);
if (handler.canRead())
return CanRead;
}

return 0;
}

QImageIOHandler *DcrawPlugin::create(QIODevice *device, const QByteArray &format) const
{
DcrawHandler *handler = new DcrawHandler;
handler->setDevice(device);
handler->setFormat(format);
return handler;
}

Q_EXPORT_PLUGIN2(dcrawplugin, DcrawPlugin)

20 changes: 20 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawplugin.h
@@ -0,0 +1,20 @@
#include <QByteArray>
#include <QIODevice>
#include <QImageIOHandler>
#include <QImageIOPlugin>
#include <QObject>
#include <QStringList>

class DcrawPlugin : public QImageIOPlugin
{

Q_OBJECT

public:

QStringList keys() const;
Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
QImageIOHandler *create(QIODevice *device, const QByteArray &format) const;

};

17 changes: 17 additions & 0 deletions mythplugins/mythgallery/dcrawplugin/dcrawplugin.pro
@@ -0,0 +1,17 @@
include ( ../../mythconfig.mak )
include ( ../../settings.pro )
include ( ../../programs-libs.pro )

TEMPLATE = lib
CONFIG += plugin static
TARGET = dcrawplugin

# Input
HEADERS += config.h
HEADERS += dcrawformats.h
HEADERS += dcrawhandler.h
HEADERS += dcrawplugin.h
SOURCES += dcrawformats.cpp
SOURCES += dcrawhandler.cpp
SOURCES += dcrawplugin.cpp

9 changes: 8 additions & 1 deletion mythplugins/mythgallery/mythgallery.pro
Expand Up @@ -4,5 +4,12 @@

TEMPLATE = subdirs

include (config.pro)

!exists( config.pro ) {
error(Missing config.pro: please run the configure script)
}

# Directories
SUBDIRS = mythgallery theme i18n
SUBDIRS += mythgallery theme i18n

9 changes: 9 additions & 0 deletions mythplugins/mythgallery/mythgallery/galleryutil.cpp
Expand Up @@ -32,6 +32,10 @@
#include "galleryutil.h"
#include "thumbgenerator.h"

#ifdef DCRAW_SUPPORT
#include "../dcrawplugin/dcrawformats.h"
#endif // DCRAW_SUPPORT

#ifdef EXIF_SUPPORT
#include <libexif/exif-data.h>
#include <libexif/exif-entry.h>
Expand All @@ -57,6 +61,11 @@ QStringList GalleryUtil::GetImageFilter(void)
filt.push_back("*.tiff");
filt.push_back("*.bmp");
filt.push_back("*.gif");

#ifdef DCRAW_SUPPORT
filt << DcrawFormats::getFilters();
#endif // DCRAW_SUPPORT

return filt;
}

Expand Down

0 comments on commit 3a4a359

Please sign in to comment.