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

This commit is contained in:
Andreas Huggel 2008-04-15 03:46:01 +00:00
parent 1c86a6e297
commit 654d51a366
34 changed files with 2089 additions and 25 deletions

View File

@ -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 \

View File

@ -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"));

160
src/bmpimage.cpp Normal file
View File

@ -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

133
src/bmpimage.hpp Normal file
View File

@ -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_

View File

@ -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!

View File

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

View File

@ -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

View File

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

View File

@ -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);

141
src/gifimage.cpp Normal file
View File

@ -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

134
src/gifimage.hpp Normal file
View File

@ -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_

View File

@ -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;

View File

@ -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

266
src/jp2image.cpp Normal file
View File

@ -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

133
src/jp2image.hpp Normal file
View File

@ -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_

View File

@ -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;

View File

@ -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
//@{

View File

@ -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!

View File

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

View File

@ -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!

View File

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

View File

@ -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);
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
long index = 8;
index += chunkLength(pData, index) + PNG_CHUNK_HEADER_SIZE;
while(index < size-PNG_CHUNK_HEADER_SIZE)

View File

@ -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

View File

@ -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:

339
src/psdimage.cpp Normal file
View File

@ -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

150
src/psdimage.hpp Normal file
View File

@ -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_

View File

@ -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!

View File

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

170
src/tgaimage.cpp Normal file
View File

@ -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

135
src/tgaimage.hpp Normal file
View File

@ -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_

View File

@ -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!

View File

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

View File

@ -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 };

View File

@ -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 ---------------------------------------------------------