Added read support for jp2 and psd images, stubs for gif, bmp and tga images, and pixelWidth and pixelHeight methods on Image (Marco Piovanelli).
parent
1c86a6e297
commit
654d51a366
@ -0,0 +1,160 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: bmpimage.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Marco Piovanelli, Ovolabs (marco)
|
||||
History: 05-Mar-2007, marco: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id$")
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
#include "bmpimage.hpp"
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
BmpImage::BmpImage(BasicIo::AutoPtr io)
|
||||
: Image(ImageType::bmp, mdNone, io)
|
||||
{
|
||||
} // BmpImage::BmpImage
|
||||
|
||||
void BmpImage::setExifData(const ExifData& /*exifData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Exif metadata", "BMP"));
|
||||
}
|
||||
|
||||
void BmpImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "IPTC metadata", "BMP"));
|
||||
}
|
||||
|
||||
void BmpImage::setComment(const std::string& /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(32, "Image comment", "BMP"));
|
||||
}
|
||||
|
||||
void BmpImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Exiv2::BmpImage::readMetadata: Reading Windows bitmap file " << io_->path() << "\n";
|
||||
#endif
|
||||
if (io_->open() != 0)
|
||||
{
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (!isBmpType(*io_, false))
|
||||
{
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(3, "BMP");
|
||||
}
|
||||
clearMetadata();
|
||||
|
||||
/*
|
||||
The Windows bitmap header goes as follows -- all numbers are in little-endian byte order:
|
||||
|
||||
offset length name description
|
||||
====== ======= ===================== =======
|
||||
0 2 bytes signature always 'BM'
|
||||
2 4 bytes bitmap size
|
||||
6 4 bytes reserved
|
||||
10 4 bytes bitmap offset
|
||||
14 4 bytes header size
|
||||
18 4 bytes bitmap width
|
||||
22 4 bytes bitmap height
|
||||
26 2 bytes plane count
|
||||
28 2 bytes depth
|
||||
30 4 bytes compression 0 = none; 1 = RLE, 8 bits/pixel; 2 = RLE, 4 bits/pixel; 3 = bitfield; 4 = JPEG; 5 = PNG
|
||||
34 4 bytes image size size of the raw bitmap data, in bytes
|
||||
38 4 bytes horizontal resolution (in pixels per meter)
|
||||
42 4 bytes vertical resolution (in pixels per meter)
|
||||
46 4 bytes color count
|
||||
50 4 bytes important colors number of "important" colors
|
||||
*/
|
||||
byte buf[54];
|
||||
if (io_->read(buf, sizeof(buf)) == sizeof(buf))
|
||||
{
|
||||
pixelWidth_ = getLong(buf + 18, littleEndian);
|
||||
pixelHeight_ = getLong(buf + 22, littleEndian);
|
||||
}
|
||||
} // BmpImage::readMetadata
|
||||
|
||||
void BmpImage::writeMetadata()
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(31, "BMP"));
|
||||
} // BmpImage::writeMetadata
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newBmpInstance(BasicIo::AutoPtr io, bool /*create*/)
|
||||
{
|
||||
Image::AutoPtr image(new BmpImage(io));
|
||||
if (!image->good())
|
||||
{
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isBmpType(BasicIo& iIo, bool advance)
|
||||
{
|
||||
const int32_t len = 2;
|
||||
const unsigned char BmpImageId[2] = { 'B', 'M' };
|
||||
byte buf[len];
|
||||
iIo.read(buf, len);
|
||||
if (iIo.error() || iIo.eof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool matched = (memcmp(buf, BmpImageId, len) == 0);
|
||||
if (!advance || !matched)
|
||||
{
|
||||
iIo.seek(-len, BasicIo::cur);
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
} // namespace Exiv2
|
@ -0,0 +1,133 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file bmpimage.hpp
|
||||
@brief Windows Bitmap (BMP) image
|
||||
@version $Rev$
|
||||
@author Marco Piovanelli, Ovolabs (marco)
|
||||
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
|
||||
@date 05-Mar-2007, marco: created
|
||||
*/
|
||||
#ifndef BMPIMAGE_HPP_
|
||||
#define BMPIMAGE_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add Windows Bitmap (BMP) to the supported image formats
|
||||
namespace ImageType {
|
||||
const int bmp = 14; //!< Windows bitmap (bmp) image type (see class BmpImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access Windows bitmaps. This is just a stub - we only
|
||||
read width and height.
|
||||
*/
|
||||
class BmpImage : public Image {
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
BmpImage(const BmpImage& rhs);
|
||||
//! Assignment operator
|
||||
BmpImage& operator=(const BmpImage& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to open a Windows bitmap image. Since the
|
||||
constructor can not return a result, callers should check the
|
||||
good() method after object construction to determine success
|
||||
or failure.
|
||||
@param io An auto-pointer that owns a BasicIo instance used for
|
||||
reading and writing image metadata. \b Important: The constructor
|
||||
takes ownership of the passed in BasicIo instance through the
|
||||
auto-pointer. Callers should not continue to use the BasicIo
|
||||
instance after it is passed to this method. Use the Image::io()
|
||||
method to get a temporary reference.
|
||||
*/
|
||||
BmpImage(BasicIo::AutoPtr io);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet(?) implemented. Calling it will throw an Error(31).
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setExifData(const ExifData& exifData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Not supported. Calling this function will throw an instance
|
||||
of Error(32).
|
||||
*/
|
||||
void setComment(const std::string& comment);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
std::string mimeType() const { return "image/x-ms-bmp"; }
|
||||
//@}
|
||||
|
||||
}; // class BmpImage
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
// These could be static private functions on Image subclasses but then
|
||||
// ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new BmpImage instance and return an auto-pointer to it.
|
||||
Caller owns the returned object and the auto-pointer ensures that
|
||||
it will be deleted.
|
||||
*/
|
||||
Image::AutoPtr newBmpInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a Windows Bitmap image.
|
||||
bool isBmpType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef BMPIMAGE_HPP_
|
@ -0,0 +1,141 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: gifimage.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Marco Piovanelli, Ovolabs (marco)
|
||||
History: 26-Feb-2007, marco: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id$")
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
#include "gifimage.hpp"
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
GifImage::GifImage(BasicIo::AutoPtr io)
|
||||
: Image(ImageType::gif, mdNone, io)
|
||||
{
|
||||
} // GifImage::GifImage
|
||||
|
||||
void GifImage::setExifData(const ExifData& /*exifData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Exif metadata", "GIF"));
|
||||
}
|
||||
|
||||
void GifImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "IPTC metadata", "GIF"));
|
||||
}
|
||||
|
||||
void GifImage::setComment(const std::string& /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(32, "Image comment", "GIF"));
|
||||
}
|
||||
|
||||
void GifImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Exiv2::GifImage::readMetadata: Reading GIF file " << io_->path() << "\n";
|
||||
#endif
|
||||
if (io_->open() != 0)
|
||||
{
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (!isGifType(*io_, true))
|
||||
{
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(3, "GIF");
|
||||
}
|
||||
clearMetadata();
|
||||
|
||||
byte buf[4];
|
||||
if (io_->read(buf, sizeof(buf)) == sizeof(buf))
|
||||
{
|
||||
pixelWidth_ = getShort(buf, littleEndian);
|
||||
pixelHeight_ = getShort(buf + 2, littleEndian);
|
||||
}
|
||||
} // GifImage::readMetadata
|
||||
|
||||
void GifImage::writeMetadata()
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(31, "GIF"));
|
||||
} // GifImage::writeMetadata
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newGifInstance(BasicIo::AutoPtr io, bool /*create*/)
|
||||
{
|
||||
Image::AutoPtr image(new GifImage(io));
|
||||
if (!image->good())
|
||||
{
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isGifType(BasicIo& iIo, bool advance)
|
||||
{
|
||||
const int32_t len = 6;
|
||||
const unsigned char Gif87aId[8] = { 'G', 'I', 'F', '8', '7', 'a' };
|
||||
const unsigned char Gif89aId[8] = { 'G', 'I', 'F', '8', '9', 'a' };
|
||||
byte buf[len];
|
||||
iIo.read(buf, len);
|
||||
if (iIo.error() || iIo.eof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool matched = (memcmp(buf, Gif87aId, len) == 0)
|
||||
|| (memcmp(buf, Gif89aId, len) == 0);
|
||||
if (!advance || !matched)
|
||||
{
|
||||
iIo.seek(-len, BasicIo::cur);
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
} // namespace Exiv2
|
@ -0,0 +1,134 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file gifimage.hpp
|
||||
@brief GIF image, implemented using the following references:
|
||||
<a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF89 specification</a> by W3C<br>
|
||||
@version $Rev$
|
||||
@author Marco Piovanelli, Ovolabs (marco)
|
||||
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
|
||||
@date 26-Feb-2007, marco: created
|
||||
*/
|
||||
#ifndef GIFIMAGE_HPP_
|
||||
#define GIFIMAGE_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add GIF to the supported image formats
|
||||
namespace ImageType {
|
||||
const int gif = 11; //!< GIF image type (see class GifImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access raw GIF images. Exif/IPTC metadata are supported
|
||||
directly.
|
||||
*/
|
||||
class GifImage : public Image {
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
GifImage(const GifImage& rhs);
|
||||
//! Assignment operator
|
||||
GifImage& operator=(const GifImage& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to open a GIF image. Since the
|
||||
constructor can not return a result, callers should check the
|
||||
good() method after object construction to determine success
|
||||
or failure.
|
||||
@param io An auto-pointer that owns a BasicIo instance used for
|
||||
reading and writing image metadata. \b Important: The constructor
|
||||
takes ownership of the passed in BasicIo instance through the
|
||||
auto-pointer. Callers should not continue to use the BasicIo
|
||||
instance after it is passed to this method. Use the Image::io()
|
||||
method to get a temporary reference.
|
||||
*/
|
||||
GifImage(BasicIo::AutoPtr io);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet(?) implemented. Calling it will throw an Error(31).
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setExifData(const ExifData& exifData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Not supported. Calling this function will throw an instance
|
||||
of Error(32).
|
||||
*/
|
||||
void setComment(const std::string& comment);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
std::string mimeType() const { return "image/gif"; }
|
||||
//@}
|
||||
|
||||
}; // class GifImage
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
// These could be static private functions on Image subclasses but then
|
||||
// ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new GifImage instance and return an auto-pointer to it.
|
||||
Caller owns the returned object and the auto-pointer ensures that
|
||||
it will be deleted.
|
||||
*/
|
||||
Image::AutoPtr newGifInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a GIF image.
|
||||
bool isGifType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef GIFIMAGE_HPP_
|
@ -0,0 +1,266 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: jp2image.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Marco Piovanelli, Ovolabs (marco)
|
||||
History: 12-Mar-2007, marco: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id$")
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
#include "jp2image.hpp"
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// JPEG-2000 box types
|
||||
const uint32_t kJp2BoxTypeJp2Header = 0x6a703268; // 'jp2h'
|
||||
const uint32_t kJp2BoxTypeImageHeader = 0x69686472; // 'ihdr'
|
||||
const uint32_t kJp2BoxTypeUuid = 0x75756964; // 'uuid'
|
||||
|
||||
// JPEG-2000 UUIDs for embedded metadata
|
||||
//
|
||||
// See http://www.jpeg.org/public/wg1n2600.doc for information about embedding IPTC-NAA data in JPEG-2000 files
|
||||
// See http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf for information about embedding XMP data in JPEG-2000 files
|
||||
const char* const kJp2UuidExif = "JpgTiffExif->JP2";
|
||||
const char* const kJp2UuidIptc = "\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38";
|
||||
const char* const kJp2UuidXmp = "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac";
|
||||
|
||||
//! @cond IGNORE
|
||||
struct Jp2BoxHeader {
|
||||
uint32_t boxLength;
|
||||
uint32_t boxType;
|
||||
};
|
||||
|
||||
struct Jp2ImageHeaderBox {
|
||||
uint32_t imageHeight;
|
||||
uint32_t imageWidth;
|
||||
uint16_t componentCount;
|
||||
uint8_t bitsPerComponent;
|
||||
uint8_t compressionType;
|
||||
uint8_t colorspaceIsUnknown;
|
||||
uint8_t intellectualPropertyFlag;
|
||||
uint16_t compressionTypeProfile;
|
||||
};
|
||||
|
||||
struct Jp2UuidBox {
|
||||
uint8_t uuid[16];
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
Jp2Image::Jp2Image(BasicIo::AutoPtr io)
|
||||
: Image(ImageType::jp2, mdExif | mdIptc | mdXmp, io)
|
||||
{
|
||||
} // Jp2Image::Jp2Image
|
||||
|
||||
void Jp2Image::setExifData(const ExifData& /*exifData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Exif metadata", "JP2"));
|
||||
}
|
||||
|
||||
void Jp2Image::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "IPTC metadata", "JP2"));
|
||||
}
|
||||
|
||||
void Jp2Image::setComment(const std::string& /*comment*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Image comment", "JP2"));
|
||||
}
|
||||
|
||||
void Jp2Image::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Exiv2::Jp2Image::readMetadata: Reading JPEG-2000 file " << io_->path() << "\n";
|
||||
#endif
|
||||
if (io_->open() != 0)
|
||||
{
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (!isJp2Type(*io_, true))
|
||||
{
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(3, "JPEG-2000");
|
||||
}
|
||||
|
||||
Jp2BoxHeader box = {0,0};
|
||||
Jp2BoxHeader subBox = {0,0};
|
||||
Jp2ImageHeaderBox ihdr = {0,0,0,0,0,0,0,0};
|
||||
Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
||||
long curOffset = io_->tell();
|
||||
|
||||
while (io_->read((byte*)&box, sizeof(box)) == sizeof(box))
|
||||
{
|
||||
box.boxLength = getLong((byte*)&box.boxLength, bigEndian);
|
||||
box.boxType = getLong((byte*)&box.boxType, bigEndian);
|
||||
|
||||
if (box.boxLength == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch(box.boxType)
|
||||
{
|
||||
case kJp2BoxTypeJp2Header:
|
||||
{
|
||||
if (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox))
|
||||
{
|
||||
subBox.boxLength = getLong((byte*)&subBox.boxLength, bigEndian);
|
||||
subBox.boxType = getLong((byte*)&subBox.boxType, bigEndian);
|
||||
|
||||
if((subBox.boxType == kJp2BoxTypeImageHeader) && (io_->read((byte*)&ihdr, sizeof(ihdr)) == sizeof(ihdr)))
|
||||
{
|
||||
ihdr.imageHeight = getLong((byte*)&ihdr.imageHeight, bigEndian);
|
||||
ihdr.imageWidth = getLong((byte*)&ihdr.imageWidth, bigEndian);
|
||||
ihdr.componentCount = getShort((byte*)&ihdr.componentCount, bigEndian);
|
||||
ihdr.compressionTypeProfile = getShort((byte*)&ihdr.compressionTypeProfile, bigEndian);
|
||||
|
||||
pixelWidth_ = ihdr.imageWidth;
|
||||
pixelHeight_ = ihdr.imageHeight;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kJp2BoxTypeUuid:
|
||||
{
|
||||
if (io_->read((byte*)&uuid, sizeof(uuid)) == sizeof(uuid))
|
||||
{
|
||||
if(memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid)) == 0)
|
||||
{
|
||||
// we've hit an embedded Exif block
|
||||
DataBuf rawExif(box.boxLength - (sizeof(box) + sizeof(uuid)));
|
||||
io_->read(rawExif.pData_, rawExif.size_);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
if (exifData_.load(rawExif.pData_, rawExif.size_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to decode Exif metadata.\n";
|
||||
#endif
|
||||
exifData_.clear();
|
||||
}
|
||||
}
|
||||
else if(memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid)) == 0)
|
||||
{
|
||||
// we've hit an embedded IPTC block
|
||||
DataBuf rawIPTC(box.boxLength - (sizeof(box) + sizeof(uuid)));
|
||||
io_->read(rawIPTC.pData_, rawIPTC.size_);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
if (iptcData_.load(rawIPTC.pData_, rawIPTC.size_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to decode IPTC metadata.\n";
|
||||
#endif
|
||||
iptcData_.clear();
|
||||
}
|
||||
}
|
||||
else if(memcmp(uuid.uuid, kJp2UuidXmp, sizeof(uuid)) == 0)
|
||||
{
|
||||
// we've hit an embedded XMP block
|
||||
DataBuf xmpPacket(box.boxLength - (sizeof(box) + sizeof(uuid)));
|
||||
io_->read(xmpPacket.pData_, xmpPacket.size_);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
xmpPacket_.assign(reinterpret_cast<char *>(xmpPacket.pData_), xmpPacket.size_);
|
||||
if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to decode XMP metadata.\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curOffset += box.boxLength;
|
||||
if(io_->seek(curOffset, BasicIo::beg) != 0)
|
||||
{
|
||||
break; // Todo: should throw an error here
|
||||
}
|
||||
}
|
||||
} // Jp2Image::readMetadata
|
||||
|
||||
void Jp2Image::writeMetadata()
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(31, "JP2"));
|
||||
} // Jp2Image::writeMetadata
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newJp2Instance(BasicIo::AutoPtr io, bool /*create*/)
|
||||
{
|
||||
Image::AutoPtr image(new Jp2Image(io));
|
||||
if (!image->good())
|
||||
{
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isJp2Type(BasicIo& iIo, bool advance)
|
||||
{
|
||||
// see section B.1.1 (JPEG 2000 Signature box) of JPEG-2000 specification
|
||||
const int32_t len = 12;
|
||||
const unsigned char Jp2Header[len] = { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a };
|
||||
byte buf[len];
|
||||
iIo.read(buf, len);
|
||||
if (iIo.error() || iIo.eof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool matched = (memcmp(buf, Jp2Header, len) == 0);
|
||||
if (!advance || !matched)
|
||||
{
|
||||
iIo.seek(-len, BasicIo::cur);
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
} // namespace Exiv2
|
@ -0,0 +1,133 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file jp2image.hpp
|
||||
@brief JPEG-2000 image, implemented using the following references:
|
||||
<a href="http://jpeg.org/public/fcd15444-6.pdf">ISO/IEC JTC 1/SC 29/WG1 N2401: JPEG 2000 Part 6 FCD 15444-6</a><br>
|
||||
@version $Rev$
|
||||
@author Marco Piovanelli, Ovolabs (marco)
|
||||
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
|
||||
@date 12-Mar-2007, marco: created
|
||||
*/
|
||||
#ifndef JP2IMAGE_HPP_
|
||||
#define JP2IMAGE_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add JPEG-2000 to the supported image formats
|
||||
namespace ImageType {
|
||||
const int jp2 = 15; //!< JPEG-2000 image type
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access JPEG-2000 images.
|
||||
*/
|
||||
class Jp2Image : public Image {
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
Jp2Image(const Jp2Image& rhs);
|
||||
//! Assignment operator
|
||||
Jp2Image& operator=(const Jp2Image& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to open a JPEG-2000 image. Since the
|
||||
constructor can not return a result, callers should check the
|
||||
good() method after object construction to determine success
|
||||
or failure.
|
||||
@param io An auto-pointer that owns a BasicIo instance used for
|
||||
reading and writing image metadata. \b Important: The constructor
|
||||
takes ownership of the passed in BasicIo instance through the
|
||||
auto-pointer. Callers should not continue to use the BasicIo
|
||||
instance after it is passed to this method. Use the Image::io()
|
||||
method to get a temporary reference.
|
||||
*/
|
||||
Jp2Image(BasicIo::AutoPtr io);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet implemented. Calling it will throw an Error(31).
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Todo: Not supported yet. Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setExifData(const ExifData& exifData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet. Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setComment(const std::string& comment);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
std::string mimeType() const { return "image/jp2"; }
|
||||
//@}
|
||||
|
||||
}; // class Jp2Image
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
// These could be static private functions on Image subclasses but then
|
||||
// ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new Jp2Image instance and return an auto-pointer to it.
|
||||
Caller owns the returned object and the auto-pointer ensures that
|
||||
it will be deleted.
|
||||
*/
|
||||
Image::AutoPtr newJp2Instance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a JPEG-2000 image.
|
||||
bool isJp2Type(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef JP2IMAGE_HPP_
|
@ -0,0 +1,339 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: psdimage.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Marco Piovanelli, Ovolabs (marco)
|
||||
History: 05-Mar-2007, marco: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id$")
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
#include "psdimage.hpp"
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// Todo: Consolidate with existing code in struct Photoshop (jpgimage.hpp):
|
||||
// Extend this helper to a proper class with all required functionality,
|
||||
// then move it here or into a separate file?
|
||||
|
||||
const uint32_t kPhotoshopResourceType = 0x3842494d; // '8BIM'
|
||||
|
||||
//! @cond IGNORE
|
||||
struct PhotoshopResourceBlock {
|
||||
uint32_t resourceType; // always kPhotoshopResourceType
|
||||
uint16_t resourceId;
|
||||
unsigned char resourceName[2]; // Pascal string (length byte + characters), padded to an even size -- this assumes the empty string
|
||||
uint32_t resourceDataSize;
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
// Photoshop resource IDs (Cf. <http://search.cpan.org/~bettelli/Image-MetaData-JPEG-0.15/lib/Image/MetaData/JPEG/TagLists.pod>)
|
||||
enum {
|
||||
kPhotoshopResourceID_Photoshop2Info = 0x03e8, // [obsolete -- Photoshop 2.0 only] General information -- contains five 2-byte values: number of channels, rows, columns, depth and mode
|
||||
kPhotoshopResourceID_MacintoshClassicPrintInfo = 0x03e9, // [optional] Macintosh classic print record (120 bytes)
|
||||
kPhotoshopResourceID_MacintoshCarbonPrintInfo = 0x03ea, // [optional] Macintosh carbon print info (variable-length XML format)
|
||||
kPhotoshopResourceID_Photoshop2ColorTable = 0x03eb, // [obsolete -- Photoshop 2.0 only] Indexed color table
|
||||
kPhotoshopResourceID_ResolutionInfo = 0x03ed, // PhotoshopResolutionInfo structure (see below)
|
||||
kPhotoshopResourceID_AlphaChannelsNames = 0x03ee, // as a series of Pstrings
|
||||
kPhotoshopResourceID_DisplayInfo = 0x03ef, // see appendix A in Photoshop SDK
|
||||
kPhotoshopResourceID_PStringCaption = 0x03f0, // [optional] the caption, as a Pstring
|
||||
kPhotoshopResourceID_BorderInformation = 0x03f1, // border width and units
|
||||
kPhotoshopResourceID_BackgroundColor = 0x03f2, // see additional Adobe information
|
||||
kPhotoshopResourceID_PrintFlags = 0x03f3, // labels, crop marks, colour bars, ecc...
|
||||
kPhotoshopResourceID_BWHalftoningInfo = 0x03f4, // Gray-scale and multich. half-toning info
|
||||
kPhotoshopResourceID_ColorHalftoningInfo = 0x03f5, // Colour half-toning information
|
||||
kPhotoshopResourceID_DuotoneHalftoningInfo = 0x03f6, // Duo-tone half-toning information
|
||||
kPhotoshopResourceID_BWTransferFunc = 0x03f7, // Gray-scale and multich. transfer function
|
||||
kPhotoshopResourceID_ColorTransferFuncs = 0x03f8, // Colour transfer function
|
||||
kPhotoshopResourceID_DuotoneTransferFuncs = 0x03f9, // Duo-tone transfer function
|
||||
kPhotoshopResourceID_DuotoneImageInfo = 0x03fa, // Duo-tone image information
|
||||
kPhotoshopResourceID_EffectiveBW = 0x03fb, // two bytes for the effective black and white values
|
||||
kPhotoshopResourceID_ObsoletePhotoshopTag1 = 0x03fc, // [obsolete]
|
||||
kPhotoshopResourceID_EPSOptions = 0x03fd, // Encapsulated Postscript options
|
||||
kPhotoshopResourceID_QuickMaskInfo = 0x03fe, // Quick Mask information. 2 bytes containing Quick Mask channel ID, 1 byte boolean indicating whether the mask was initially empty.
|
||||
kPhotoshopResourceID_ObsoletePhotoshopTag2 = 0x03ff, // [obsolete]
|
||||
kPhotoshopResourceID_LayerStateInfo = 0x0400, // index of target layer (0 means bottom)
|
||||
kPhotoshopResourceID_WorkingPathInfo = 0x0401, // should not be saved to the file
|
||||
kPhotoshopResourceID_LayersGroupInfo = 0x0402, // for grouping layers together
|
||||
kPhotoshopResourceID_ObsoletePhotoshopTag3 = 0x0403, // [obsolete] ??
|
||||
kPhotoshopResourceID_IPTC_NAA = 0x0404, // IPTC/NAA data
|
||||
kPhotoshopResourceID_RawImageMode = 0x0405, // image mode for raw format files
|
||||
kPhotoshopResourceID_JPEGQuality = 0x0406, // [private]
|
||||
kPhotoshopResourceID_GridGuidesInfo = 0x0408, // see additional Adobe information
|
||||
kPhotoshopResourceID_ThumbnailResource = 0x0409, // see additional Adobe information
|
||||
kPhotoshopResourceID_CopyrightFlag = 0x040a, // true if image is copyrighted
|
||||
kPhotoshopResourceID_URL = 0x040b, // text string with a resource locator
|
||||
kPhotoshopResourceID_ThumbnailResource2 = 0x040c, // see additional Adobe information
|
||||
kPhotoshopResourceID_GlobalAngle = 0x040d, // global lighting angle for effects layer
|
||||
kPhotoshopResourceID_ColorSamplersResource = 0x040e, // see additional Adobe information
|
||||
kPhotoshopResourceID_ICCProfile = 0x040f, // see notes from Internat. Color Consortium
|
||||
kPhotoshopResourceID_Watermark = 0x0410, // one byte
|
||||
kPhotoshopResourceID_ICCUntagged = 0x0411, // 1 means intentionally untagged
|
||||
kPhotoshopResourceID_EffectsVisible = 0x0412, // 1 byte to show/hide all effects layers
|
||||
kPhotoshopResourceID_SpotHalftone = 0x0413, // version, length and data
|
||||
kPhotoshopResourceID_IDsBaseValue = 0x0414, // base value for new layers ID's
|
||||
kPhotoshopResourceID_UnicodeAlphaNames = 0x0415, // length plus Unicode string
|
||||
kPhotoshopResourceID_IndexedColourTableCount = 0x0416, // [Photoshop 6.0 and later] 2 bytes
|
||||
kPhotoshopResourceID_TransparentIndex = 0x0417, // [Photoshop 6.0 and later] 2 bytes
|
||||
kPhotoshopResourceID_GlobalAltitude = 0x0419, // [Photoshop 6.0 and later] 4 bytes
|
||||
kPhotoshopResourceID_Slices = 0x041a, // [Photoshop 6.0 and later] see additional Adobe info
|
||||
kPhotoshopResourceID_WorkflowURL = 0x041b, // [Photoshop 6.0 and later] 4 bytes length + Unicode string
|
||||
kPhotoshopResourceID_JumpToXPEP = 0x041c, // [Photoshop 6.0 and later] see additional Adobe info
|
||||
kPhotoshopResourceID_AlphaIdentifiers = 0x041d, // [Photoshop 6.0 and later] 4*(n+1) bytes
|
||||
kPhotoshopResourceID_URLList = 0x041e, // [Photoshop 6.0 and later] structured Unicode URL's
|
||||
kPhotoshopResourceID_VersionInfo = 0x0421, // [Photoshop 6.0 and later] see additional Adobe info
|
||||
kPhotoshopResourceID_ExifInfo = 0x0422, // [Photoshop 7.0?] Exif metadata
|
||||
kPhotoshopResourceID_XMPPacket = 0x0424, // [Photoshop 7.0?] XMP packet -- see http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf
|
||||
kPhotoshopResourceID_ClippingPathName = 0x0bb7, // [Photoshop 6.0 and later] name of clipping path
|
||||
kPhotoshopResourceID_MorePrintFlags = 0x2710 // [Photoshop 6.0 and later] Print flags information. 2 bytes version (=1), 1 byte center crop marks, 1 byte (=0), 4 bytes bleed width value, 2 bytes bleed width scale.
|
||||
};
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
PsdImage::PsdImage(BasicIo::AutoPtr io)
|
||||
: Image(ImageType::psd, mdExif | mdIptc | mdXmp, io)
|
||||
{
|
||||
} // PsdImage::PsdImage
|
||||
|
||||
void PsdImage::setExifData(const ExifData& /*exifData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Exif metadata", "Photoshop"));
|
||||
}
|
||||
|
||||
void PsdImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "IPTC metadata", "Photoshop"));
|
||||
}
|
||||
|
||||
void PsdImage::setComment(const std::string& /*comment*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Image comment", "Photoshop"));
|
||||
}
|
||||
|
||||
void PsdImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Exiv2::PsdImage::readMetadata: Reading Photoshop file " << io_->path() << "\n";
|
||||
#endif
|
||||
if (io_->open() != 0)
|
||||
{
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (!isPsdType(*io_, false))
|
||||
{
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
clearMetadata();
|
||||
|
||||
/*
|
||||
The Photoshop header goes as follows -- all numbers are in big-endian byte order:
|
||||
|
||||
offset length name description
|
||||
====== ======= ========= =========
|
||||
0 4 bytes signature always '8BPS'
|
||||
4 2 bytes version always equal to 1
|
||||
6 6 bytes reserved must be zero
|
||||
12 2 bytes channels number of channels in the image, including alpha channels (1 to 24)
|
||||
14 4 bytes rows the height of the image in pixels
|
||||
18 4 bytes columns the width of the image in pixels
|
||||
22 2 bytes depth the number of bits per channel
|
||||
24 2 bytes mode the color mode of the file; Supported values are: Bitmap=0; Grayscale=1; Indexed=2; RGB=3; CMYK=4; Multichannel=7; Duotone=8; Lab=9
|
||||
*/
|
||||
byte buf[26];
|
||||
if (io_->read(buf, 26) != 26)
|
||||
{
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
pixelWidth_ = getLong(buf + 18, bigEndian);
|
||||
pixelHeight_ = getLong(buf + 14, bigEndian);
|
||||
|
||||
// immediately following the image header is the color mode data section,
|
||||
// the first four bytes of which specify the byte size of the whole section
|
||||
if (io_->read(buf, 4) != 4)
|
||||
{
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
|
||||
// skip it
|
||||
uint32_t colorDataLength = getLong(buf, bigEndian);
|
||||
if (io_->seek(colorDataLength, BasicIo::cur))
|
||||
{
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
|
||||
// after the color data section, comes a list of resource blocks, preceeded by the total byte size
|
||||
if (io_->read(buf, 4) != 4)
|
||||
{
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
uint32_t resourcesLength = getLong(buf, bigEndian);
|
||||
while (resourcesLength > 0)
|
||||
{
|
||||
if (io_->read(buf, 8) != 8)
|
||||
{
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
|
||||
// read resource type and ID
|
||||
uint32_t resourceType = getLong(buf, bigEndian);
|
||||
uint16_t resourceId = getShort(buf + 4, bigEndian);
|
||||
|
||||
if (resourceType != kPhotoshopResourceType)
|
||||
{
|
||||
break; // bad resource type
|
||||
}
|
||||
uint32_t resourceNameLength = buf[6] & ~1;
|
||||
|
||||
// skip the resource name, plus any padding
|
||||
io_->seek(resourceNameLength, BasicIo::cur);
|
||||
|
||||
// read resource size
|
||||
if (io_->read(buf, 4) != 4)
|
||||
{
|
||||
throw Error(3, "Photoshop");
|
||||
}
|
||||
uint32_t resourceSize = getLong(buf, bigEndian);
|
||||
uint32_t curOffset = io_->tell();
|
||||
|
||||
processResourceBlock(resourceId, resourceSize);
|
||||
resourceSize = (resourceSize + 1) & ~1; // pad to even
|
||||
io_->seek(curOffset + resourceSize, BasicIo::beg);
|
||||
resourcesLength -= (12 + resourceNameLength + resourceSize);
|
||||
}
|
||||
|
||||
} // PsdImage::readMetadata
|
||||
|
||||
void PsdImage::processResourceBlock(uint16_t resourceId, uint32_t resourceSize)
|
||||
{
|
||||
switch(resourceId)
|
||||
{
|
||||
case kPhotoshopResourceID_IPTC_NAA:
|
||||
{
|
||||
DataBuf rawIPTC(resourceSize);
|
||||
io_->read(rawIPTC.pData_, rawIPTC.size_);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
if (iptcData_.load(rawIPTC.pData_, rawIPTC.size_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to decode IPTC metadata.\n";
|
||||
#endif
|
||||
iptcData_.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kPhotoshopResourceID_ExifInfo:
|
||||
{
|
||||
DataBuf rawExif(resourceSize);
|
||||
io_->read(rawExif.pData_, rawExif.size_);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
if (exifData_.load(rawExif.pData_, rawExif.size_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to decode Exif metadata.\n";
|
||||
#endif
|
||||
exifData_.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kPhotoshopResourceID_XMPPacket:
|
||||
{
|
||||
DataBuf xmpPacket(resourceSize);
|
||||
io_->read(xmpPacket.pData_, xmpPacket.size_);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
xmpPacket_.assign(reinterpret_cast<char *>(xmpPacket.pData_), xmpPacket.size_);
|
||||
if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to decode XMP metadata.\n";
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PsdImage::writeMetadata()
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(31, "Photoshop"));
|
||||
} // PsdImage::writeMetadata
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newPsdInstance(BasicIo::AutoPtr io, bool /*create*/)
|
||||
{
|
||||
Image::AutoPtr image(new PsdImage(io));
|
||||
if (!image->good())
|
||||
{
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isPsdType(BasicIo& iIo, bool advance)
|
||||
{
|
||||
const int32_t len = 6;
|
||||
const unsigned char PsdHeader[6] = { '8', 'B', 'P', 'S', 0, 1 };
|
||||
byte buf[len];
|
||||
iIo.read(buf, len);
|
||||
if (iIo.error() || iIo.eof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool matched = (memcmp(buf, PsdHeader, len) == 0);
|
||||
if (!advance || !matched)
|
||||
{
|
||||
iIo.seek(-len, BasicIo::cur);
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
} // namespace Exiv2
|
@ -0,0 +1,150 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file psdimage.hpp
|
||||
@brief Photoshop image, implemented using the following references:
|
||||
<a href="http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf">Adobe Photoshop 6.0 File Format Specification</a> by Adobe<br>
|
||||
@version $Rev$
|
||||
@author Marco Piovanelli, Ovolabs (marco)
|
||||
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
|
||||
@date 05-Mar-2007, marco: created
|
||||
*/
|
||||
#ifndef PSDIMAGE_HPP_
|
||||
#define PSDIMAGE_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add PSD to the supported image formats
|
||||
namespace ImageType {
|
||||
const int psd = 12; //!< Photoshop (PSD) image type (see class PsdImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access raw Photoshop images.
|
||||
*/
|
||||
class PsdImage : public Image {
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
PsdImage(const PsdImage& rhs);
|
||||
//! Assignment operator
|
||||
PsdImage& operator=(const PsdImage& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to open a Photoshop image. Since the
|
||||
constructor can not return a result, callers should check the
|
||||
good() method after object construction to determine success
|
||||
or failure.
|
||||
@param io An auto-pointer that owns a BasicIo instance used for
|
||||
reading and writing image metadata. \b Important: The constructor
|
||||
takes ownership of the passed in BasicIo instance through the
|
||||
auto-pointer. Callers should not continue to use the BasicIo
|
||||
instance after it is passed to this method. Use the Image::io()
|
||||
method to get a temporary reference.
|
||||
*/
|
||||
PsdImage(BasicIo::AutoPtr io);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet implemented. Calling it will throw an Error(31).
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Todo: Not supported yet. Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setExifData(const ExifData& exifData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet. Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet. Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setComment(const std::string& comment);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Return the MIME type of the image.
|
||||
|
||||
The MIME type returned for Photoshop images is "image/x-photoshop".
|
||||
|
||||
@note This should really be "image/vnd.adobe.photoshop"
|
||||
(officially registered with IANA in December 2005 -- see
|
||||
http://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop)
|
||||
but Apple, as of Tiger (10.4.8), maps this official MIME type to a
|
||||
dynamic UTI, rather than "com.adobe.photoshop-image" as it should.
|
||||
*/
|
||||
std::string mimeType() const { return "image/x-photoshop"; }
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void processResourceBlock(uint16_t resourceId, uint32_t resourceSize);
|
||||
//@}
|
||||
|
||||
}; // class PsdImage
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
// These could be static private functions on Image subclasses but then
|
||||
// ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new PsdImage instance and return an auto-pointer to it.
|
||||
Caller owns the returned object and the auto-pointer ensures that
|
||||
it will be deleted.
|
||||
*/
|
||||
Image::AutoPtr newPsdInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a Photoshop image.
|
||||
bool isPsdType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef PSDIMAGE_HPP_
|
@ -0,0 +1,170 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: tgaimage.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Marco Piovanelli, Ovolabs (marco)
|
||||
History: 05-Mar-2007, marco: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id$")
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
#include "tgaimage.hpp"
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
TgaImage::TgaImage(BasicIo::AutoPtr io)
|
||||
: Image(ImageType::tga, mdNone, io)
|
||||
{
|
||||
} // TgaImage::TgaImage
|
||||
|
||||
void TgaImage::setExifData(const ExifData& /*exifData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "Exif metadata", "TGA"));
|
||||
}
|
||||
|
||||
void TgaImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(32, "IPTC metadata", "TGA"));
|
||||
}
|
||||
|
||||
void TgaImage::setComment(const std::string& /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(32, "Image comment", "TGA"));
|
||||
}
|
||||
|
||||
void TgaImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Exiv2::TgaImage::readMetadata: Reading TARGA file " << io_->path() << "\n";
|
||||
#endif
|
||||
if (io_->open() != 0)
|
||||
{
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (!isTgaType(*io_, false))
|
||||
{
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(3, "TGA");
|
||||
}
|
||||
clearMetadata();
|
||||
|
||||
/*
|
||||
The TARGA header goes as follows -- all numbers are in little-endian byte order:
|
||||
|
||||
offset length name description
|
||||
====== ======= ======================= ===========
|
||||
0 1 byte ID length length of image ID (0 to 255)
|
||||
1 1 byte color map type 0 = no color map; 1 = color map included
|
||||
2 1 byte image type 0 = no image;
|
||||
1 = uncompressed color-mapped;
|
||||
2 = uncompressed true-color;
|
||||
3 = uncompressed black-and-white;
|
||||
9 = RLE-encoded color mapped;
|
||||
10 = RLE-encoded true-color;
|
||||
11 = RLE-encoded black-and-white
|
||||
3 5 bytes color map specification
|
||||
8 2 bytes x-origin of image
|
||||
10 2 bytes y-origin of image
|
||||
12 2 bytes image width
|
||||
14 2 bytes image height
|
||||
16 1 byte pixel depth
|
||||
17 1 byte image descriptor
|
||||
*/
|
||||
byte buf[18];
|
||||
if (io_->read(buf, sizeof(buf)) == sizeof(buf))
|
||||
{
|
||||
pixelWidth_ = getShort(buf + 12, littleEndian);
|
||||
pixelHeight_ = getShort(buf + 14, littleEndian);
|
||||
}
|
||||
} // TgaImage::readMetadata
|
||||
|
||||
void TgaImage::writeMetadata()
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(31, "TGA"));
|
||||
} // TgaImage::writeMetadata
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newTgaInstance(BasicIo::AutoPtr io, bool /*create*/)
|
||||
{
|
||||
Image::AutoPtr image(new TgaImage(io));
|
||||
if (!image->good())
|
||||
{
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isTgaType(BasicIo& iIo, bool /*advance*/)
|
||||
{
|
||||
// not all TARGA files have a signature string, so first just try to match the file name extension
|
||||
std::string path = iIo.path();
|
||||
if(path.rfind(".tga") != std::string::npos || path.rfind(".TGA") != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
byte buf[26];
|
||||
long curPos = iIo.tell();
|
||||
iIo.seek(-26, BasicIo::end);
|
||||
if (iIo.error() || iIo.eof())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
iIo.read(buf, sizeof(buf));
|
||||
if (iIo.error())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// some TARGA files, but not all, have a signature string at the end
|
||||
bool matched = (memcmp(buf + 8, "TRUEVISION-XFILE", 16) == 0);
|
||||
iIo.seek(curPos, BasicIo::beg);
|
||||
return matched;
|
||||
}
|
||||
} // namespace Exiv2
|
@ -0,0 +1,135 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file tgaimage.hpp
|
||||
@brief Truevision TARGA v2 image, implemented using the following references:
|
||||
<a href="http://en.wikipedia.org/wiki/Truevision_TGA">Truevision TGA page on Wikipedia</a><br>
|
||||
<a href="http://www.gamers.org/dEngine/quake3/TGA.ps.gz">TGA(tm) File Format Specification</a>
|
||||
@version $Rev$
|
||||
@author Marco Piovanelli, Ovolabs (marco)
|
||||
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
|
||||
@date 05-Mar-2007, marco: created
|
||||
*/
|
||||
#ifndef TGAIMAGE_HPP_
|
||||
#define TGAIMAGE_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add TARGA to the supported image formats
|
||||
namespace ImageType {
|
||||
const int tga = 13; //!< Truevision TARGA (tga) image type (see class TgaImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access raw TARGA images. This is just a stub - we only
|
||||
read width and height.
|
||||
*/
|
||||
class TgaImage : public Image {
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
TgaImage(const TgaImage& rhs);
|
||||
//! Assignment operator
|
||||
TgaImage& operator=(const TgaImage& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to open a Targa image. Since the
|
||||
constructor can not return a result, callers should check the
|
||||
good() method after object construction to determine success
|
||||
or failure.
|
||||
@param io An auto-pointer that owns a BasicIo instance used for
|
||||
reading and writing image metadata. \b Important: The constructor
|
||||
takes ownership of the passed in BasicIo instance through the
|
||||
auto-pointer. Callers should not continue to use the BasicIo
|
||||
instance after it is passed to this method. Use the Image::io()
|
||||
method to get a temporary reference.
|
||||
*/
|
||||
TgaImage(BasicIo::AutoPtr io);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet(?) implemented. Calling it will throw an Error(31).
|
||||
*/
|
||||
void writeMetadata();
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setExifData(const ExifData& exifData);
|
||||
/*!
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(32).
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Not supported. Calling this function will throw an instance
|
||||
of Error(32).
|
||||
*/
|
||||
void setComment(const std::string& comment);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
std::string mimeType() const { return "image/targa"; }
|
||||
//@}
|
||||
|
||||
}; // class TgaImage
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
// These could be static private functions on Image subclasses but then
|
||||
// ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new TgaImage instance and return an auto-pointer to it.
|
||||
Caller owns the returned object and the auto-pointer ensures that
|
||||
it will be deleted.
|
||||
*/
|
||||
Image::AutoPtr newTgaInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a Targa v2 image.
|
||||
bool isTgaType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef TGAIMAGE_HPP_
|
Loading…
Reference in New Issue