Added Fujifilm read-support for RAF images.

v0.27.3
Andreas Huggel 19 years ago
parent 649c0ef494
commit b2f2b95bcb

@ -80,7 +80,8 @@ ifdef HAVE_LIBZ
CCSRC += pngimage.cpp \
pngchunk.cpp
endif
CCSRC += sigmamn.cpp \
CCSRC += rafimage.cpp \
sigmamn.cpp \
sonymn.cpp \
tags.cpp \
tiffcomposite.cpp \

@ -44,14 +44,15 @@ EXIV2_RCSID("@(#) $Id$")
#include "error.hpp"
#include "futils.hpp"
#include "jpgimage.hpp"
#include "cr2image.hpp"
#include "crwimage.hpp"
#include "jpgimage.hpp"
#include "mrwimage.hpp"
#include "tiffimage.hpp"
#ifdef EXV_HAVE_LIBZ
# include "pngimage.hpp"
#endif // EXV_HAVE_LIBZ
#include "rafimage.hpp"
#include "tiffimage.hpp"
// + standard includes
#include <cerrno>
@ -83,6 +84,7 @@ namespace Exiv2 {
#ifdef EXV_HAVE_LIBZ
{ ImageType::png, newPngInstance, isPngType, amRead, amRead, amNone },
#endif // EXV_HAVE_LIBZ
{ ImageType::raf, newRafInstance, isRafType, amRead, amRead, amNone },
// End of list marker
{ ImageType::none, 0, 0, amNone, amNone, amNone }
};

@ -0,0 +1,190 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2007 Andreas Huggel <ahuggel@gmx.net>
*
* This program is part of the Exiv2 distribution.
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
/*
File: rafimage.cpp
Version: $Rev$
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 05-Feb-07, ahu: created
Credits: See header file
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
// *****************************************************************************
// included header files
#ifdef _MSC_VER
# include "exv_msvc.h"
#else
# include "exv_conf.h"
#endif
#include "rafimage.hpp"
#include "tiffparser.hpp"
#include "image.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
// + standard includes
#include <string>
#include <cstring>
#include <iostream>
#include <cassert>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
RafImage::RafImage(BasicIo::AutoPtr io, bool create)
: Image(mdExif | mdIptc), io_(io)
{
if (create) {
IoCloser closer(*io_);
io_->open();
}
} // RafImage::RafImage
bool RafImage::good() const
{
if (io_->open() != 0) return false;
IoCloser closer(*io_);
return isThisType(*io_, false);
}
AccessMode RafImage::checkMode(MetadataId metadataId) const
{
return ImageFactory::checkMode(ImageType::raf, metadataId);
}
void RafImage::clearMetadata()
{
clearExifData();
clearIptcData();
}
void RafImage::setMetadata(const Image& image)
{
setExifData(image.exifData());
setIptcData(image.iptcData());
}
void RafImage::clearExifData()
{
exifData_.clear();
}
void RafImage::setExifData(const ExifData& exifData)
{
exifData_ = exifData;
}
void RafImage::clearIptcData()
{
iptcData_.clear();
}
void RafImage::setIptcData(const IptcData& iptcData)
{
iptcData_ = iptcData;
}
void RafImage::clearComment()
{
// not supported, do nothing
}
void RafImage::setComment(const std::string& /*comment*/)
{
// not supported
throw(Error(32, "Image comment", "RAF"));
}
void RafImage::readMetadata()
{
#ifdef DEBUG
std::cerr << "Reading RAF file " << io_->path() << "\n";
#endif
if (io_->open() != 0) throw Error(9, io_->path(), strError());
IoCloser closer(*io_);
// Ensure that this is the correct image type
if (!isThisType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "RAF");
}
if (io_->seek(84, BasicIo::beg) != 0) throw Error(14);
byte tmp[4];
io_->read(tmp, 4);
if (io_->error() || io_->eof()) throw Error(14);
uint32_t const pos = getULong(tmp, bigEndian) + 4;
if (io_->seek(pos, BasicIo::beg) != 0) throw Error(14);
io_->read(tmp, 2);
if (io_->error() || io_->eof()) throw Error(14);
DataBuf buf(getUShort(tmp, bigEndian) - 10);
if (io_->seek(pos + 8, BasicIo::beg) != 0) throw Error(14);
io_->read(buf.pData_, buf.size_);
if (io_->error() || io_->eof()) throw Error(14);
clearMetadata();
TiffParser::decode(this, buf.pData_, buf.size_,
TiffCreator::create, TiffDecoder::findDecoder);
} // RafImage::readMetadata
void RafImage::writeMetadata()
{
/*
Todo: implement me!
*/
throw(Error(31, "metadata", "RAF"));
} // RafImage::writeMetadata
bool RafImage::isThisType(BasicIo& iIo, bool advance) const
{
return isRafType(iIo, advance);
}
// *************************************************************************
// free functions
Image::AutoPtr newRafInstance(BasicIo::AutoPtr io, bool create)
{
Image::AutoPtr image(new RafImage(io, create));
if (!image->good()) {
image.reset();
}
return image;
}
bool isRafType(BasicIo& iIo, bool advance)
{
const int32_t len = 8;
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof()) {
return false;
}
int rc = memcmp(buf, "FUJIFILM", 8);
if (!advance || rc != 0) {
iIo.seek(-len, BasicIo::cur);
}
return rc == 0;
}
} // namespace Exiv2

@ -0,0 +1,176 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2007 Andreas Huggel <ahuggel@gmx.net>
*
* This program is part of the Exiv2 distribution.
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
/*!
@file rafimage.hpp
@brief Fujifilm RAW image
@version $Rev$
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 05-Feb-07, ahu: created
*/
#ifndef RAFIMAGE_HPP_
#define RAFIMAGE_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "iptc.hpp"
#include "image.hpp"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add RAF to the supported image formats
namespace ImageType {
const int raf = 8; //!< RAF image type (see class RafImage)
}
/*!
@brief Class to access raw RAF images. Exif metadata is supported
directly, IPTC is read from the Exif data, if present.
*/
class RafImage : public Image {
//! @name NOT Implemented
//@{
//! Copy constructor
RafImage(const RafImage& rhs);
//! Assignment operator
RafImage& operator=(const RafImage& rhs);
//@}
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing RAF image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
RafImage(BasicIo::AutoPtr io, bool create);
//! Destructor
~RafImage() {}
//@}
//! @name Manipulators
//@{
void readMetadata();
/*!
@brief Todo: Write metadata back to the image. This method is not
yet implemented. Calling it will throw an Error(31).
*/
void writeMetadata();
void setExifData(const ExifData& exifData);
void clearExifData();
void setIptcData(const IptcData& iptcData);
void clearIptcData();
/*!
@brief Not supported. RAF format does not contain a comment.
Calling this function will throw an Error(32).
*/
void setComment(const std::string& comment);
void clearComment();
void setMetadata(const Image& image);
void clearMetadata();
ExifData& exifData() { return exifData_; }
IptcData& iptcData() { return iptcData_; }
//@}
//! @name Accessors
//@{
bool good() const;
const ExifData& exifData() const { return exifData_; }
const IptcData& iptcData() const { return iptcData_; }
std::string comment() const { return comment_; }
BasicIo& io() const { return *io_; }
AccessMode checkMode(MetadataId metadataId) const;
//@}
private:
//! @name Accessors
//@{
/*!
@brief Determine if the content of the BasicIo instance is a RAF image.
The advance flag determines if the read position in the stream is
moved (see below). This applies only if the type matches and the
function returns true. If the type does not match, the stream
position is not changed. However, if reading from the stream fails,
the stream position is undefined. Consult the stream state to obtain
more information in this case.
@param iIo BasicIo instance to read from.
@param advance Flag indicating whether the position of the io
should be advanced by the number of characters read to
analyse the data (true) or left at its original
position (false). This applies only if the type matches.
@return true if the data matches the type of this class;<BR>
false if the data does not match
*/
bool isThisType(BasicIo& iIo, bool advance) const;
/*!
@brief Todo: Write RAF header. Not implemented yet.
*/
int writeHeader(BasicIo& oIo) const;
//@}
// DATA
BasicIo::AutoPtr io_; //!< Image data io pointer
ExifData exifData_; //!< Exif data container
IptcData iptcData_; //!< IPTC data container
std::string comment_; //!< User comment
}; // class RafImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new RafImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
Image::AutoPtr newRafInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a RAF image.
bool isRafType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef RAFIMAGE_HPP_
Loading…
Cancel
Save