Added Image::AutoPtr and related updates

Changed some local buffers to DataBuf
v0.27.3
Andreas Huggel 21 years ago
parent 61171b5857
commit f40fba88bf

@ -3,7 +3,7 @@ Library Features:
+ add ExifData::erase(tag) + add ExifData::erase(tag)
+ Thumbnail support: set (re-calculate) + Thumbnail support: set (re-calculate)
+ operator>> for Value, since we already have read()? + operator>> for Value, since we already have read()?
+ Use auto_ptr where applicable + Use auto_ptr and DataBuf where applicable
+ Use size_t where appropriate + Use size_t where appropriate
+ Support TIFF type ids + Support TIFF type ids
+ Support for broken IFD makernotes (which have corrupted IFD offsets) + Support for broken IFD makernotes (which have corrupted IFD offsets)
@ -13,9 +13,7 @@ Library Features:
+ Write an example using low level IFD classes to print summary Exif info + Write an example using low level IFD classes to print summary Exif info
+ Implement proper error handling + Implement proper error handling
+ Complete support to create Exif data from scratch: + Complete support to create Exif data from scratch:
+ set makernote, write makernote tags
+ set thumbnail, write thumbnail tags + set thumbnail, write thumbnail tags
+ read and write unknown tags
+ Make it possible to force write from metadata (just an optional arg to write?) + Make it possible to force write from metadata (just an optional arg to write?)
+ Get rid of Image::detach and make Image open files on-demand + Get rid of Image::detach and make Image open files on-demand

@ -20,13 +20,13 @@
*/ */
/* /*
File: actions.cpp File: actions.cpp
Version: $Name: $ $Revision: 1.37 $ Version: $Name: $ $Revision: 1.38 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 08-Dec-03, ahu: created History: 08-Dec-03, ahu: created
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.37 $ $RCSfile: actions.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.38 $ $RCSfile: actions.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -559,14 +559,14 @@ namespace Action {
<< ": Failed to open the file\n"; << ": Failed to open the file\n";
return -1; return -1;
} }
Exiv2::Image* pImage = Exiv2::ImageFactory::instance().open(path_); Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::instance().open(path_);
if (!pImage) { if (image.get() == 0) {
std::cerr << path_ std::cerr << path_
<< ": The file contains data of an unknown image type\n"; << ": The file contains data of an unknown image type\n";
return -2; return -2;
} }
int rc = pImage->readMetadata(); int rc = image->readMetadata();
pImage->detach(); image->detach();
if (rc) { if (rc) {
std::cerr << path_ std::cerr << path_
<< ": Could not read metadata\n"; << ": Could not read metadata\n";
@ -575,8 +575,7 @@ namespace Action {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
std::cout << "Jpeg comment: "; std::cout << "Jpeg comment: ";
} }
std::cout << pImage->comment() << "\n"; std::cout << image->comment() << "\n";
delete pImage;
return 0; return 0;
} // Print::printComment } // Print::printComment
@ -968,61 +967,62 @@ namespace {
<< ": Failed to open the file\n"; << ": Failed to open the file\n";
return -1; return -1;
} }
Exiv2::Image* pSource = Exiv2::ImageFactory::instance().open(source); Exiv2::Image::AutoPtr sourceImage
if (!pSource) { = Exiv2::ImageFactory::instance().open(source);
if (sourceImage.get() == 0) {
std::cerr << source std::cerr << source
<< ": The file contains data of an unknown image type\n"; << ": The file contains data of an unknown image type\n";
return -2; return -2;
} }
int rc = pSource->readMetadata(); int rc = sourceImage->readMetadata();
pSource->detach(); sourceImage->detach();
if (rc) { if (rc) {
std::cerr << source std::cerr << source
<< ": Could not read metadata\n"; << ": Could not read metadata\n";
return 1; return 1;
} }
Exiv2::Image* pTarget = Exiv2::ImageFactory::instance().open(target); Exiv2::Image::AutoPtr targetImage
if (!pTarget) { = Exiv2::ImageFactory::instance().open(target);
pTarget = Exiv2::ImageFactory::instance().create(Exiv2::Image::exv, if (targetImage.get() == 0) {
target); targetImage
= Exiv2::ImageFactory::instance().create(Exiv2::Image::exv, target);
} }
if (!pTarget) { if (targetImage.get() == 0) {
std::cerr << target std::cerr << target
<< ": Could not open nor create the file\n"; << ": Could not open nor create the file\n";
return 2; return 2;
} }
if ( Params::instance().target_ & Params::ctExif if ( Params::instance().target_ & Params::ctExif
&& pSource->sizeExifData() > 0) { && sourceImage->sizeExifData() > 0) {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
std::cout << "Writing Exif data from " << source std::cout << "Writing Exif data from " << source
<< " to " << target << "\n"; << " to " << target << "\n";
} }
pTarget->setExifData(pSource->exifData(), pSource->sizeExifData()); targetImage->setExifData(sourceImage->exifData(),
sourceImage->sizeExifData());
} }
if ( Params::instance().target_ & Params::ctIptc if ( Params::instance().target_ & Params::ctIptc
&& pSource->sizeIptcData() > 0) { && sourceImage->sizeIptcData() > 0) {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
std::cout << "Writing Iptc data from " << source std::cout << "Writing Iptc data from " << source
<< " to " << target << "\n"; << " to " << target << "\n";
} }
pTarget->setIptcData(pSource->iptcData(), pSource->sizeIptcData()); targetImage->setIptcData(sourceImage->iptcData(),
sourceImage->sizeIptcData());
} }
if ( Params::instance().target_ & Params::ctComment if ( Params::instance().target_ & Params::ctComment
&& !pSource->comment().empty()) { && !sourceImage->comment().empty()) {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
std::cout << "Writing Jpeg comment from " << source std::cout << "Writing Jpeg comment from " << source
<< " to " << target << "\n"; << " to " << target << "\n";
} }
pTarget->setComment(pSource->comment()); targetImage->setComment(sourceImage->comment());
} }
rc = pTarget->writeMetadata(); rc = targetImage->writeMetadata();
if (rc) { if (rc) {
std::cerr << target << std::cerr << target <<
": Could not write metadata to file, rc = " << rc << "\n"; ": Could not write metadata to file, rc = " << rc << "\n";
} }
delete pSource;
delete pTarget;
return rc; return rc;
} // metacopy } // metacopy
} }

@ -20,14 +20,14 @@
*/ */
/* /*
File: exif.cpp File: exif.cpp
Version: $Name: $ $Revision: 1.63 $ Version: $Name: $ $Revision: 1.64 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 26-Jan-04, ahu: created History: 26-Jan-04, ahu: created
11-Feb-04, ahu: isolated as a component 11-Feb-04, ahu: isolated as a component
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.63 $ $RCSfile: exif.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.64 $ $RCSfile: exif.cpp,v $");
// Define DEBUG_MAKERNOTE to output debug information to std::cerr // Define DEBUG_MAKERNOTE to output debug information to std::cerr
#undef DEBUG_MAKERNOTE #undef DEBUG_MAKERNOTE
@ -160,19 +160,19 @@ namespace Exiv2 {
TiffThumbnail& TiffThumbnail::operator=(const TiffThumbnail& rhs) TiffThumbnail& TiffThumbnail::operator=(const TiffThumbnail& rhs)
{ {
byte* pNewImage = 0; DataBuf newImage;
if (rhs.pImage_ && rhs.size_ > 0) { if (rhs.pImage_ && rhs.size_ > 0) {
pNewImage = new byte[rhs.size_]; newImage.alloc(rhs.size_);
memcpy(pNewImage, rhs.pImage_, rhs.size_); memcpy(newImage.pData_, rhs.pImage_, rhs.size_);
tiffHeader_.read(rhs.pImage_); tiffHeader_.read(rhs.pImage_);
ifd_.read(pNewImage + tiffHeader_.offset(), ifd_.read(newImage.pData_ + tiffHeader_.offset(),
rhs.size_ - tiffHeader_.offset(), rhs.size_ - tiffHeader_.offset(),
tiffHeader_.byteOrder(), tiffHeader_.offset()); tiffHeader_.byteOrder(), tiffHeader_.offset());
} }
offset_ = rhs.offset_; offset_ = rhs.offset_;
size_ = rhs.size_; size_ = rhs.size_;
delete[] pImage_; delete[] pImage_;
pImage_ = pNewImage; pImage_ = newImage.release();
return *this; return *this;
} }
@ -385,15 +385,15 @@ namespace Exiv2 {
JpegThumbnail& JpegThumbnail::operator=(const JpegThumbnail& rhs) JpegThumbnail& JpegThumbnail::operator=(const JpegThumbnail& rhs)
{ {
byte* pNewImage = 0; DataBuf newImage;
if (rhs.pImage_ && rhs.size_ > 0) { if (rhs.pImage_ && rhs.size_ > 0) {
pNewImage = new byte[rhs.size_]; newImage.alloc(rhs.size_);
memcpy(pNewImage, rhs.pImage_, rhs.size_); memcpy(newImage.pData_, rhs.pImage_, rhs.size_);
} }
offset_ = rhs.offset_; offset_ = rhs.offset_;
size_ = rhs.size_; size_ = rhs.size_;
delete[] pImage_; delete[] pImage_;
pImage_ = pNewImage; pImage_ = newImage.release();
return *this; return *this;
} }
@ -511,23 +511,23 @@ namespace Exiv2 {
int ExifData::read(const std::string& path) int ExifData::read(const std::string& path)
{ {
if (!fileExists(path, true)) return -1; if (!fileExists(path, true)) return -1;
Image* pImage = ImageFactory::instance().open(path); Image::AutoPtr image = ImageFactory::instance().open(path);
if (pImage) { if (image.get() == 0) {
int rc = pImage->readMetadata(); // We don't know this type of file
return -2;
}
int rc = image->readMetadata();
if (rc == 0) { if (rc == 0) {
if (pImage->sizeExifData() > 0) { if (image->sizeExifData() > 0) {
rc = read(pImage->exifData(), pImage->sizeExifData()); rc = read(image->exifData(), image->sizeExifData());
} }
else { else {
rc = 3; rc = 3;
} }
} }
delete pImage;
return rc; return rc;
} }
// We don't know this type of file
return -2;
}
int ExifData::read(const byte* buf, long len) int ExifData::read(const byte* buf, long len)
{ {
@ -633,16 +633,15 @@ namespace Exiv2 {
int ExifData::erase(const std::string& path) const int ExifData::erase(const std::string& path) const
{ {
if (!fileExists(path, true)) return -1; if (!fileExists(path, true)) return -1;
Image* pImage = ImageFactory::instance().open(path); Image::AutoPtr image = ImageFactory::instance().open(path);
if (pImage == 0) return -2; if (image.get() == 0) return -2;
// Read all metadata then erase only Exif data // Read all metadata then erase only Exif data
int rc = pImage->readMetadata(); int rc = image->readMetadata();
if (rc == 0) { if (rc == 0) {
pImage->clearExifData(); image->clearExifData();
rc = pImage->writeMetadata(); rc = image->writeMetadata();
} }
delete pImage;
return rc; return rc;
} // ExifData::erase } // ExifData::erase
@ -652,20 +651,19 @@ namespace Exiv2 {
if (count() == 0 && !pThumbnail_) return erase(path); if (count() == 0 && !pThumbnail_) return erase(path);
if (!fileExists(path, true)) return -1; if (!fileExists(path, true)) return -1;
Image* pImage = ImageFactory::instance().open(path); Image::AutoPtr image = ImageFactory::instance().open(path);
if (pImage == 0) return -2; if (image.get() == 0) return -2;
DataBuf buf(size()); DataBuf buf(size());
long actualSize = copy(buf.pData_); long actualSize = copy(buf.pData_);
assert(actualSize <= buf.size_); assert(actualSize <= buf.size_);
// Read all metadata to preserve non-Exif data // Read all metadata to preserve non-Exif data
int rc = pImage->readMetadata(); int rc = image->readMetadata();
if (rc == 0) { if (rc == 0) {
pImage->setExifData(buf.pData_, actualSize); image->setExifData(buf.pData_, actualSize);
rc = pImage->writeMetadata(); rc = image->writeMetadata();
} }
delete pImage;
return rc; return rc;
} // ExifData::write } // ExifData::write

@ -20,7 +20,7 @@
*/ */
/* /*
File: image.cpp File: image.cpp
Version: $Name: $ $Revision: 1.26 $ Version: $Name: $ $Revision: 1.27 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
Brad Schick (brad) <schick@robotbattle.com> Brad Schick (brad) <schick@robotbattle.com>
History: 26-Jan-04, ahu: created History: 26-Jan-04, ahu: created
@ -29,7 +29,7 @@
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.26 $ $RCSfile: image.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.27 $ $RCSfile: image.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -71,14 +71,14 @@ namespace Exiv2 {
@brief Create a new ExvImage instance and return a pointer to it. Caller @brief Create a new ExvImage instance and return a pointer to it. Caller
is responsible to delete the object when it is no longer needed. is responsible to delete the object when it is no longer needed.
*/ */
Image* newExvInstance(const std::string& path, FILE* fp); Image::AutoPtr newExvInstance(const std::string& path, FILE* fp);
//! Check if the file ifp is an EXV file. //! Check if the file ifp is an EXV file.
bool isExvType(FILE* ifp, bool advance); bool isExvType(FILE* ifp, bool advance);
/*! /*!
@brief Create a new JpegImage instance and return a pointer to it. Caller @brief Create a new JpegImage instance and return an auto-pointer to it.
is responsible to delete the object when it is no longer needed. Caller owns the returned object.
*/ */
Image* newJpegInstance(const std::string& path, FILE* fp); Image::AutoPtr newJpegInstance(const std::string& path, FILE* fp);
//! Check if the file ifp is a JPEG image. //! Check if the file ifp is a JPEG image.
bool isJpegType(FILE* ifp, bool advance); bool isJpegType(FILE* ifp, bool advance);
@ -125,31 +125,33 @@ namespace Exiv2 {
return type; return type;
} // ImageFactory::getType } // ImageFactory::getType
Image* ImageFactory::open(const std::string& path) const Image::AutoPtr ImageFactory::open(const std::string& path) const
{ {
Image::AutoPtr image;
FILE* ifp = fopen(path.c_str(), "rb"); FILE* ifp = fopen(path.c_str(), "rb");
if (!ifp) return 0; if (!ifp) return image;
Image* pImage = 0;
Registry::const_iterator b = registry_.begin(); Registry::const_iterator b = registry_.begin();
Registry::const_iterator e = registry_.end(); Registry::const_iterator e = registry_.end();
for (Registry::const_iterator i = b; i != e; ++i) for (Registry::const_iterator i = b; i != e; ++i)
{ {
if (i->second.isThisType(ifp, false)) { if (i->second.isThisType(ifp, false)) {
pImage = i->second.newInstance(path, ifp); image = Image::AutoPtr(i->second.newInstance(path, ifp));
break; break;
} }
} }
return pImage; return image;
} // ImageFactory::open } // ImageFactory::open
Image* ImageFactory::create(Image::Type type, const std::string& path) const Image::AutoPtr ImageFactory::create(Image::Type type,
const std::string& path) const
{ {
Registry::const_iterator i = registry_.find(type); Registry::const_iterator i = registry_.find(type);
if (i != registry_.end()) { if (i != registry_.end()) {
return i->second.newInstance(path, 0); return i->second.newInstance(path, 0);
} }
return 0; Image::AutoPtr p;
return p;
} // ImageFactory::create } // ImageFactory::create
@ -709,20 +711,17 @@ namespace Exiv2 {
return isJpegType(ifp, advance); return isJpegType(ifp, advance);
} }
Image* newJpegInstance(const std::string& path, FILE* fp) Image::AutoPtr newJpegInstance(const std::string& path, FILE* fp)
{ {
Image* pImage = 0; Image::AutoPtr image;
if (fp == 0) { if (fp == 0) {
pImage = new JpegImage(path, true); image = Image::AutoPtr(new JpegImage(path, true));
if (!pImage->good()) { if (!image->good()) delete image.release();
delete pImage;
pImage = 0;
}
} }
else { else {
pImage = new JpegImage(path, fp); image = Image::AutoPtr(new JpegImage(path, fp));
} }
return pImage; return image;
} }
bool isJpegType(FILE* ifp, bool advance) bool isJpegType(FILE* ifp, bool advance)
@ -765,20 +764,17 @@ namespace Exiv2 {
return isExvType(ifp, advance); return isExvType(ifp, advance);
} }
Image* newExvInstance(const std::string& path, FILE* fp) Image::AutoPtr newExvInstance(const std::string& path, FILE* fp)
{ {
Image* pImage = 0; Image::AutoPtr image;
if (fp == 0) { if (fp == 0) {
pImage = new ExvImage(path, true); image = Image::AutoPtr(new ExvImage(path, true));
if (!pImage->good()) { if (!image->good()) delete image.release();
delete pImage;
pImage = 0;
}
} }
else { else {
pImage = new ExvImage(path, fp); image = Image::AutoPtr(new ExvImage(path, fp));
} }
return pImage; return image;
} }
bool isExvType(FILE* ifp, bool advance) bool isExvType(FILE* ifp, bool advance)

@ -21,7 +21,7 @@
/*! /*!
@file image.hpp @file image.hpp
@brief Class JpegImage to access JPEG images @brief Class JpegImage to access JPEG images
@version $Name: $ $Revision: 1.20 $ @version $Name: $ $Revision: 1.21 $
@author Andreas Huggel (ahu) @author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@author Brad Schick (brad) @author Brad Schick (brad)
@ -40,19 +40,12 @@
// + standard includes // + standard includes
#include <string> #include <string>
#include <map> #include <map>
#include <memory>
// ***************************************************************************** // *****************************************************************************
// namespace extensions // namespace extensions
namespace Exiv2 { namespace Exiv2 {
//! Type for function pointer that creates new Image instances
typedef class Image* (*NewInstanceFct)(const std::string& path, FILE* ifp);
//! Type for function pointer that checks image types
typedef bool (*IsThisTypeFct)(FILE* ifp, bool advance);
// ***************************************************************************** // *****************************************************************************
// class definitions // class definitions
@ -61,6 +54,9 @@ namespace Exiv2 {
*/ */
class Image { class Image {
public: public:
//! Image auto_ptr type
typedef std::auto_ptr<Image> AutoPtr;
//! Supported image formats //! Supported image formats
enum Type { none, jpeg, exv }; enum Type { none, jpeg, exv };
@ -181,6 +177,12 @@ namespace Exiv2 {
}; // class Image }; // class Image
//! Type for function pointer that creates new Image instances
typedef Image::AutoPtr (*NewInstanceFct)(const std::string& path,
FILE* ifp);
//! Type for function pointer that checks image types
typedef bool (*IsThisTypeFct)(FILE* ifp, bool advance);
/*! /*!
@brief Image factory. @brief Image factory.
@ -218,21 +220,19 @@ namespace Exiv2 {
@param path %Image file. The contents of the file are tested to @param path %Image file. The contents of the file are tested to
determine the image type to open. File extension is ignored. determine the image type to open. File extension is ignored.
@return A pointer that owns an %Image of the type derived from the @return A pointer that owns an %Image of the type derived from the
file. Caller must delete the returned object. If no image type file. If no image type could be determined, the pointer is 0.
could be determined, the pointer is 0.
*/ */
Image* open(const std::string& path) const; Image::AutoPtr open(const std::string& path) const;
/*! /*!
@brief Create an %Image of the requested type by creating a new @brief Create an %Image of the requested type by creating a new
file. If the file already exists, it will be overwritten. file. If the file already exists, it will be overwritten.
@param type Type of the image to be created. @param type Type of the image to be created.
@param path %Image file. The contents of the file are tested to @param path %Image file. The contents of the file are tested to
determine the image type to open. File extension is ignored. determine the image type to open. File extension is ignored.
@return A pointer that owns an %Image of the requested type. Caller @return An auto-pointer that owns an %Image of the requested type.
must delete the returned object. If the image type is not If the image type is not supported, the pointer is 0.
supported, the pointer is 0.
*/ */
Image* create(Image::Type type, const std::string& path) const; Image::AutoPtr create(Image::Type type, const std::string& path) const;
/*! /*!
@brief Returns the image type of the provided file. @brief Returns the image type of the provided file.
@param path %Image file. The contents of the file are tested to @param path %Image file. The contents of the file are tested to
@ -481,7 +481,7 @@ namespace Exiv2 {
@brief Helper class to access JPEG images @brief Helper class to access JPEG images
*/ */
class JpegImage : public JpegBase { class JpegImage : public JpegBase {
friend Image* newJpegInstance(const std::string& path, FILE* fp); friend Image::AutoPtr newJpegInstance(const std::string& path, FILE* fp);
friend bool isJpegType(FILE* ifp, bool advance); friend bool isJpegType(FILE* ifp, bool advance);
public: public:
//! @name Creators //! @name Creators
@ -550,7 +550,7 @@ namespace Exiv2 {
//! Helper class to access %Exiv2 files //! Helper class to access %Exiv2 files
class ExvImage : public JpegBase { class ExvImage : public JpegBase {
friend Image* newExvInstance(const std::string& path, FILE* fp); friend Image::AutoPtr newExvInstance(const std::string& path, FILE* fp);
friend bool isExvType(FILE* ifp, bool advance); friend bool isExvType(FILE* ifp, bool advance);
public: public:
//! @name Creators //! @name Creators

@ -20,13 +20,13 @@
*/ */
/* /*
File: iptc.cpp File: iptc.cpp
Version: $Name: $ $Revision: 1.6 $ Version: $Name: $ $Revision: 1.7 $
Author(s): Brad Schick (brad) <schick@robotbattle.com> Author(s): Brad Schick (brad) <schick@robotbattle.com>
History: 31-July-04, brad: created History: 31-July-04, brad: created
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.6 $ $RCSfile: iptc.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.7 $ $RCSfile: iptc.cpp,v $");
// Define DEBUG_MAKERNOTE to output debug information to std::cerr // Define DEBUG_MAKERNOTE to output debug information to std::cerr
#undef DEBUG_MAKERNOTE #undef DEBUG_MAKERNOTE
@ -114,23 +114,23 @@ namespace Exiv2 {
int IptcData::read(const std::string& path) int IptcData::read(const std::string& path)
{ {
if (!fileExists(path, true)) return -1; if (!fileExists(path, true)) return -1;
Image* pImage = ImageFactory::instance().open(path); Image::AutoPtr image = ImageFactory::instance().open(path);
if (pImage) { if (image.get() == 0) {
int rc = pImage->readMetadata(); // We don't know this type of file
return -2;
}
int rc = image->readMetadata();
if (rc == 0) { if (rc == 0) {
if (pImage->sizeIptcData() > 0) { if (image->sizeIptcData() > 0) {
rc = read(pImage->iptcData(), pImage->sizeIptcData()); rc = read(image->iptcData(), image->sizeIptcData());
} }
else { else {
rc = 3; rc = 3;
} }
} }
delete pImage;
return rc; return rc;
} }
// We don't know this type of file
return -2;
}
int IptcData::read(const byte* buf, long len) int IptcData::read(const byte* buf, long len)
{ {
@ -204,16 +204,15 @@ namespace Exiv2 {
int IptcData::erase(const std::string& path) const int IptcData::erase(const std::string& path) const
{ {
if (!fileExists(path, true)) return -1; if (!fileExists(path, true)) return -1;
Image* pImage = ImageFactory::instance().open(path); Image::AutoPtr image = ImageFactory::instance().open(path);
if (pImage == 0) return -2; if (image.get() == 0) return -2;
// Read all metadata then erase only Iptc data // Read all metadata then erase only Iptc data
int rc = pImage->readMetadata(); int rc = image->readMetadata();
if (rc == 0) { if (rc == 0) {
pImage->clearIptcData(); image->clearIptcData();
rc = pImage->writeMetadata(); rc = image->writeMetadata();
} }
delete pImage;
return rc; return rc;
} // IptcData::erase } // IptcData::erase
@ -223,18 +222,17 @@ namespace Exiv2 {
if (count() == 0) return erase(path); if (count() == 0) return erase(path);
if (!fileExists(path, true)) return -1; if (!fileExists(path, true)) return -1;
Image* pImage = ImageFactory::instance().open(path); Image::AutoPtr image = ImageFactory::instance().open(path);
if (pImage == 0) return -2; if (image.get() == 0) return -2;
updateBuffer(); updateBuffer();
// Read all metadata to preserve non-Iptc data // Read all metadata to preserve non-Iptc data
int rc = pImage->readMetadata(); int rc = image->readMetadata();
if (rc == 0) { if (rc == 0) {
pImage->setIptcData(pData_, size_); image->setIptcData(pData_, size_);
rc = pImage->writeMetadata(); rc = image->writeMetadata();
} }
delete pImage;
return rc; return rc;
} // IptcData::write } // IptcData::write

@ -22,7 +22,7 @@
Abstract : Tester application for image file handling Abstract : Tester application for image file handling
File : metacopy.cpp File : metacopy.cpp
Version : $Name: $ $Revision: 1.1 $ Version : $Name: $ $Revision: 1.2 $
Author(s): Brad Schick (brad) <schick@robotbattle.com> Author(s): Brad Schick (brad) <schick@robotbattle.com>
History : 13-Jul-04, brad: created History : 13-Jul-04, brad: created
*/ */
@ -50,8 +50,9 @@ try {
return 2; return 2;
} }
Exiv2::Image* readImg = Exiv2::ImageFactory::instance().open(params.read_); Exiv2::Image::AutoPtr readImg
if (!readImg) { = Exiv2::ImageFactory::instance().open(params.read_);
if (readImg.get() == 0) {
std::cerr << params.progname() << std::cerr << params.progname() <<
": Could not read file (" << params.read_ << ")\n"; ": Could not read file (" << params.read_ << ")\n";
return 4; return 4;
@ -63,8 +64,9 @@ try {
} }
readImg->detach(); readImg->detach();
Exiv2::Image* writeImg = Exiv2::ImageFactory::instance().open(params.write_); Exiv2::Image::AutoPtr writeImg
if (!writeImg) { = Exiv2::ImageFactory::instance().open(params.write_);
if (writeImg.get() == 0) {
std::cerr << params.progname() << std::cerr << params.progname() <<
": Could not read file (" << params.write_ << ")\n"; ": Could not read file (" << params.write_ << ")\n";
return 6; return 6;
@ -93,8 +95,6 @@ try {
return 8; return 8;
} }
delete readImg;
delete writeImg;
return 0; return 0;
} }
catch (Exiv2::Error& e) { catch (Exiv2::Error& e) {

@ -20,14 +20,14 @@
*/ */
/* /*
File: types.cpp File: types.cpp
Version: $Name: $ $Revision: 1.13 $ Version: $Name: $ $Revision: 1.14 $
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net> Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
History: 26-Jan-04, ahu: created History: 26-Jan-04, ahu: created
11-Feb-04, ahu: isolated as a component 11-Feb-04, ahu: isolated as a component
*/ */
// ***************************************************************************** // *****************************************************************************
#include "rcsid.hpp" #include "rcsid.hpp"
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.13 $ $RCSfile: types.cpp,v $"); EXIV2_RCSID("@(#) $Name: $ $Revision: 1.14 $ $RCSfile: types.cpp,v $");
// ***************************************************************************** // *****************************************************************************
// included header files // included header files
@ -77,6 +77,23 @@ namespace Exiv2 {
return typeInfoTable_[ typeId < lastTypeId ? typeId : 0 ].size_; return typeInfoTable_[ typeId < lastTypeId ? typeId : 0 ].size_;
} }
void DataBuf::alloc(long size)
{
if (size > size_) {
delete[] pData_;
size_ = size;
pData_ = new byte[size];
}
}
byte* DataBuf::release()
{
byte* p = pData_;
pData_ = 0;
size_ = 0;
return p;
}
// ************************************************************************* // *************************************************************************
// free functions // free functions

@ -21,7 +21,7 @@
/*! /*!
@file types.hpp @file types.hpp
@brief Type definitions for %Exiv2 and related functionality @brief Type definitions for %Exiv2 and related functionality
@version $Name: $ $Revision: 1.21 $ @version $Name: $ $Revision: 1.22 $
@author Andreas Huggel (ahu) @author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created<BR> @date 09-Jan-04, ahu: created<BR>
@ -123,7 +123,7 @@ namespace Exiv2 {
care of memory allocation and deletion. Its primary use is meant to care of memory allocation and deletion. Its primary use is meant to
be as a stack variable in functions that need a temporary data be as a stack variable in functions that need a temporary data
buffer. Todo: this should be some sort of smart pointer, buffer. Todo: this should be some sort of smart pointer,
essentially an std:auto_ptr for a character array. But it isn't. essentially an std::auto_ptr for a character array. But it isn't...
*/ */
class DataBuf { class DataBuf {
// Not implemented // Not implemented
@ -139,8 +139,12 @@ namespace Exiv2 {
//! Destructor, deletes the allocated buffer //! Destructor, deletes the allocated buffer
~DataBuf() { delete[] pData_; } ~DataBuf() { delete[] pData_; }
//! Allocate a data buffer of the given size //! Allocate a data buffer of the given size
void alloc(long size) void alloc(long size);
{ if( size > size_ ){delete[] pData_; size_ = size; pData_ = new byte[size];} } /*!
@brief Release ownership of the buffer to the caller. Returns pointer
value, resets pData_ and size_ to 0.
*/
byte* release();
//! The current size of the buffer //! The current size of the buffer
long size_; long size_;
//! Pointer to the buffer, 0 if none has been allocated //! Pointer to the buffer, 0 if none has been allocated

Loading…
Cancel
Save