Changed ImageFactory to use a static registry (to make it re-entrant without using a locking mechanism), introduced new ImageType namespace (for identifiers for image formats, these can be added without modifying image.*), tweaked image related documentation
This commit is contained in:
parent
bcf10895aa
commit
ef7aae6fa3
@ -52,7 +52,7 @@ CCHDR = exv_conf.h exv_msvc.h mn.hpp rcsid.hpp
|
||||
|
||||
# Add library C++ source files to this list
|
||||
CCSRC = basicio.cpp canonmn.cpp crwimage.cpp datasets.cpp error.cpp exif.cpp \
|
||||
futils.cpp fujimn.cpp ifd.cpp image.cpp iptc.cpp jpgimage.cpp \
|
||||
futils.cpp fujimn.cpp ifd.cpp image.cpp imgreg.cpp iptc.cpp jpgimage.cpp \
|
||||
makernote.cpp metadatum.cpp nikonmn.cpp olympusmn.cpp panasonicmn.cpp \
|
||||
sigmamn.cpp sonymn.cpp tags.cpp types.cpp value.cpp
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
|
||||
#include "actions.hpp"
|
||||
#include "image.hpp"
|
||||
#include "jpgimage.hpp"
|
||||
#include "exiv2.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "types.hpp"
|
||||
@ -1289,7 +1290,7 @@ namespace {
|
||||
}
|
||||
else {
|
||||
targetImage
|
||||
= Exiv2::ImageFactory::create(Exiv2::Image::exv, target);
|
||||
= Exiv2::ImageFactory::create(Exiv2::ImageType::exv, target);
|
||||
assert(targetImage.get() != 0);
|
||||
}
|
||||
if ( Params::instance().target_ & Params::ctExif
|
||||
|
||||
@ -60,18 +60,6 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
// Local functions. These could be static private functions on Image
|
||||
// subclasses but then ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new CrwImage 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 newCrwInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a CRW image.
|
||||
bool isCrwType(BasicIo& iIo, bool advance);
|
||||
|
||||
const byte CrwImage::blank_[] = {
|
||||
0x00
|
||||
};
|
||||
@ -182,14 +170,6 @@ namespace Exiv2 {
|
||||
// Todo: implement me!
|
||||
} // CrwImage::writeMetadata
|
||||
|
||||
//! @cond IGNORE
|
||||
CrwImage::CrwRegister::CrwRegister()
|
||||
{
|
||||
ImageFactory::registerImage(
|
||||
Image::crw, newCrwInstance, isCrwType);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
bool CrwImage::isThisType(BasicIo& iIo, bool advance) const
|
||||
{
|
||||
return isCrwType(iIo, advance);
|
||||
|
||||
118
src/crwimage.hpp
118
src/crwimage.hpp
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*!
|
||||
@file crwimage.hpp
|
||||
@brief Class CrwImage to access Canon CRW images.<BR>
|
||||
@brief Class CrwImage to access Canon Crw images.<BR>
|
||||
References:<BR>
|
||||
<a href="http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html">The Canon RAW (CRW) File Format</a> by Phil Harvey
|
||||
@version $Rev$
|
||||
@ -56,29 +56,38 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
|
||||
//! Function pointer for functions to extract Exif tags from a CRW entry
|
||||
//! Function pointer for functions to extract Exif tags from a Crw entry
|
||||
typedef void (*CrwExtractFct)(const CiffComponent&,
|
||||
const CrwMapInfo*,
|
||||
Image&,
|
||||
ByteOrder);
|
||||
|
||||
//! Function pointer for functions to insert CRW entries from an Exif tag
|
||||
//! Function pointer for functions to insert Crw entries from an Exif tag
|
||||
typedef void (*CrwInsertFct)();
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
/*!
|
||||
@brief Class to access Canon CRW images.
|
||||
// Add Crw to the supported image formats
|
||||
namespace ImageType {
|
||||
const int crw = 3; //!< Crw image type (see class CrwImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access raw Canon Crw images. Only Exif metadata and a
|
||||
comment are supported. Crw format does not contain Iptc metadata.
|
||||
*/
|
||||
class CrwImage : public Image {
|
||||
friend bool isCrwType(BasicIo& iIo, bool advance);
|
||||
|
||||
// NOT Implemented
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
CrwImage(const CrwImage& rhs);
|
||||
//! Assignment operator
|
||||
CrwImage& operator=(const CrwImage& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
@ -104,39 +113,23 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Read all metadata from the image. Before this method
|
||||
is called, the various metadata types (Iptc, Exif) will be empty.
|
||||
|
||||
This method returns success even when no metadata is found in
|
||||
the image. Callers must therefore check the size of individual
|
||||
metadata types before accessing the data.
|
||||
|
||||
@throw Error if opening or reading of the file fails or the image
|
||||
data is not valid (does not look like CRW data).
|
||||
*/
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Write metadata back to the image.
|
||||
|
||||
All existing metadata sections in the image are either created,
|
||||
replaced, or erased. If values for a given metadata type have been
|
||||
assigned, a section for that metadata type will either be created or
|
||||
replaced. If no values have been assigned to a given metadata type,
|
||||
any exists section for that metadata type will be removed from the
|
||||
image.
|
||||
|
||||
@throw Error if the operation fails
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Assign new exif data. The new exif data is not written
|
||||
to the image until the writeMetadata() method is called.
|
||||
@param exifData An ExifData instance holding exif data to be copied
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet implemented.
|
||||
*/
|
||||
void writeMetadata();
|
||||
void setExifData(const ExifData& exifData);
|
||||
void clearExifData();
|
||||
/*!
|
||||
@brief Not supported. Crw format does not contain Iptc metadata.
|
||||
Calling this function will raise an exception (Error).
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Not supported. Crw format does not contain Iptc metadata.
|
||||
Calling this function will raise an exception (Error).
|
||||
*/
|
||||
void clearIptcData();
|
||||
void setComment(const std::string& comment);
|
||||
void clearComment();
|
||||
@ -155,13 +148,6 @@ namespace Exiv2 {
|
||||
BasicIo& io() const { return *io_; }
|
||||
//@}
|
||||
|
||||
//! @cond IGNORE
|
||||
// Public only so that we can create a static instance
|
||||
struct CrwRegister{
|
||||
CrwRegister();
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
private:
|
||||
|
||||
//! @name Manipulators
|
||||
@ -191,18 +177,13 @@ namespace Exiv2 {
|
||||
*/
|
||||
bool isThisType(BasicIo& iIo, bool advance) const;
|
||||
/*!
|
||||
@brief Writes a Crw header (aka signature) to the BasicIo instance.
|
||||
@param oIo BasicIo instance that the header is written to.
|
||||
@return 0 if successful;<BR>
|
||||
2 if the input image is invalid or can not be read;<BR>
|
||||
4 if the temporary image can not be written to;<BR>
|
||||
-3 other temporary errors;<BR>
|
||||
@brief Todo: Write Crw header. Not implemented yet.
|
||||
*/
|
||||
int writeHeader(BasicIo& oIo) const;
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
static const byte blank_[]; //!< Minimal CRW image
|
||||
static const byte blank_[]; //!< Minimal Crw image
|
||||
|
||||
BasicIo::AutoPtr io_; //!< Image data io pointer
|
||||
ExifData exifData_; //!< Exif data container
|
||||
@ -211,8 +192,6 @@ namespace Exiv2 {
|
||||
|
||||
}; // class CrwImage
|
||||
|
||||
static CrwImage::CrwRegister crwReg;
|
||||
|
||||
/*!
|
||||
Base class for all objects in a raw metadata parse tree.
|
||||
Defines the interface for raw metadata composites.
|
||||
@ -280,7 +259,7 @@ namespace Exiv2 {
|
||||
|
||||
/*!
|
||||
@brief Interface class for components of the CIFF directory hierarchy of
|
||||
a CRW (Canon Raw data) image. Both CIFF directories as well as
|
||||
a Crw (Canon Raw data) image. Both CIFF directories as well as
|
||||
entries implement this interface.
|
||||
*/
|
||||
class CiffComponent : public RawMetadata {
|
||||
@ -371,7 +350,7 @@ namespace Exiv2 {
|
||||
|
||||
/*!
|
||||
@brief This class models one directory entry of a CIFF directory of
|
||||
a CRW (Canon Raw data) image.
|
||||
a Crw (Canon Raw data) image.
|
||||
*/
|
||||
class CiffEntry : public CiffComponent {
|
||||
public:
|
||||
@ -399,7 +378,7 @@ namespace Exiv2 {
|
||||
|
||||
}; // class CiffEntry
|
||||
|
||||
//! This class models a CIFF directory of a CRW (Canon Raw data) image.
|
||||
//! This class models a CIFF directory of a Crw (Canon Raw data) image.
|
||||
class CiffDirectory : public CiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
@ -458,7 +437,7 @@ namespace Exiv2 {
|
||||
|
||||
}; // class CiffDirectory
|
||||
|
||||
//! This class models the header of a CRW (Canon Raw data) image.
|
||||
//! This class models the header of a Crw (Canon Raw data) image.
|
||||
class CiffHeader : public RawMetadata {
|
||||
public:
|
||||
//! @name Creators
|
||||
@ -499,11 +478,11 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
static const char signature_[]; //!< Canon CRW signature "HEAPCCDR"
|
||||
static const char signature_[]; //!< Canon Crw signature "HEAPCCDR"
|
||||
|
||||
private:
|
||||
// DATA
|
||||
CiffDirectory* rootDirectory_; //!< Pointer to the root directory
|
||||
CiffDirectory* rootDirectory_; //!< Pointer to the root directory
|
||||
ByteOrder byteOrder_; //!< Applicable byte order
|
||||
uint32_t offset_; //!< Offset to the start of the root dir
|
||||
|
||||
@ -533,8 +512,8 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
uint16_t crwTagId_; //!< CRW tag id
|
||||
uint16_t crwDir_; //!< CRW directory tag
|
||||
uint16_t crwTagId_; //!< Crw tag id
|
||||
uint16_t crwDir_; //!< Crw directory tag
|
||||
uint32_t size_; //!< Data size (overwrites the size from the entry)
|
||||
uint16_t tag_; //!< Exif tag to map to
|
||||
IfdId ifdId_; //!< Exif Ifd id to map to
|
||||
@ -544,7 +523,7 @@ namespace Exiv2 {
|
||||
}; // struct CrwMapInfo
|
||||
|
||||
/*!
|
||||
@brief Static class providing mapping functionality from CRW entries
|
||||
@brief Static class providing mapping functionality from Crw entries
|
||||
to image metadata and vice versa
|
||||
*/
|
||||
class CrwMap {
|
||||
@ -556,7 +535,7 @@ namespace Exiv2 {
|
||||
|
||||
public:
|
||||
/*!
|
||||
@brief Extract image metadata from a CRW entry convert and add it
|
||||
@brief Extract image metadata from a Crw entry convert and add it
|
||||
to the image metadata.
|
||||
|
||||
@param ciffComponent Source CIFF entry
|
||||
@ -569,11 +548,11 @@ namespace Exiv2 {
|
||||
ByteOrder byteOrder);
|
||||
|
||||
private:
|
||||
//! Return conversion information for one CRW \em dir and \em tagId
|
||||
//! Return conversion information for one Crw \em dir and \em tagId
|
||||
static const CrwMapInfo* crwMapInfo(uint16_t dir, uint16_t tagId);
|
||||
|
||||
/*!
|
||||
@brief Standard extraction function to convert CRW entries to
|
||||
@brief Standard extraction function to convert Crw entries to
|
||||
Exif metadata.
|
||||
|
||||
Uses the mapping defined in the conversion structure \em crwMapInfo
|
||||
@ -633,6 +612,21 @@ namespace Exiv2 {
|
||||
|
||||
}; // class CrwMap
|
||||
|
||||
// *****************************************************************************
|
||||
// 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 CrwImage 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 newCrwInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a Crw image.
|
||||
bool isCrwType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef CRWIMAGE_HPP_
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "image.hpp"
|
||||
#include "jpgimage.hpp"
|
||||
#include "exif.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
@ -79,7 +80,7 @@ catch (Exiv2::AnyError& e) {
|
||||
|
||||
void write(const std::string& file, Exiv2::ExifData& ed)
|
||||
{
|
||||
Image::AutoPtr image = ImageFactory::create(Image::exv, file);
|
||||
Image::AutoPtr image = ImageFactory::create(Exiv2::ImageType::exv, file);
|
||||
assert(image.get() != 0);
|
||||
|
||||
image->setExifData(ed);
|
||||
|
||||
@ -78,6 +78,7 @@ namespace Exiv2 {
|
||||
ErrMsg( 32, "%1: CRW images don't support JPEG comments"), // %1=function
|
||||
ErrMsg( 33, "This does not look like a CRW image"),
|
||||
ErrMsg( 34, "%1: Not supported"), // %1=function
|
||||
ErrMsg( 35, "ImageFactory registry full"),
|
||||
|
||||
// Last error message (message is not used)
|
||||
ErrMsg( -2, "(Unknown Error)")
|
||||
|
||||
@ -44,10 +44,6 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// Ensure registration with factory
|
||||
#include "jpgimage.hpp"
|
||||
#include "crwimage.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
@ -67,70 +63,50 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
int ImageFactory::Init::count = 0;
|
||||
|
||||
ImageFactory::Init::Init()
|
||||
const ImageFactory::Registry* ImageFactory::find(int imageType)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
ImageFactory::Init::~Init()
|
||||
{
|
||||
if (--count == 0) {
|
||||
Exiv2::ImageFactory::cleanup();
|
||||
for (unsigned int i = 0; registry_[i].imageType_ != ImageType::none; ++i) {
|
||||
if (registry_[i].imageType_ == imageType) return ®istry_[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ImageFactory::Registry* ImageFactory::registry_ = 0;
|
||||
|
||||
void ImageFactory::cleanup()
|
||||
void ImageFactory::registerImage(int type,
|
||||
NewInstanceFct newInst,
|
||||
IsThisTypeFct isType)
|
||||
{
|
||||
delete registry_;
|
||||
registry_ = 0;
|
||||
}
|
||||
|
||||
void ImageFactory::init()
|
||||
{
|
||||
if (0 == registry_) {
|
||||
registry_ = new Registry;
|
||||
unsigned int i = 0;
|
||||
for (; i < MAX_IMAGE_FORMATS; ++i) {
|
||||
if (registry_[i].imageType_ == ImageType::none) {
|
||||
registry_[i] = Registry(type, newInst, isType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == MAX_IMAGE_FORMATS) throw Error(35);
|
||||
}
|
||||
|
||||
void ImageFactory::registerImage(Image::Type type,
|
||||
NewInstanceFct newInst, IsThisTypeFct isType)
|
||||
{
|
||||
init();
|
||||
assert (newInst && isType);
|
||||
(*registry_)[type] = ImageFcts(newInst, isType);
|
||||
}
|
||||
|
||||
Image::Type ImageFactory::getType(const std::string& path)
|
||||
int ImageFactory::getType(const std::string& path)
|
||||
{
|
||||
FileIo fileIo(path);
|
||||
return getType(fileIo);
|
||||
}
|
||||
|
||||
Image::Type ImageFactory::getType(const byte* data, long size)
|
||||
int ImageFactory::getType(const byte* data, long size)
|
||||
{
|
||||
MemIo memIo(data, size);
|
||||
return getType(memIo);
|
||||
}
|
||||
|
||||
Image::Type ImageFactory::getType(BasicIo& io)
|
||||
int ImageFactory::getType(BasicIo& io)
|
||||
{
|
||||
if (io.open() != 0) return Image::none;
|
||||
if (io.open() != 0) return ImageType::none;
|
||||
IoCloser closer(io);
|
||||
Image::Type type = Image::none;
|
||||
Registry::const_iterator b = registry_->begin();
|
||||
Registry::const_iterator e = registry_->end();
|
||||
for (Registry::const_iterator i = b; i != e; ++i)
|
||||
{
|
||||
if (i->second.isThisType(io, false)) {
|
||||
type = i->first;
|
||||
break;
|
||||
for (unsigned int i = 0; registry_[i].imageType_ != ImageType::none; ++i) {
|
||||
if (registry_[i].isThisType_(io, false)) {
|
||||
return registry_[i].imageType_;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
return ImageType::none;
|
||||
} // ImageFactory::getType
|
||||
|
||||
Image::AutoPtr ImageFactory::open(const std::string& path)
|
||||
@ -154,19 +130,15 @@ namespace Exiv2 {
|
||||
if (io->open() != 0) {
|
||||
throw Error(9, io->path(), strError());
|
||||
}
|
||||
Image::AutoPtr image;
|
||||
Registry::const_iterator b = registry_->begin();
|
||||
Registry::const_iterator e = registry_->end();
|
||||
for (Registry::const_iterator i = b; i != e; ++i) {
|
||||
if (i->second.isThisType(*io, false)) {
|
||||
image = i->second.newInstance(io, false);
|
||||
break;
|
||||
for (unsigned int i = 0; registry_[i].imageType_ != ImageType::none; ++i) {
|
||||
if (registry_[i].isThisType_(*io, false)) {
|
||||
return registry_[i].newInstance_(io, false);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
return Image::AutoPtr();
|
||||
} // ImageFactory::open
|
||||
|
||||
Image::AutoPtr ImageFactory::create(Image::Type type,
|
||||
Image::AutoPtr ImageFactory::create(int type,
|
||||
const std::string& path)
|
||||
{
|
||||
std::auto_ptr<FileIo> fileIo(new FileIo(path));
|
||||
@ -181,7 +153,7 @@ namespace Exiv2 {
|
||||
return image;
|
||||
}
|
||||
|
||||
Image::AutoPtr ImageFactory::create(Image::Type type)
|
||||
Image::AutoPtr ImageFactory::create(int type)
|
||||
{
|
||||
BasicIo::AutoPtr io(new MemIo);
|
||||
Image::AutoPtr image = create(type, io);
|
||||
@ -189,13 +161,13 @@ namespace Exiv2 {
|
||||
return image;
|
||||
}
|
||||
|
||||
Image::AutoPtr ImageFactory::create(Image::Type type,
|
||||
Image::AutoPtr ImageFactory::create(int type,
|
||||
BasicIo::AutoPtr io)
|
||||
{
|
||||
// BasicIo instance does not need to be open
|
||||
Registry::const_iterator i = registry_->find(type);
|
||||
if (i != registry_->end()) {
|
||||
return i->second.newInstance(io, true);
|
||||
const Registry* r = find(type);
|
||||
if (0 != r) {
|
||||
return r->newInstance_(io, true);
|
||||
}
|
||||
return Image::AutoPtr();
|
||||
} // ImageFactory::create
|
||||
|
||||
145
src/image.hpp
145
src/image.hpp
@ -54,6 +54,12 @@ namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Supported image formats
|
||||
namespace ImageType {
|
||||
const int none = 0; //!< Not an image
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Abstract base class defining the interface for an image. This is
|
||||
the top-level interface to the Exiv2 library.
|
||||
@ -63,10 +69,7 @@ namespace Exiv2 {
|
||||
read, write, and save metadata.
|
||||
*/
|
||||
class Image {
|
||||
public:
|
||||
//! Supported image formats
|
||||
enum Type { none, jpeg, exv, crw };
|
||||
|
||||
public:
|
||||
//! Image auto_ptr type
|
||||
typedef std::auto_ptr<Image> AutoPtr;
|
||||
|
||||
@ -79,9 +82,17 @@ namespace Exiv2 {
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read metadata from assigned image. Before this method
|
||||
is called, the various metadata types (Iptc, Exif) will be empty.
|
||||
@throw Error In case of failure.
|
||||
@brief Read all metadata supported by a specific image format from the
|
||||
image. Before this method is called, the various metadata types
|
||||
will be empty.
|
||||
|
||||
This method returns success even if no metadata is found in the
|
||||
image. Callers must therefore check the size of individual metadata
|
||||
types before accessing the data.
|
||||
|
||||
@throw Error if opening or reading of the file fails or the image
|
||||
data is not valid (does not look like data of the specific image
|
||||
type).
|
||||
*/
|
||||
virtual void readMetadata() =0;
|
||||
/*!
|
||||
@ -154,50 +165,50 @@ namespace Exiv2 {
|
||||
virtual bool good() const =0;
|
||||
/*!
|
||||
@brief Returns an ExifData instance containing currently buffered
|
||||
exif data.
|
||||
Exif data.
|
||||
|
||||
The exif data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The exif
|
||||
The Exif data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The Exif
|
||||
data in the returned instance will be written to the image when
|
||||
writeMetadata() is called.
|
||||
|
||||
@return read only ExifData instance containing exif values
|
||||
@return read only ExifData instance containing Exif values
|
||||
*/
|
||||
virtual const ExifData& exifData() const =0;
|
||||
/*!
|
||||
@brief Returns an ExifData instance containing currently buffered
|
||||
exif data.
|
||||
Exif data.
|
||||
|
||||
The contained exif data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The exif
|
||||
The contained Exif data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The Exif
|
||||
data in the returned instance will be written to the image when
|
||||
writeMetadata() is called.
|
||||
|
||||
@return modifiable ExifData instance containing exif values
|
||||
@return modifiable ExifData instance containing Exif values
|
||||
*/
|
||||
virtual ExifData& exifData() =0;
|
||||
/*!
|
||||
@brief Returns an IptcData instance containing currently buffered
|
||||
iptc data.
|
||||
Iptc data.
|
||||
|
||||
The contained iptc data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The iptc
|
||||
The contained Iptc data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The Iptc
|
||||
data in the returned instance will be written to the image when
|
||||
writeMetadata() is called.
|
||||
|
||||
@return modifiable IptcData instance containing iptc values
|
||||
@return modifiable IptcData instance containing Iptc values
|
||||
*/
|
||||
virtual const IptcData& iptcData() const =0;
|
||||
/*!
|
||||
@brief Returns an ExifData instance containing currently buffered
|
||||
exif data.
|
||||
@brief Returns an IptcData instance containing currently buffered
|
||||
Iptc data.
|
||||
|
||||
The contained iptc data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The iptc
|
||||
The contained Iptc data may have been read from the image by
|
||||
a previous call to readMetadata() or added directly. The Iptc
|
||||
data in the returned instance will be written to the image when
|
||||
writeMetadata() is called.
|
||||
|
||||
@return modifiable IptcData instance containing iptc values
|
||||
@return modifiable IptcData instance containing Iptc values
|
||||
*/
|
||||
virtual IptcData& iptcData() =0;
|
||||
/*!
|
||||
@ -266,7 +277,7 @@ namespace Exiv2 {
|
||||
@param newInst Function pointer for creating image instances.
|
||||
@param isType Function pointer to test for matching image types.
|
||||
*/
|
||||
static void registerImage(Image::Type type,
|
||||
static void registerImage(int type,
|
||||
NewInstanceFct newInst,
|
||||
IsThisTypeFct isType);
|
||||
//@}
|
||||
@ -324,7 +335,7 @@ namespace Exiv2 {
|
||||
type.
|
||||
@throw Error If the image type is not supported.
|
||||
*/
|
||||
static Image::AutoPtr create(Image::Type type, const std::string& path);
|
||||
static Image::AutoPtr create(int type, const std::string& path);
|
||||
/*!
|
||||
@brief Create an Image subclass of the requested type by creating a
|
||||
new image in memory.
|
||||
@ -333,7 +344,7 @@ namespace Exiv2 {
|
||||
type.
|
||||
@throw Error If the image type is not supported
|
||||
*/
|
||||
static Image::AutoPtr create(Image::Type type);
|
||||
static Image::AutoPtr create(int type);
|
||||
/*!
|
||||
@brief Create an Image subclass of the requested type by writing a
|
||||
new image to a BasicIo instance. If the BasicIo instance already
|
||||
@ -348,14 +359,14 @@ namespace Exiv2 {
|
||||
@return An auto-pointer that owns an Image instance of the requested
|
||||
type. If the image type is not supported, the pointer is 0.
|
||||
*/
|
||||
static Image::AutoPtr create(Image::Type type, BasicIo::AutoPtr io);
|
||||
static Image::AutoPtr create(int type, BasicIo::AutoPtr io);
|
||||
/*!
|
||||
@brief Returns the image type of the provided file.
|
||||
@param path %Image file. The contents of the file are tested to
|
||||
determine the image type. File extension is ignored.
|
||||
@return %Image type or Image::none if the type is not recognized.
|
||||
*/
|
||||
static Image::Type getType(const std::string& path);
|
||||
static int getType(const std::string& path);
|
||||
/*!
|
||||
@brief Returns the image type of the provided data buffer.
|
||||
@param data Pointer to a data buffer containing an image. The contents
|
||||
@ -363,7 +374,7 @@ namespace Exiv2 {
|
||||
@param size Number of bytes pointed to by \em data.
|
||||
@return %Image type or Image::none if the type is not recognized.
|
||||
*/
|
||||
static Image::Type getType(const byte* data, long size);
|
||||
static int getType(const byte* data, long size);
|
||||
/*!
|
||||
@brief Returns the image type of data provided by a BasicIo instance.
|
||||
The passed in \em io instance is (re)opened by this method.
|
||||
@ -371,28 +382,9 @@ namespace Exiv2 {
|
||||
of the image data are tested to determine the type.
|
||||
@return %Image type or Image::none if the type is not recognized.
|
||||
*/
|
||||
static Image::Type getType(BasicIo& io);
|
||||
static int getType(BasicIo& io);
|
||||
//@}
|
||||
|
||||
/*!
|
||||
@brief Class Init is used to execute initialisation and termination
|
||||
code exactly once, at the begin and end of the program.
|
||||
|
||||
See Bjarne Stroustrup, 'The C++ Programming Language 3rd
|
||||
Edition', section 21.5.2 for details about this pattern.
|
||||
*/
|
||||
class Init {
|
||||
static int count; //!< Counts calls to constructor
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Perform one-time initialisations.
|
||||
Init();
|
||||
//! Perform one-time cleanup operations.
|
||||
~Init();
|
||||
//@}
|
||||
};
|
||||
|
||||
private:
|
||||
//! @name Creators
|
||||
//@{
|
||||
@ -400,27 +392,38 @@ namespace Exiv2 {
|
||||
ImageFactory();
|
||||
//! Prevent copy construction: not implemented.
|
||||
ImageFactory(const ImageFactory& rhs);
|
||||
//! Creates the private static instance
|
||||
static void init();
|
||||
//@}
|
||||
|
||||
//! Struct for storing image function pointers.
|
||||
struct ImageFcts
|
||||
//! Struct for storing image types and function pointers.
|
||||
struct Registry
|
||||
{
|
||||
NewInstanceFct newInstance;
|
||||
IsThisTypeFct isThisType;
|
||||
ImageFcts(NewInstanceFct newInst, IsThisTypeFct isType)
|
||||
: newInstance(newInst), isThisType(isType) {}
|
||||
ImageFcts() : newInstance(0), isThisType(0) {}
|
||||
//! Default constructor
|
||||
Registry()
|
||||
: imageType_(ImageType::none),
|
||||
newInstance_(0),
|
||||
isThisType_(0)
|
||||
{}
|
||||
//! Constructor
|
||||
Registry(int imageType,
|
||||
NewInstanceFct newInstance,
|
||||
IsThisTypeFct isThisType)
|
||||
: imageType_(imageType),
|
||||
newInstance_(newInstance),
|
||||
isThisType_(isThisType)
|
||||
{}
|
||||
int imageType_;
|
||||
NewInstanceFct newInstance_;
|
||||
IsThisTypeFct isThisType_;
|
||||
};
|
||||
|
||||
// DATA
|
||||
//! Type used to store Image creation functions
|
||||
typedef std::map<Image::Type, ImageFcts> Registry;
|
||||
//! List of image types and corresponding creation functions.
|
||||
static Registry* registry_;
|
||||
}; // class ImageFactory
|
||||
//! Return the registry entry for type
|
||||
static const Registry* find(int imageType);
|
||||
|
||||
// DATA
|
||||
static const unsigned int MAX_IMAGE_FORMATS = 32;
|
||||
//! List of image types and corresponding creation functions.
|
||||
static Registry registry_[MAX_IMAGE_FORMATS];
|
||||
}; // class ImageFactory
|
||||
|
||||
//! Helper class modelling the TIFF header structure.
|
||||
class TiffHeader {
|
||||
@ -478,16 +481,4 @@ namespace Exiv2 {
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
namespace {
|
||||
/*!
|
||||
Each translation unit that includes image.hpp declares its own
|
||||
Init object. The destructor ensures that the factory is properly
|
||||
freed exactly once.
|
||||
|
||||
See Bjarne Stroustrup, 'The C++ Programming Language 3rd
|
||||
Edition', section 21.5.2 for details about this pattern.
|
||||
*/
|
||||
Exiv2::ImageFactory::Init imageFactoryInit;
|
||||
}
|
||||
|
||||
#endif // #ifndef IMAGE_HPP_
|
||||
|
||||
50
src/imgreg.cpp
Normal file
50
src/imgreg.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
File: imgreg.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 19-Sep-05, ahu: created
|
||||
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id$");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "image.hpp"
|
||||
#include "jpgimage.hpp"
|
||||
#include "crwimage.hpp"
|
||||
|
||||
// + standard includes
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
ImageFactory::Registry ImageFactory::registry_[] = {
|
||||
Registry(ImageType::jpeg, newJpegInstance, isJpegType),
|
||||
Registry(ImageType::exv, newExvInstance, isExvType),
|
||||
Registry(ImageType::crw, newCrwInstance, isCrwType)
|
||||
};
|
||||
|
||||
} // namespace Exiv2
|
||||
@ -49,25 +49,6 @@ EXIV2_RCSID("@(#) $Id$");
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
// Local functions. These could be static private functions on Image
|
||||
// subclasses but then ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new ExvImage 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 newExvInstance(BasicIo::AutoPtr io, bool create);
|
||||
//! Check if the file iIo is an EXV file
|
||||
bool isExvType(BasicIo& iIo, bool advance);
|
||||
/*!
|
||||
@brief Create a new JpegImage 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 newJpegInstance(BasicIo::AutoPtr io, bool create);
|
||||
//! Check if the file iIo is a JPEG image.
|
||||
bool isJpegType(BasicIo& iIo, bool advance);
|
||||
|
||||
const byte JpegBase::sos_ = 0xda;
|
||||
const byte JpegBase::eoi_ = 0xd9;
|
||||
@ -549,14 +530,6 @@ namespace Exiv2 {
|
||||
: JpegBase(io, create, blank_, sizeof(blank_))
|
||||
{
|
||||
}
|
||||
|
||||
//! @cond IGNORE
|
||||
JpegImage::JpegRegister::JpegRegister()
|
||||
{
|
||||
ImageFactory::registerImage(
|
||||
Image::jpeg, newJpegInstance, isJpegType);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
int JpegImage::writeHeader(BasicIo& outIo) const
|
||||
{
|
||||
@ -605,14 +578,6 @@ namespace Exiv2 {
|
||||
{
|
||||
}
|
||||
|
||||
//! @cond IGNORE
|
||||
ExvImage::ExvRegister::ExvRegister()
|
||||
{
|
||||
ImageFactory::registerImage(
|
||||
Image::exv, newExvInstance, isExvType);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
int ExvImage::writeHeader(BasicIo& outIo) const
|
||||
{
|
||||
// Exv header
|
||||
|
||||
110
src/jpgimage.hpp
110
src/jpgimage.hpp
@ -50,6 +50,12 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Supported jpeg image formats
|
||||
namespace ImageType {
|
||||
const int jpeg = 1; //!< Jpeg image type (see class JpegImage)
|
||||
const int exv = 2; //!< Exv image type (see class ExvImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Abstract helper base class to access JPEG images.
|
||||
*/
|
||||
@ -62,36 +68,8 @@ namespace Exiv2 {
|
||||
//@}
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read all metadata from the image. Before this method
|
||||
is called, the various metadata types (Iptc, Exif) will be empty.
|
||||
|
||||
This method returns success even when no metadata is found in
|
||||
the image. Callers must therefore check the size of individual
|
||||
metadata types before accessing the data.
|
||||
|
||||
@throw Error if opening or reading of the file fails or the image
|
||||
data is not valid (does not look like JPEG data).
|
||||
*/
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Write metadata back to the image.
|
||||
|
||||
All existing metadata sections in the image are either created,
|
||||
replaced, or erased. If values for a given metadata type have been
|
||||
assigned, a section for that metadata type will either be created or
|
||||
replaced. If no values have been assigned to a given metadata type,
|
||||
any exists section for that metadata type will be removed from the
|
||||
image.
|
||||
|
||||
@throw Error if the operation fails
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Assign new exif data. The new exif data is not written
|
||||
to the image until the writeMetadata() method is called.
|
||||
@param exifData An ExifData instance holding exif data to be copied
|
||||
*/
|
||||
void setExifData(const ExifData& exifData);
|
||||
void clearExifData();
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
@ -141,7 +119,7 @@ namespace Exiv2 {
|
||||
@brief Writes the image header (aka signature) to the BasicIo instance.
|
||||
@param oIo BasicIo instance that the header is written to.
|
||||
@return 0 if successful;<BR>
|
||||
4 if the output file can not be written to;<BR>
|
||||
4 if the output file can not be written to
|
||||
*/
|
||||
virtual int writeHeader(BasicIo& oIo) const =0;
|
||||
//@}
|
||||
@ -164,7 +142,7 @@ namespace Exiv2 {
|
||||
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;<BR>
|
||||
false if the data does not match
|
||||
*/
|
||||
virtual bool isThisType(BasicIo& iIo, bool advance) const =0;
|
||||
//@}
|
||||
@ -196,7 +174,7 @@ namespace Exiv2 {
|
||||
when the BasicIo instance is positioned one byte past the end of a
|
||||
Jpeg segment.
|
||||
@return the next Jpeg segment marker if successful;<BR>
|
||||
-1 if a maker was not found before EOF;<BR>
|
||||
-1 if a maker was not found before EOF
|
||||
*/
|
||||
int advanceToMarker() const;
|
||||
/*!
|
||||
@ -275,27 +253,9 @@ namespace Exiv2 {
|
||||
//! Destructor
|
||||
~JpegImage() {}
|
||||
//@}
|
||||
|
||||
//! @cond IGNORE
|
||||
// Public only so that we can create a static instance
|
||||
struct JpegRegister{
|
||||
JpegRegister();
|
||||
};
|
||||
//! @endcond
|
||||
protected:
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Determine if the content of the BasicIo instance is a Jpeg image.
|
||||
See base class for more details.
|
||||
@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 a Jpeg image;<BR>
|
||||
false if the data does not match;<BR>
|
||||
*/
|
||||
bool isThisType(BasicIo& iIo, bool advance) const;
|
||||
//@}
|
||||
//! @name Manipulators
|
||||
@ -306,7 +266,7 @@ namespace Exiv2 {
|
||||
@return 0 if successful;<BR>
|
||||
2 if the input image is invalid or can not be read;<BR>
|
||||
4 if the temporary image can not be written to;<BR>
|
||||
-3 other temporary errors;<BR>
|
||||
-3 other temporary errors
|
||||
*/
|
||||
int writeHeader(BasicIo& oIo) const;
|
||||
//@}
|
||||
@ -324,8 +284,6 @@ namespace Exiv2 {
|
||||
JpegImage& operator=(const JpegImage& rhs);
|
||||
}; // class JpegImage
|
||||
|
||||
static JpegImage::JpegRegister jpegReg;
|
||||
|
||||
//! Helper class to access %Exiv2 files
|
||||
class ExvImage : public JpegBase {
|
||||
friend bool isExvType(BasicIo& iIo, bool advance);
|
||||
@ -351,37 +309,13 @@ namespace Exiv2 {
|
||||
//! Destructor
|
||||
~ExvImage() {}
|
||||
//@}
|
||||
|
||||
//! @cond IGNORE
|
||||
// Public only so that we can create a static instance
|
||||
struct ExvRegister{
|
||||
ExvRegister();
|
||||
};
|
||||
//! @endcond
|
||||
protected:
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Determine if the content of the BasicIo instance is an Exv
|
||||
image. See base class for more details.
|
||||
@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 a Jpeg image;<BR>
|
||||
false if the data does not match;<BR>
|
||||
*/
|
||||
virtual bool isThisType(BasicIo& iIo, bool advance) const;
|
||||
//@}
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Writes an Exv header (aka signature) to the BasicIo instance.
|
||||
@param oIo BasicIo instance that the header is written to.
|
||||
@return 0 if successful;<BR>
|
||||
4 if the output file can not be written to;<BR>
|
||||
*/
|
||||
int writeHeader(BasicIo& oIo) const;
|
||||
//@}
|
||||
private:
|
||||
@ -398,8 +332,28 @@ namespace Exiv2 {
|
||||
ExvImage& operator=(const ExvImage& rhs);
|
||||
}; // class ExvImage
|
||||
|
||||
static ExvImage::ExvRegister exvReg;
|
||||
// *****************************************************************************
|
||||
// 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 JpegImage 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 newJpegInstance(BasicIo::AutoPtr io, bool create);
|
||||
//! Check if the file iIo is a JPEG image.
|
||||
bool isJpegType(BasicIo& iIo, bool advance);
|
||||
/*!
|
||||
@brief Create a new ExvImage 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 newExvInstance(BasicIo::AutoPtr io, bool create);
|
||||
//! Check if the file iIo is an EXV file
|
||||
bool isExvType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
|
||||
#endif // #ifndef JPGIMAGE_HPP_
|
||||
|
||||
Loading…
Reference in New Issue
Block a user