Preview API changes.

This commit is contained in:
Andreas Huggel 2008-10-14 17:04:04 +00:00
parent 9870e3aea5
commit 9578e81236
3 changed files with 107 additions and 70 deletions

View File

@ -11,32 +11,32 @@
int main(int argc, char* const argv[])
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " file\n";
return 1;
}
std::string filename(argv[1]);
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(filename);
assert(image.get() != 0);
image->readMetadata();
Exiv2::PreviewImageLoader loader(*image);
Exiv2::PreviewPropertiesList list = loader.getPreviewPropertiesList();
for (Exiv2::PreviewPropertiesList::iterator pos = list.begin(); pos != list.end(); pos++)
{
std::cout << "found preview " << pos->id_
Exiv2::PreviewManager loader(*image);
Exiv2::PreviewPropertiesList list = loader.getPreviewProperties();
for (Exiv2::PreviewPropertiesList::iterator pos = list.begin(); pos != list.end(); pos++) {
std::cout << "Preview " << pos->id_
<< ", size: " << pos->size_
<< ", " << pos->width_ << 'x' << pos->height_
<< "\n";
Exiv2::PreviewImage image = loader.getPreviewImage(*pos);
char buf[50];
sprintf(buf, "%dx%d",pos->width_, pos->height_);
image.writeFile(std::string(argv[1]) + "_" + buf);
Exiv2::PreviewImage preview = loader.getPreviewImage(*pos);
preview.writeFile(filename + "_"
+ Exiv2::toString(pos->width_) + "x"
+ Exiv2::toString(pos->height_));
}
// Cleanup
Exiv2::XmpParser::terminate();
return 0;
}

View File

@ -293,33 +293,58 @@ namespace Exiv2 {
{ "Thumbnail", 0, 0 } // 5
};
PreviewImage::PreviewImage(const PreviewProperties &properties, DataBuf &data)
: properties_(properties), data_(data)
PreviewImage::PreviewImage(const PreviewProperties& properties, DataBuf data)
: properties_(properties)
{
pData_ = data.pData_;
size_ = data.size_;
data.release();
}
PreviewImage::PreviewImage(const PreviewImage &src)
: properties_(src.properties_), data_(const_cast<DataBuf&>(src.data_))
PreviewImage::~PreviewImage()
{
delete[] pData_;
}
PreviewImage::PreviewImage(const PreviewImage& rhs)
{
properties_ = rhs.properties_;
pData_ = new byte[rhs.size_];
memcpy(pData_, rhs.pData_, rhs.size_);
size_ = rhs.size_;
}
PreviewImage& PreviewImage::operator=(const PreviewImage& rhs)
{
if (this == &rhs) return *this;
if (rhs.size_ > size_) {
delete[] pData_;
pData_ = new byte[rhs.size_];
}
properties_ = rhs.properties_;
memcpy(pData_, rhs.pData_, rhs.size_);
size_ = rhs.size_;
return *this;
}
long PreviewImage::writeFile(const std::string& path) const
{
std::string name = path + extension();
return Exiv2::writeFile(data_, name);
// Todo: Creating a DataBuf here unnecessarily copies the memory
return Exiv2::writeFile(DataBuf(pData_, size_), name);
}
DataBuf &PreviewImage::data()
DataBuf PreviewImage::copy() const
{
return data_;
return DataBuf(pData_, size_);
}
const char* PreviewImage::mimeType() const
std::string PreviewImage::mimeType() const
{
return properties_.mimeType_;
}
const char* PreviewImage::extension() const
std::string PreviewImage::extension() const
{
return properties_.extension_;
}
@ -491,7 +516,7 @@ namespace Exiv2 {
if (buf.size_ == 0) { // direct data
buf = DataBuf(pos->size());
pos->copy(buf.pData_, littleEndian /*does not matter*/);
pos->copy(buf.pData_, invalidByteOrder);
}
buf.pData_[0] = 0xff; // fix Minolta thumbnails with invalid jpeg header
@ -547,23 +572,18 @@ namespace Exiv2 {
}
else {
pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".TileOffsets"));
if (pos != exifData.end()) {
offsetTag_ = "TileOffsets";
sizeTag_ = "TileByteCounts";
offsetCount = pos->value().count();
}
else {
return;
}
if (pos == exifData.end()) return;
offsetTag_ = "TileOffsets";
sizeTag_ = "TileByteCounts";
offsetCount = pos->value().count();
}
pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + '.' + sizeTag_));
if (pos != exifData.end()) {
if (offsetCount != pos->value().count()) return;
for (int i = 0; i < offsetCount; i++)
size_ += pos->value().toLong(i);
if (pos == exifData.end()) return;
if (offsetCount != pos->value().count()) return;
for (int i = 0; i < offsetCount; i++) {
size_ += pos->value().toLong(i);
}
else return;
if (size_ == 0) return;
@ -680,12 +700,12 @@ namespace Exiv2 {
return DataBuf(&blob[0], static_cast<long>(blob.size()));
}
PreviewImageLoader::PreviewImageLoader(const Image& image)
PreviewManager::PreviewManager(const Image& image)
: image_(image)
{
}
PreviewPropertiesList PreviewImageLoader::getPreviewPropertiesList() const
PreviewPropertiesList PreviewManager::getPreviewProperties() const
{
PreviewPropertiesList list;
// go through the loader table and store all successfuly created loaders in the list
@ -699,13 +719,14 @@ namespace Exiv2 {
return list;
}
PreviewImage PreviewImageLoader::getPreviewImage(const PreviewProperties &properties) const
PreviewImage PreviewManager::getPreviewImage(const PreviewProperties &properties) const
{
Loader::AutoPtr loader = Loader::create(properties.id_, image_);
DataBuf buf;
if (loader.get()) {
buf = loader->getData();
}
return PreviewImage(properties, buf);
}
} // namespace Exiv2

View File

@ -20,7 +20,7 @@
*/
/*!
@file preview.hpp
@brief Classes to access preview images embedded in an image.
@brief Classes to access all preview images embedded in an image.
@version $Rev$
@author Vladimir Nadvornik (vn)
<a href="mailto:nadvornik@suse.cz">nadvornik@suse.cz</a>
@ -35,6 +35,9 @@
#include "image.hpp"
#include "basicio.hpp"
#include <string>
#include <vector>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
@ -50,20 +53,15 @@ namespace Exiv2 {
*/
struct EXIV2API PreviewProperties {
//! Preview image mime type.
const char* mimeType_;
std::string mimeType_;
//! Preview image extension.
const char* extension_;
std::string extension_;
//! Preview image size in bytes.
uint32_t size_;
//! Preview image width in pixels or 0 for unknown width.
uint32_t width_;
//! Preview image height in pixels or 0 for unknown height.
uint32_t height_;
//! Identifies type of preview image.
PreviewId id_;
};
@ -75,31 +73,41 @@ namespace Exiv2 {
@brief Class that holds preview image properties and data buffer.
*/
class EXIV2API PreviewImage {
friend class PreviewManager;
public:
//! @name Constructors
//@{
//! Constructor.
PreviewImage(const PreviewProperties& properties, DataBuf& data);
//! Copy constructor
PreviewImage(const PreviewImage& src);
PreviewImage(const PreviewImage& rhs);
//! Destructor.
~PreviewImage();
//@}
//! @name Manipulators
//@{
//! Assignment operator
PreviewImage& operator=(const PreviewImage& rhs);
//@}
//! @name Accessors
//@{
/*!
@brief Return a reference to image data.
@brief Return a copy of the preview image data. The caller owns
this copy and %DataBuf ensures that it will be deleted.
*/
DataBuf& data();
DataBuf copy() const;
/*!
@brief Return a pointer to the image data for read-only access.
*/
const byte* pData() const;
/*!
@brief Write the thumbnail image to a file.
A filename extension is appended to \em path according to the image
type of the thumbnail, so \em path should not include an extension.
type of the preview image, so \em path should not include an extension.
The function will overwrite an existing file of the same name.
@param path File name of the thumbnail without extension.
@param path File name of the preview image without extension.
@return The number of bytes written.
*/
long writeFile(const std::string& path) const;
@ -107,13 +115,12 @@ namespace Exiv2 {
@brief Return the MIME type of the preview image, usually either
\c "image/tiff" or \c "image/jpeg".
*/
const char* mimeType() const;
std::string mimeType() const;
/*!
@brief Return the file extension for the format of the preview image
(".tif" or ".jpg").
*/
const char* extension() const;
std::string extension() const;
/*!
@brief Return the size of the preview image in bytes.
*/
@ -121,35 +128,44 @@ namespace Exiv2 {
//@}
private:
PreviewProperties properties_;
DataBuf data_;
//! Private constructor
EXV_DLLLOCAL PreviewImage(const PreviewProperties& properties, DataBuf data);
PreviewProperties properties_; //!< Preview image properties
byte* pData_; //!< Pointer to the preview image data
uint32_t size_; //!< Size of the preview image data
}; // class PreviewImage
/*!
@brief Class for extracting preview images from image metadata.
*/
class EXIV2API PreviewImageLoader {
class EXIV2API PreviewManager {
public:
//! @name Constructors
//@{
//! Constructor.
PreviewImageLoader(const Image& image);
PreviewManager(const Image& image);
//@}
//! @name Accessors
//@{
/*!
@brief Return list of preview properties.
@brief Return the properties of all preview images in a list
sorted by preview width * height, starting with the smallest
preview image.
*/
PreviewPropertiesList getPreviewPropertiesList() const;
PreviewPropertiesList getPreviewProperties() const;
/*!
@brief Return image data for given properties.
@brief Return the preview image for the given preview properties.
*/
PreviewImage getPreviewImage(const PreviewProperties& properties) const;
//@}
private:
const Image& image_;
}; // class PreviewImageLoader
}; // class PreviewManager
} // namespace Exiv2
#endif // #ifndef PREVIEW_HPP_