Added read support for jp2 and psd images, stubs for gif, bmp and tga images, and pixelWidth and pixelHeight methods on Image (Marco Piovanelli).

v0.27.3
Andreas Huggel 17 years ago
parent 1c86a6e297
commit 654d51a366

@ -68,6 +68,7 @@ CCHDR = exv_conf.h \
# Add library C++ source files to this list
CCSRC = basicio.cpp \
bmpimage.cpp \
canonmn.cpp \
convert.cpp \
cr2image.cpp \
@ -77,9 +78,11 @@ CCSRC = basicio.cpp \
exif.cpp \
futils.cpp \
fujimn.cpp \
gifimage.cpp \
ifd.cpp \
image.cpp \
iptc.cpp \
jp2image.cpp \
jpgimage.cpp \
makernote.cpp \
makernote2.cpp \
@ -94,11 +97,13 @@ ifdef HAVE_LIBZ
CCSRC += pngimage.cpp \
pngchunk.cpp
endif
CCSRC += rafimage.cpp \
CCSRC += psdimage.cpp \
rafimage.cpp \
sigmamn.cpp \
pentaxmn.cpp \
sonymn.cpp \
tags.cpp \
tgaimage.cpp \
tiffcomposite.cpp \
tiffimage.cpp \
tiffparser.cpp \

@ -241,11 +241,6 @@ namespace Action {
assert(image.get() != 0);
image->readMetadata();
Exiv2::ExifData& exifData = image->exifData();
if (exifData.empty()) {
std::cerr << path_ << ": "
<< _("No Exif data found in the file\n");
return -3;
}
align_ = 16;
// Filename
@ -259,6 +254,20 @@ namespace Action {
std::cout << buf.st_size << " " << _("Bytes") << std::endl;
}
// MIME type
printLabel(_("MIME type"));
std::cout << image->mimeType() << "\n";
// Image size
printLabel(_("Image size"));
std::cout << image->pixelWidth() << " x " << image->pixelHeight() << "\n";
if (exifData.empty()) {
std::cerr << path_ << ": "
<< _("No Exif data found in the file\n");
return -3;
}
// Camera make
printTag(exifData, "Exif.Image.Make", _("Camera make"));

@ -0,0 +1,160 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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: bmpimage.cpp
Version: $Rev$
Author(s): Marco Piovanelli, Ovolabs (marco)
History: 05-Mar-2007, marco: created
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
//#define DEBUG 1
// *****************************************************************************
// included header files
#ifdef _MSC_VER
# include "exv_msvc.h"
#else
# include "exv_conf.h"
#endif
#include "bmpimage.hpp"
#include "image.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
// + standard includes
#include <string>
#include <cstring>
#include <iostream>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
BmpImage::BmpImage(BasicIo::AutoPtr io)
: Image(ImageType::bmp, mdNone, io)
{
} // BmpImage::BmpImage
void BmpImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!
throw(Error(32, "Exif metadata", "BMP"));
}
void BmpImage::setIptcData(const IptcData& /*iptcData*/)
{
// Todo: implement me!
throw(Error(32, "IPTC metadata", "BMP"));
}
void BmpImage::setComment(const std::string& /*comment*/)
{
// not supported
throw(Error(32, "Image comment", "BMP"));
}
void BmpImage::readMetadata()
{
#ifdef DEBUG
std::cerr << "Exiv2::BmpImage::readMetadata: Reading Windows bitmap 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 (!isBmpType(*io_, false))
{
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "BMP");
}
clearMetadata();
/*
The Windows bitmap header goes as follows -- all numbers are in little-endian byte order:
offset length name description
====== ======= ===================== =======
0 2 bytes signature always 'BM'
2 4 bytes bitmap size
6 4 bytes reserved
10 4 bytes bitmap offset
14 4 bytes header size
18 4 bytes bitmap width
22 4 bytes bitmap height
26 2 bytes plane count
28 2 bytes depth
30 4 bytes compression 0 = none; 1 = RLE, 8 bits/pixel; 2 = RLE, 4 bits/pixel; 3 = bitfield; 4 = JPEG; 5 = PNG
34 4 bytes image size size of the raw bitmap data, in bytes
38 4 bytes horizontal resolution (in pixels per meter)
42 4 bytes vertical resolution (in pixels per meter)
46 4 bytes color count
50 4 bytes important colors number of "important" colors
*/
byte buf[54];
if (io_->read(buf, sizeof(buf)) == sizeof(buf))
{
pixelWidth_ = getLong(buf + 18, littleEndian);
pixelHeight_ = getLong(buf + 22, littleEndian);
}
} // BmpImage::readMetadata
void BmpImage::writeMetadata()
{
// Todo: implement me!
throw(Error(31, "BMP"));
} // BmpImage::writeMetadata
// *************************************************************************
// free functions
Image::AutoPtr newBmpInstance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new BmpImage(io));
if (!image->good())
{
image.reset();
}
return image;
}
bool isBmpType(BasicIo& iIo, bool advance)
{
const int32_t len = 2;
const unsigned char BmpImageId[2] = { 'B', 'M' };
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof())
{
return false;
}
bool matched = (memcmp(buf, BmpImageId, len) == 0);
if (!advance || !matched)
{
iIo.seek(-len, BasicIo::cur);
}
return matched;
}
} // namespace Exiv2

@ -0,0 +1,133 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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 bmpimage.hpp
@brief Windows Bitmap (BMP) image
@version $Rev$
@author Marco Piovanelli, Ovolabs (marco)
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
@date 05-Mar-2007, marco: created
*/
#ifndef BMPIMAGE_HPP_
#define BMPIMAGE_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "iptc.hpp"
#include "image.hpp"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add Windows Bitmap (BMP) to the supported image formats
namespace ImageType {
const int bmp = 14; //!< Windows bitmap (bmp) image type (see class BmpImage)
}
/*!
@brief Class to access Windows bitmaps. This is just a stub - we only
read width and height.
*/
class BmpImage : public Image {
//! @name NOT Implemented
//@{
//! Copy constructor
BmpImage(const BmpImage& rhs);
//! Assignment operator
BmpImage& operator=(const BmpImage& rhs);
//@}
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a Windows bitmap image. 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.
*/
BmpImage(BasicIo::AutoPtr io);
//@}
//! @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();
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setExifData(const ExifData& exifData);
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setIptcData(const IptcData& iptcData);
/*!
@brief Not supported. Calling this function will throw an instance
of Error(32).
*/
void setComment(const std::string& comment);
//@}
//! @name Accessors
//@{
std::string mimeType() const { return "image/x-ms-bmp"; }
//@}
}; // class BmpImage
// *****************************************************************************
// 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 BmpImage 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 newBmpInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Windows Bitmap image.
bool isBmpType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef BMPIMAGE_HPP_

@ -93,6 +93,18 @@ namespace Exiv2 {
{
} // Cr2Image::Cr2Image
int Cr2Image::pixelWidth() const
{
Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
return (widthIter == exifData_.end()) ? 0 : widthIter->toLong();
}
int Cr2Image::pixelHeight() const
{
Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
return (heightIter == exifData_.end()) ? 0 : heightIter->toLong();
}
void Cr2Image::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!

@ -106,6 +106,8 @@ namespace Exiv2 {
//! @name Accessors
//@{
std::string mimeType() const { return "image/x-canon-cr2"; }
int pixelWidth() const;
int pixelHeight() const;
//@}
private:

@ -170,6 +170,18 @@ namespace Exiv2 {
{
} // CrwImage::CrwImage
int CrwImage::pixelWidth() const
{
Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
return (widthIter == exifData_.end()) ? 0 : widthIter->toLong();
}
int CrwImage::pixelHeight() const
{
Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
return (heightIter == exifData_.end()) ? 0 : heightIter->toLong();
}
void CrwImage::setIptcData(const IptcData& /*iptcData*/)
{
// not supported

@ -121,6 +121,8 @@ namespace Exiv2 {
//! @name Accessors
//@{
std::string mimeType() const { return "image/x-canon-crw"; }
int pixelWidth() const;
int pixelHeight() const;
//@}
private:

@ -147,7 +147,7 @@ int main(int argc, char* const argv[])
for (Params::Files::const_iterator i = params.files_.begin();
i != params.files_.end(); ++i) {
if (params.verbose_) {
std::cout << _("File") << " " << std::setw(w) << n++ << "/" << s << ": "
std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << s << ": "
<< *i << std::endl;
}
int ret = task->run(*i);

@ -0,0 +1,141 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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: gifimage.cpp
Version: $Rev$
Author(s): Marco Piovanelli, Ovolabs (marco)
History: 26-Feb-2007, marco: created
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
//#define DEBUG 1
// *****************************************************************************
// included header files
#ifdef _MSC_VER
# include "exv_msvc.h"
#else
# include "exv_conf.h"
#endif
#include "gifimage.hpp"
#include "image.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
// + standard includes
#include <string>
#include <cstring>
#include <iostream>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
GifImage::GifImage(BasicIo::AutoPtr io)
: Image(ImageType::gif, mdNone, io)
{
} // GifImage::GifImage
void GifImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!
throw(Error(32, "Exif metadata", "GIF"));
}
void GifImage::setIptcData(const IptcData& /*iptcData*/)
{
// Todo: implement me!
throw(Error(32, "IPTC metadata", "GIF"));
}
void GifImage::setComment(const std::string& /*comment*/)
{
// not supported
throw(Error(32, "Image comment", "GIF"));
}
void GifImage::readMetadata()
{
#ifdef DEBUG
std::cerr << "Exiv2::GifImage::readMetadata: Reading GIF 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 (!isGifType(*io_, true))
{
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "GIF");
}
clearMetadata();
byte buf[4];
if (io_->read(buf, sizeof(buf)) == sizeof(buf))
{
pixelWidth_ = getShort(buf, littleEndian);
pixelHeight_ = getShort(buf + 2, littleEndian);
}
} // GifImage::readMetadata
void GifImage::writeMetadata()
{
// Todo: implement me!
throw(Error(31, "GIF"));
} // GifImage::writeMetadata
// *************************************************************************
// free functions
Image::AutoPtr newGifInstance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new GifImage(io));
if (!image->good())
{
image.reset();
}
return image;
}
bool isGifType(BasicIo& iIo, bool advance)
{
const int32_t len = 6;
const unsigned char Gif87aId[8] = { 'G', 'I', 'F', '8', '7', 'a' };
const unsigned char Gif89aId[8] = { 'G', 'I', 'F', '8', '9', 'a' };
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof())
{
return false;
}
bool matched = (memcmp(buf, Gif87aId, len) == 0)
|| (memcmp(buf, Gif89aId, len) == 0);
if (!advance || !matched)
{
iIo.seek(-len, BasicIo::cur);
}
return matched;
}
} // namespace Exiv2

@ -0,0 +1,134 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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 gifimage.hpp
@brief GIF image, implemented using the following references:
<a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF89 specification</a> by W3C<br>
@version $Rev$
@author Marco Piovanelli, Ovolabs (marco)
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
@date 26-Feb-2007, marco: created
*/
#ifndef GIFIMAGE_HPP_
#define GIFIMAGE_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "iptc.hpp"
#include "image.hpp"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add GIF to the supported image formats
namespace ImageType {
const int gif = 11; //!< GIF image type (see class GifImage)
}
/*!
@brief Class to access raw GIF images. Exif/IPTC metadata are supported
directly.
*/
class GifImage : public Image {
//! @name NOT Implemented
//@{
//! Copy constructor
GifImage(const GifImage& rhs);
//! Assignment operator
GifImage& operator=(const GifImage& rhs);
//@}
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a GIF image. 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.
*/
GifImage(BasicIo::AutoPtr io);
//@}
//! @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();
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setExifData(const ExifData& exifData);
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setIptcData(const IptcData& iptcData);
/*!
@brief Not supported. Calling this function will throw an instance
of Error(32).
*/
void setComment(const std::string& comment);
//@}
//! @name Accessors
//@{
std::string mimeType() const { return "image/gif"; }
//@}
}; // class GifImage
// *****************************************************************************
// 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 GifImage 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 newGifInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a GIF image.
bool isGifType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef GIFIMAGE_HPP_

@ -54,6 +54,11 @@ EXIV2_RCSID("@(#) $Id$")
#include "rafimage.hpp"
#include "tiffimage.hpp"
#include "orfimage.hpp"
#include "gifimage.hpp"
#include "psdimage.hpp"
#include "tgaimage.hpp"
#include "bmpimage.hpp"
#include "jp2image.hpp"
#include "xmpsidecar.hpp"
// + standard includes
@ -84,12 +89,17 @@ namespace Exiv2 {
{ ImageType::mrw, newMrwInstance, isMrwType, amRead, amRead, amRead, amNone },
{ ImageType::tiff, newTiffInstance, isTiffType, amRead, amRead, amRead, amNone },
{ ImageType::orf, newOrfInstance, isOrfType, amRead, amRead, amRead, amNone },
#ifdef EXV_HAVE_LIBZ
#ifdef EXV_HAVE_LIBZ
{ ImageType::png, newPngInstance, isPngType, amRead, amRead, amRead, amNone },
#endif // EXV_HAVE_LIBZ
#endif // EXV_HAVE_LIBZ
{ ImageType::raf, newRafInstance, isRafType, amRead, amRead, amRead, amNone },
{ ImageType::xmp, newXmpInstance, isXmpType, amNone, amNone, amReadWrite, amNone },
// End of list marker
{ ImageType::gif, newGifInstance, isGifType, amNone, amNone, amNone, amNone },
{ ImageType::psd, newPsdInstance, isPsdType, amRead, amRead, amRead, amNone },
{ ImageType::tga, newTgaInstance, isTgaType, amNone, amNone, amNone, amNone },
{ ImageType::bmp, newBmpInstance, isBmpType, amNone, amNone, amNone, amNone },
{ ImageType::jp2, newJp2Instance, isJp2Type, amRead, amRead, amRead, amNone },
// End of list marker
{ ImageType::none, 0, 0, amNone, amNone, amNone, amNone }
};
@ -102,6 +112,8 @@ namespace Exiv2 {
uint16_t supportedMetadata,
BasicIo::AutoPtr io)
: io_(io),
pixelWidth_(0),
pixelHeight_(0),
imageType_(imageType),
supportedMetadata_(supportedMetadata),
#ifdef EXV_HAVE_XMP_TOOLKIT
@ -214,6 +226,8 @@ namespace Exiv2 {
if (!r) throw Error(13, type);
AccessMode am = amNone;
switch (metadataId) {
case mdNone:
break;
case mdExif:
am = r->exifSupport_;
break;

@ -295,6 +295,14 @@ namespace Exiv2 {
specific MIME type may exist (e.g., "image/x-nikon-nef").
*/
virtual std::string mimeType() const =0;
/*!
@brief Return the pixel width of the image.
*/
virtual int pixelWidth() const { return pixelWidth_; }
/*!
@brief Return the pixel height of the image.
*/
virtual int pixelHeight() const { return pixelHeight_; }
/*!
@brief Returns an ExifData instance containing currently buffered
Exif data.
@ -378,6 +386,8 @@ namespace Exiv2 {
XmpData xmpData_; //!< XMP data container
std::string comment_; //!< User comment
std::string xmpPacket_; //!< XMP packet
int pixelWidth_; //!< image pixel width
int pixelHeight_; //!< image pixel height
private:
//! @name NOT implemented

@ -0,0 +1,266 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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: jp2image.cpp
Version: $Rev$
Author(s): Marco Piovanelli, Ovolabs (marco)
History: 12-Mar-2007, marco: created
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
//#define DEBUG 1
// *****************************************************************************
// included header files
#ifdef _MSC_VER
# include "exv_msvc.h"
#else
# include "exv_conf.h"
#endif
#include "jp2image.hpp"
#include "image.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
// + standard includes
#include <string>
#include <cstring>
#include <iostream>
// JPEG-2000 box types
const uint32_t kJp2BoxTypeJp2Header = 0x6a703268; // 'jp2h'
const uint32_t kJp2BoxTypeImageHeader = 0x69686472; // 'ihdr'
const uint32_t kJp2BoxTypeUuid = 0x75756964; // 'uuid'
// JPEG-2000 UUIDs for embedded metadata
//
// See http://www.jpeg.org/public/wg1n2600.doc for information about embedding IPTC-NAA data in JPEG-2000 files
// See http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf for information about embedding XMP data in JPEG-2000 files
const char* const kJp2UuidExif = "JpgTiffExif->JP2";
const char* const kJp2UuidIptc = "\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38";
const char* const kJp2UuidXmp = "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac";
//! @cond IGNORE
struct Jp2BoxHeader {
uint32_t boxLength;
uint32_t boxType;
};
struct Jp2ImageHeaderBox {
uint32_t imageHeight;
uint32_t imageWidth;
uint16_t componentCount;
uint8_t bitsPerComponent;
uint8_t compressionType;
uint8_t colorspaceIsUnknown;
uint8_t intellectualPropertyFlag;
uint16_t compressionTypeProfile;
};
struct Jp2UuidBox {
uint8_t uuid[16];
};
//! @endcond
// *****************************************************************************
// class member definitions
namespace Exiv2 {
Jp2Image::Jp2Image(BasicIo::AutoPtr io)
: Image(ImageType::jp2, mdExif | mdIptc | mdXmp, io)
{
} // Jp2Image::Jp2Image
void Jp2Image::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!
throw(Error(32, "Exif metadata", "JP2"));
}
void Jp2Image::setIptcData(const IptcData& /*iptcData*/)
{
// Todo: implement me!
throw(Error(32, "IPTC metadata", "JP2"));
}
void Jp2Image::setComment(const std::string& /*comment*/)
{
// Todo: implement me!
throw(Error(32, "Image comment", "JP2"));
}
void Jp2Image::readMetadata()
{
#ifdef DEBUG
std::cerr << "Exiv2::Jp2Image::readMetadata: Reading JPEG-2000 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 (!isJp2Type(*io_, true))
{
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "JPEG-2000");
}
Jp2BoxHeader box = {0,0};
Jp2BoxHeader subBox = {0,0};
Jp2ImageHeaderBox ihdr = {0,0,0,0,0,0,0,0};
Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
long curOffset = io_->tell();
while (io_->read((byte*)&box, sizeof(box)) == sizeof(box))
{
box.boxLength = getLong((byte*)&box.boxLength, bigEndian);
box.boxType = getLong((byte*)&box.boxType, bigEndian);
if (box.boxLength == 0)
{
break;
}
switch(box.boxType)
{
case kJp2BoxTypeJp2Header:
{
if (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox))
{
subBox.boxLength = getLong((byte*)&subBox.boxLength, bigEndian);
subBox.boxType = getLong((byte*)&subBox.boxType, bigEndian);
if((subBox.boxType == kJp2BoxTypeImageHeader) && (io_->read((byte*)&ihdr, sizeof(ihdr)) == sizeof(ihdr)))
{
ihdr.imageHeight = getLong((byte*)&ihdr.imageHeight, bigEndian);
ihdr.imageWidth = getLong((byte*)&ihdr.imageWidth, bigEndian);
ihdr.componentCount = getShort((byte*)&ihdr.componentCount, bigEndian);
ihdr.compressionTypeProfile = getShort((byte*)&ihdr.compressionTypeProfile, bigEndian);
pixelWidth_ = ihdr.imageWidth;
pixelHeight_ = ihdr.imageHeight;
}
}
break;
}
case kJp2BoxTypeUuid:
{
if (io_->read((byte*)&uuid, sizeof(uuid)) == sizeof(uuid))
{
if(memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid)) == 0)
{
// we've hit an embedded Exif block
DataBuf rawExif(box.boxLength - (sizeof(box) + sizeof(uuid)));
io_->read(rawExif.pData_, rawExif.size_);
if (io_->error() || io_->eof()) throw Error(14);
if (exifData_.load(rawExif.pData_, rawExif.size_)) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to decode Exif metadata.\n";
#endif
exifData_.clear();
}
}
else if(memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid)) == 0)
{
// we've hit an embedded IPTC block
DataBuf rawIPTC(box.boxLength - (sizeof(box) + sizeof(uuid)));
io_->read(rawIPTC.pData_, rawIPTC.size_);
if (io_->error() || io_->eof()) throw Error(14);
if (iptcData_.load(rawIPTC.pData_, rawIPTC.size_)) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to decode IPTC metadata.\n";
#endif
iptcData_.clear();
}
}
else if(memcmp(uuid.uuid, kJp2UuidXmp, sizeof(uuid)) == 0)
{
// we've hit an embedded XMP block
DataBuf xmpPacket(box.boxLength - (sizeof(box) + sizeof(uuid)));
io_->read(xmpPacket.pData_, xmpPacket.size_);
if (io_->error() || io_->eof()) throw Error(14);
xmpPacket_.assign(reinterpret_cast<char *>(xmpPacket.pData_), xmpPacket.size_);
if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to decode XMP metadata.\n";
#endif
}
}
}
break;
}
default:
{
break;
}
}
curOffset += box.boxLength;
if(io_->seek(curOffset, BasicIo::beg) != 0)
{
break; // Todo: should throw an error here
}
}
} // Jp2Image::readMetadata
void Jp2Image::writeMetadata()
{
// Todo: implement me!
throw(Error(31, "JP2"));
} // Jp2Image::writeMetadata
// *************************************************************************
// free functions
Image::AutoPtr newJp2Instance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new Jp2Image(io));
if (!image->good())
{
image.reset();
}
return image;
}
bool isJp2Type(BasicIo& iIo, bool advance)
{
// see section B.1.1 (JPEG 2000 Signature box) of JPEG-2000 specification
const int32_t len = 12;
const unsigned char Jp2Header[len] = { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a };
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof())
{
return false;
}
bool matched = (memcmp(buf, Jp2Header, len) == 0);
if (!advance || !matched)
{
iIo.seek(-len, BasicIo::cur);
}
return matched;
}
} // namespace Exiv2

@ -0,0 +1,133 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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 jp2image.hpp
@brief JPEG-2000 image, implemented using the following references:
<a href="http://jpeg.org/public/fcd15444-6.pdf">ISO/IEC JTC 1/SC 29/WG1 N2401: JPEG 2000 Part 6 FCD 15444-6</a><br>
@version $Rev$
@author Marco Piovanelli, Ovolabs (marco)
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
@date 12-Mar-2007, marco: created
*/
#ifndef JP2IMAGE_HPP_
#define JP2IMAGE_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "iptc.hpp"
#include "image.hpp"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add JPEG-2000 to the supported image formats
namespace ImageType {
const int jp2 = 15; //!< JPEG-2000 image type
}
/*!
@brief Class to access JPEG-2000 images.
*/
class Jp2Image : public Image {
//! @name NOT Implemented
//@{
//! Copy constructor
Jp2Image(const Jp2Image& rhs);
//! Assignment operator
Jp2Image& operator=(const Jp2Image& rhs);
//@}
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a JPEG-2000 image. 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.
*/
Jp2Image(BasicIo::AutoPtr io);
//@}
//! @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();
/*!
@brief Todo: Not supported yet. Calling this function will throw
an instance of Error(32).
*/
void setExifData(const ExifData& exifData);
/*!
@brief Todo: Not supported yet. Calling this function will throw
an instance of Error(32).
*/
void setIptcData(const IptcData& iptcData);
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setComment(const std::string& comment);
//@}
//! @name Accessors
//@{
std::string mimeType() const { return "image/jp2"; }
//@}
}; // class Jp2Image
// *****************************************************************************
// 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 Jp2Image 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 newJp2Instance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a JPEG-2000 image.
bool isJp2Type(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef JP2IMAGE_HPP_

@ -57,6 +57,28 @@ namespace Exiv2 {
const byte JpegBase::app1_ = 0xe1;
const byte JpegBase::app13_ = 0xed;
const byte JpegBase::com_ = 0xfe;
// Start of Frame markers, nondifferential Huffman-coding frames
const byte JpegBase::sof0_ = 0xc0; // start of frame 0, baseline DCT
const byte JpegBase::sof1_ = 0xc1; // start of frame 1, extended sequential DCT, Huffman coding
const byte JpegBase::sof2_ = 0xc2; // start of frame 2, progressive DCT, Huffman coding
const byte JpegBase::sof3_ = 0xc3; // start of frame 3, lossless sequential, Huffman coding
// Start of Frame markers, differential Huffman-coding frames
const byte JpegBase::sof5_ = 0xc5; // start of frame 5, differential sequential DCT, Huffman coding
const byte JpegBase::sof6_ = 0xc6; // start of frame 6, differential progressive DCT, Huffman coding
const byte JpegBase::sof7_ = 0xc7; // start of frame 7, differential lossless, Huffman coding
// Start of Frame markers, nondifferential arithmetic-coding frames
const byte JpegBase::sof9_ = 0xc9; // start of frame 9, extended sequential DCT, arithmetic coding
const byte JpegBase::sof10_ = 0xca; // start of frame 10, progressive DCT, arithmetic coding
const byte JpegBase::sof11_ = 0xcb; // start of frame 11, lossless sequential, arithmetic coding
// Start of Frame markers, differential arithmetic-coding frames
const byte JpegBase::sof13_ = 0xcd; // start of frame 13, differential sequential DCT, arithmetic coding
const byte JpegBase::sof14_ = 0xce; // start of frame 14, progressive DCT, arithmetic coding
const byte JpegBase::sof15_ = 0xcf; // start of frame 15, differential lossless, arithmetic coding
const char JpegBase::exifId_[] = "Exif\0\0";
const char JpegBase::jfifId_[] = "JFIF\0";
const char JpegBase::xmpId_[] = "http://ns.adobe.com/xap/1.0/\0";
@ -255,7 +277,7 @@ namespace Exiv2 {
throw Error(15);
}
clearMetadata();
int search = 4;
int search = 5;
const long bufMinSize = 36;
long bufRead = 0;
DataBuf buf(bufMinSize);
@ -377,6 +399,18 @@ namespace Exiv2 {
}
--search;
}
else if ( pixelHeight_ == 0
&& ( marker == sof0_ || marker == sof1_ || marker == sof2_
|| marker == sof3_ || marker == sof5_ || marker == sof6_
|| marker == sof7_ || marker == sof9_ || marker == sof10_
|| marker == sof11_ || marker == sof13_ || marker == sof14_
|| marker == sof15_)) {
// we hit a SOFn (start-of-frame) marker
if (size < 8) throw Error(15);
pixelHeight_ = getUShort(buf.pData_ + 3, bigEndian);
pixelWidth_ = getUShort(buf.pData_ + 5, bigEndian);
if (pixelHeight_ != 0) --search;
}
else {
if (size < 2) {
rc = 4;

@ -189,6 +189,19 @@ namespace Exiv2 {
static const byte app1_; //!< JPEG APP1 marker
static const byte app13_; //!< JPEG APP13 marker
static const byte com_; //!< JPEG Comment marker
static const byte sof0_; //!< JPEG Start-Of-Frame marker
static const byte sof1_; //!< JPEG Start-Of-Frame marker
static const byte sof2_; //!< JPEG Start-Of-Frame marker
static const byte sof3_; //!< JPEG Start-Of-Frame marker
static const byte sof5_; //!< JPEG Start-Of-Frame marker
static const byte sof6_; //!< JPEG Start-Of-Frame marker
static const byte sof7_; //!< JPEG Start-Of-Frame marker
static const byte sof9_; //!< JPEG Start-Of-Frame marker
static const byte sof10_; //!< JPEG Start-Of-Frame marker
static const byte sof11_; //!< JPEG Start-Of-Frame marker
static const byte sof13_; //!< JPEG Start-Of-Frame marker
static const byte sof14_; //!< JPEG Start-Of-Frame marker
static const byte sof15_; //!< JPEG Start-Of-Frame marker
static const char exifId_[]; //!< Exif identifier
static const char jfifId_[]; //!< JFIF identifier
static const char xmpId_[]; //!< XMP packet identifier
@ -268,6 +281,7 @@ namespace Exiv2 {
//@{
std::string mimeType() const { return "image/jpeg"; }
//@}
protected:
//! @name Accessors
//@{
@ -326,6 +340,7 @@ namespace Exiv2 {
//@{
std::string mimeType() const { return "image/x-exv"; }
//@}
protected:
//! @name Accessors
//@{

@ -59,6 +59,26 @@ namespace Exiv2 {
{
} // MrwImage::MrwImage
int MrwImage::pixelWidth() const
{
ExifData::const_iterator imageWidth;
if ((imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth"))) != exifData_.end())
{
return imageWidth->toLong();
}
return 0;
}
int MrwImage::pixelHeight() const
{
ExifData::const_iterator imageHeight;
if ((imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageLength"))) != exifData_.end())
{
return imageHeight->toLong();
}
return 0;
}
void MrwImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!

@ -104,6 +104,8 @@ namespace Exiv2 {
//! @name Accessors
//@{
std::string mimeType() const { return "image/x-minolta-mrw"; }
int pixelWidth() const;
int pixelHeight() const;
//@}
private:

@ -59,6 +59,26 @@ namespace Exiv2 {
{
} // OrfImage::OrfImage
int OrfImage::pixelWidth() const
{
ExifData::const_iterator imageWidth;
if ((imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth"))) != exifData_.end())
{
return imageWidth->toLong();
}
return 0;
}
int OrfImage::pixelHeight() const
{
ExifData::const_iterator imageHeight;
if ((imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageLength"))) != exifData_.end())
{
return imageHeight->toLong();
}
return 0;
}
void OrfImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!

@ -104,6 +104,8 @@ namespace Exiv2 {
//! @name Accessors
//@{
std::string mimeType() const { return "image/x-olympus-orf"; }
int pixelWidth() const;
int pixelHeight() const;
//@}
private:

@ -81,15 +81,27 @@ namespace {
// class member definitions
namespace Exiv2 {
void PngChunk::decode(Image* pImage,
const byte* pData,
long size)
void PngChunk::decode(Image* pImage,
const byte* pData,
long size,
int* outWidth,
int* outHeight)
{
assert(pImage != 0);
assert(pData != 0);
assert(outWidth != 0);
assert(outHeight != 0);
// look for a tEXt chunk
long index = 8;
// extract width and height from IHDR chunk, which *must* be the first chunk in the PNG file
if (strncmp((const char *)PNG_CHUNK_TYPE(pData, index), "IHDR", 4) == 0)
{
*outWidth = getLong((const byte*)&PNG_CHUNK_DATA(pData, index, 0), bigEndian);
*outHeight = getLong((const byte*)&PNG_CHUNK_DATA(pData, index, 4), bigEndian);
}
// look for a tEXt chunk
index += chunkLength(pData, index) + PNG_CHUNK_HEADER_SIZE;
while(index < size-PNG_CHUNK_HEADER_SIZE)

@ -69,10 +69,14 @@ namespace Exiv2 {
@param pData Pointer to the data buffer. Must point to PNG chunk data;
no checks are performed.
@param size Length of the data buffer.
@param outWidth Integer pointer to be set to the width of the image.
@param outHeight Integer pointer to be set to the height of the image.
*/
static void decode(Image* pImage,
const byte* pData,
long size);
long size,
int* outWidth,
int* outHeight);
private:
//! @name Accessors

@ -99,7 +99,7 @@ namespace Exiv2 {
throw Error(3, "PNG");
}
clearMetadata();
PngChunk::decode(this, io_->mmap(), io_->size());
PngChunk::decode(this, io_->mmap(), io_->size(), &pixelWidth_, &pixelHeight_);
/*
Todo:

@ -0,0 +1,339 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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: psdimage.cpp
Version: $Rev$
Author(s): Marco Piovanelli, Ovolabs (marco)
History: 05-Mar-2007, marco: created
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
//#define DEBUG 1
// *****************************************************************************
// included header files
#ifdef _MSC_VER
# include "exv_msvc.h"
#else
# include "exv_conf.h"
#endif
#include "psdimage.hpp"
#include "image.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
// + standard includes
#include <string>
#include <cstring>
#include <iostream>
// Todo: Consolidate with existing code in struct Photoshop (jpgimage.hpp):
// Extend this helper to a proper class with all required functionality,
// then move it here or into a separate file?
const uint32_t kPhotoshopResourceType = 0x3842494d; // '8BIM'
//! @cond IGNORE
struct PhotoshopResourceBlock {
uint32_t resourceType; // always kPhotoshopResourceType
uint16_t resourceId;
unsigned char resourceName[2]; // Pascal string (length byte + characters), padded to an even size -- this assumes the empty string
uint32_t resourceDataSize;
};
//! @endcond
// Photoshop resource IDs (Cf. <http://search.cpan.org/~bettelli/Image-MetaData-JPEG-0.15/lib/Image/MetaData/JPEG/TagLists.pod>)
enum {
kPhotoshopResourceID_Photoshop2Info = 0x03e8, // [obsolete -- Photoshop 2.0 only] General information -- contains five 2-byte values: number of channels, rows, columns, depth and mode
kPhotoshopResourceID_MacintoshClassicPrintInfo = 0x03e9, // [optional] Macintosh classic print record (120 bytes)
kPhotoshopResourceID_MacintoshCarbonPrintInfo = 0x03ea, // [optional] Macintosh carbon print info (variable-length XML format)
kPhotoshopResourceID_Photoshop2ColorTable = 0x03eb, // [obsolete -- Photoshop 2.0 only] Indexed color table
kPhotoshopResourceID_ResolutionInfo = 0x03ed, // PhotoshopResolutionInfo structure (see below)
kPhotoshopResourceID_AlphaChannelsNames = 0x03ee, // as a series of Pstrings
kPhotoshopResourceID_DisplayInfo = 0x03ef, // see appendix A in Photoshop SDK
kPhotoshopResourceID_PStringCaption = 0x03f0, // [optional] the caption, as a Pstring
kPhotoshopResourceID_BorderInformation = 0x03f1, // border width and units
kPhotoshopResourceID_BackgroundColor = 0x03f2, // see additional Adobe information
kPhotoshopResourceID_PrintFlags = 0x03f3, // labels, crop marks, colour bars, ecc...
kPhotoshopResourceID_BWHalftoningInfo = 0x03f4, // Gray-scale and multich. half-toning info
kPhotoshopResourceID_ColorHalftoningInfo = 0x03f5, // Colour half-toning information
kPhotoshopResourceID_DuotoneHalftoningInfo = 0x03f6, // Duo-tone half-toning information
kPhotoshopResourceID_BWTransferFunc = 0x03f7, // Gray-scale and multich. transfer function
kPhotoshopResourceID_ColorTransferFuncs = 0x03f8, // Colour transfer function
kPhotoshopResourceID_DuotoneTransferFuncs = 0x03f9, // Duo-tone transfer function
kPhotoshopResourceID_DuotoneImageInfo = 0x03fa, // Duo-tone image information
kPhotoshopResourceID_EffectiveBW = 0x03fb, // two bytes for the effective black and white values
kPhotoshopResourceID_ObsoletePhotoshopTag1 = 0x03fc, // [obsolete]
kPhotoshopResourceID_EPSOptions = 0x03fd, // Encapsulated Postscript options
kPhotoshopResourceID_QuickMaskInfo = 0x03fe, // Quick Mask information. 2 bytes containing Quick Mask channel ID, 1 byte boolean indicating whether the mask was initially empty.
kPhotoshopResourceID_ObsoletePhotoshopTag2 = 0x03ff, // [obsolete]
kPhotoshopResourceID_LayerStateInfo = 0x0400, // index of target layer (0 means bottom)
kPhotoshopResourceID_WorkingPathInfo = 0x0401, // should not be saved to the file
kPhotoshopResourceID_LayersGroupInfo = 0x0402, // for grouping layers together
kPhotoshopResourceID_ObsoletePhotoshopTag3 = 0x0403, // [obsolete] ??
kPhotoshopResourceID_IPTC_NAA = 0x0404, // IPTC/NAA data
kPhotoshopResourceID_RawImageMode = 0x0405, // image mode for raw format files
kPhotoshopResourceID_JPEGQuality = 0x0406, // [private]
kPhotoshopResourceID_GridGuidesInfo = 0x0408, // see additional Adobe information
kPhotoshopResourceID_ThumbnailResource = 0x0409, // see additional Adobe information
kPhotoshopResourceID_CopyrightFlag = 0x040a, // true if image is copyrighted
kPhotoshopResourceID_URL = 0x040b, // text string with a resource locator
kPhotoshopResourceID_ThumbnailResource2 = 0x040c, // see additional Adobe information
kPhotoshopResourceID_GlobalAngle = 0x040d, // global lighting angle for effects layer
kPhotoshopResourceID_ColorSamplersResource = 0x040e, // see additional Adobe information
kPhotoshopResourceID_ICCProfile = 0x040f, // see notes from Internat. Color Consortium
kPhotoshopResourceID_Watermark = 0x0410, // one byte
kPhotoshopResourceID_ICCUntagged = 0x0411, // 1 means intentionally untagged
kPhotoshopResourceID_EffectsVisible = 0x0412, // 1 byte to show/hide all effects layers
kPhotoshopResourceID_SpotHalftone = 0x0413, // version, length and data
kPhotoshopResourceID_IDsBaseValue = 0x0414, // base value for new layers ID's
kPhotoshopResourceID_UnicodeAlphaNames = 0x0415, // length plus Unicode string
kPhotoshopResourceID_IndexedColourTableCount = 0x0416, // [Photoshop 6.0 and later] 2 bytes
kPhotoshopResourceID_TransparentIndex = 0x0417, // [Photoshop 6.0 and later] 2 bytes
kPhotoshopResourceID_GlobalAltitude = 0x0419, // [Photoshop 6.0 and later] 4 bytes
kPhotoshopResourceID_Slices = 0x041a, // [Photoshop 6.0 and later] see additional Adobe info
kPhotoshopResourceID_WorkflowURL = 0x041b, // [Photoshop 6.0 and later] 4 bytes length + Unicode string
kPhotoshopResourceID_JumpToXPEP = 0x041c, // [Photoshop 6.0 and later] see additional Adobe info
kPhotoshopResourceID_AlphaIdentifiers = 0x041d, // [Photoshop 6.0 and later] 4*(n+1) bytes
kPhotoshopResourceID_URLList = 0x041e, // [Photoshop 6.0 and later] structured Unicode URL's
kPhotoshopResourceID_VersionInfo = 0x0421, // [Photoshop 6.0 and later] see additional Adobe info
kPhotoshopResourceID_ExifInfo = 0x0422, // [Photoshop 7.0?] Exif metadata
kPhotoshopResourceID_XMPPacket = 0x0424, // [Photoshop 7.0?] XMP packet -- see http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf
kPhotoshopResourceID_ClippingPathName = 0x0bb7, // [Photoshop 6.0 and later] name of clipping path
kPhotoshopResourceID_MorePrintFlags = 0x2710 // [Photoshop 6.0 and later] Print flags information. 2 bytes version (=1), 1 byte center crop marks, 1 byte (=0), 4 bytes bleed width value, 2 bytes bleed width scale.
};
// *****************************************************************************
// class member definitions
namespace Exiv2 {
PsdImage::PsdImage(BasicIo::AutoPtr io)
: Image(ImageType::psd, mdExif | mdIptc | mdXmp, io)
{
} // PsdImage::PsdImage
void PsdImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!
throw(Error(32, "Exif metadata", "Photoshop"));
}
void PsdImage::setIptcData(const IptcData& /*iptcData*/)
{
// Todo: implement me!
throw(Error(32, "IPTC metadata", "Photoshop"));
}
void PsdImage::setComment(const std::string& /*comment*/)
{
// Todo: implement me!
throw(Error(32, "Image comment", "Photoshop"));
}
void PsdImage::readMetadata()
{
#ifdef DEBUG
std::cerr << "Exiv2::PsdImage::readMetadata: Reading Photoshop 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 (!isPsdType(*io_, false))
{
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "Photoshop");
}
clearMetadata();
/*
The Photoshop header goes as follows -- all numbers are in big-endian byte order:
offset length name description
====== ======= ========= =========
0 4 bytes signature always '8BPS'
4 2 bytes version always equal to 1
6 6 bytes reserved must be zero
12 2 bytes channels number of channels in the image, including alpha channels (1 to 24)
14 4 bytes rows the height of the image in pixels
18 4 bytes columns the width of the image in pixels
22 2 bytes depth the number of bits per channel
24 2 bytes mode the color mode of the file; Supported values are: Bitmap=0; Grayscale=1; Indexed=2; RGB=3; CMYK=4; Multichannel=7; Duotone=8; Lab=9
*/
byte buf[26];
if (io_->read(buf, 26) != 26)
{
throw Error(3, "Photoshop");
}
pixelWidth_ = getLong(buf + 18, bigEndian);
pixelHeight_ = getLong(buf + 14, bigEndian);
// immediately following the image header is the color mode data section,
// the first four bytes of which specify the byte size of the whole section
if (io_->read(buf, 4) != 4)
{
throw Error(3, "Photoshop");
}
// skip it
uint32_t colorDataLength = getLong(buf, bigEndian);
if (io_->seek(colorDataLength, BasicIo::cur))
{
throw Error(3, "Photoshop");
}
// after the color data section, comes a list of resource blocks, preceeded by the total byte size
if (io_->read(buf, 4) != 4)
{
throw Error(3, "Photoshop");
}
uint32_t resourcesLength = getLong(buf, bigEndian);
while (resourcesLength > 0)
{
if (io_->read(buf, 8) != 8)
{
throw Error(3, "Photoshop");
}
// read resource type and ID
uint32_t resourceType = getLong(buf, bigEndian);
uint16_t resourceId = getShort(buf + 4, bigEndian);
if (resourceType != kPhotoshopResourceType)
{
break; // bad resource type
}
uint32_t resourceNameLength = buf[6] & ~1;
// skip the resource name, plus any padding
io_->seek(resourceNameLength, BasicIo::cur);
// read resource size
if (io_->read(buf, 4) != 4)
{
throw Error(3, "Photoshop");
}
uint32_t resourceSize = getLong(buf, bigEndian);
uint32_t curOffset = io_->tell();
processResourceBlock(resourceId, resourceSize);
resourceSize = (resourceSize + 1) & ~1; // pad to even
io_->seek(curOffset + resourceSize, BasicIo::beg);
resourcesLength -= (12 + resourceNameLength + resourceSize);
}
} // PsdImage::readMetadata
void PsdImage::processResourceBlock(uint16_t resourceId, uint32_t resourceSize)
{
switch(resourceId)
{
case kPhotoshopResourceID_IPTC_NAA:
{
DataBuf rawIPTC(resourceSize);
io_->read(rawIPTC.pData_, rawIPTC.size_);
if (io_->error() || io_->eof()) throw Error(14);
if (iptcData_.load(rawIPTC.pData_, rawIPTC.size_)) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to decode IPTC metadata.\n";
#endif
iptcData_.clear();
}
break;
}
case kPhotoshopResourceID_ExifInfo:
{
DataBuf rawExif(resourceSize);
io_->read(rawExif.pData_, rawExif.size_);
if (io_->error() || io_->eof()) throw Error(14);
if (exifData_.load(rawExif.pData_, rawExif.size_)) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to decode Exif metadata.\n";
#endif
exifData_.clear();
}
break;
}
case kPhotoshopResourceID_XMPPacket:
{
DataBuf xmpPacket(resourceSize);
io_->read(xmpPacket.pData_, xmpPacket.size_);
if (io_->error() || io_->eof()) throw Error(14);
xmpPacket_.assign(reinterpret_cast<char *>(xmpPacket.pData_), xmpPacket.size_);
if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) {
#ifndef SUPPRESS_WARNINGS
std::cerr << "Warning: Failed to decode XMP metadata.\n";
#endif
}
break;
}
default:
{
break;
}
}
}
void PsdImage::writeMetadata()
{
// Todo: implement me!
throw(Error(31, "Photoshop"));
} // PsdImage::writeMetadata
// *************************************************************************
// free functions
Image::AutoPtr newPsdInstance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new PsdImage(io));
if (!image->good())
{
image.reset();
}
return image;
}
bool isPsdType(BasicIo& iIo, bool advance)
{
const int32_t len = 6;
const unsigned char PsdHeader[6] = { '8', 'B', 'P', 'S', 0, 1 };
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof())
{
return false;
}
bool matched = (memcmp(buf, PsdHeader, len) == 0);
if (!advance || !matched)
{
iIo.seek(-len, BasicIo::cur);
}
return matched;
}
} // namespace Exiv2

@ -0,0 +1,150 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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 psdimage.hpp
@brief Photoshop image, implemented using the following references:
<a href="http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf">Adobe Photoshop 6.0 File Format Specification</a> by Adobe<br>
@version $Rev$
@author Marco Piovanelli, Ovolabs (marco)
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
@date 05-Mar-2007, marco: created
*/
#ifndef PSDIMAGE_HPP_
#define PSDIMAGE_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "iptc.hpp"
#include "image.hpp"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add PSD to the supported image formats
namespace ImageType {
const int psd = 12; //!< Photoshop (PSD) image type (see class PsdImage)
}
/*!
@brief Class to access raw Photoshop images.
*/
class PsdImage : public Image {
//! @name NOT Implemented
//@{
//! Copy constructor
PsdImage(const PsdImage& rhs);
//! Assignment operator
PsdImage& operator=(const PsdImage& rhs);
//@}
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a Photoshop image. 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.
*/
PsdImage(BasicIo::AutoPtr io);
//@}
//! @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();
/*!
@brief Todo: Not supported yet. Calling this function will throw
an instance of Error(32).
*/
void setExifData(const ExifData& exifData);
/*!
@brief Todo: Not supported yet. Calling this function will throw
an instance of Error(32).
*/
void setIptcData(const IptcData& iptcData);
/*!
@brief Todo: Not supported yet. Calling this function will throw
an instance of Error(32).
*/
void setComment(const std::string& comment);
//@}
//! @name Accessors
//@{
/*!
@brief Return the MIME type of the image.
The MIME type returned for Photoshop images is "image/x-photoshop".
@note This should really be "image/vnd.adobe.photoshop"
(officially registered with IANA in December 2005 -- see
http://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop)
but Apple, as of Tiger (10.4.8), maps this official MIME type to a
dynamic UTI, rather than "com.adobe.photoshop-image" as it should.
*/
std::string mimeType() const { return "image/x-photoshop"; }
//@}
private:
//! @name Manipulators
//@{
void processResourceBlock(uint16_t resourceId, uint32_t resourceSize);
//@}
}; // class PsdImage
// *****************************************************************************
// 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 PsdImage 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 newPsdInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Photoshop image.
bool isPsdType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef PSDIMAGE_HPP_

@ -59,6 +59,18 @@ namespace Exiv2 {
{
} // RafImage::RafImage
int RafImage::pixelWidth() const
{
Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
return (widthIter == exifData_.end()) ? 0 : widthIter->toLong();
}
int RafImage::pixelHeight() const
{
Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
return (heightIter == exifData_.end()) ? 0 : heightIter->toLong();
}
void RafImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!

@ -103,6 +103,8 @@ namespace Exiv2 {
//! @name Accessors
//@{
std::string mimeType() const { return "image/x-fuji-raf"; }
int pixelWidth() const;
int pixelHeight() const;
//@}
private:

@ -0,0 +1,170 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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: tgaimage.cpp
Version: $Rev$
Author(s): Marco Piovanelli, Ovolabs (marco)
History: 05-Mar-2007, marco: created
*/
// *****************************************************************************
#include "rcsid.hpp"
EXIV2_RCSID("@(#) $Id$")
//#define DEBUG 1
// *****************************************************************************
// included header files
#ifdef _MSC_VER
# include "exv_msvc.h"
#else
# include "exv_conf.h"
#endif
#include "tgaimage.hpp"
#include "image.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
// + standard includes
#include <string>
#include <cstring>
#include <iostream>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
TgaImage::TgaImage(BasicIo::AutoPtr io)
: Image(ImageType::tga, mdNone, io)
{
} // TgaImage::TgaImage
void TgaImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!
throw(Error(32, "Exif metadata", "TGA"));
}
void TgaImage::setIptcData(const IptcData& /*iptcData*/)
{
// Todo: implement me!
throw(Error(32, "IPTC metadata", "TGA"));
}
void TgaImage::setComment(const std::string& /*comment*/)
{
// not supported
throw(Error(32, "Image comment", "TGA"));
}
void TgaImage::readMetadata()
{
#ifdef DEBUG
std::cerr << "Exiv2::TgaImage::readMetadata: Reading TARGA 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 (!isTgaType(*io_, false))
{
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "TGA");
}
clearMetadata();
/*
The TARGA header goes as follows -- all numbers are in little-endian byte order:
offset length name description
====== ======= ======================= ===========
0 1 byte ID length length of image ID (0 to 255)
1 1 byte color map type 0 = no color map; 1 = color map included
2 1 byte image type 0 = no image;
1 = uncompressed color-mapped;
2 = uncompressed true-color;
3 = uncompressed black-and-white;
9 = RLE-encoded color mapped;
10 = RLE-encoded true-color;
11 = RLE-encoded black-and-white
3 5 bytes color map specification
8 2 bytes x-origin of image
10 2 bytes y-origin of image
12 2 bytes image width
14 2 bytes image height
16 1 byte pixel depth
17 1 byte image descriptor
*/
byte buf[18];
if (io_->read(buf, sizeof(buf)) == sizeof(buf))
{
pixelWidth_ = getShort(buf + 12, littleEndian);
pixelHeight_ = getShort(buf + 14, littleEndian);
}
} // TgaImage::readMetadata
void TgaImage::writeMetadata()
{
// Todo: implement me!
throw(Error(31, "TGA"));
} // TgaImage::writeMetadata
// *************************************************************************
// free functions
Image::AutoPtr newTgaInstance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new TgaImage(io));
if (!image->good())
{
image.reset();
}
return image;
}
bool isTgaType(BasicIo& iIo, bool /*advance*/)
{
// not all TARGA files have a signature string, so first just try to match the file name extension
std::string path = iIo.path();
if(path.rfind(".tga") != std::string::npos || path.rfind(".TGA") != std::string::npos)
{
return true;
}
byte buf[26];
long curPos = iIo.tell();
iIo.seek(-26, BasicIo::end);
if (iIo.error() || iIo.eof())
{
return false;
}
iIo.read(buf, sizeof(buf));
if (iIo.error())
{
return false;
}
// some TARGA files, but not all, have a signature string at the end
bool matched = (memcmp(buf + 8, "TRUEVISION-XFILE", 16) == 0);
iIo.seek(curPos, BasicIo::beg);
return matched;
}
} // namespace Exiv2

@ -0,0 +1,135 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2008 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 tgaimage.hpp
@brief Truevision TARGA v2 image, implemented using the following references:
<a href="http://en.wikipedia.org/wiki/Truevision_TGA">Truevision TGA page on Wikipedia</a><br>
<a href="http://www.gamers.org/dEngine/quake3/TGA.ps.gz">TGA(tm) File Format Specification</a>
@version $Rev$
@author Marco Piovanelli, Ovolabs (marco)
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
@date 05-Mar-2007, marco: created
*/
#ifndef TGAIMAGE_HPP_
#define TGAIMAGE_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "iptc.hpp"
#include "image.hpp"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add TARGA to the supported image formats
namespace ImageType {
const int tga = 13; //!< Truevision TARGA (tga) image type (see class TgaImage)
}
/*!
@brief Class to access raw TARGA images. This is just a stub - we only
read width and height.
*/
class TgaImage : public Image {
//! @name NOT Implemented
//@{
//! Copy constructor
TgaImage(const TgaImage& rhs);
//! Assignment operator
TgaImage& operator=(const TgaImage& rhs);
//@}
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a Targa image. 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.
*/
TgaImage(BasicIo::AutoPtr io);
//@}
//! @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();
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setExifData(const ExifData& exifData);
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(32).
*/
void setIptcData(const IptcData& iptcData);
/*!
@brief Not supported. Calling this function will throw an instance
of Error(32).
*/
void setComment(const std::string& comment);
//@}
//! @name Accessors
//@{
std::string mimeType() const { return "image/targa"; }
//@}
}; // class TgaImage
// *****************************************************************************
// 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 TgaImage 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 newTgaInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Targa v2 image.
bool isTgaType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef TGAIMAGE_HPP_

@ -59,6 +59,26 @@ namespace Exiv2 {
{
} // TiffImage::TiffImage
int TiffImage::pixelWidth() const
{
ExifData::const_iterator imageWidth;
if ((imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth"))) != exifData_.end())
{
return imageWidth->toLong();
}
return 0;
}
int TiffImage::pixelHeight() const
{
ExifData::const_iterator imageHeight;
if ((imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageLength"))) != exifData_.end())
{
return imageHeight->toLong();
}
return 0;
}
void TiffImage::setExifData(const ExifData& /*exifData*/)
{
// Todo: implement me!

@ -103,6 +103,8 @@ namespace Exiv2 {
//! @name Accessors
//@{
std::string mimeType() const { return "image/tiff"; }
int pixelWidth() const;
int pixelHeight() const;
//@}
private:

@ -90,7 +90,7 @@ namespace Exiv2 {
enum ByteOrder { invalidByteOrder, littleEndian, bigEndian };
//! An identifier for each type of metadata
enum MetadataId { mdExif=1, mdIptc=2, mdComment=4, mdXmp=8 };
enum MetadataId { mdNone=0, mdExif=1, mdIptc=2, mdComment=4, mdXmp=8 };
//! An identifier for each mode of metadata support
enum AccessMode { amNone=0, amRead=1, amWrite=2, amReadWrite=3 };

@ -204,10 +204,16 @@ Renaming file to ./20060127_225027.jpg
Print --------------------------------------------------------------------
File 1/15: exiv2-empty.jpg
exiv2-empty.jpg File name : exiv2-empty.jpg
exiv2-empty.jpg File size : 4745 Bytes
exiv2-empty.jpg MIME type : image/jpeg
exiv2-empty.jpg Image size : 150 x 91
exiv2-empty.jpg: No Exif data found in the file
File 2/15: 20031214_000043.jpg
20031214_000043.jpg File name : 20031214_000043.jpg
20031214_000043.jpg File size : 12425 Bytes
20031214_000043.jpg MIME type : image/jpeg
20031214_000043.jpg Image size : 150 x 91
20031214_000043.jpg Camera make : Canon
20031214_000043.jpg Camera model : Canon PowerShot S40
20031214_000043.jpg Image timestamp : 2003:12:14 00:00:43
@ -230,9 +236,11 @@ File 2/15: 20031214_000043.jpg
20031214_000043.jpg Copyright :
20031214_000043.jpg Exif comment :
File 3 /15: 20000506_020544.jpg
File 3/15: 20000506_020544.jpg
20000506_020544.jpg File name : 20000506_020544.jpg
20000506_020544.jpg File size : 19152 Bytes
20000506_020544.jpg MIME type : image/jpeg
20000506_020544.jpg Image size : 150 x 91
20000506_020544.jpg Camera make : NIKON
20000506_020544.jpg Camera model : E990
20000506_020544.jpg Image timestamp : 2000:05:06 02:05:44
@ -255,9 +263,11 @@ File 3 /15: 20000506_020544.jpg
20000506_020544.jpg Copyright :
20000506_020544.jpg Exif comment :
File 4 /15: 20040329_224245.jpg
File 4/15: 20040329_224245.jpg
20040329_224245.jpg File name : 20040329_224245.jpg
20040329_224245.jpg File size : 44129 Bytes
20040329_224245.jpg MIME type : image/jpeg
20040329_224245.jpg Image size : 150 x 91
20040329_224245.jpg Camera make : NIKON CORPORATION
20040329_224245.jpg Camera model : NIKON D70
20040329_224245.jpg Image timestamp : 2004:03:29 22:42:45
@ -280,9 +290,11 @@ File 4 /15: 20040329_224245.jpg
20040329_224245.jpg Copyright :
20040329_224245.jpg Exif comment :
File 5 /15: 20010405_235039.jpg
File 5/15: 20010405_235039.jpg
20010405_235039.jpg File name : 20010405_235039.jpg
20010405_235039.jpg File size : 11984 Bytes
20010405_235039.jpg MIME type : image/jpeg
20010405_235039.jpg Image size : 150 x 91
20010405_235039.jpg Camera make : NIKON
20010405_235039.jpg Camera model : E950
20010405_235039.jpg Image timestamp : 2001:04:05 23:50:39
@ -305,9 +317,11 @@ File 5 /15: 20010405_235039.jpg
20010405_235039.jpg Copyright :
20010405_235039.jpg Exif comment :
File 6 /15: 20030925_201850.jpg
File 6/15: 20030925_201850.jpg
20030925_201850.jpg File name : 20030925_201850.jpg
20030925_201850.jpg File size : 17033 Bytes
20030925_201850.jpg MIME type : image/jpeg
20030925_201850.jpg Image size : 150 x 91
20030925_201850.jpg Camera make : Canon
20030925_201850.jpg Camera model : Canon EOS 300D DIGITAL
20030925_201850.jpg Image timestamp : 2003:09:25 20:18:50
@ -330,9 +344,11 @@ File 6 /15: 20030925_201850.jpg
20030925_201850.jpg Copyright :
20030925_201850.jpg Exif comment :
File 7 /15: 20001026_044550.jpg
File 7/15: 20001026_044550.jpg
20001026_044550.jpg File name : 20001026_044550.jpg
20001026_044550.jpg File size : 26485 Bytes
20001026_044550.jpg MIME type : image/jpeg
20001026_044550.jpg Image size : 150 x 91
20001026_044550.jpg Camera make : Eastman Kodak Company
20001026_044550.jpg Camera model : DC210 Zoom (V05.00)
20001026_044550.jpg Image timestamp : 2000:10:26 04:45:50
@ -355,9 +371,11 @@ File 7 /15: 20001026_044550.jpg
20001026_044550.jpg Copyright :
20001026_044550.jpg Exif comment :
File 8 /15: 20030926_111535.jpg
File 8/15: 20030926_111535.jpg
20030926_111535.jpg File name : 20030926_111535.jpg
20030926_111535.jpg File size : 15537 Bytes
20030926_111535.jpg MIME type : image/jpeg
20030926_111535.jpg Image size : 150 x 91
20030926_111535.jpg Camera make : FUJIFILM
20030926_111535.jpg Camera model : FinePixS2Pro
20030926_111535.jpg Image timestamp : 2003:09:26 11:15:35
@ -380,9 +398,11 @@ File 8 /15: 20030926_111535.jpg
20030926_111535.jpg Copyright :
20030926_111535.jpg Exif comment :
File 9 /15: 20040316_075137.jpg
File 9/15: 20040316_075137.jpg
20040316_075137.jpg File name : 20040316_075137.jpg
20040316_075137.jpg File size : 18307 Bytes
20040316_075137.jpg MIME type : image/jpeg
20040316_075137.jpg Image size : 150 x 91
20040316_075137.jpg Camera make : SIGMA
20040316_075137.jpg Camera model : SIGMA SD10
20040316_075137.jpg Image timestamp : 2004:03:16 07:51:37
@ -408,6 +428,8 @@ File 9 /15: 20040316_075137.jpg
File 10/15: 20040208_093744.jpg
20040208_093744.jpg File name : 20040208_093744.jpg
20040208_093744.jpg File size : 19152 Bytes
20040208_093744.jpg MIME type : image/jpeg
20040208_093744.jpg Image size : 150 x 91
20040208_093744.jpg Camera make : OLYMPUS CORPORATION
20040208_093744.jpg Camera model : C8080WZ
20040208_093744.jpg Image timestamp : 2004:02:08 09:37:44
@ -433,6 +455,8 @@ File 10/15: 20040208_093744.jpg
File 11/15: 20050218_212016.jpg
20050218_212016.jpg File name : 20050218_212016.jpg
20050218_212016.jpg File size : 32041 Bytes
20050218_212016.jpg MIME type : image/jpeg
20050218_212016.jpg Image size : 150 x 91
20050218_212016.jpg Camera make : Panasonic
20050218_212016.jpg Camera model : DMC-FZ5
20050218_212016.jpg Image timestamp : 2005:02:18 21:20:16
@ -458,6 +482,8 @@ File 11/15: 20050218_212016.jpg
File 12/15: 20050527_051833.jpg
20050527_051833.jpg File name : 20050527_051833.jpg
20050527_051833.jpg File size : 22844 Bytes
20050527_051833.jpg MIME type : image/jpeg
20050527_051833.jpg Image size : 150 x 91
20050527_051833.jpg Camera make : SONY
20050527_051833.jpg Camera model : DSC-W7
20050527_051833.jpg Image timestamp : 2005:05:27 05:18:33
@ -484,6 +510,8 @@ File 13/15: 20060802_095200.jpg
Warning: Makernote: Pointer to next IFD is out of bounds; ignored.
20060802_095200.jpg File name : 20060802_095200.jpg
20060802_095200.jpg File size : 20733 Bytes
20060802_095200.jpg MIME type : image/jpeg
20060802_095200.jpg Image size : 150 x 91
20060802_095200.jpg Camera make : Canon
20060802_095200.jpg Camera model : Canon EOS 20D
20060802_095200.jpg Image timestamp : 2006:08:02 09:52:00
@ -509,6 +537,8 @@ Warning: Makernote: Pointer to next IFD is out of bounds; ignored.
File 14/15: 20001004_015404.jpg
20001004_015404.jpg File name : 20001004_015404.jpg
20001004_015404.jpg File size : 20617 Bytes
20001004_015404.jpg MIME type : image/jpeg
20001004_015404.jpg Image size : 150 x 91
20001004_015404.jpg Camera make : Canon
20001004_015404.jpg Camera model : Canon EOS D30
20001004_015404.jpg Image timestamp : 2000:10:04 01:54:04
@ -534,6 +564,8 @@ File 14/15: 20001004_015404.jpg
File 15/15: 20060127_225027.jpg
20060127_225027.jpg File name : 20060127_225027.jpg
20060127_225027.jpg File size : 13449 Bytes
20060127_225027.jpg MIME type : image/jpeg
20060127_225027.jpg Image size : 150 x 91
20060127_225027.jpg Camera make : Canon
20060127_225027.jpg Camera model : Canon PowerShot A520
20060127_225027.jpg Image timestamp : 2006:01:27 22:50:27
@ -4893,34 +4925,94 @@ Erasing Exif data from the file
File 15/15: 20060127_225027.jpg
Erasing Exif data from the file
File 1/15: exiv2-empty.jpg
exiv2-empty.jpg File name : exiv2-empty.jpg
exiv2-empty.jpg File size : 4745 Bytes
exiv2-empty.jpg MIME type : image/jpeg
exiv2-empty.jpg Image size : 150 x 91
exiv2-empty.jpg: No Exif data found in the file
File 2/15: 20031214_000043.jpg
20031214_000043.jpg File name : 20031214_000043.jpg
20031214_000043.jpg File size : 4745 Bytes
20031214_000043.jpg MIME type : image/jpeg
20031214_000043.jpg Image size : 150 x 91
20031214_000043.jpg: No Exif data found in the file
File 3/15: 20000506_020544.jpg
20000506_020544.jpg File name : 20000506_020544.jpg
20000506_020544.jpg File size : 4745 Bytes
20000506_020544.jpg MIME type : image/jpeg
20000506_020544.jpg Image size : 150 x 91
20000506_020544.jpg: No Exif data found in the file
File 4/15: 20040329_224245.jpg
20040329_224245.jpg File name : 20040329_224245.jpg
20040329_224245.jpg File size : 4745 Bytes
20040329_224245.jpg MIME type : image/jpeg
20040329_224245.jpg Image size : 150 x 91
20040329_224245.jpg: No Exif data found in the file
File 5/15: 20010405_235039.jpg
20010405_235039.jpg File name : 20010405_235039.jpg
20010405_235039.jpg File size : 4745 Bytes
20010405_235039.jpg MIME type : image/jpeg
20010405_235039.jpg Image size : 150 x 91
20010405_235039.jpg: No Exif data found in the file
File 6/15: 20030925_201850.jpg
20030925_201850.jpg File name : 20030925_201850.jpg
20030925_201850.jpg File size : 4745 Bytes
20030925_201850.jpg MIME type : image/jpeg
20030925_201850.jpg Image size : 150 x 91
20030925_201850.jpg: No Exif data found in the file
File 7/15: 20001026_044550.jpg
20001026_044550.jpg File name : 20001026_044550.jpg
20001026_044550.jpg File size : 4745 Bytes
20001026_044550.jpg MIME type : image/jpeg
20001026_044550.jpg Image size : 150 x 91
20001026_044550.jpg: No Exif data found in the file
File 8/15: 20030926_111535.jpg
20030926_111535.jpg File name : 20030926_111535.jpg
20030926_111535.jpg File size : 4745 Bytes
20030926_111535.jpg MIME type : image/jpeg
20030926_111535.jpg Image size : 150 x 91
20030926_111535.jpg: No Exif data found in the file
File 9/15: 20040316_075137.jpg
20040316_075137.jpg File name : 20040316_075137.jpg
20040316_075137.jpg File size : 4745 Bytes
20040316_075137.jpg MIME type : image/jpeg
20040316_075137.jpg Image size : 150 x 91
20040316_075137.jpg: No Exif data found in the file
File 10/15: 20040208_093744.jpg
20040208_093744.jpg File name : 20040208_093744.jpg
20040208_093744.jpg File size : 4745 Bytes
20040208_093744.jpg MIME type : image/jpeg
20040208_093744.jpg Image size : 150 x 91
20040208_093744.jpg: No Exif data found in the file
File 11/15: 20050218_212016.jpg
20050218_212016.jpg File name : 20050218_212016.jpg
20050218_212016.jpg File size : 4745 Bytes
20050218_212016.jpg MIME type : image/jpeg
20050218_212016.jpg Image size : 150 x 91
20050218_212016.jpg: No Exif data found in the file
File 12/15: 20050527_051833.jpg
20050527_051833.jpg File name : 20050527_051833.jpg
20050527_051833.jpg File size : 4745 Bytes
20050527_051833.jpg MIME type : image/jpeg
20050527_051833.jpg Image size : 150 x 91
20050527_051833.jpg: No Exif data found in the file
File 13/15: 20060802_095200.jpg
20060802_095200.jpg File name : 20060802_095200.jpg
20060802_095200.jpg File size : 4745 Bytes
20060802_095200.jpg MIME type : image/jpeg
20060802_095200.jpg Image size : 150 x 91
20060802_095200.jpg: No Exif data found in the file
File 14/15: 20001004_015404.jpg
20001004_015404.jpg File name : 20001004_015404.jpg
20001004_015404.jpg File size : 4745 Bytes
20001004_015404.jpg MIME type : image/jpeg
20001004_015404.jpg Image size : 150 x 91
20001004_015404.jpg: No Exif data found in the file
File 15/15: 20060127_225027.jpg
20060127_225027.jpg File name : 20060127_225027.jpg
20060127_225027.jpg File size : 4745 Bytes
20060127_225027.jpg MIME type : image/jpeg
20060127_225027.jpg Image size : 150 x 91
20060127_225027.jpg: No Exif data found in the file
Insert Exif data ---------------------------------------------------------

Loading…
Cancel
Save