From f40fba88bf70516b4a75a7355631c021d1142ec3 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Tue, 12 Oct 2004 16:23:08 +0000 Subject: [PATCH] Added Image::AutoPtr and related updates Changed some local buffers to DataBuf --- src/Todo | 4 +-- src/actions.cpp | 54 ++++++++++++++++++------------------ src/exif.cpp | 72 +++++++++++++++++++++++------------------------- src/image.cpp | 58 ++++++++++++++++++-------------------- src/image.hpp | 38 ++++++++++++------------- src/iptc.cpp | 58 +++++++++++++++++++------------------- src/metacopy.cpp | 14 +++++----- src/types.cpp | 21 ++++++++++++-- src/types.hpp | 12 +++++--- 9 files changed, 171 insertions(+), 160 deletions(-) diff --git a/src/Todo b/src/Todo index 5183d802..619ed920 100644 --- a/src/Todo +++ b/src/Todo @@ -3,7 +3,7 @@ Library Features: + add ExifData::erase(tag) + Thumbnail support: set (re-calculate) + 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 + Support TIFF type ids + 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 + Implement proper error handling + Complete support to create Exif data from scratch: - + set makernote, write makernote 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?) + Get rid of Image::detach and make Image open files on-demand diff --git a/src/actions.cpp b/src/actions.cpp index 99dac679..498928b7 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -20,13 +20,13 @@ */ /* File: actions.cpp - Version: $Name: $ $Revision: 1.37 $ + Version: $Name: $ $Revision: 1.38 $ Author(s): Andreas Huggel (ahu) History: 08-Dec-03, ahu: created */ // ***************************************************************************** #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 @@ -559,14 +559,14 @@ namespace Action { << ": Failed to open the file\n"; return -1; } - Exiv2::Image* pImage = Exiv2::ImageFactory::instance().open(path_); - if (!pImage) { + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::instance().open(path_); + if (image.get() == 0) { std::cerr << path_ << ": The file contains data of an unknown image type\n"; return -2; } - int rc = pImage->readMetadata(); - pImage->detach(); + int rc = image->readMetadata(); + image->detach(); if (rc) { std::cerr << path_ << ": Could not read metadata\n"; @@ -575,8 +575,7 @@ namespace Action { if (Params::instance().verbose_) { std::cout << "Jpeg comment: "; } - std::cout << pImage->comment() << "\n"; - delete pImage; + std::cout << image->comment() << "\n"; return 0; } // Print::printComment @@ -968,61 +967,62 @@ namespace { << ": Failed to open the file\n"; return -1; } - Exiv2::Image* pSource = Exiv2::ImageFactory::instance().open(source); - if (!pSource) { + Exiv2::Image::AutoPtr sourceImage + = Exiv2::ImageFactory::instance().open(source); + if (sourceImage.get() == 0) { std::cerr << source << ": The file contains data of an unknown image type\n"; return -2; } - int rc = pSource->readMetadata(); - pSource->detach(); + int rc = sourceImage->readMetadata(); + sourceImage->detach(); if (rc) { std::cerr << source << ": Could not read metadata\n"; return 1; } - Exiv2::Image* pTarget = Exiv2::ImageFactory::instance().open(target); - if (!pTarget) { - pTarget = Exiv2::ImageFactory::instance().create(Exiv2::Image::exv, - target); + Exiv2::Image::AutoPtr targetImage + = Exiv2::ImageFactory::instance().open(target); + if (targetImage.get() == 0) { + targetImage + = Exiv2::ImageFactory::instance().create(Exiv2::Image::exv, target); } - if (!pTarget) { + if (targetImage.get() == 0) { std::cerr << target << ": Could not open nor create the file\n"; return 2; } if ( Params::instance().target_ & Params::ctExif - && pSource->sizeExifData() > 0) { + && sourceImage->sizeExifData() > 0) { if (Params::instance().verbose_) { std::cout << "Writing Exif data from " << source << " to " << target << "\n"; } - pTarget->setExifData(pSource->exifData(), pSource->sizeExifData()); + targetImage->setExifData(sourceImage->exifData(), + sourceImage->sizeExifData()); } if ( Params::instance().target_ & Params::ctIptc - && pSource->sizeIptcData() > 0) { + && sourceImage->sizeIptcData() > 0) { if (Params::instance().verbose_) { std::cout << "Writing Iptc data from " << source << " to " << target << "\n"; } - pTarget->setIptcData(pSource->iptcData(), pSource->sizeIptcData()); + targetImage->setIptcData(sourceImage->iptcData(), + sourceImage->sizeIptcData()); } if ( Params::instance().target_ & Params::ctComment - && !pSource->comment().empty()) { + && !sourceImage->comment().empty()) { if (Params::instance().verbose_) { std::cout << "Writing Jpeg comment from " << source << " to " << target << "\n"; } - pTarget->setComment(pSource->comment()); + targetImage->setComment(sourceImage->comment()); } - rc = pTarget->writeMetadata(); + rc = targetImage->writeMetadata(); if (rc) { std::cerr << target << ": Could not write metadata to file, rc = " << rc << "\n"; } - delete pSource; - delete pTarget; return rc; - } // metacopy } diff --git a/src/exif.cpp b/src/exif.cpp index 1e0f41e2..5ce5bcd0 100644 --- a/src/exif.cpp +++ b/src/exif.cpp @@ -20,14 +20,14 @@ */ /* File: exif.cpp - Version: $Name: $ $Revision: 1.63 $ + Version: $Name: $ $Revision: 1.64 $ Author(s): Andreas Huggel (ahu) History: 26-Jan-04, ahu: created 11-Feb-04, ahu: isolated as a component */ // ***************************************************************************** #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 #undef DEBUG_MAKERNOTE @@ -160,19 +160,19 @@ namespace Exiv2 { TiffThumbnail& TiffThumbnail::operator=(const TiffThumbnail& rhs) { - byte* pNewImage = 0; + DataBuf newImage; if (rhs.pImage_ && rhs.size_ > 0) { - pNewImage = new byte[rhs.size_]; - memcpy(pNewImage, rhs.pImage_, rhs.size_); + newImage.alloc(rhs.size_); + memcpy(newImage.pData_, rhs.pImage_, rhs.size_); tiffHeader_.read(rhs.pImage_); - ifd_.read(pNewImage + tiffHeader_.offset(), + ifd_.read(newImage.pData_ + tiffHeader_.offset(), rhs.size_ - tiffHeader_.offset(), tiffHeader_.byteOrder(), tiffHeader_.offset()); } offset_ = rhs.offset_; size_ = rhs.size_; delete[] pImage_; - pImage_ = pNewImage; + pImage_ = newImage.release(); return *this; } @@ -385,15 +385,15 @@ namespace Exiv2 { JpegThumbnail& JpegThumbnail::operator=(const JpegThumbnail& rhs) { - byte* pNewImage = 0; + DataBuf newImage; if (rhs.pImage_ && rhs.size_ > 0) { - pNewImage = new byte[rhs.size_]; - memcpy(pNewImage, rhs.pImage_, rhs.size_); + newImage.alloc(rhs.size_); + memcpy(newImage.pData_, rhs.pImage_, rhs.size_); } offset_ = rhs.offset_; size_ = rhs.size_; delete[] pImage_; - pImage_ = pNewImage; + pImage_ = newImage.release(); return *this; } @@ -511,22 +511,22 @@ namespace Exiv2 { int ExifData::read(const std::string& path) { if (!fileExists(path, true)) return -1; - Image* pImage = ImageFactory::instance().open(path); - if (pImage) { - int rc = pImage->readMetadata(); - if (rc == 0) { - if (pImage->sizeExifData() > 0) { - rc = read(pImage->exifData(), pImage->sizeExifData()); - } - else { - rc = 3; - } + Image::AutoPtr image = ImageFactory::instance().open(path); + if (image.get() == 0) { + // We don't know this type of file + return -2; + } + + int rc = image->readMetadata(); + if (rc == 0) { + if (image->sizeExifData() > 0) { + rc = read(image->exifData(), image->sizeExifData()); + } + else { + rc = 3; } - delete pImage; - return rc; } - // We don't know this type of file - return -2; + return rc; } int ExifData::read(const byte* buf, long len) @@ -633,16 +633,15 @@ namespace Exiv2 { int ExifData::erase(const std::string& path) const { if (!fileExists(path, true)) return -1; - Image* pImage = ImageFactory::instance().open(path); - if (pImage == 0) return -2; + Image::AutoPtr image = ImageFactory::instance().open(path); + if (image.get() == 0) return -2; // Read all metadata then erase only Exif data - int rc = pImage->readMetadata(); + int rc = image->readMetadata(); if (rc == 0) { - pImage->clearExifData(); - rc = pImage->writeMetadata(); + image->clearExifData(); + rc = image->writeMetadata(); } - delete pImage; return rc; } // ExifData::erase @@ -652,20 +651,19 @@ namespace Exiv2 { if (count() == 0 && !pThumbnail_) return erase(path); if (!fileExists(path, true)) return -1; - Image* pImage = ImageFactory::instance().open(path); - if (pImage == 0) return -2; + Image::AutoPtr image = ImageFactory::instance().open(path); + if (image.get() == 0) return -2; DataBuf buf(size()); long actualSize = copy(buf.pData_); assert(actualSize <= buf.size_); // Read all metadata to preserve non-Exif data - int rc = pImage->readMetadata(); + int rc = image->readMetadata(); if (rc == 0) { - pImage->setExifData(buf.pData_, actualSize); - rc = pImage->writeMetadata(); + image->setExifData(buf.pData_, actualSize); + rc = image->writeMetadata(); } - delete pImage; return rc; } // ExifData::write diff --git a/src/image.cpp b/src/image.cpp index d5739c87..979f580a 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -20,7 +20,7 @@ */ /* File: image.cpp - Version: $Name: $ $Revision: 1.26 $ + Version: $Name: $ $Revision: 1.27 $ Author(s): Andreas Huggel (ahu) Brad Schick (brad) History: 26-Jan-04, ahu: created @@ -29,7 +29,7 @@ */ // ***************************************************************************** #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 @@ -71,14 +71,14 @@ namespace Exiv2 { @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. */ - 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. bool isExvType(FILE* ifp, bool advance); /*! - @brief Create a new JpegImage instance and return a pointer to it. Caller - is responsible to delete the object when it is no longer needed. + @brief Create a new JpegImage instance and return an auto-pointer to it. + 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. bool isJpegType(FILE* ifp, bool advance); @@ -125,31 +125,33 @@ namespace Exiv2 { return type; } // 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"); - if (!ifp) return 0; + if (!ifp) return image; - Image* pImage = 0; Registry::const_iterator b = registry_.begin(); Registry::const_iterator e = registry_.end(); for (Registry::const_iterator i = b; i != e; ++i) { if (i->second.isThisType(ifp, false)) { - pImage = i->second.newInstance(path, ifp); + image = Image::AutoPtr(i->second.newInstance(path, ifp)); break; } } - return pImage; + return image; } // 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); if (i != registry_.end()) { return i->second.newInstance(path, 0); } - return 0; + Image::AutoPtr p; + return p; } // ImageFactory::create @@ -709,20 +711,17 @@ namespace Exiv2 { 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) { - pImage = new JpegImage(path, true); - if (!pImage->good()) { - delete pImage; - pImage = 0; - } + image = Image::AutoPtr(new JpegImage(path, true)); + if (!image->good()) delete image.release(); } else { - pImage = new JpegImage(path, fp); + image = Image::AutoPtr(new JpegImage(path, fp)); } - return pImage; + return image; } bool isJpegType(FILE* ifp, bool advance) @@ -765,20 +764,17 @@ namespace Exiv2 { 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) { - pImage = new ExvImage(path, true); - if (!pImage->good()) { - delete pImage; - pImage = 0; - } + image = Image::AutoPtr(new ExvImage(path, true)); + if (!image->good()) delete image.release(); } else { - pImage = new ExvImage(path, fp); + image = Image::AutoPtr(new ExvImage(path, fp)); } - return pImage; + return image; } bool isExvType(FILE* ifp, bool advance) diff --git a/src/image.hpp b/src/image.hpp index 1eeb19f2..06f81698 100644 --- a/src/image.hpp +++ b/src/image.hpp @@ -21,7 +21,7 @@ /*! @file image.hpp @brief Class JpegImage to access JPEG images - @version $Name: $ $Revision: 1.20 $ + @version $Name: $ $Revision: 1.21 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @author Brad Schick (brad) @@ -40,19 +40,12 @@ // + standard includes #include #include - +#include // ***************************************************************************** // namespace extensions 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 @@ -61,6 +54,9 @@ namespace Exiv2 { */ class Image { public: + //! Image auto_ptr type + typedef std::auto_ptr AutoPtr; + //! Supported image formats enum Type { none, jpeg, exv }; @@ -181,6 +177,12 @@ namespace Exiv2 { }; // 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. @@ -218,21 +220,19 @@ namespace Exiv2 { @param path %Image file. The contents of the file are tested to determine the image type to open. File extension is ignored. @return A pointer that owns an %Image of the type derived from the - file. Caller must delete the returned object. If no image type - could be determined, the pointer is 0. + file. If no image type 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 file. If the file already exists, it will be overwritten. @param type Type of the image to be created. @param path %Image file. The contents of the file are tested to determine the image type to open. File extension is ignored. - @return A pointer that owns an %Image of the requested type. Caller - must delete the returned object. If the image type is not - supported, the pointer is 0. + @return An auto-pointer that owns an %Image of the requested type. + If the image type is not 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. @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 */ 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); public: //! @name Creators @@ -550,7 +550,7 @@ namespace Exiv2 { //! Helper class to access %Exiv2 files 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); public: //! @name Creators diff --git a/src/iptc.cpp b/src/iptc.cpp index e68a0c91..e17801d6 100644 --- a/src/iptc.cpp +++ b/src/iptc.cpp @@ -20,13 +20,13 @@ */ /* File: iptc.cpp - Version: $Name: $ $Revision: 1.6 $ + Version: $Name: $ $Revision: 1.7 $ Author(s): Brad Schick (brad) History: 31-July-04, brad: created */ // ***************************************************************************** #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 #undef DEBUG_MAKERNOTE @@ -114,22 +114,22 @@ namespace Exiv2 { int IptcData::read(const std::string& path) { if (!fileExists(path, true)) return -1; - Image* pImage = ImageFactory::instance().open(path); - if (pImage) { - int rc = pImage->readMetadata(); - if (rc == 0) { - if (pImage->sizeIptcData() > 0) { - rc = read(pImage->iptcData(), pImage->sizeIptcData()); - } - else { - rc = 3; - } + Image::AutoPtr image = ImageFactory::instance().open(path); + if (image.get() == 0) { + // We don't know this type of file + return -2; + } + + int rc = image->readMetadata(); + if (rc == 0) { + if (image->sizeIptcData() > 0) { + rc = read(image->iptcData(), image->sizeIptcData()); + } + else { + rc = 3; } - delete pImage; - return rc; } - // We don't know this type of file - return -2; + return rc; } int IptcData::read(const byte* buf, long len) @@ -204,16 +204,15 @@ namespace Exiv2 { int IptcData::erase(const std::string& path) const { if (!fileExists(path, true)) return -1; - Image* pImage = ImageFactory::instance().open(path); - if (pImage == 0) return -2; + Image::AutoPtr image = ImageFactory::instance().open(path); + if (image.get() == 0) return -2; // Read all metadata then erase only Iptc data - int rc = pImage->readMetadata(); - if( rc == 0 ) { - pImage->clearIptcData(); - rc = pImage->writeMetadata(); + int rc = image->readMetadata(); + if (rc == 0) { + image->clearIptcData(); + rc = image->writeMetadata(); } - delete pImage; return rc; } // IptcData::erase @@ -223,18 +222,17 @@ namespace Exiv2 { if (count() == 0) return erase(path); if (!fileExists(path, true)) return -1; - Image* pImage = ImageFactory::instance().open(path); - if (pImage == 0) return -2; + Image::AutoPtr image = ImageFactory::instance().open(path); + if (image.get() == 0) return -2; updateBuffer(); // Read all metadata to preserve non-Iptc data - int rc = pImage->readMetadata(); - if( rc == 0 ) { - pImage->setIptcData(pData_, size_); - rc = pImage->writeMetadata(); + int rc = image->readMetadata(); + if (rc == 0) { + image->setIptcData(pData_, size_); + rc = image->writeMetadata(); } - delete pImage; return rc; } // IptcData::write diff --git a/src/metacopy.cpp b/src/metacopy.cpp index e5b23d93..595b4320 100644 --- a/src/metacopy.cpp +++ b/src/metacopy.cpp @@ -22,7 +22,7 @@ Abstract : Tester application for image file handling File : metacopy.cpp - Version : $Name: $ $Revision: 1.1 $ + Version : $Name: $ $Revision: 1.2 $ Author(s): Brad Schick (brad) History : 13-Jul-04, brad: created */ @@ -50,8 +50,9 @@ try { return 2; } - Exiv2::Image* readImg = Exiv2::ImageFactory::instance().open(params.read_); - if (!readImg) { + Exiv2::Image::AutoPtr readImg + = Exiv2::ImageFactory::instance().open(params.read_); + if (readImg.get() == 0) { std::cerr << params.progname() << ": Could not read file (" << params.read_ << ")\n"; return 4; @@ -63,8 +64,9 @@ try { } readImg->detach(); - Exiv2::Image* writeImg = Exiv2::ImageFactory::instance().open(params.write_); - if (!writeImg) { + Exiv2::Image::AutoPtr writeImg + = Exiv2::ImageFactory::instance().open(params.write_); + if (writeImg.get() == 0) { std::cerr << params.progname() << ": Could not read file (" << params.write_ << ")\n"; return 6; @@ -93,8 +95,6 @@ try { return 8; } - delete readImg; - delete writeImg; return 0; } catch (Exiv2::Error& e) { diff --git a/src/types.cpp b/src/types.cpp index 1845be66..cd4011bf 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -20,14 +20,14 @@ */ /* File: types.cpp - Version: $Name: $ $Revision: 1.13 $ + Version: $Name: $ $Revision: 1.14 $ Author(s): Andreas Huggel (ahu) History: 26-Jan-04, ahu: created 11-Feb-04, ahu: isolated as a component */ // ***************************************************************************** #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 @@ -76,6 +76,23 @@ namespace Exiv2 { { 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 diff --git a/src/types.hpp b/src/types.hpp index b1469f5f..6e8065fd 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -21,7 +21,7 @@ /*! @file types.hpp @brief Type definitions for %Exiv2 and related functionality - @version $Name: $ $Revision: 1.21 $ + @version $Name: $ $Revision: 1.22 $ @author Andreas Huggel (ahu) ahuggel@gmx.net @date 09-Jan-04, ahu: created
@@ -123,7 +123,7 @@ namespace Exiv2 { care of memory allocation and deletion. Its primary use is meant to be as a stack variable in functions that need a temporary data 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 { // Not implemented @@ -139,8 +139,12 @@ namespace Exiv2 { //! Destructor, deletes the allocated buffer ~DataBuf() { delete[] pData_; } //! Allocate a data buffer of the given size - void alloc(long size) - { if( size > size_ ){delete[] pData_; size_ = size; pData_ = new byte[size];} } + void alloc(long 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 long size_; //! Pointer to the buffer, 0 if none has been allocated