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:
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"));
|
||||
|
||||
|
||||
160
src/bmpimage.cpp
Normal file
160
src/bmpimage.cpp
Normal 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
133
src/bmpimage.hpp
Normal 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_
|
||||
@ -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);
|
||||
|
||||
141
src/gifimage.cpp
Normal file
141
src/gifimage.cpp
Normal 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
134
src/gifimage.hpp
Normal 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_
|
||||
@ -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
|
||||
|
||||
266
src/jp2image.cpp
Normal file
266
src/jp2image.cpp
Normal 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
133
src/jp2image.hpp
Normal 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_
|
||||
@ -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);
|
||||
|
||||
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)
|
||||
|
||||
@ -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:
|
||||
|
||||
339
src/psdimage.cpp
Normal file
339
src/psdimage.cpp
Normal 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
150
src/psdimage.hpp
Normal 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_
|
||||
@ -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:
|
||||
|
||||
170
src/tgaimage.cpp
Normal file
170
src/tgaimage.cpp
Normal 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
135
src/tgaimage.hpp
Normal 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_
|
||||
@ -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…
Reference in New Issue
Block a user