Merge pull request #2118 from Exiv2/main_NewDelete

Refactoring & Cleanup (Moving to size_t usage & less naked new/deletes)
main
Luis Díaz Más 3 years ago committed by GitHub
commit 5ca423d292
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -59,9 +59,12 @@
#ifdef EXV_HAVE_UNISTD_H
# include <unistd.h> // for stat()
#endif
#ifdef _MSC_VER
#if defined(_WIN32) || defined(__CYGWIN__)
# include <sys/utime.h>
#include <Windows.h>
#include <fcntl.h>
#include <io.h>
#else
# include <utime.h>
#endif
@ -204,17 +207,17 @@ namespace Action {
std::stringstream output(std::stringstream::out|std::stringstream::binary);
result = printStructure(output, option, path);
if ( result == 0 ) {
size_t size = static_cast<long>(output.str().size());
Exiv2::DataBuf iccProfile(static_cast<long>(size));
Exiv2::DataBuf ascii(static_cast<long>(size * 3 + 1));
size_t size = output.str().size();
Exiv2::DataBuf iccProfile(size);
Exiv2::DataBuf ascii(size * 3 + 1);
ascii.write_uint8(size * 3, 0);
iccProfile.copyBytes(0,output.str().c_str(),size);
if (Exiv2::base64encode(iccProfile.c_data(), size, reinterpret_cast<char*>(ascii.data()), size * 3)) {
long chunk = 60 ;
std::string code = std::string("data:") + std::string(ascii.c_str());
long length = static_cast<long>(code.size());
for ( long start = 0 ; start < length ; start += chunk ) {
long count = (start+chunk) < length ? chunk : length - start ;
std::string code = std::string("data:") + ascii.c_str();
size_t length = code.size();
for ( size_t start = 0 ; start < length ; start += chunk ) {
size_t count = (start+chunk) < length ? chunk : length - start ;
std::cout << code.substr(start,count) << std::endl;
}
}
@ -304,7 +307,7 @@ namespace Action {
}
else {
auto dataBuf = exifThumb.copy();
if (dataBuf.size() == 0) {
if (dataBuf.empty()) {
std::cout << _("None");
}
else {
@ -567,7 +570,7 @@ namespace Action {
std::ostringstream os;
// #1114 - show negative values for SByte
if (md.typeId() == Exiv2::signedByte) {
for ( long c = 0 ; c < md.value().count() ; c++ ) {
for ( size_t c = 0 ; c < md.value().count() ; c++ ) {
const auto value = md.value().toInt64(c);
os << (c?" ":"") << std::dec << (value < 128 ? value : value - 256);
}
@ -589,7 +592,7 @@ namespace Action {
std::cout << std::endl;
Exiv2::DataBuf buf(md.size());
md.copy(buf.data(), pImage->byteOrder());
Exiv2::hexdump(std::cout, buf.c_data(), buf.size());
Exiv2::hexdump(std::cout, buf.c_data(), static_cast<long>(buf.size()));
}
std::cout << std::endl;
return true;
@ -911,8 +914,7 @@ namespace Action {
else {
if ( (Params::instance().target_ & Params::ctStdInOut) != 0 ) {
Exiv2::DataBuf buf = exifThumb.copy();
std::cout.write(reinterpret_cast<char*>(buf.data()),
buf.size());
std::cout.write(buf.c_str(), buf.size());
return 0;
}
@ -927,7 +929,7 @@ namespace Action {
<< thumbPath << std::endl;
}
}
rc = exifThumb.writeFile(thumb);
rc = static_cast<int>(exifThumb.writeFile(thumb));
if (rc == 0) {
std::cerr << path_ << ": " << _("Exif data doesn't contain a thumbnail\n");
}
@ -990,15 +992,14 @@ namespace Action {
} else {
if ( bStdout ) { // -eC-
std::cout.write(image->iccProfile().c_str(),
image->iccProfile().size());
std::cout.write(image->iccProfile().c_str(), image->iccProfile().size());
} else {
if (Params::instance().verbose_) {
std::cout << _("Writing iccProfile: ") << target << std::endl;
}
Exiv2::FileIo iccFile(target);
iccFile.open("wb") ;
iccFile.write(image->iccProfile().c_data(),image->iccProfile().size());
iccFile.write(image->iccProfile().c_data(), image->iccProfile().size());
iccFile.close();
}
}
@ -1022,7 +1023,7 @@ namespace Action {
std::cout << pvImg.size() << " " << _("bytes") << ") "
<< _("to file") << " " << pvPath << std::endl;
}
long rc = pvImg.writeFile(pvFile);
auto rc = pvImg.writeFile(pvFile);
if (rc == 0) {
std::cerr << path_ << ": " << _("Image does not have preview")
<< " " << num << "\n";
@ -1087,7 +1088,7 @@ namespace Action {
return 1;
} // Insert::run
int Insert::insertXmpPacket(const std::string& path,const std::string& xmpPath)
int Insert::insertXmpPacket(const std::string& path,const std::string& xmpPath)
{
int rc = 0;
bool bStdin = xmpPath == "-" ;
@ -1118,7 +1119,7 @@ namespace Action {
int Insert::insertXmpPacket(const std::string& path, const Exiv2::DataBuf& xmpBlob, bool usePacket)
{
std::string xmpPacket;
for ( long i = 0 ; i < xmpBlob.size() ; i++ ) {
for ( size_t i = 0 ; i < xmpBlob.size() ; i++ ) {
xmpPacket += static_cast<char>(xmpBlob.read_uint8(i));
}
auto image = Exiv2::ImageFactory::open(path);
@ -1132,7 +1133,7 @@ namespace Action {
return 0;
}
int Insert::insertIccProfile(const std::string& path,const std::string& iccPath)
int Insert::insertIccProfile(const std::string& path,const std::string& iccPath)
{
int rc = 0;
// for path "foo.XXX", do a binary copy of "foo.icc"
@ -1820,11 +1821,15 @@ namespace {
bool bStdout = tgt == "-";
Exiv2::DataBuf stdIn;
if ( bStdin )
Exiv2::Image::UniquePtr sourceImage;
if ( bStdin ) {
Params::instance().getStdin(stdIn);
auto ioStdin = std::make_unique<Exiv2::MemIo>(stdIn.c_data(), stdIn.size());
sourceImage = Exiv2::ImageFactory::open(std::move(ioStdin));
} else {
sourceImage = Exiv2::ImageFactory::open(source);
}
auto ioStdin = std::make_unique<Exiv2::MemIo>(stdIn.c_data(),stdIn.size());
auto sourceImage = bStdin ? Exiv2::ImageFactory::open(std::move(ioStdin)) : Exiv2::ImageFactory::open(source);
assert(sourceImage);
sourceImage->readMetadata();

@ -37,16 +37,24 @@
#include <cstring>
#include <cassert>
#include <cctype>
#include <regex>
#if defined(_MSC_VER)
#if defined(_WIN32) || defined(__CYGWIN__)
#include <Windows.h>
#include <fcntl.h>
#include <io.h>
#else
#include <unistd.h>
#endif
// *****************************************************************************
// local declarations
namespace {
const Params::YodAdjust emptyYodAdjust_[] = {
{ false, "-Y", 0 },
{ false, "-O", 0 },
{ false, "-D", 0 },
};
//! List of all command identifiers and corresponding strings
const CmdIdAndString cmdIdAndString[] = {
@ -181,7 +189,6 @@ int main(int argc, char* const argv[])
}
taskFactory.cleanup();
Params::cleanup();
Exiv2::XmpParser::terminate();
}
} catch (const std::exception& exc) {
@ -195,26 +202,38 @@ int main(int argc, char* const argv[])
// *****************************************************************************
// class Params
Params* Params::instance_ = nullptr;
const Params::YodAdjust Params::emptyYodAdjust_[] = {
{ false, "-Y", 0 },
{ false, "-O", 0 },
{ false, "-D", 0 },
};
Params& Params::instance()
Params::Params() : optstring_(":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q:"),
help_(false),
version_(false),
verbose_(false),
force_(false),
binary_(false),
unknown_(true),
preserve_(false),
timestamp_(false),
timestampOnly_(false),
fileExistsPolicy_(askPolicy),
adjust_(false),
printMode_(pmSummary),
printItems_(0),
printTags_(Exiv2::mdNone),
action_(0),
target_(ctExif|ctIptc|ctComment|ctXmp),
adjustment_(0),
format_("%Y%m%d_%H%M%S"),
formatSet_(false),
first_(true)
{
if (nullptr == instance_) {
instance_ = new Params;
}
return *instance_;
yodAdjust_[yodYear] = emptyYodAdjust_[yodYear];
yodAdjust_[yodMonth] = emptyYodAdjust_[yodMonth];
yodAdjust_[yodDay] = emptyYodAdjust_[yodDay];
}
void Params::cleanup()
Params& Params::instance()
{
delete instance_;
instance_ = nullptr;
static Params instance_;
return instance_;
}
void Params::version(bool verbose, std::ostream& os)
@ -968,7 +987,7 @@ static int readFileToBuf(FILE* f,Exiv2::DataBuf& buf)
void Params::getStdin(Exiv2::DataBuf& buf)
{
// copy stdin to stdinBuf
if ( stdinBuf.size() == 0 ) {
if (stdinBuf.empty()) {
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__) || defined(_MSC_VER)
DWORD fdwMode;
_setmode(fileno(stdin), O_BINARY);
@ -993,7 +1012,7 @@ void Params::getStdin(Exiv2::DataBuf& buf)
// this is only used to simulate reading from stdin when debugging
// to simulate exiv2 -pX foo.jpg | exiv2 -iXX- bar.jpg
// exiv2 -pX foo.jpg > ~/temp/stdin ; exiv2 -iXX- bar.jpg
if ( stdinBuf.size() == 0 ) {
if ( stdinBuf.empty()) {
const char* path = "/Users/rmills/temp/stdin";
FILE* f = fopen(path,"rb");
if ( f ) {
@ -1019,56 +1038,55 @@ void Params::getStdin(Exiv2::DataBuf& buf)
} // Params::getStdin()
using long_t = std::map<std::string, std::string>;
int Params::getopt(int argc, char* const Argv[])
{
auto argv = new char*[argc + 1];
std::vector<char *> argv(argc+1);
argv[argc] = nullptr;
long_t longs;
longs["--adjust" ] = "-a";
longs["--binary" ] = "-b";
longs["--comment" ] = "-c";
longs["--delete" ] = "-d";
longs["--days" ] = "-D";
longs["--extract" ] = "-e";
longs["--force" ] = "-f";
longs["--Force" ] = "-F";
longs["--grep" ] = "-g";
longs["--help" ] = "-h";
longs["--insert" ] = "-i";
longs["--keep" ] = "-k";
longs["--key" ] = "-K";
longs["--location" ] = "-l";
longs["--modify" ] = "-m";
longs["--Modify" ] = "-M";
longs["--encode" ] = "-n";
longs["--months" ] = "-O";
longs["--print" ] = "-p";
longs["--Print" ] = "-P";
longs["--quiet" ] = "-q";
longs["--log" ] = "-Q";
longs["--rename" ] = "-r";
longs["--suffix" ] = "-S";
longs["--timestamp"] = "-t";
longs["--Timestamp"] = "-T";
longs["--unknown" ] = "-u";
longs["--verbose" ] = "-v";
longs["--Version" ] = "-V";
longs["--version" ] = "-V";
longs["--years" ] = "-Y";
const std::unordered_map<std::string, std::string> longs {
{"--adjust" , "-a"},
{"--binary" , "-b"},
{"--comment" , "-c"},
{"--delete" , "-d"},
{"--days" , "-D"},
{"--extract" , "-e"},
{"--force" , "-f"},
{"--Force" , "-F"},
{"--grep" , "-g"},
{"--help" , "-h"},
{"--insert" , "-i"},
{"--keep" , "-k"},
{"--key" , "-K"},
{"--location" , "-l"},
{"--modify" , "-m"},
{"--Modify" , "-M"},
{"--encode" , "-n"},
{"--months" , "-O"},
{"--print" , "-p"},
{"--Print" , "-P"},
{"--quiet" , "-q"},
{"--log" , "-Q"},
{"--rename" , "-r"},
{"--suffix" , "-S"},
{"--timestamp", "-t"},
{"--Timestamp", "-T"},
{"--unknown" , "-u"},
{"--verbose" , "-v"},
{"--Version" , "-V"},
{"--version" , "-V"},
{"--years" , "-Y"},
};
for ( int i = 0 ; i < argc ; i++ ) {
std::string arg(Argv[i]);
if (longs.find(arg) != longs.end() ) {
argv[i] = ::strdup(longs[arg].c_str());
argv[i] = ::strdup(longs.at(arg).c_str());
} else {
argv[i] = ::strdup(Argv[i]);
}
}
int rc = Util::Getopt::getopt(argc, argv, optstring_);
int rc = Util::Getopt::getopt(argc, argv.data(), optstring_);
// Further consistency checks
if (help_ || version_) {
goto cleanup;
@ -1141,10 +1159,9 @@ int Params::getopt(int argc, char* const Argv[])
// cleanup the argument vector
for (int i = 0; i < argc; i++)
::free(argv[i]);
delete [] argv;
return rc;
} // Params::getopt
}
// *****************************************************************************
// local implementations

@ -35,21 +35,15 @@
#include "getopt.hpp"
// + standard includes
#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <regex>
#ifdef EXV_HAVE_UNISTD_H
#include <unistd.h>
#endif
// stdin handler includes
#ifndef _MSC_VER
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#if defined(__CYGWIN__) || defined(__MINGW__)
#include <windows.h>
#else
@ -57,12 +51,6 @@
#endif
#endif
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__) || defined(_MSC_VER)
#include <fcntl.h>
#include <io.h>
#endif
// *****************************************************************************
// class definitions
@ -160,9 +148,6 @@ public:
//! Prevent copy-construction: not implemented.
Params(const Params& rhs) = delete;
//! Destructor
static void cleanup();
//! Enumerates print modes
enum PrintMode {
pmSummary,
@ -256,44 +241,11 @@ public:
Exiv2::DataBuf stdinBuf; //!< DataBuf with the binary bytes from stdin
private:
//! Pointer to the global Params object.
static Params* instance_;
//! Initializer for year, month and day adjustment info.
static const YodAdjust emptyYodAdjust_[];
bool first_;
Params();
private:
/*!
@brief Default constructor. Note that optstring_ is initialized here.
The c'tor is private to force instantiation through instance().
*/
Params() : optstring_(":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q:"),
help_(false),
version_(false),
verbose_(false),
force_(false),
binary_(false),
unknown_(true),
preserve_(false),
timestamp_(false),
timestampOnly_(false),
fileExistsPolicy_(askPolicy),
adjust_(false),
printMode_(pmSummary),
printItems_(0),
printTags_(Exiv2::mdNone),
action_(0),
target_(ctExif|ctIptc|ctComment|ctXmp),
adjustment_(0),
format_("%Y%m%d_%H%M%S"),
formatSet_(false),
first_(true)
{
yodAdjust_[yodYear] = emptyYodAdjust_[yodYear];
yodAdjust_[yodMonth] = emptyYodAdjust_[yodMonth];
yodAdjust_[yodDay] = emptyYodAdjust_[yodDay];
}
//! @name Helpers
//@{

@ -100,7 +100,7 @@ namespace Exiv2 {
@return Number of bytes written to IO source successfully;<BR>
0 if failure;
*/
virtual long write(const byte* data, long wcount) = 0;
virtual size_t write(const byte* data, size_t wcount) = 0;
/*!
@brief Write data that is read from another BasicIo instance to
the IO source. Current IO position is advanced by the number
@ -110,7 +110,7 @@ namespace Exiv2 {
@return Number of bytes written to IO source successfully;<BR>
0 if failure;
*/
virtual long write(BasicIo& src) = 0;
virtual size_t write(BasicIo& src) = 0;
/*!
@brief Write one byte to the IO source. Current IO position is
advanced by one byte.
@ -129,7 +129,7 @@ namespace Exiv2 {
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
virtual DataBuf read(long rcount) = 0;
virtual DataBuf read(size_t rcount) = 0;
/*!
@brief Read data from the IO source. Reading starts at the current
IO position and the position is advanced by the number of bytes
@ -142,7 +142,7 @@ namespace Exiv2 {
@return Number of bytes read from IO source successfully;<BR>
0 if failure;
*/
virtual long read(byte* buf, long rcount) = 0;
virtual size_t read(byte* buf, size_t rcount) = 0;
/*!
@brief Safe version of `read()` that checks for errors and throws
an exception if the read was unsuccessful.
@ -153,7 +153,7 @@ namespace Exiv2 {
read if \em rcount bytes are not available.
@param err Error code to use if an exception is thrown.
*/
void readOrThrow(byte* buf, long rcount, ErrorCode err);
void readOrThrow(byte* buf, size_t rcount, ErrorCode err);
/*!
@brief Read one byte from the IO source. Current IO position is
advanced by one byte.
@ -352,7 +352,7 @@ namespace Exiv2 {
@return Number of bytes written to the file successfully;<BR>
0 if failure;
*/
long write(const byte* data, long wcount) override;
size_t write(const byte* data, size_t wcount) override;
/*!
@brief Write data that is read from another BasicIo instance to
the file. The file position is advanced by the number
@ -362,7 +362,7 @@ namespace Exiv2 {
@return Number of bytes written to the file successfully;<BR>
0 if failure;
*/
long write(BasicIo& src) override;
size_t write(BasicIo& src) override;
/*!
@brief Write one byte to the file. The file position is
advanced by one byte.
@ -381,7 +381,7 @@ namespace Exiv2 {
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
DataBuf read(long rcount) override;
DataBuf read(size_t rcount) override;
/*!
@brief Read data from the file. Reading starts at the current
file position and the position is advanced by the number of
@ -394,7 +394,7 @@ namespace Exiv2 {
@return Number of bytes read from the file successfully;<BR>
0 if failure;
*/
long read(byte* buf, long rcount) override;
size_t read(byte* buf, size_t rcount) override;
/*!
@brief Read one byte from the file. The file position is
advanced by one byte.
@ -519,11 +519,10 @@ namespace Exiv2 {
@brief Constructor that accepts a block of memory. A copy-on-write
algorithm allows read operations directly from the original data
and will create a copy of the buffer on the first write operation.
@param data Pointer to data. Data must be at least \em size
bytes long
@param data Pointer to data. Data must be at least \em size bytes long
@param size Number of bytes to copy.
*/
MemIo(const byte* data, long size);
MemIo(const byte* data, size_t size);
//! Destructor. Releases all managed memory
~MemIo() override;
//@}
@ -552,7 +551,7 @@ namespace Exiv2 {
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
long write(const byte* data, long wcount) override;
size_t write(const byte* data, size_t wcount) override;
/*!
@brief Write data that is read from another BasicIo instance to
the memory block. If needed, the size of the internal memory
@ -563,7 +562,7 @@ namespace Exiv2 {
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
long write(BasicIo& src) override;
size_t write(BasicIo& src) override;
/*!
@brief Write one byte to the memory block. The IO position is
advanced by one byte.
@ -582,7 +581,7 @@ namespace Exiv2 {
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
DataBuf read(long rcount) override;
DataBuf read(size_t rcount) override;
/*!
@brief Read data from the memory block. Reading starts at the current
IO position and the position is advanced by the number of
@ -595,7 +594,7 @@ namespace Exiv2 {
@return Number of bytes read from the memory block successfully;<BR>
0 if failure;
*/
long read(byte* buf, long rcount) override;
size_t read(byte* buf, size_t rcount) override;
/*!
@brief Read one byte from the memory block. The IO position is
advanced by one byte.
@ -764,6 +763,7 @@ namespace Exiv2 {
class EXIV2API RemoteIo : public BasicIo {
public:
//! Destructor. Releases all managed memory.
RemoteIo();
~RemoteIo() override;
//@}
@ -790,7 +790,7 @@ namespace Exiv2 {
@brief Not support this method.
@return 0 means failure
*/
long write(const byte* data, long wcount) override;
size_t write(const byte* data, size_t wcount) override;
/*!
@brief Write data that is read from another BasicIo instance to the remote file.
@ -805,7 +805,7 @@ namespace Exiv2 {
@note The write access is only supported by http, https, ssh.
*/
long write(BasicIo& src) override;
size_t write(BasicIo& src) override;
/*!
@brief Not support
@ -824,7 +824,7 @@ namespace Exiv2 {
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
DataBuf read(long rcount) override;
DataBuf read(size_t rcount) override;
/*!
@brief Read data from the memory blocks. Reading starts at the current
IO position and the position is advanced by the number of
@ -839,7 +839,7 @@ namespace Exiv2 {
@return Number of bytes read from the memory block successfully;<BR>
0 if failure;
*/
long read(byte* buf, long rcount) override;
size_t read(byte* buf, size_t rcount) override;
/*!
@brief Read one byte from the memory blocks. The IO position is
advanced by one byte.
@ -916,7 +916,7 @@ namespace Exiv2 {
// Pimpl idiom
class Impl;
//! Pointer to implementation
Impl* p_ {nullptr};
std::unique_ptr<Impl> p_;
}; // class RemoteIo
/*!
@ -973,13 +973,13 @@ namespace Exiv2 {
will call RemoteIo::write(const byte* data, long wcount) if the write
access is available for the protocol. Otherwise, it throws the Error.
*/
long write(const byte* data, long wcount) override;
size_t write(const byte* data, size_t wcount) override;
/*!
@brief Write access is only available for some protocols. This method
will call RemoteIo::write(BasicIo& src) if the write access is available
for the protocol. Otherwise, it throws the Error.
*/
long write(BasicIo& src) override;
size_t write(BasicIo& src) override;
// NOT IMPLEMENTED
//! Copy constructor
@ -1007,7 +1007,7 @@ namespace Exiv2 {
@return Return the number of bytes written.
@throw Error In case of failure.
*/
EXIV2API long writeFile(const DataBuf& buf, const std::string& path);
EXIV2API size_t writeFile(const DataBuf& buf, const std::string& path);
#ifdef EXV_USE_CURL
/*!
@brief The callback function is called by libcurl to write the data

@ -118,10 +118,10 @@ namespace Exiv2
std::ostream &out,
bool bTrace,
uint8_t version,
uint32_t width_offset,
uint32_t height_offset,
uint32_t size_offset,
uint32_t relative_position);
size_t width_offset,
size_t height_offset,
size_t size_offset,
size_t relative_position);
//@}
//! @name Manipulators
@ -138,7 +138,7 @@ namespace Exiv2
uint32_t pixelWidth() const override;
uint32_t pixelHeight() const override;
//@}
Exiv2::ByteOrder endian_{Exiv2::bigEndian};
private:

@ -145,7 +145,7 @@ namespace Exiv2 {
@return Return -1 if the %Exifdatum does not have a value yet or the
value has no data area, else 0.
*/
int setDataArea(const byte* buf, long len);
int setDataArea(const byte* buf, size_t len);
//@}
//! @name Accessors
@ -183,7 +183,7 @@ namespace Exiv2 {
//! Return the size in bytes of one component of this type
long typeSize() const override;
//! Return the number of components in the value
long count() const override;
size_t count() const override;
//! Return the size of the value in bytes
long size() const override;
//! Return the value as a string.
@ -195,7 +195,7 @@ namespace Exiv2 {
Value::UniquePtr getValue() const override;
const Value& value() const override;
//! Return the size of the data area.
long sizeDataArea() const;
size_t sizeDataArea() const;
/*!
@brief Return a copy of the data area of the value. The caller owns
this copy and %DataBuf ensures that it will be deleted.
@ -254,7 +254,7 @@ namespace Exiv2 {
@param path File name of the thumbnail without extension.
@return The number of bytes written.
*/
long writeFile(const std::string& path) const;
size_t writeFile(const std::string& path) const;
/*!
@brief Return the MIME type of the thumbnail, either \c "image/tiff"
or \c "image/jpeg".
@ -311,12 +311,7 @@ namespace Exiv2 {
applications may have problems with that. (The preview
application that comes with OS X for one.) - David Harvey.
*/
void setJpegThumbnail(
const std::string& path,
URational xres,
URational yres,
uint16_t unit
);
void setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit);
/*!
@brief Set the Exif thumbnail to the JPEG image pointed to by \em buf,
and size \em size. Set XResolution, YResolution and
@ -334,13 +329,7 @@ namespace Exiv2 {
applications may have problems with that. (The preview
application that comes with OS X for one.) - David Harvey.
*/
void setJpegThumbnail(
const byte* buf,
long size,
URational xres,
URational yres,
uint16_t unit
);
void setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit);
/*!
@brief Set the Exif thumbnail to the JPEG image \em path.
@ -367,7 +356,7 @@ namespace Exiv2 {
@note No checks on the image format or size are performed.
@note Additional existing Exif thumbnail tags are not modified.
*/
void setJpegThumbnail(const byte* buf, long size);
void setJpegThumbnail(const byte* buf, size_t size);
/*!
@brief Delete the thumbnail from the Exif data. Removes all
Exif.%Thumbnail.*, i.e., Exif IFD1 tags.
@ -474,15 +463,14 @@ namespace Exiv2 {
*/
const_iterator findKey(const ExifKey& key) const;
//! Return true if there is no Exif metadata
bool empty() const { return count() == 0; }
bool empty() const { return exifMetadata_.empty(); }
//! Get the number of metadata entries
long count() const { return static_cast<long>(exifMetadata_.size()); }
size_t count() const { return exifMetadata_.size(); }
//@}
private:
// DATA
ExifMetadata exifMetadata_;
}; // class ExifData
/*!
@ -506,11 +494,7 @@ namespace Exiv2 {
@param size Length of the data buffer
@return Byte order in which the data is encoded.
*/
static ByteOrder decode(
ExifData& exifData,
const byte* pData,
uint32_t size
);
static ByteOrder decode(ExifData& exifData, const byte* pData, size_t size);
/*!
@brief Encode Exif metadata from the provided metadata to binary Exif
format.
@ -552,7 +536,7 @@ namespace Exiv2 {
static WriteMethod encode(
Blob& blob,
const byte* pData,
uint32_t size,
size_t size,
ByteOrder byteOrder,
const ExifData& exifData
);

@ -561,7 +561,7 @@ namespace Exiv2 {
matches that of the data buffer.
@throw Error If the memory contains data of an unknown image type.
*/
static Image::UniquePtr open(const byte* data, long size);
static Image::UniquePtr open(const byte* data, size_t size);
/*!
@brief Create an Image subclass of the appropriate type by reading
the provided BasicIo instance. %Image type is derived from the
@ -630,7 +630,7 @@ namespace Exiv2 {
@param size Number of bytes pointed to by \em data.
@return %Image type or Image::none if the type is not recognized.
*/
static ImageType getType(const byte* data, long size);
static ImageType getType(const byte* data, size_t size);
/*!
@brief Returns the image type of data provided by a BasicIo instance.
The passed in \em io instance is (re)opened by this method.
@ -684,7 +684,7 @@ namespace Exiv2 {
// template, inline and free functions
//! Append \em len bytes pointed to by \em buf to \em blob.
EXIV2API void append(Exiv2::Blob& blob, const byte* buf, uint32_t len);
EXIV2API void append(Exiv2::Blob& blob, const byte* buf, size_t len);
} // namespace Exiv2

@ -136,7 +136,7 @@ namespace Exiv2 {
TypeId typeId() const override;
const char* typeName() const override;
long typeSize() const override;
long count() const override;
size_t count() const override;
long size() const override;
std::string toString() const override;
std::string toString(long n) const override;
@ -291,23 +291,17 @@ namespace Exiv2 {
@return 0 if successful;<BR>
5 if the binary IPTC data is invalid or corrupt
*/
static int decode(
IptcData& iptcData,
const byte* pData,
uint32_t size
);
static int decode(IptcData& iptcData, const byte* pData, uint32_t size);
/*!
@brief Encode the IPTC datasets from \em iptcData to a binary
representation in IPTC IIM4 format.
@brief Encode the IPTC datasets from \em iptcData to a binary representation in IPTC IIM4 format.
Convert the IPTC datasets to binary format and return it. Caller owns
the returned buffer. The copied data follows the IPTC IIM4 standard.
@return Data buffer containing the binary IPTC data in IPTC IIM4 format.
*/
static DataBuf encode(
const IptcData& iptcData
);
static DataBuf encode(const IptcData& iptcData);
private:
// Constant data

@ -57,8 +57,7 @@ namespace Exiv2 {
@return true if the IRB marker is known and the buffer is big enough to check this;<BR>
false otherwise
*/
static bool isIrb(const byte* pPsData,
long sizePsData);
static bool isIrb(const byte* pPsData, size_t sizePsData);
/*!
@brief Validates all IRBs
@ -67,8 +66,7 @@ namespace Exiv2 {
@return true if all IRBs are valid;<BR>
false otherwise
*/
static bool valid(const byte* pPsData,
long sizePsData);
static bool valid(const byte* pPsData, size_t sizePsData);
/*!
@brief Locates the data for a %Photoshop tag in a %Photoshop formated memory
buffer. Operates on raw data to simplify reuse.
@ -87,7 +85,7 @@ namespace Exiv2 {
-2 if the pPsData buffer does not contain valid data.
*/
static int locateIrb(const byte *pPsData,
long sizePsData,
size_t sizePsData,
uint16_t psTag,
const byte **record,
uint32_t *const sizeHdr,
@ -96,7 +94,7 @@ namespace Exiv2 {
@brief Forwards to locateIrb() with \em psTag = \em iptc_
*/
static int locateIptcIrb(const byte *pPsData,
long sizePsData,
size_t sizePsData,
const byte **record,
uint32_t *const sizeHdr,
uint32_t *const sizeData);
@ -104,7 +102,7 @@ namespace Exiv2 {
@brief Forwards to locatePreviewIrb() with \em psTag = \em preview_
*/
static int locatePreviewIrb(const byte *pPsData,
long sizePsData,
size_t sizePsData,
const byte **record,
uint32_t *const sizeHdr,
uint32_t *const sizeData);
@ -117,9 +115,7 @@ namespace Exiv2 {
@param iptcData Iptc data to embed, may be empty
@return A data buffer containing the new IRB buffer, may have 0 size
*/
static DataBuf setIptcIrb(const byte* pPsData,
long sizePsData,
const IptcData& iptcData);
static DataBuf setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData);
}; // class Photoshop
@ -132,13 +128,6 @@ namespace Exiv2 {
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
@warning This function is not thread safe and intended for exiv2 -pS for debugging.
*/
void printStructure(std::ostream& out, PrintStructureOption option, int depth) override;
//@}
@ -177,7 +166,7 @@ namespace Exiv2 {
BasicIo::UniquePtr io,
bool create,
const byte initData[],
long dataSize);
size_t dataSize);
//@}
//! @name Accessors
@ -254,7 +243,7 @@ namespace Exiv2 {
@return 0 if successful;<BR>
4 if the image can not be written to.
*/
int initImage(const byte initData[], long dataSize);
int initImage(const byte initData[], size_t dataSize);
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@ -279,6 +268,8 @@ namespace Exiv2 {
byte advanceToMarker(ErrorCode err) const;
//@}
DataBuf readNextSegment(byte marker);
/*!
@brief Is the marker followed by a non-zero payload?
@param marker The marker at the start of a segment

@ -206,7 +206,7 @@ namespace Exiv2 {
//! Return the size in bytes of one component of this type
virtual long typeSize() const =0;
//! Return the number of components in the value
virtual long count() const =0;
virtual size_t count() const =0;
//! Return the size of the value in bytes
virtual long size() const =0;
//! Return the value as a string.

@ -44,7 +44,7 @@ namespace Exiv2 {
//! Preview image extension.
std::string extension_;
//! Preview image size in bytes.
uint32_t size_;
size_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.
@ -99,7 +99,7 @@ namespace Exiv2 {
@param path File name of the preview image without extension.
@return The number of bytes written.
*/
long writeFile(const std::string& path) const;
size_t writeFile(const std::string& path) const;
/*!
@brief Return the MIME type of the preview image, usually either
\c "image/tiff" or \c "image/jpeg".

@ -135,7 +135,7 @@ namespace Exiv2 {
IptcData& iptcData,
XmpData& xmpData,
const byte* pData,
uint32_t size
size_t size
);
/*!
@brief Encode metadata from the provided metadata to TIFF format.

@ -152,7 +152,7 @@ namespace Exiv2 {
//! Return the type id for a type name
static TypeId typeId(const std::string& typeName);
//! Return the size in bytes of one element of this type
static long typeSize(TypeId typeId);
static size_t typeSize(TypeId typeId);
};
@ -166,56 +166,39 @@ namespace Exiv2 {
//! @name Creators
//@{
//! Default constructor
DataBuf();
DataBuf() = default;
//! Constructor with an initial buffer size
explicit DataBuf(long size);
explicit DataBuf(size_t size);
//! Constructor, copies an existing buffer
DataBuf(const byte* pData, long size);
/*!
@brief Copy constructor. Copies an existing DataBuf.
*/
DataBuf(const DataBuf& rhs);
/*!
@brief Move constructor. Transfers the buffer to the newly created
object similar to std::unique_ptr, i.e., the original object is
modified.
*/
DataBuf(DataBuf&& rhs);
//! Destructor, deletes the allocated buffer
~DataBuf();
DataBuf(const byte* pData, size_t size);
//@}
//! @name Manipulators
//@{
/*!
@brief Assignment operator. Transfers the buffer and releases the
buffer at the original object similar to std::unique_ptr, i.e.,
the original object is modified.
*/
DataBuf& operator=(DataBuf&& rhs);
// No copy assignment.
DataBuf& operator=(const DataBuf&) = delete;
/*!
@brief Allocate a data buffer of at least the given size. Note that if
the requested \em size is less than the current buffer size, no
new memory is allocated and the buffer size doesn't change.
*/
void alloc(long size);
void alloc(size_t size);
/*!
@brief Resize the buffer. Existing data is preserved (like std::realloc()).
*/
void resize(long size);
void resize(size_t size);
//! Reset value
void reset();
//@}
//! Fill the buffer with zeros.
void clear();
using iterator = std::vector<byte>::iterator;
using const_iterator = std::vector<byte>::const_iterator;
inline iterator begin() noexcept { return pData_.begin(); }
inline const_iterator cbegin() const noexcept { return pData_.cbegin(); }
inline iterator end() noexcept { return pData_.end(); }
inline const_iterator cend() const noexcept { return pData_.end(); }
long size() const { return size_; }
size_t size() const { return pData_.size(); }
uint8_t read_uint8(size_t offset) const;
void write_uint8(size_t offset, uint8_t x);
@ -244,13 +227,11 @@ namespace Exiv2 {
//! Returns a (read-only) C-style string pointer.
const char* c_str(size_t offset = 0) const;
bool empty() const {return pData_.empty(); }
private:
// DATA
//! Pointer to the buffer, 0 if none has been allocated
byte* pData_;
//! The current size of the buffer
long size_;
}; // class DataBuf
std::vector<byte> pData_;
};
/*!
* @brief Create a new Slice from a DataBuf given the bounds.

@ -58,18 +58,17 @@ namespace Exiv2 {
//! Virtual destructor.
virtual ~Value() = default;
//@}
//! @name Manipulators
//@{
/*!
@brief Read the value from a character buffer.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@param byteOrder Applicable byte order (little or big endian).
/// @brief Read the value from a character buffer.
/// @param buf Pointer to the data buffer to read from
/// @param len Number of bytes in the data buffer
/// @param byteOrder Applicable byte order (little or big endian).
/// @return 0 if successful.
virtual int read(const byte* buf, size_t len, ByteOrder byteOrder) =0;
@return 0 if successful.
*/
virtual int read(const byte* buf, long len, ByteOrder byteOrder) =0;
/*!
@brief Set the value from a string buffer. The format of the string
corresponds to that of the write() method, i.e., a string
@ -93,7 +92,7 @@ namespace Exiv2 {
@param len Size of the data area
@return Return -1 if the value has no data area, else 0.
*/
virtual int setDataArea(const byte* buf, long len);
virtual int setDataArea(const byte* buf, size_t len);
//@}
//! @name Accessors
@ -118,9 +117,9 @@ namespace Exiv2 {
*/
virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
//! Return the number of components of the value
virtual long count() const =0;
virtual size_t count() const =0;
//! Return the size of the value in bytes
virtual long size() const =0;
virtual size_t size() const =0;
/*!
@brief Write the value to an output stream. You do not usually have
to use this function; it is used for the implementation of
@ -139,7 +138,7 @@ namespace Exiv2 {
of this method may be undefined if there is no <EM>n</EM>-th
component.
*/
virtual std::string toString(long n) const;
virtual std::string toString(size_t n) const;
/*!
@brief Convert the <EM>n</EM>-th component of the value to an int64_t.
The behaviour of this method may be undefined if there is no
@ -147,7 +146,7 @@ namespace Exiv2 {
@return The converted value.
*/
virtual int64_t toInt64(long n =0) const =0;
virtual int64_t toInt64(size_t n =0) const =0;
/*!
@brief Convert the <EM>n</EM>-th component of the value to a float.
The behaviour of this method may be undefined if there is no
@ -155,7 +154,7 @@ namespace Exiv2 {
@return The converted value.
*/
virtual uint32_t toUint32(long n =0) const =0;
virtual uint32_t toUint32(size_t n =0) const =0;
/*!
@brief Convert the <EM>n</EM>-th component of the value to a float.
The behaviour of this method may be undefined if there is no
@ -163,7 +162,7 @@ namespace Exiv2 {
@return The converted value.
*/
virtual float toFloat(long n =0) const =0;
virtual float toFloat(size_t n =0) const =0;
/*!
@brief Convert the <EM>n</EM>-th component of the value to a Rational.
The behaviour of this method may be undefined if there is no
@ -171,9 +170,9 @@ namespace Exiv2 {
@return The converted value.
*/
virtual Rational toRational(long n =0) const =0;
virtual Rational toRational(size_t n =0) const =0;
//! Return the size of the data area, 0 if there is none.
virtual long sizeDataArea() const;
virtual size_t sizeDataArea() const;
/*!
@brief Return a copy of the data area if the value has one. The
caller owns this copy and DataBuf ensures that it will be
@ -246,8 +245,7 @@ namespace Exiv2 {
virtual Value* clone_() const =0;
// DATA
TypeId type_; //!< Type of the data
}; // class Value
};
//! Output operator for Value types
inline std::ostream& operator<<(std::ostream& os, const Value& value)
@ -271,19 +269,7 @@ namespace Exiv2 {
//! @name Manipulators
//@{
/*!
@brief Read the value from a character buffer.
@note The byte order is required by the interface but not
used by this method, so just use the default.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@param byteOrder Byte order. Not needed.
@return 0 if successful.
*/
int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override;
int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
//! Set the data from a string of integer values (e.g., "0 1 2 3")
int read(const std::string& buf) override;
//@}
@ -305,19 +291,19 @@ namespace Exiv2 {
@return Number of characters written.
*/
long copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
long count() const override;
long size() const override;
size_t count() const override;
size_t size() const override;
std::ostream& write(std::ostream& os) const override;
/*!
@brief Return the <EM>n</EM>-th component of the value as a string.
The behaviour of this method may be undefined if there is no
<EM>n</EM>-th component.
*/
std::string toString(long n) const override;
int64_t toInt64(long n = 0) const override;
uint32_t toUint32(long n = 0) const override;
float toFloat(long n = 0) const override;
Rational toRational(long n = 0) const override;
std::string toString(size_t n) const override;
int64_t toInt64(size_t n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
float toFloat(size_t n = 0) const override;
Rational toRational(size_t n = 0) const override;
//@}
private:
@ -358,19 +344,7 @@ namespace Exiv2 {
//@{
//! Read the value from buf. This default implementation uses buf as it is.
int read(const std::string& buf) override;
/*!
@brief Read the value from a character buffer.
@note The byte order is required by the interface but not used by this
method, so just use the default.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@param byteOrder Byte order. Not needed.
@return 0 if successful.
*/
int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override;
int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
//@}
//! @name Accessors
@ -390,12 +364,12 @@ namespace Exiv2 {
@return Number of characters written.
*/
long copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
long count() const override;
long size() const override;
int64_t toInt64(long n = 0) const override;
uint32_t toUint32(long n = 0) const override;
float toFloat(long n = 0) const override;
Rational toRational(long n = 0) const override;
size_t count() const override;
size_t size() const override;
int64_t toInt64(size_t n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
float toFloat(size_t n = 0) const override;
Rational toRational(size_t n = 0) const override;
std::ostream& write(std::ostream& os) const override;
//@}
@ -568,10 +542,7 @@ namespace Exiv2 {
1 if an invalid character set is encountered
*/
int read(const std::string& comment) override;
/*!
@brief Read the comment from a byte buffer.
*/
int read(const byte* buf, long len, ByteOrder byteOrder) override;
int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
//@}
//! @name Accessors
@ -646,7 +617,7 @@ namespace Exiv2 {
XmpArrayType xmpArrayType() const;
//! Return XMP struct, indicates if an XMP value is a structure.
XmpStruct xmpStruct() const;
long size() const override;
size_t size() const override;
/*!
@brief Write value to a character data buffer.
@ -669,21 +640,9 @@ namespace Exiv2 {
void setXmpArrayType(XmpArrayType xmpArrayType);
//! Set the XMP struct type to indicate that an XMP value is a structure.
void setXmpStruct(XmpStruct xmpStruct =xsStruct);
/*!
@brief Read the value from a character buffer.
Uses read(const std::string& buf)
@note The byte order is required by the interface but not used by this
method, so just use the default.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@param byteOrder Byte order. Not needed.
@return 0 if successful.
*/
int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override;
/// @note Uses read(const std::string& buf)
int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
int read(const std::string& buf) override = 0;
//@}
@ -744,36 +703,36 @@ namespace Exiv2 {
//! @name Accessors
//@{
UniquePtr clone() const;
long size() const override;
long count() const override;
size_t size() const override;
size_t count() const override;
/*!
@brief Convert the value to an int64_t.
The optional parameter \em n is not used and is ignored.
@return The converted value.
*/
int64_t toInt64(long n = 0) const override;
int64_t toInt64(size_t n = 0) const override;
/*!
@brief Convert the value to an uint32_t.
The optional parameter \em n is not used and is ignored.
@return The converted value.
*/
uint32_t toUint32(long n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
/*!
@brief Convert the value to a float.
The optional parameter \em n is not used and is ignored.
@return The converted value.
*/
float toFloat(long n = 0) const override;
float toFloat(size_t n = 0) const override;
/*!
@brief Convert the value to a Rational.
The optional parameter \em n is not used and is ignored.
@return The converted value.
*/
Rational toRational(long n = 0) const override;
Rational toRational(size_t n = 0) const override;
std::ostream& write(std::ostream& os) const override;
//@}
@ -826,17 +785,17 @@ namespace Exiv2 {
//! @name Accessors
//@{
UniquePtr clone() const;
long count() const override;
size_t count() const override;
/*!
@brief Return the <EM>n</EM>-th component of the value as a string.
The behaviour of this method may be undefined if there is no
<EM>n</EM>-th component.
*/
std::string toString(long n) const override;
int64_t toInt64(long n = 0) const override;
uint32_t toUint32(long n = 0) const override;
float toFloat(long n = 0) const override;
Rational toRational(long n = 0) const override;
std::string toString(size_t n) const override;
int64_t toInt64(size_t n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
float toFloat(size_t n = 0) const override;
Rational toRational(size_t n = 0) const override;
/*!
@brief Write all elements of the value to \em os, separated by commas.
@ -925,7 +884,7 @@ namespace Exiv2 {
//! @name Accessors
//@{
UniquePtr clone() const;
long count() const override;
size_t count() const override;
/*!
@brief Return the text value associated with the default language
qualifier \c x-default. The parameter \em n is not used, but
@ -933,17 +892,17 @@ namespace Exiv2 {
string and sets the ok-flag to \c false if there is no
default value.
*/
std::string toString(long n) const override;
std::string toString(size_t n) const override;
/*!
@brief Return the text value associated with the language qualifier
\em qualifier. Returns an empty string and sets the ok-flag
to \c false if there is no entry for the language qualifier.
*/
std::string toString(const std::string& qualifier) const;
int64_t toInt64(long n = 0) const override;
uint32_t toUint32(long n = 0) const override;
float toFloat(long n = 0) const override;
Rational toRational(long n = 0) const override;
int64_t toInt64(size_t n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
float toFloat(size_t n = 0) const override;
Rational toRational(size_t n = 0) const override;
/*!
@brief Write all elements of the value to \em os, separated by commas.
@ -999,20 +958,10 @@ namespace Exiv2 {
//! @name Manipulators
//@{
/*!
@brief Read the value from a character buffer.
@note The byte order is required by the interface but not used by this
method, so just use the default.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@param byteOrder Byte order. Not needed.
@return 0 if successful<BR>
1 in case of an unsupported date format
*/
int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override;
/// @return 0 if successful<BR>
/// 1 in case of an unsupported date format
int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
/*!
@brief Set the value to that of the string buf.
@ -1046,17 +995,17 @@ namespace Exiv2 {
//! Return date struct containing date information
virtual const Date& getDate() const;
long count() const override;
long size() const override;
size_t count() const override;
size_t size() const override;
std::ostream& write(std::ostream& os) const override;
//! Return the value as a UNIX calender time converted to int64_t.
int64_t toInt64(long n = 0) const override;
int64_t toInt64(size_t n = 0) const override;
//! Return the value as a UNIX calender time converted to uint32_t.
uint32_t toUint32(long n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
//! Return the value as a UNIX calender time converted to float.
float toFloat(long n = 0) const override;
float toFloat(size_t n = 0) const override;
//! Return the value as a UNIX calender time converted to Rational.
Rational toRational(long n = 0) const override;
Rational toRational(size_t n = 0) const override;
//@}
private:
@ -1107,20 +1056,10 @@ namespace Exiv2 {
//! @name Manipulators
//@{
/*!
@brief Read the value from a character buffer.
@note The byte order is required by the interface but not used by this
method, so just use the default.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@param byteOrder Byte order. Not needed.
@return 0 if successful<BR>
1 in case of an unsupported time format
*/
int read(const byte* buf, long len, ByteOrder byteOrder = invalidByteOrder) override;
/// @return 0 if successful<BR>
/// 1 in case of an unsupported time format
int read(const byte* buf, size_t len, ByteOrder byteOrder = invalidByteOrder) override;
/*!
@brief Set the value to that of the string buf.
@ -1153,17 +1092,17 @@ namespace Exiv2 {
long copy(byte* buf, ByteOrder byteOrder = invalidByteOrder) const override;
//! Return time struct containing time information
virtual const Time& getTime() const;
long count() const override;
long size() const override;
size_t count() const override;
size_t size() const override;
std::ostream& write(std::ostream& os) const override;
//! Returns number of seconds in the day in UTC.
int64_t toInt64(long n = 0) const override;
int64_t toInt64(size_t n = 0) const override;
//! Returns number of seconds in the day in UTC.
uint32_t toUint32(long n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
//! Returns number of seconds in the day in UTC converted to float.
float toFloat(long n = 0) const override;
float toFloat(size_t n = 0) const override;
//! Returns number of seconds in the day in UTC converted to Rational.
Rational toRational(long n = 0) const override;
Rational toRational(size_t n = 0) const override;
//@}
private:
@ -1233,7 +1172,7 @@ namespace Exiv2 {
//@{
//! Assignment operator.
ValueType<T>& operator=(const ValueType<T>& rhs);
int read(const byte* buf, long len, ByteOrder byteOrder) override;
int read(const byte* buf, size_t len, ByteOrder byteOrder) override;
/*!
@brief Set the data from a string of values of type T (e.g.,
"0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
@ -1245,15 +1184,15 @@ namespace Exiv2 {
@brief Set the data area. This method copies (clones) the buffer
pointed to by buf.
*/
int setDataArea(const byte* buf, long len) override;
int setDataArea(const byte* buf, size_t len) override;
//@}
//! @name Accessors
//@{
UniquePtr clone() const { return UniquePtr(clone_()); }
long copy(byte* buf, ByteOrder byteOrder) const override;
long count() const override;
long size() const override;
size_t count() const override;
size_t size() const override;
std::ostream& write(std::ostream& os) const override;
/*!
@brief Return the <EM>n</EM>-th component of the value as a string.
@ -1261,13 +1200,13 @@ namespace Exiv2 {
<EM>n</EM>-th
component.
*/
std::string toString(long n) const override;
int64_t toInt64(long n = 0) const override;
uint32_t toUint32(long n = 0) const override;
float toFloat(long n = 0) const override;
Rational toRational(long n = 0) const override;
std::string toString(size_t n) const override;
int64_t toInt64(size_t n = 0) const override;
uint32_t toUint32(size_t n = 0) const override;
float toFloat(size_t n = 0) const override;
Rational toRational(size_t n = 0) const override;
//! Return the size of the data area.
long sizeDataArea() const override;
size_t sizeDataArea() const override;
/*!
@brief Return a copy of the data area in a DataBuf. The caller owns
this copy and DataBuf ensures that it will be deleted.
@ -1294,7 +1233,7 @@ namespace Exiv2 {
private:
//! Utility for toInt64, toUint32, etc.
template<typename I>
inline I float_to_integer_helper(long n) const {
inline I float_to_integer_helper(size_t n) const {
const auto v = value_.at(n);
if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
@ -1306,7 +1245,7 @@ namespace Exiv2 {
//! Utility for toInt64, toUint32, etc.
template<typename I>
inline I rational_to_integer_helper(long n) const {
inline I rational_to_integer_helper(size_t n) const {
const auto& t = value_.at(n);
const auto a = t.first;
const auto b = t.second;
@ -1355,7 +1294,7 @@ namespace Exiv2 {
//! Pointer to the buffer, nullptr if none has been allocated
byte* pDataArea_{nullptr};
//! The current size of the buffer
long sizeDataArea_{0};
size_t sizeDataArea_{0};
}; // class ValueType
//! Unsigned short value type
@ -1586,13 +1525,13 @@ namespace Exiv2 {
}
template<typename T>
int ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder)
{
value_.clear();
long ts = TypeInfo::typeSize(typeId());
size_t ts = TypeInfo::typeSize(typeId());
if (ts > 0)
if (len % ts != 0) len = (len / ts) * ts;
for (long i = 0; i < len; i += ts) {
for (size_t i = 0; i < len; i += ts) {
value_.push_back(getValue<T>(buf + i, byteOrder));
}
return 0;
@ -1624,13 +1563,13 @@ namespace Exiv2 {
}
template<typename T>
long ValueType<T>::count() const
size_t ValueType<T>::count() const
{
return static_cast<long>(value_.size());
return value_.size();
}
template<typename T>
long ValueType<T>::size() const
size_t ValueType<T>::size() const
{
return static_cast<long>(TypeInfo::typeSize(typeId()) * value_.size());
}
@ -1655,7 +1594,7 @@ namespace Exiv2 {
}
template<typename T>
std::string ValueType<T>::toString(long n) const
std::string ValueType<T>::toString(size_t n) const
{
ok_ = true;
return Exiv2::toString<T>(value_.at(n));
@ -1663,13 +1602,13 @@ namespace Exiv2 {
// Default implementation
template<typename T>
int64_t ValueType<T>::toInt64(long n) const
int64_t ValueType<T>::toInt64(size_t n) const
{
ok_ = true;
return static_cast<int64_t>(value_.at(n));
}
template<typename T>
uint32_t ValueType<T>::toUint32(long n) const
uint32_t ValueType<T>::toUint32(size_t n) const
{
ok_ = true;
return static_cast<uint32_t>(value_.at(n));
@ -1678,58 +1617,59 @@ namespace Exiv2 {
#define LARGE_INT 1000000
// Specialization for double
template<>
inline int64_t ValueType<double>::toInt64(long n) const
inline int64_t ValueType<double>::toInt64(size_t n) const
{
return float_to_integer_helper<int64_t>(n);
}
template<>
inline uint32_t ValueType<double>::toUint32(long n) const
inline uint32_t ValueType<double>::toUint32(size_t n) const
{
return float_to_integer_helper<uint32_t>(n);
}
// Specialization for float
template<>
inline int64_t ValueType<float>::toInt64(long n) const
inline int64_t ValueType<float>::toInt64(size_t n) const
{
return float_to_integer_helper<int64_t>(n);
}
template<>
inline uint32_t ValueType<float>::toUint32(long n) const
inline uint32_t ValueType<float>::toUint32(size_t n) const
{
return float_to_integer_helper<uint32_t>(n);
}
// Specialization for rational
template<>
inline int64_t ValueType<Rational>::toInt64(long n) const
inline int64_t ValueType<Rational>::toInt64(size_t n) const
{
return rational_to_integer_helper<int64_t>(n);
}
template<>
inline uint32_t ValueType<Rational>::toUint32(long n) const
inline uint32_t ValueType<Rational>::toUint32(size_t n) const
{
return rational_to_integer_helper<uint32_t>(n);
}
// Specialization for unsigned rational
template<>
inline int64_t ValueType<URational>::toInt64(long n) const
inline int64_t ValueType<URational>::toInt64(size_t n) const
{
return rational_to_integer_helper<int64_t>(n);
}
template<>
inline uint32_t ValueType<URational>::toUint32(long n) const
inline uint32_t ValueType<URational>::toUint32(size_t n) const
{
return rational_to_integer_helper<uint32_t>(n);
}
// Default implementation
template<typename T>
float ValueType<T>::toFloat(long n) const
float ValueType<T>::toFloat(size_t n) const
{
ok_ = true;
return static_cast<float>(value_.at(n));
}
// Specialization for rational
template<>
inline float ValueType<Rational>::toFloat(long n) const
inline float ValueType<Rational>::toFloat(size_t n) const
{
ok_ = (value_.at(n).second != 0);
if (!ok_) return 0.0f;
@ -1737,7 +1677,7 @@ namespace Exiv2 {
}
// Specialization for unsigned rational
template<>
inline float ValueType<URational>::toFloat(long n) const
inline float ValueType<URational>::toFloat(size_t n) const
{
ok_ = (value_.at(n).second != 0);
if (!ok_) return 0.0f;
@ -1745,28 +1685,28 @@ namespace Exiv2 {
}
// Default implementation
template<typename T>
Rational ValueType<T>::toRational(long n) const
Rational ValueType<T>::toRational(size_t n) const
{
ok_ = true;
return {value_.at(n), 1};
}
// Specialization for rational
template<>
inline Rational ValueType<Rational>::toRational(long n) const
inline Rational ValueType<Rational>::toRational(size_t n) const
{
ok_ = true;
return {value_.at(n).first, value_.at(n).second};
}
// Specialization for unsigned rational
template<>
inline Rational ValueType<URational>::toRational(long n) const
inline Rational ValueType<URational>::toRational(size_t n) const
{
ok_ = true;
return {value_.at(n).first, value_.at(n).second};
}
// Specialization for float.
template<>
inline Rational ValueType<float>::toRational(long n) const
inline Rational ValueType<float>::toRational(size_t n) const
{
ok_ = true;
// Warning: This is a very simple conversion, see floatToRationalCast()
@ -1774,7 +1714,7 @@ namespace Exiv2 {
}
// Specialization for double.
template<>
inline Rational ValueType<double>::toRational(long n) const
inline Rational ValueType<double>::toRational(size_t n) const
{
ok_ = true;
// Warning: This is a very simple conversion, see floatToRationalCast()
@ -1782,7 +1722,7 @@ namespace Exiv2 {
}
template<typename T>
long ValueType<T>::sizeDataArea() const
size_t ValueType<T>::sizeDataArea() const
{
return sizeDataArea_;
}
@ -1794,7 +1734,7 @@ namespace Exiv2 {
}
template<typename T>
int ValueType<T>::setDataArea(const byte* buf, long len)
int ValueType<T>::setDataArea(const byte* buf, size_t len)
{
byte* tmp = nullptr;
if (len > 0) {

@ -131,7 +131,7 @@ namespace Exiv2 {
// Todo: Remove this method from the baseclass
//! The Exif typeSize doesn't make sense here. Return 0.
long typeSize() const override;
long count() const override;
size_t count() const override;
long size() const override;
std::string toString() const override;
std::string toString(long n) const override;

@ -57,7 +57,7 @@ try {
std::cout << "Added a few tags the quick way.\n";
// Create a ASCII string value (note the use of create)
Exiv2::Value::UniquePtr v = Exiv2::Value::create(Exiv2::asciiString);
auto v = Exiv2::Value::create(Exiv2::asciiString);
// Set the value to a string
v->read("1999:12:31 23:59:59");
// Add the value together with its key to the Exif data container
@ -66,16 +66,16 @@ try {
std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n";
// Now create a more interesting value (without using the create method)
Exiv2::URationalValue::UniquePtr rv(new Exiv2::URationalValue);
Exiv2::URationalValue rv;
// Set two rational components from a string
rv->read("1/2 1/3");
rv.read("1/2 1/3");
// Add more elements through the extended interface of rational value
rv->value_.emplace_back(2, 3);
rv->value_.emplace_back(3, 4);
rv.value_.emplace_back(2, 3);
rv.value_.emplace_back(3, 4);
// Add the key and value pair to the Exif data
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
exifData.add(key, rv.get());
std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n";
exifData.add(key, &rv);
std::cout << "Added key \"" << key << "\", value \"" << rv << "\"\n";
// *************************************************************************
// Modify Exif data
@ -92,18 +92,21 @@ try {
// Alternatively, we can use findKey()
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
auto pos = exifData.findKey(key);
if (pos == exifData.end()) throw Exiv2::Error(Exiv2::kerErrorMessage, "Key not found");
if (pos == exifData.end())
throw Exiv2::Error(Exiv2::kerErrorMessage, "Key not found");
// Get a pointer to a copy of the value
v = pos->getValue();
// Downcast the Value pointer to its actual type
auto prv = dynamic_cast<Exiv2::URationalValue*>(v.release());
auto prv = dynamic_cast<Exiv2::URationalValue*>(v.get());
if (prv == nullptr)
throw Exiv2::Error(Exiv2::kerErrorMessage, "Downcast failed");
rv = Exiv2::URationalValue::UniquePtr(prv);
rv = Exiv2::URationalValue(*prv);
// Modify the value directly through the interface of URationalValue
rv->value_.at(2) = {88, 77};
rv.value_.at(2) = {88, 77};
// Copy the modified value back to the metadatum
pos->setValue(rv.get());
pos->setValue(&rv);
std::cout << "Modified key \"" << key
<< "\", new value \"" << pos->value() << "\"\n";

@ -65,8 +65,10 @@ int main(int argc, char* const argv[])
if ( argc >= 5 ) {
int blocksize = argc==6 ? atoi(ba) : 10000;
// ensure blocksize is sane
if (blocksize>1024*1024) blocksize=10000;
Exiv2::byte* bytes = blocksize > 0 ? new Exiv2::byte[blocksize] : nullptr;
if (blocksize>1024*1024)
blocksize=10000;
std::vector<Exiv2::byte> bytes (blocksize);
// copy fileIn from a remote location.
BasicIo::UniquePtr io = Exiv2::ImageFactory::createIo(fr);
@ -78,11 +80,11 @@ int main(int argc, char* const argv[])
Error(Exiv2::kerFileOpenFailed, output.path() , "w+b", strError());
}
size_t l = 0;
if ( bytes ) {
int r ;
while ( (r=io->read(bytes,blocksize)) > 0 ) {
if ( !bytes.empty() ) {
size_t r ;
while ( (r=io->read(bytes.data(),blocksize)) > 0 ) {
l += r;
output.write(bytes,r) ;
output.write(bytes.data(),r) ;
}
} else {
// read/write byte-wise (#1029)
@ -90,7 +92,6 @@ int main(int argc, char* const argv[])
output.putb(io->getb()) ;
}
}
delete[] bytes;
output.close();
}
@ -142,7 +143,7 @@ int main(int argc, char* const argv[])
throw Error(Exiv2::kerFileOpenFailed, f2, "w+b", strError());
}
long readCount = 0;
size_t readCount = 0;
byte buf[32];
while ((readCount=fileOut1.read(buf, sizeof(buf)))) {
if (memIo2.write(buf, readCount) != readCount) {
@ -179,7 +180,7 @@ int WriteReadSeek(BasicIo &io)
throw Error(Exiv2::kerDataSourceOpenFailed, io.path(), strError());
}
IoCloser closer(io);
if (static_cast<size_t>(io.write(reinterpret_cast<const byte*>(tester1), static_cast<long>(size1))) != size1) {
if (io.write(reinterpret_cast<const byte*>(tester1), size1) != size1) {
std::cerr << ": WRS initial write failed\n";
return 2;
}
@ -232,7 +233,7 @@ int WriteReadSeek(BasicIo &io)
}
io.seek(insert, BasicIo::beg);
if (static_cast<size_t>(io.write(reinterpret_cast<const byte*>(tester2), static_cast<long>(size2))) != size2) {
if (io.write(reinterpret_cast<const byte*>(tester2), size2) != size2) {
std::cerr << ": WRS bad write 1\n";
return 9;
}
@ -242,7 +243,7 @@ int WriteReadSeek(BasicIo &io)
throw Error(Exiv2::kerDataSourceOpenFailed, io.path(), strError());
}
std::memset(buf, -1, sizeof(buf));
if (static_cast<size_t>(io.read(buf, sizeof(buf))) != insert + size2) {
if (io.read(buf, sizeof(buf)) != insert + size2) {
std::cerr << ": WRS something went wrong\n";
return 10;
}

@ -47,7 +47,7 @@ int main(int argc, char* const argv[])
}
Exiv2::DataBuf buf(static_cast<long>(io.size()));
std::cout << "Reading " << buf.size() << " bytes from " << data << "\n";
long readBytes = io.read(buf.data(), buf.size());
const size_t readBytes = io.read(buf.data(), buf.size());
if (readBytes != buf.size() || io.error() || io.eof()) {
throw Exiv2::Error(Exiv2::kerFailedToReadImageData);
}

@ -49,9 +49,9 @@ try {
}
// Use MemIo to increase test coverage.
Exiv2::BasicIo::UniquePtr fileIo(new Exiv2::FileIo(params.read_));
Exiv2::BasicIo::UniquePtr memIo(new Exiv2::MemIo);
memIo->transfer(*fileIo);
Exiv2::FileIo fileIo(params.read_);
auto memIo = std::make_unique<Exiv2::MemIo>();
memIo->transfer(fileIo);
Exiv2::Image::UniquePtr readImg = Exiv2::ImageFactory::open(std::move(memIo));
assert(readImg.get() != 0);
@ -59,7 +59,9 @@ try {
Exiv2::Image::UniquePtr writeImg = Exiv2::ImageFactory::open(params.write_);
assert(writeImg.get() != 0);
if (params.preserve_) writeImg->readMetadata();
if (params.preserve_) {
writeImg->readMetadata();
}
if (params.iptc_) {
writeImg->setIptcData(readImg->iptcData());
}

@ -84,14 +84,14 @@ void mini1(const char* path)
enforce(wm == wmIntrusive, Exiv2::kerErrorMessage, "encode returned an unexpected value");
std::cout << "Test 3: Wrote non-empty Exif data without original binary data:\n";
exifData.clear();
ByteOrder bo = ExifParser::decode(exifData, &blob[0], static_cast<uint32_t>(blob.size()));
ByteOrder bo = ExifParser::decode(exifData, &blob[0], blob.size());
enforce(bo == bigEndian, Exiv2::kerErrorMessage, "decode returned an unexpected value");
print(exifData);
}
void mini9(const char* path)
{
TiffImage tiffImage(BasicIo::UniquePtr(new FileIo(path)), false);
TiffImage tiffImage(std::make_unique<FileIo>(path), false);
tiffImage.readMetadata();
std::cout << "MIME type: " << tiffImage.mimeType() << "\n";

@ -69,7 +69,7 @@ try {
if (file.open("wb") != 0) {
throw Exiv2::Error(Exiv2::kerFileOpenFailed, filename, "wb", Exiv2::strError());
}
if (file.write(reinterpret_cast<const Exiv2::byte*>(xmpPacket.data()), static_cast<long>(xmpPacket.size())) == 0) {
if (file.write(reinterpret_cast<const Exiv2::byte*>(xmpPacket.data()), xmpPacket.size()) == 0) {
throw Exiv2::Error(Exiv2::kerCallFailed, filename, Exiv2::strError(), "FileIo::write");
}
Exiv2::XmpParser::terminate();

@ -87,8 +87,8 @@ namespace {
}
namespace Exiv2 {
void BasicIo::readOrThrow(byte* buf, long rcount, ErrorCode err) {
const long nread = read(buf, rcount);
void BasicIo::readOrThrow(byte* buf, size_t rcount, ErrorCode err) {
const size_t nread = read(buf, rcount);
enforce(nread == rcount, err);
enforce(!error(), err);
}
@ -219,7 +219,7 @@ namespace Exiv2 {
} // FileIo::Impl::stat
FileIo::FileIo(const std::string& path)
: p_(new Impl(path))
: p_(std::make_unique<Impl>(path))
{
}
@ -336,25 +336,29 @@ namespace Exiv2 {
p_->path_ = path;
}
long FileIo::write(const byte* data, long wcount)
size_t FileIo::write(const byte* data, size_t wcount)
{
assert(p_->fp_ != 0);
if (p_->switchMode(Impl::opWrite) != 0) return 0;
return static_cast<long>(std::fwrite(data, 1, wcount, p_->fp_));
if (p_->switchMode(Impl::opWrite) != 0)
return 0;
return std::fwrite(data, 1, wcount, p_->fp_);
}
long FileIo::write(BasicIo& src)
size_t FileIo::write(BasicIo& src)
{
assert(p_->fp_ != 0);
if (static_cast<BasicIo*>(this) == &src) return 0;
if (!src.isopen()) return 0;
if (p_->switchMode(Impl::opWrite) != 0) return 0;
if (static_cast<BasicIo*>(this) == &src)
return 0;
if (!src.isopen())
return 0;
if (p_->switchMode(Impl::opWrite) != 0)
return 0;
byte buf[4096];
long readCount = 0;
long writeTotal = 0;
size_t readCount = 0;
size_t writeTotal = 0;
while ((readCount = src.read(buf, sizeof(buf)))) {
long writeCount = static_cast<long>(std::fwrite(buf, 1, readCount, p_->fp_));
size_t writeCount = std::fwrite(buf, 1, readCount, p_->fp_);
writeTotal += writeCount;
if (writeCount != readCount) {
// try to reset back to where write stopped
@ -548,35 +552,37 @@ namespace Exiv2 {
int FileIo::close()
{
int rc = 0;
if (munmap() != 0) rc = 2;
if (munmap() != 0)
rc = 2;
if (p_->fp_ != nullptr) {
if (std::fclose(p_->fp_) != 0) rc |= 1;
if (std::fclose(p_->fp_) != 0)
rc |= 1;
p_->fp_ = nullptr;
}
return rc;
}
DataBuf FileIo::read(long rcount)
DataBuf FileIo::read(size_t rcount)
{
assert(p_->fp_ != 0);
if (static_cast<size_t>(rcount) > size())
throw Error(kerInvalidMalloc);
DataBuf buf(rcount);
long readCount = read(buf.data(), buf.size());
if (readCount < 0) {
size_t readCount = read(buf.data(), buf.size());
if (readCount == 0) {
throw Error(kerInputDataReadFailed);
}
buf.resize(readCount);
return buf;
}
long FileIo::read(byte* buf, long rcount)
size_t FileIo::read(byte* buf, size_t rcount)
{
assert(p_->fp_ != 0);
if (p_->switchMode(Impl::opRead) != 0) {
return 0;
}
return static_cast<long>(std::fread(buf, 1, rcount, p_->fp_));
return std::fread(buf, 1, rcount, p_->fp_);
}
int FileIo::getb()
@ -609,25 +615,25 @@ namespace Exiv2 {
class MemIo::Impl final{
public:
Impl() = default; //!< Default constructor
Impl(const byte* data, long size); //!< Constructor 2
Impl(const byte* data, size_t size); //!< Constructor 2
// DATA
byte* data_{nullptr}; //!< Pointer to the start of the memory area
long idx_{0}; //!< Index into the memory area
long size_{0}; //!< Size of the memory area
long sizeAlloced_{0}; //!< Size of the allocated buffer
size_t idx_{0}; //!< Index into the memory area
size_t size_{0}; //!< Size of the memory area
size_t sizeAlloced_{0}; //!< Size of the allocated buffer
bool isMalloced_{false}; //!< Was the buffer allocated?
bool eof_{false}; //!< EOF indicator
// METHODS
void reserve(long wcount); //!< Reserve memory
void reserve(size_t wcount); //!< Reserve memory
// NOT IMPLEMENTED
Impl(const Impl& rhs) = delete; //!< Copy constructor
Impl& operator=(const Impl& rhs) = delete; //!< Assignment
}; // class MemIo::Impl
MemIo::Impl::Impl(const byte* data, long size) : data_(const_cast<byte*>(data)), size_(size)
MemIo::Impl::Impl(const byte* data, size_t size) : data_(const_cast<byte*>(data)), size_(size)
{
}
@ -700,15 +706,15 @@ namespace Exiv2 {
size_t size_{0};
}; // class BlockMap
void MemIo::Impl::reserve(long wcount)
void MemIo::Impl::reserve(size_t wcount)
{
const long need = wcount + idx_;
long blockSize = 32*1024; // 32768 `
const long maxBlockSize = 4*1024*1024;
const size_t need = wcount + idx_;
size_t blockSize = 32*1024; // 32768
const size_t maxBlockSize = 4*1024*1024;
if (!isMalloced_) {
// Minimum size for 1st block
long size = std::max(blockSize * (1 + need / blockSize), size_);
size_t size = std::max(blockSize * (1 + need / blockSize), size_);
auto data = static_cast<byte*>(std::malloc(size));
if (data == nullptr) {
throw Error(kerMallocFailed);
@ -726,7 +732,7 @@ namespace Exiv2 {
blockSize = 2*sizeAlloced_ ;
if ( blockSize > maxBlockSize ) blockSize = maxBlockSize ;
// Allocate in blocks
long want = blockSize * (1 + need / blockSize );
size_t want = blockSize * (1 + need / blockSize );
data_ = static_cast<byte*>(std::realloc(data_, want));
if (data_ == nullptr) {
throw Error(kerMallocFailed);
@ -738,12 +744,12 @@ namespace Exiv2 {
}
MemIo::MemIo()
: p_(new Impl())
: p_(std::make_unique<Impl>())
{
}
MemIo::MemIo(const byte* data, long size)
: p_(new Impl(data, size))
MemIo::MemIo(const byte* data, size_t size)
: p_(std::make_unique<Impl>(data, size))
{
}
@ -754,7 +760,7 @@ namespace Exiv2 {
}
}
long MemIo::write(const byte* data, long wcount)
size_t MemIo::write(const byte* data, size_t wcount)
{
p_->reserve(wcount);
assert(p_->isMalloced_);
@ -794,14 +800,14 @@ namespace Exiv2 {
if (error() || src.error()) throw Error(kerMemoryTransferFailed, strError());
}
long MemIo::write(BasicIo& src)
size_t MemIo::write(BasicIo& src)
{
if (static_cast<BasicIo*>(this) == &src) return 0;
if (!src.isopen()) return 0;
byte buf[4096];
long readCount = 0;
long writeTotal = 0;
size_t readCount = 0;
size_t writeTotal = 0;
while ((readCount = src.read(buf, sizeof(buf)))) {
write(buf, readCount);
writeTotal += readCount;
@ -831,7 +837,7 @@ namespace Exiv2 {
if (newIdx < 0)
return 1;
if (newIdx > p_->size_) {
if (newIdx > static_cast<int64_t>(p_->size_)) {
p_->eof_ = true;
return 1;
}
@ -853,7 +859,7 @@ namespace Exiv2 {
long MemIo::tell() const
{
return p_->idx_;
return static_cast<long>(p_->idx_);
}
size_t MemIo::size() const
@ -878,18 +884,18 @@ namespace Exiv2 {
return 0;
}
DataBuf MemIo::read(long rcount)
DataBuf MemIo::read(size_t rcount)
{
DataBuf buf(rcount);
long readCount = read(buf.data(), buf.size());
size_t readCount = read(buf.data(), buf.size());
buf.resize(readCount);
return buf;
}
long MemIo::read(byte* buf, long rcount)
size_t MemIo::read(byte* buf, size_t rcount)
{
const long avail = std::max(p_->size_ - p_->idx_, 0L);
const long allow = std::min(rcount, avail);
const size_t avail = std::max(p_->size_ - p_->idx_, static_cast<size_t>(0));
const size_t allow = std::min(rcount, avail);
if (allow > 0) {
std::memcpy(buf, &p_->data_[p_->idx_], allow);
}
@ -1073,11 +1079,11 @@ namespace Exiv2 {
size_t blockSize_; //!< Size of the block memory.
BlockMap* blocksMap_; //!< An array contains all blocksMap
size_t size_; //!< The file size
long idx_; //!< Index into the memory area
size_t idx_; //!< Index into the memory area
bool isMalloced_; //!< Was the blocksMap_ allocated?
bool eof_; //!< EOF indicator
Protocol protocol_; //!< the protocol of url
uint32_t totalRead_; //!< bytes requested from host
size_t totalRead_; //!< bytes requested from host
// METHODS
/*!
@ -1168,11 +1174,12 @@ namespace Exiv2 {
delete[] blocksMap_;
}
RemoteIo::RemoteIo() = default;
RemoteIo::~RemoteIo()
{
if (p_) {
close();
delete p_;
}
}
@ -1226,12 +1233,12 @@ namespace Exiv2 {
return 0;
}
long RemoteIo::write(const byte* /* unused data*/, long /* unused wcount*/)
size_t RemoteIo::write(const byte* /* unused data*/, size_t /* unused wcount*/)
{
return 0; // means failure
}
long RemoteIo::write(BasicIo& src)
size_t RemoteIo::write(BasicIo& src)
{
assert(p_->isMalloced_);
if (!src.isopen()) return 0;
@ -1255,7 +1262,7 @@ namespace Exiv2 {
while (blockIndex < nBlocks && !src.eof() && !findDiff) {
size_t blockSize = p_->blocksMap_[blockIndex].getSize();
bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data
size_t readCount = static_cast<size_t>(src.read(buf.data(), static_cast<long>(blockSize)));
size_t readCount = src.read(buf.data(), blockSize);
byte* blockData = p_->blocksMap_[blockIndex].getData();
for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
if ((!isFakeData && buf[i] != blockData[i]) || (isFakeData && buf[i] != 0)) {
@ -1277,7 +1284,7 @@ namespace Exiv2 {
findDiff = true;
} else {
bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data
size_t readCount = src.read(buf.data(), static_cast<long>(blockSize));
size_t readCount = src.read(buf.data(), blockSize);
byte* blockData = p_->blocksMap_[blockIndex].getData();
for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
if ((!isFakeData && buf[readCount - i - 1] != blockData[blockSize - i - 1]) || (isFakeData && buf[readCount - i - 1] != 0)) {
@ -1295,9 +1302,9 @@ namespace Exiv2 {
auto data = static_cast<byte*>(std::malloc(dataSize));
src.seek(left, BasicIo::beg);
src.read(data, dataSize);
p_->writeRemote(data, static_cast<size_t>(dataSize), static_cast<long>(left),
static_cast<long>(p_->size_ - right));
if (data) std::free(data);
p_->writeRemote(data, dataSize, static_cast<long>(left), static_cast<long>(p_->size_ - right));
if (data)
std::free(data);
}
return static_cast<long>(src.size());
}
@ -1307,24 +1314,25 @@ namespace Exiv2 {
return 0;
}
DataBuf RemoteIo::read(long rcount)
DataBuf RemoteIo::read(size_t rcount)
{
DataBuf buf(rcount);
long readCount = read(buf.data(), buf.size());
if (readCount < 0) {
size_t readCount = read(buf.data(), buf.size());
if (readCount == 0) {
throw Error(kerInputDataReadFailed);
}
buf.resize(readCount);
return buf;
}
long RemoteIo::read(byte* buf, long rcount)
size_t RemoteIo::read(byte* buf, size_t rcount)
{
assert(p_->isMalloced_);
if (p_->eof_) return 0;
if (p_->eof_)
return 0;
p_->totalRead_ += rcount;
size_t allow = std::min(rcount, (long)( p_->size_ - p_->idx_));
size_t allow = std::min(rcount, ( p_->size_ - p_->idx_));
size_t lowBlock = p_->idx_ /p_->blockSize_;
size_t highBlock = (p_->idx_ + allow)/p_->blockSize_;
@ -1351,16 +1359,16 @@ namespace Exiv2 {
std::free(fakeData);
p_->idx_ += static_cast<long>(totalRead);
p_->eof_ = (p_->idx_ == static_cast<long>(p_->size_));
p_->idx_ += totalRead;
p_->eof_ = (p_->idx_ == p_->size_);
return static_cast<long>(totalRead);
return totalRead;
}
int RemoteIo::getb()
{
assert(p_->isMalloced_);
if (p_->idx_ == static_cast<long>(p_->size_)) {
if (p_->idx_ == p_->size_) {
p_->eof_ = true;
return EOF;
}
@ -1395,10 +1403,10 @@ namespace Exiv2 {
// #1198. Don't return 1 when asked to seek past EOF. Stay calm and set eof_
// if (newIdx < 0 || newIdx > (long) p_->size_) return 1;
p_->idx_ = static_cast<long>(newIdx);
p_->eof_ = newIdx > static_cast<long>(p_->size_);
if (p_->idx_ > static_cast<long>(p_->size_))
p_->idx_ = static_cast<long>(p_->size_);
p_->idx_ = static_cast<size_t>(newIdx);
p_->eof_ = newIdx > static_cast<int64_t>(p_->size_);
if (p_->idx_ > p_->size_)
p_->idx_ = p_->size_;
return 0;
}
@ -1432,7 +1440,7 @@ namespace Exiv2 {
long RemoteIo::tell() const
{
return p_->idx_;
return static_cast<long>(p_->idx_);
}
size_t RemoteIo::size() const
@ -1588,11 +1596,10 @@ namespace Exiv2 {
// encode base64
size_t encodeLength = ((size + 2) / 3) * 4 + 1;
auto encodeData = new char[encodeLength];
base64encode(data, size, encodeData, encodeLength);
std::vector<char> encodeData (encodeLength);
base64encode(data, size, encodeData.data(), encodeLength);
// url encode
const std::string urlencodeData = urlencode(encodeData);
delete[] encodeData;
const std::string urlencodeData = urlencode(encodeData.data());
std::stringstream ss;
ss << "path=" << hostInfo_.Path << "&"
@ -1613,9 +1620,10 @@ namespace Exiv2 {
throw Error(kerFileOpenFailed, "http",Exiv2::Internal::stringFormat("%d",serverCode), hostInfo_.Path);
}
}
HttpIo::HttpIo(const std::string& url, size_t blockSize)
{
p_ = new HttpImpl(url, blockSize);
p_ = std::make_unique<HttpImpl>(url, blockSize);
}
#ifdef EXV_USE_CURL
@ -1776,11 +1784,10 @@ namespace Exiv2 {
// encode base64
size_t encodeLength = ((size + 2) / 3) * 4 + 1;
auto encodeData = new char[encodeLength];
base64encode(data, size, encodeData, encodeLength);
std::vector<char> encodeData (encodeLength);
base64encode(data, size, encodeData.data(), encodeLength);
// url encode
const std::string urlencodeData = urlencode(encodeData);
delete[] encodeData;
const std::string urlencodeData = urlencode(encodeData.data());
std::stringstream ss;
ss << "path=" << hostInfo.Path << "&"
<< "from=" << from << "&"
@ -1806,7 +1813,7 @@ namespace Exiv2 {
curl_easy_cleanup(curl_);
}
long CurlIo::write(const byte* data, long wcount)
size_t CurlIo::write(const byte* data, size_t wcount)
{
if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) {
return RemoteIo::write(data, wcount);
@ -1814,7 +1821,7 @@ namespace Exiv2 {
throw Error(kerErrorMessage, "doesnt support write for this protocol.");
}
long CurlIo::write(BasicIo& src)
size_t CurlIo::write(BasicIo& src)
{
if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) {
return RemoteIo::write(src);
@ -1824,7 +1831,7 @@ namespace Exiv2 {
CurlIo::CurlIo(const std::string& url, size_t blockSize)
{
p_ = new CurlImpl(url, blockSize);
p_ = std::make_unique<CurlImpl>(url, blockSize);
}
#endif
@ -1843,14 +1850,14 @@ namespace Exiv2 {
throw Error(kerCallFailed, path, strError(), "::stat");
}
DataBuf buf(st.st_size);
long len = file.read(buf.data(), buf.size());
const size_t len = file.read(buf.data(), buf.size());
if (len != buf.size()) {
throw Error(kerCallFailed, path, strError(), "FileIo::read");
}
return buf;
}
long writeFile(const DataBuf& buf, const std::string& path)
size_t writeFile(const DataBuf& buf, const std::string& path)
{
FileIo file(path);
if (file.open("wb") != 0) {

@ -237,24 +237,24 @@ namespace Exiv2
// read data in box and restore file position
long restore = io_->tell();
enforce(box_length >= hdrsize, Exiv2::kerCorruptedMetadata);
enforce(box_length - hdrsize <= static_cast<size_t>(pbox_end - restore), Exiv2::kerCorruptedMetadata);
enforce(box_length - hdrsize <= static_cast<uint64_t>(pbox_end - restore), Exiv2::kerCorruptedMetadata);
const long buffer_size = static_cast<long>(box_length - hdrsize);
const size_t buffer_size = static_cast<size_t>(box_length - hdrsize);
if (skipBox(box_type)) {
if (bTrace) {
out << std::endl;
}
// The enforce() above checks that restore + buffer_size won't
// exceed pbox_end, and by implication, won't exceed LONG_MAX
return restore + buffer_size;
return restore + static_cast<long>(buffer_size);
}
DataBuf data(buffer_size);
const long box_end = restore + data.size();
const long box_end = restore + static_cast<long>(data.size());
io_->read(data.data(), data.size());
io_->seek(restore, BasicIo::beg);
long skip = 0; // read position in data.pData_
size_t skip = 0; // read position in data.pData_
uint8_t version = 0;
uint32_t flags = 0;
@ -303,8 +303,8 @@ namespace Exiv2
std::string id;
// Check that the string has a '\0' terminator.
const char* str = data.c_str(skip);
const auto maxlen = static_cast<size_t>(data.size() - skip);
enforce(strnlen(str, maxlen) < maxlen, Exiv2::kerCorruptedMetadata);
const size_t maxlen = data.size() - skip;
enforce(maxlen > 0 && strnlen(str, maxlen) < maxlen, Exiv2::kerCorruptedMetadata);
std::string name(str);
if (name.find("Exif") != std::string::npos) { // "Exif" or "ExifExif"
exifID_ = ID;
@ -366,7 +366,7 @@ namespace Exiv2
#else
skip++;
#endif
enforce(data.size() - skip >= (version < 2 ? 2 : 4), Exiv2::kerCorruptedMetadata);
enforce(data.size() - skip >= (version < 2u ? 2u : 4u), Exiv2::kerCorruptedMetadata);
uint32_t itemCount = version < 2 ? data.read_uint16(skip, endian_)
: data.read_uint32(skip, endian_);
skip += version < 2 ? 2 : 4;
@ -376,11 +376,11 @@ namespace Exiv2
out << std::endl;
bLF = false;
}
long step = static_cast<long>((box_length - 16) / itemCount); // length of data per item.
long base = skip;
size_t step = (static_cast<size_t>(box_length) - 16) / itemCount; // length of data per item.
size_t base = skip;
for (uint32_t i = 0; i < itemCount; i++) {
skip = base + i * step; // move in 14, 16 or 18 byte steps
enforce(data.size() - skip >= (version > 2 ? 4 : 2), Exiv2::kerCorruptedMetadata);
enforce(data.size() - skip >= (version > 2u ? 4u : 2u), Exiv2::kerCorruptedMetadata);
enforce(data.size() - skip >= step, Exiv2::kerCorruptedMetadata);
uint32_t ID = version > 2 ? data.read_uint32(skip, endian_)
: data.read_uint16(skip, endian_);
@ -423,8 +423,7 @@ namespace Exiv2
// 12.1.5.2
case TAG_colr: {
if (data.size() >=
static_cast<long>(skip + 4 + 8)) { // .____.HLino..__mntrR 2 0 0 0 0 12 72 76 105 110 111 2 16 ...
if (data.size() >= (skip + 4 + 8)) { // .____.HLino..__mntrR 2 0 0 0 0 12 72 76 105 110 111 2 16 ...
// https://www.ics.uci.edu/~dan/class/267/papers/jpeg2000.pdf
uint8_t meth = data.read_uint8(skip+0);
uint8_t prec = data.read_uint8(skip+1);
@ -518,26 +517,26 @@ namespace Exiv2
{
enforce(start <= io_->size(), kerCorruptedMetadata);
enforce(length <= io_->size() - start, kerCorruptedMetadata);
enforce(start <= static_cast<unsigned long>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
enforce(length <= static_cast<unsigned long>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
enforce(start <= std::numeric_limits<uint64_t>::max(), kerCorruptedMetadata);
enforce(length <= std::numeric_limits<uint64_t>::max(), kerCorruptedMetadata);
// read and parse exif data
long restore = io_->tell();
DataBuf exif(static_cast<long>(length));
DataBuf exif(static_cast<size_t>(length));
io_->seek(static_cast<long>(start),BasicIo::beg);
if ( exif.size() > 8 && io_->read(exif.data(),exif.size()) == exif.size() ) {
// hunt for "II" or "MM"
long eof = 0xffffffff; // impossible value for punt
long punt = eof;
for ( long i = 0 ; i < exif.size() -8 && punt==eof ; i+=2) {
for ( size_t i = 0 ; i < exif.size() -8 && punt==eof ; i+=2) {
if ( exif.read_uint8(i) == exif.read_uint8(i+1) )
if ( exif.read_uint8(i) == 'I' || exif.read_uint8(i) == 'M' )
punt = i;
punt = static_cast<long>(i);
}
if ( punt != eof ) {
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(),
exif.c_data(punt), exif.size()-punt, root_tag,
Internal::TiffMapping::findDecoder);
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt),
static_cast<uint32_t>(exif.size()-punt), root_tag,
Internal::TiffMapping::findDecoder);
}
}
io_->seek(restore,BasicIo::beg);
@ -547,9 +546,9 @@ namespace Exiv2
{
if (length > 8) {
enforce(length - 8 <= io_->size() - io_->tell(), kerCorruptedMetadata);
enforce(length - 8 <= static_cast<unsigned long>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
DataBuf data(static_cast<long>(length - 8));
long bufRead = io_->read(data.data(), data.size());
enforce(length - 8 <= std::numeric_limits<uint64_t>::max(), kerCorruptedMetadata);
DataBuf data(static_cast<size_t>(length) - 8);
const size_t bufRead = io_->read(data.data(), data.size());
if (io_->error())
throw Error(kerFailedToReadImageData);
@ -557,7 +556,7 @@ namespace Exiv2
throw Error(kerInputDataReadFailed);
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(),
data.c_data(), data.size(), root_tag,
data.c_data(), static_cast<uint32_t>(data.size()), root_tag,
Internal::TiffMapping::findDecoder);
}
}
@ -569,13 +568,13 @@ namespace Exiv2
enforce(length <= io_->size() - start, kerCorruptedMetadata);
long restore = io_->tell() ;
enforce(start <= static_cast<unsigned long>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
enforce(start <= std::numeric_limits<uint64_t>::max(), kerCorruptedMetadata);
io_->seek(static_cast<long>(start),BasicIo::beg);
enforce(length < static_cast<unsigned long>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
DataBuf xmp(static_cast<long>(length+1));
enforce(length < std::numeric_limits<uint64_t>::max(), kerCorruptedMetadata);
DataBuf xmp(static_cast<size_t>(length+1));
xmp.write_uint8(static_cast<size_t>(length), 0); // ensure xmp is null terminated!
if ( io_->read(xmp.data(), static_cast<long>(length)) != static_cast<long>(length) )
if ( io_->read(xmp.data(), static_cast<size_t>(length)) != length )
throw Error(kerInputDataReadFailed);
if ( io_->error() )
throw Error(kerFailedToReadImageData);
@ -589,14 +588,15 @@ namespace Exiv2
}
}
/// \todo instead of passing the last 4 parameters, pass just one and build the different offsets inside
void BmffImage::parseCr3Preview(DataBuf &data,
std::ostream& out,
bool bTrace,
uint8_t version,
uint32_t width_offset,
uint32_t height_offset,
uint32_t size_offset,
uint32_t relative_position)
size_t width_offset,
size_t height_offset,
size_t size_offset,
size_t relative_position)
{
// Derived from https://github.com/lclevy/canon_cr3
long here = io_->tell();
@ -604,7 +604,7 @@ namespace Exiv2
here <= std::numeric_limits<long>::max() - static_cast<long>(relative_position),
kerCorruptedMetadata);
NativePreview nativePreview;
nativePreview.position_ = here + relative_position;
nativePreview.position_ = here + static_cast<long>(relative_position);
nativePreview.width_ = data.read_uint16(width_offset, endian_);
nativePreview.height_ = data.read_uint16(height_offset, endian_);
nativePreview.size_ = data.read_uint32(size_offset, endian_);

@ -225,14 +225,15 @@ namespace Exiv2 {
{
// format is: "YYMM#00#00DDHH#00#00MM#00#00#00#00" or "YYMM#00#00DDHH#00#00MMSS#00#00#00"
std::vector<char> numbers;
for(long i=0; i<value.size(); i++)
for(size_t i=0; i<value.size(); i++)
{
const auto l = value.toInt64(i);
if(l!=0)
{
numbers.push_back(static_cast<char>(l));
};
};
}
}
if(numbers.size()>=10)
{
//year
@ -544,14 +545,15 @@ namespace Exiv2 {
{
// format is: "YYMM#00#00DDHH#00#00MM#00#00#00#00"
std::vector<char> numbers;
for(long i=0; i<value.size(); i++)
for(size_t i=0; i<value.size(); i++)
{
const auto l = value.toInt64(i);
const char l = static_cast<char>(value.toInt64(i));
if(l!=0)
{
numbers.push_back(static_cast<char>(l));
};
};
numbers.push_back(l);
}
}
if(numbers.size()>=10)
{
//year

@ -483,8 +483,10 @@ namespace Exiv2 {
bool Converter::prepareExifTarget(const char* to, bool force)
{
auto pos = exifData_->findKey(ExifKey(to));
if (pos == exifData_->end()) return true;
if (!overwrite_ && !force) return false;
if (pos == exifData_->end())
return true;
if (!overwrite_ && !force)
return false;
exifData_->erase(pos);
return true;
}
@ -492,8 +494,10 @@ namespace Exiv2 {
bool Converter::prepareIptcTarget(const char* to, bool force)
{
auto pos = iptcData_->findKey(IptcKey(to));
if (pos == iptcData_->end()) return true;
if (!overwrite_ && !force) return false;
if (pos == iptcData_->end())
return true;
if (!overwrite_ && !force)
return false;
while ((pos = iptcData_->findKey(IptcKey(to))) != iptcData_->end()) {
iptcData_->erase(pos);
}
@ -503,8 +507,10 @@ namespace Exiv2 {
bool Converter::prepareXmpTarget(const char* to, bool force)
{
auto pos = xmpData_->findKey(XmpKey(to));
if (pos == xmpData_->end()) return true;
if (!overwrite_ && !force) return false;
if (pos == xmpData_->end())
return true;
if (!overwrite_ && !force)
return false;
xmpData_->erase(pos);
return true;
}
@ -512,7 +518,8 @@ namespace Exiv2 {
void Converter::cnvExifValue(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (pos == exifData_->end())
return;
std::string value = pos->toString();
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
@ -520,7 +527,8 @@ namespace Exiv2 {
#endif
return;
}
if (!prepareXmpTarget(to)) return;
if (!prepareXmpTarget(to))
return;
(*xmpData_)[to] = value;
if (erase_) exifData_->erase(pos);
}
@ -528,8 +536,10 @@ namespace Exiv2 {
void Converter::cnvExifComment(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return;
if (pos == exifData_->end())
return;
if (!prepareXmpTarget(to))
return;
const auto cv = dynamic_cast<const CommentValue*>(&pos->value());
if (cv == nullptr) {
#ifndef SUPPRESS_WARNINGS
@ -545,10 +555,12 @@ namespace Exiv2 {
void Converter::cnvExifArray(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return;
for (long i = 0; i < pos->count(); ++i) {
std::string value = pos->toString(i);
if (pos == exifData_->end())
return;
if (!prepareXmpTarget(to))
return;
for (size_t i = 0; i < pos->count(); ++i) {
std::string value = pos->toString(static_cast<long>(i));
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
@ -563,8 +575,10 @@ namespace Exiv2 {
void Converter::cnvExifDate(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return;
if (pos == exifData_->end())
return;
if (!prepareXmpTarget(to))
return;
int year=0, month=0, day=0, hour=0, min=0, sec=0;
std::string subsec;
char buf[30];
@ -692,11 +706,13 @@ namespace Exiv2 {
void Converter::cnvExifVersion(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return;
if (pos == exifData_->end())
return;
if (!prepareXmpTarget(to))
return;
std::ostringstream value;
for (long i = 0; i < pos->count(); ++i) {
value << static_cast<char>(pos->toInt64(i));
for (size_t i = 0; i < pos->count(); ++i) {
value << static_cast<char>(pos->toInt64(static_cast<long>(i)));
}
(*xmpData_)[to] = value.str();
if (erase_) exifData_->erase(pos);
@ -705,12 +721,14 @@ namespace Exiv2 {
void Converter::cnvExifGPSVersion(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return;
if (pos == exifData_->end())
return;
if (!prepareXmpTarget(to))
return;
std::ostringstream value;
for (long i = 0; i < pos->count(); ++i) {
for (size_t i = 0; i < pos->count(); ++i) {
if (i > 0) value << '.';
value << pos->toInt64(i);
value << pos->toInt64(static_cast<long>(i));
}
(*xmpData_)[to] = value.str();
if (erase_) exifData_->erase(pos);
@ -719,8 +737,10 @@ namespace Exiv2 {
void Converter::cnvExifFlash(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end() || pos->count() == 0) return;
if (!prepareXmpTarget(to)) return;
if (pos == exifData_->end() || pos->count() == 0)
return;
if (!prepareXmpTarget(to))
return;
auto value = pos->toInt64();
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
@ -741,8 +761,10 @@ namespace Exiv2 {
void Converter::cnvExifGPSCoord(const char* from, const char* to)
{
auto pos = exifData_->findKey(ExifKey(from));
if (pos == exifData_->end()) return;
if (!prepareXmpTarget(to)) return;
if (pos == exifData_->end())
return;
if (!prepareXmpTarget(to))
return;
if (pos->count() != 3) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
@ -785,8 +807,10 @@ namespace Exiv2 {
void Converter::cnvXmpValue(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (!prepareExifTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareExifTarget(to))
return;
std::string value;
if (!getTextValue(value, pos)) {
#ifndef SUPPRESS_WARNINGS
@ -805,9 +829,11 @@ namespace Exiv2 {
void Converter::cnvXmpComment(const char* from, const char* to)
{
if (!prepareExifTarget(to)) return;
if (!prepareExifTarget(to))
return;
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (pos == xmpData_->end())
return;
std::string value;
if (!getTextValue(value, pos)) {
#ifndef SUPPRESS_WARNINGS
@ -822,12 +848,14 @@ namespace Exiv2 {
void Converter::cnvXmpArray(const char* from, const char* to)
{
if (!prepareExifTarget(to)) return;
if (!prepareExifTarget(to))
return;
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (pos == xmpData_->end())
return;
std::ostringstream array;
for (long i = 0; i < pos->count(); ++i) {
std::string value = pos->toString(i);
for (size_t i = 0; i < pos->count(); ++i) {
std::string value = pos->toString(static_cast<long>(i));
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
@ -835,17 +863,21 @@ namespace Exiv2 {
return;
}
array << value;
if (i != pos->count() - 1) array << " ";
if (i != pos->count() - 1)
array << " ";
}
(*exifData_)[to] = array.str();
if (erase_) xmpData_->erase(pos);
if (erase_)
xmpData_->erase(pos);
}
void Converter::cnvXmpDate(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (!prepareExifTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareExifTarget(to))
return;
#ifdef EXV_HAVE_XMP_TOOLKIT
std::string value = pos->toString();
if (!pos->value().ok()) {
@ -859,9 +891,9 @@ namespace Exiv2 {
SXMPUtils::ConvertToDate(value, &datetime);
char buf[30];
if (std::string(to) != "Exif.GPSInfo.GPSTimeStamp") {
SXMPUtils::ConvertToLocalTime(&datetime);
snprintf(buf, sizeof(buf), "%4d:%02d:%02d %02d:%02d:%02d",
static_cast<int>(datetime.year),
static_cast<int>(datetime.month),
@ -871,7 +903,7 @@ namespace Exiv2 {
static_cast<int>(datetime.second));
buf[sizeof(buf) - 1] = 0;
(*exifData_)[to] = buf;
if (datetime.nanoSecond) {
const char* subsecTag = nullptr;
if (std::string(to) == "Exif.Image.DateTime") {
@ -890,9 +922,9 @@ namespace Exiv2 {
}
}
else { // "Exif.GPSInfo.GPSTimeStamp"
// Ignore the time zone, assuming the time is in UTC as it should be
URational rhour(datetime.hour, 1);
URational rmin(datetime.minute, 1);
URational rsec(datetime.second, 1);
@ -906,11 +938,11 @@ namespace Exiv2 {
rsec.second = 1000000000;
rsec.first = datetime.nanoSecond;
}
std::ostringstream array;
array << rhour << " " << rmin << " " << rsec;
(*exifData_)[to] = array.str();
prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true);
snprintf(buf, sizeof(buf), "%4d:%02d:%02d",
static_cast<int>(datetime.year),
@ -942,8 +974,10 @@ namespace Exiv2 {
void Converter::cnvXmpVersion(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (!prepareExifTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareExifTarget(to))
return;
std::string value = pos->toString();
if (!pos->value().ok() || value.length() < 4) {
#ifndef SUPPRESS_WARNINGS
@ -965,8 +999,10 @@ namespace Exiv2 {
void Converter::cnvXmpGPSVersion(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (!prepareExifTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareExifTarget(to))
return;
std::string value = pos->toString();
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
@ -984,8 +1020,10 @@ namespace Exiv2 {
void Converter::cnvXmpFlash(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Fired"));
if (pos == xmpData_->end()) return;
if (!prepareExifTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareExifTarget(to))
return;
unsigned short value = 0;
if (pos != xmpData_->end() && pos->count() > 0) {
@ -1047,8 +1085,10 @@ namespace Exiv2 {
void Converter::cnvXmpGPSCoord(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (!prepareExifTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareExifTarget(to))
return;
std::string value = pos->toString();
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
@ -1110,8 +1150,10 @@ namespace Exiv2 {
void Converter::cnvIptcValue(const char* from, const char* to)
{
auto pos = iptcData_->findKey(IptcKey(from));
if (pos == iptcData_->end()) return;
if (!prepareXmpTarget(to)) return;
if (pos == iptcData_->end())
return;
if (!prepareXmpTarget(to))
return;
while (pos != iptcData_->end()) {
if (pos->key() == from) {
std::string value = pos->toString();
@ -1136,8 +1178,10 @@ namespace Exiv2 {
void Converter::cnvXmpValueToIptc(const char* from, const char* to)
{
auto pos = xmpData_->findKey(XmpKey(from));
if (pos == xmpData_->end()) return;
if (!prepareIptcTarget(to)) return;
if (pos == xmpData_->end())
return;
if (!prepareIptcTarget(to))
return;
if (pos->typeId() == langAlt || pos->typeId() == xmpText) {
std::string value;
@ -1153,10 +1197,10 @@ namespace Exiv2 {
return;
}
int count = pos->count();
size_t count = pos->count();
bool added = false;
for (int i = 0; i < count; ++i) {
std::string value = pos->toString(i);
for (size_t i = 0; i < count; ++i) {
std::string value = pos->toString(static_cast<long>(i));
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
@ -1193,7 +1237,7 @@ namespace Exiv2 {
if (pos == exifData_->end()) continue;
DataBuf data(pos->size());
pos->copy(data.data(), littleEndian /* FIXME ? */);
MD5Update ( &context, data.c_data(), data.size());
MD5Update ( &context, data.c_data(), static_cast<uint32_t>(data.size()));
}
}
MD5Final(digest, &context);
@ -1326,7 +1370,8 @@ namespace Exiv2 {
bool convertStringCharset(std::string &str, const char* from, const char* to)
{
if (0 == strcmp(from, to)) return true; // nothing to do
if (0 == strcmp(from, to))
return true; // nothing to do
bool ret = false;
#if defined EXV_HAVE_ICONV
ret = convertStringCharsetIconv(str, from, to);
@ -1368,7 +1413,8 @@ namespace {
bool mb2wc(UINT cp, std::string& str)
{
if (str.empty()) return true;
if (str.empty())
return true;
int len = MultiByteToWideChar(cp, 0, str.c_str(), (int)str.size(), 0, 0);
if (len == 0) {
#ifdef EXIV2_DEBUG_MESSAGES
@ -1391,7 +1437,8 @@ namespace {
bool wc2mb(UINT cp, std::string& str)
{
if (str.empty()) return true;
if (str.empty())
return true;
if (str.size() & 1) {
#ifdef EXIV2_DEBUG_MESSAGES
EXV_DEBUG << "wc2mb: Size " << str.size() << " of input string is not even.\n";
@ -1506,7 +1553,8 @@ namespace {
#if defined EXV_HAVE_ICONV
bool convertStringCharsetIconv(std::string& str, const char* from, const char* to)
{
if (0 == strcmp(from, to)) return true; // nothing to do
if (0 == strcmp(from, to))
return true; // nothing to do
bool ret = true;
iconv_t cd;

@ -177,7 +177,7 @@ namespace Exiv2 {
ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end());
}
std::unique_ptr<TiffHeaderBase> header(new Cr2Header(byteOrder));
Cr2Header header(byteOrder);
OffsetWriter offsetWriter;
offsetWriter.setOrigin(OffsetWriter::cr2RawIfdOffset, Cr2Header::offset2addr(), byteOrder);
return TiffParserWorker::encode(io,
@ -188,7 +188,7 @@ namespace Exiv2 {
xmpData,
Tag::root,
TiffMapping::findEncoder,
header.get(),
&header,
&offsetWriter);
}

@ -101,7 +101,7 @@ namespace Exiv2 {
throw Error(kerNotACrwImage);
}
clearMetadata();
DataBuf file(static_cast<long>(io().size()));
DataBuf file(io().size());
io_->read(file.data(), file.size());
CrwParser::decode(this, io_->mmap(), static_cast<uint32_t>(io_->size()));
@ -120,7 +120,7 @@ namespace Exiv2 {
// Ensure that this is the correct image type
if (isCrwType(*io_, false)) {
// Read the image into a memory buffer
buf.alloc(static_cast<long>(io_->size()));
buf.alloc(io_->size());
io_->read(buf.data(), buf.size());
if (io_->error() || io_->eof()) {
buf.reset();
@ -129,7 +129,7 @@ namespace Exiv2 {
}
Blob blob;
CrwParser::encode(blob, buf.c_data(), buf.size(), this);
CrwParser::encode(blob, buf.c_data(), static_cast<uint32_t>(buf.size()), this);
// Write new buffer to file
auto tempIo = std::make_unique<MemIo>();

@ -169,8 +169,6 @@ namespace Exiv2 {
CiffHeader::~CiffHeader()
{
delete pRootDir_;
delete[] pPadding_;
}
CiffDirectory::~CiffDirectory()
@ -214,12 +212,12 @@ namespace Exiv2 {
throw Error(kerNotACrwImage);
}
delete[] pPadding_;
pPadding_ = new byte[offset_ - 14];
pPadding_.clear();
pPadding_.resize(offset_ - 14);
padded_ = offset_ - 14;
std::memcpy(pPadding_, pData + 14, padded_);
std::copy_n(pData+14, padded_, pPadding_.begin());
pRootDir_ = new CiffDirectory;
pRootDir_ = std::make_unique<CiffDirectory>();
pRootDir_->readDirectory(pData + offset_, size - offset_, byteOrder_);
} // CiffHeader::read
@ -329,8 +327,9 @@ namespace Exiv2 {
void CiffHeader::decode(Image& image) const
{
// Nothing to decode from the header itself, just add correct byte order
if (pRootDir_) pRootDir_->decode(image, byteOrder_);
} // CiffHeader::decode
if (pRootDir_)
pRootDir_->decode(image, byteOrder_);
}
void CiffComponent::decode(Image& image, ByteOrder byteOrder) const
{
@ -369,9 +368,9 @@ namespace Exiv2 {
append(blob, reinterpret_cast<const byte*>(signature_), 8);
o += 8;
// Pad as needed
if (pPadding_) {
if (pPadding_.empty() == false) {
assert(padded_ == offset_ - o);
append(blob, pPadding_, padded_);
append(blob, pPadding_.data(), padded_);
}
else {
for (uint32_t i = o; i < offset_; ++i) {
@ -544,7 +543,7 @@ namespace Exiv2 {
{
storage_ = std::move(buf);
pData_ = storage_.c_data();
size_ = storage_.size();
size_ = static_cast<uint32_t>(storage_.size());
if (size_ > 8 && dataLocation() == directoryData) {
tag_ &= 0x3fff;
}
@ -622,7 +621,7 @@ namespace Exiv2 {
assert(rootDirectory == 0x0000);
crwDirs.pop();
if (!pRootDir_) {
pRootDir_ = new CiffDirectory;
pRootDir_ = std::make_unique<CiffDirectory>();
}
CiffComponent* child = pRootDir_->add(crwDirs, crwTagId);
if (child) {
@ -683,7 +682,7 @@ namespace Exiv2 {
}
if (cc_ == nullptr) {
// Tag doesn't exist yet, add it
m_ = UniquePtr(new CiffEntry(crwTagId, tag()));
m_ = std::make_unique<CiffEntry>(crwTagId, tag());
cc_ = m_.get();
add(std::move(m_));
}
@ -1020,7 +1019,6 @@ namespace Exiv2 {
auto size = static_cast<uint32_t>(comment.size());
if (cc && cc->size() > size) size = cc->size();
DataBuf buf(size);
buf.clear();
buf.copyBytes(0, comment.data(), comment.size());
pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf));
}
@ -1028,7 +1026,6 @@ namespace Exiv2 {
if (cc) {
// Just delete the value, do not remove the tag
DataBuf buf(cc->size());
buf.clear();
cc->setValue(std::move(buf));
}
}
@ -1085,7 +1082,7 @@ namespace Exiv2 {
}
assert(ifdId != ifdIdNotSet);
DataBuf buf = packIfdId(image.exifData(), ifdId, pHead->byteOrder());
if (buf.size() == 0) {
if (buf.empty()) {
// Try the undecoded tag
encodeBasic(image, pCrwMapping, pHead);
}
@ -1118,7 +1115,6 @@ namespace Exiv2 {
}
if (t != 0) {
DataBuf buf(12);
buf.clear();
buf.write_uint32(0, static_cast<uint32_t>(t), pHead->byteOrder());
pHead->add(pCrwMapping->crwTagId_, pCrwMapping->crwDir_, std::move(buf));
}
@ -1153,7 +1149,6 @@ namespace Exiv2 {
size = cc->size();
}
DataBuf buf(size);
buf.clear();
if (cc) buf.copyBytes(8, cc->pData() + 8, cc->size() - 8);
if (edX != edEnd && edX->size() == 4) {
edX->copy(buf.data(), pHead->byteOrder());
@ -1198,7 +1193,6 @@ namespace Exiv2 {
{
const uint16_t size = 1024;
DataBuf buf(size);
buf.clear();
uint16_t len = 0;

@ -493,10 +493,10 @@ namespace Exiv2 {
// DATA
static const char signature_[]; //!< Canon CRW signature "HEAPCCDR"
CiffDirectory* pRootDir_ = nullptr; //!< Pointer to the root directory
std::unique_ptr<CiffDirectory> pRootDir_; //!< Pointer to the root directory
ByteOrder byteOrder_ = littleEndian; //!< Applicable byte order
uint32_t offset_ = 0; //!< Offset to the start of the root dir
byte* pPadding_ = nullptr; //!< Pointer to the (unknown) remainder
std::vector<byte> pPadding_; //!< the (unknown) remainder
uint32_t padded_ = 0; //!< Number of padding-bytes
}; // class CiffHeader

@ -107,8 +107,9 @@ namespace {
//! Write data into temp file, taking care of errors
void writeTemp(BasicIo& tempIo, const byte* data, size_t size)
{
if (size == 0) return;
if (tempIo.write(data, static_cast<long>(size)) != static_cast<long>(size)) {
if (size == 0)
return;
if (tempIo.write(data, size) != size) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to write to temporary file.\n";
#endif
@ -1079,7 +1080,7 @@ namespace Exiv2
EXV_DEBUG << "Exiv2::EpsImage:: Creating blank EPS image\n";
#endif
IoCloser closer(*io_);
if (io_->write(reinterpret_cast<const byte*>(epsBlank.data()), static_cast<long>(epsBlank.size())) != static_cast<long>(epsBlank.size())) {
if (io_->write(reinterpret_cast<const byte*>(epsBlank.data()), epsBlank.size()) != epsBlank.size()) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to write blank EPS image.\n";
#endif
@ -1157,10 +1158,10 @@ namespace Exiv2
bool isEpsType(BasicIo& iIo, bool advance)
{
// read as many bytes as needed for the longest (DOS) EPS signature
long bufSize = static_cast<long>(dosEpsSignature.size());
size_t bufSize = dosEpsSignature.size();
for (auto&& i : epsFirstLine) {
if (bufSize < static_cast<long>(i.size())) {
bufSize = static_cast<long>(i.size());
if (bufSize < i.size()) {
bufSize = i.size();
}
}
const long restore = iIo.tell(); // save

@ -181,7 +181,7 @@ namespace Exiv2 {
template<typename T>
Exiv2::Exifdatum& setValue(Exiv2::Exifdatum& exifDatum, const T& value)
{
auto v = std::unique_ptr<Exiv2::ValueType<T> >(new Exiv2::ValueType<T>);
auto v = std::make_unique<Exiv2::ValueType<T>>();
v->value_.push_back(value);
exifDatum.value_ = std::move(v);
return exifDatum;
@ -315,7 +315,7 @@ namespace Exiv2 {
return value_->read(value);
}
int Exifdatum::setDataArea(const byte* buf, long len)
int Exifdatum::setDataArea(const byte* buf, size_t len)
{
return value_.get() == nullptr ? -1 : value_->setDataArea(buf, len);
}
@ -382,17 +382,17 @@ namespace Exiv2 {
long Exifdatum::typeSize() const
{
return TypeInfo::typeSize(typeId());
return static_cast<long>(TypeInfo::typeSize(typeId()));
}
long Exifdatum::count() const
size_t Exifdatum::count() const
{
return value_.get() == nullptr ? 0 : value_->count();
}
long Exifdatum::size() const
{
return value_.get() == nullptr ? 0 : value_->size();
return value_.get() == nullptr ? 0 : static_cast<long>(value_->size());
}
std::string Exifdatum::toString() const
@ -425,7 +425,7 @@ namespace Exiv2 {
return value_.get() == nullptr ? nullptr : value_->clone();
}
long Exifdatum::sizeDataArea() const
size_t Exifdatum::sizeDataArea() const
{
return value_.get() == nullptr ? 0 : value_->sizeDataArea();
}
@ -448,7 +448,7 @@ namespace Exiv2 {
return thumbnail->copy(exifData_);
}
long ExifThumbC::writeFile(const std::string& path) const
size_t ExifThumbC::writeFile(const std::string& path) const
{
auto thumbnail = Thumbnail::create(exifData_);
if (!thumbnail.get())
@ -456,7 +456,7 @@ namespace Exiv2 {
std::string name = path + thumbnail->extension();
DataBuf buf(thumbnail->copy(exifData_));
if (buf.size() == 0)
if (buf.empty())
return 0;
return Exiv2::writeFile(buf, name);
@ -483,24 +483,13 @@ namespace Exiv2 {
{
}
void ExifThumb::setJpegThumbnail(
const std::string& path,
URational xres,
URational yres,
uint16_t unit
)
void ExifThumb::setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit)
{
DataBuf thumb = readFile(path); // may throw
setJpegThumbnail(thumb.c_data(), thumb.size(), xres, yres, unit);
}
void ExifThumb::setJpegThumbnail(
const byte* buf,
long size,
URational xres,
URational yres,
uint16_t unit
)
void ExifThumb::setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit)
{
setJpegThumbnail(buf, size);
exifData_["Exif.Thumbnail.XResolution"] = xres;
@ -514,7 +503,7 @@ namespace Exiv2 {
setJpegThumbnail(thumb.c_data(), thumb.size());
}
void ExifThumb::setJpegThumbnail(const byte* buf, long size)
void ExifThumb::setJpegThumbnail(const byte* buf, size_t size)
{
exifData_["Exif.Thumbnail.Compression"] = uint16_t(6);
Exifdatum& format = exifData_["Exif.Thumbnail.JPEGInterchangeFormat"];
@ -587,19 +576,11 @@ namespace Exiv2 {
return exifMetadata_.erase(pos);
}
ByteOrder ExifParser::decode(
ExifData& exifData,
const byte* pData,
uint32_t size
)
ByteOrder ExifParser::decode(ExifData& exifData, const byte* pData, size_t size)
{
IptcData iptcData;
XmpData xmpData;
ByteOrder bo = TiffParser::decode(exifData,
iptcData,
xmpData,
pData,
size);
ByteOrder bo = TiffParser::decode(exifData, iptcData, xmpData, pData, size);
#ifndef SUPPRESS_WARNINGS
if (!iptcData.empty()) {
EXV_WARNING << "Ignoring IPTC information encoded in the Exif data.\n";
@ -609,7 +590,7 @@ namespace Exiv2 {
}
#endif
return bo;
} // ExifParser::decode
}
//! @cond IGNORE
enum Ptt { pttLen, pttTag, pttIfd };
@ -619,13 +600,8 @@ namespace Exiv2 {
};
//! @endcond
WriteMethod ExifParser::encode(
Blob& blob,
const byte* pData,
uint32_t size,
ByteOrder byteOrder,
const ExifData& exifData
)
WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteOrder byteOrder,
const ExifData& exifData)
{
ExifData ed = exifData;
@ -696,9 +672,9 @@ namespace Exiv2 {
// Encode and check if the result fits into a JPEG Exif APP1 segment
MemIo mio1;
std::unique_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder, 0x00000008, false));
WriteMethod wm = TiffParserWorker::encode(mio1, pData, size, ed, emptyIptc, emptyXmp, Tag::root,
TiffMapping::findEncoder, header.get(), nullptr);
TiffHeader header(byteOrder, 0x00000008, false);
WriteMethod wm = TiffParserWorker::encode(mio1, pData, static_cast<uint32_t>(size), ed, emptyIptc, emptyXmp,
Tag::root, TiffMapping::findEncoder, &header, nullptr);
if (mio1.size() <= 65527) {
append(blob, mio1.mmap(), static_cast<uint32_t>(mio1.size()));
return wm;
@ -795,8 +771,8 @@ namespace Exiv2 {
// Encode the remaining Exif tags again, don't care if it fits this time
MemIo mio2;
wm = TiffParserWorker::encode(mio2, pData, size, ed, emptyIptc, emptyXmp, Tag::root, TiffMapping::findEncoder,
header.get(), nullptr);
wm = TiffParserWorker::encode(mio2, pData, static_cast<uint32_t>(size), ed, emptyIptc, emptyXmp, Tag::root,
TiffMapping::findEncoder, &header, nullptr);
append(blob, mio2.mmap(), static_cast<uint32_t>(mio2.size()));
#ifdef EXIV2_DEBUG_MESSAGES
if (wm == wmIntrusive) {
@ -868,7 +844,7 @@ namespace {
Exiv2::IptcData emptyIptc;
Exiv2::XmpData emptyXmp;
Exiv2::TiffParser::encode(io, nullptr, 0, Exiv2::littleEndian, thumb, emptyIptc, emptyXmp);
return io.read(static_cast<long>(io.size()));
return io.read(io.size());
}
const char* JpegThumbnail::mimeType() const
@ -892,8 +868,8 @@ namespace {
int64_t sumToLong(const Exiv2::Exifdatum& md)
{
int64_t sum = 0;
for (long i = 0; i < md.count(); ++i) {
sum += md.toInt64(i);
for (size_t i = 0; i < md.count(); ++i) {
sum += md.toInt64(static_cast<long>(i));
}
return sum;
}

@ -23,7 +23,9 @@
std::string string_from_unterminated(const char* data, size_t data_length)
{
if (data_length == 0) {
return {};
}
const size_t StringLength = strnlen(data, data_length);
return std::string(data, StringLength);
}

@ -406,7 +406,6 @@ namespace Exiv2 {
enforce(allocate64 <= static_cast<uint64_t>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
const long allocate = static_cast<long>(allocate64);
DataBuf buf(allocate); // allocate a buffer
buf.clear();
buf.copyBytes(0, dir.c_data(8), 4); // copy dir[8:11] into buffer (short strings)
// We have already checked that this multiplication cannot overflow.
@ -416,7 +415,7 @@ namespace Exiv2 {
if ( bOffsetIsPointer ) { // read into buffer
const long restore = io.tell(); // save
io.seekOrThrow(offset, BasicIo::beg, kerCorruptedMetadata); // position
io.readOrThrow(buf.data(), static_cast<long>(count_x_size), kerCorruptedMetadata); // read
io.readOrThrow(buf.data(), count_x_size, kerCorruptedMetadata); // read
io.seekOrThrow(restore, BasicIo::beg, kerCorruptedMetadata); // restore
}
@ -673,7 +672,7 @@ namespace Exiv2 {
if (iccProfile.size() < static_cast<long>(sizeof(long))) {
throw Error(kerInvalidIccProfile);
}
const long size = iccProfile.read_uint32(0, bigEndian);
const size_t size = iccProfile.read_uint32(0, bigEndian);
if (size != iccProfile.size()) {
throw Error(kerInvalidIccProfile);
}
@ -827,7 +826,7 @@ namespace Exiv2 {
return getType(fileIo);
}
ImageType ImageFactory::getType(const byte* data, long size)
ImageType ImageFactory::getType(const byte* data, size_t size)
{
MemIo memIo(data, size);
return getType(memIo);
@ -876,7 +875,7 @@ namespace Exiv2 {
return image;
}
Image::UniquePtr ImageFactory::open(const byte* data, long size)
Image::UniquePtr ImageFactory::open(const byte* data, size_t size)
{
auto io = std::make_unique<MemIo>(data, size);
auto image = open(std::move(io)); // may throw
@ -938,7 +937,7 @@ namespace Exiv2 {
// *****************************************************************************
// template, inline and free functions
void append(Blob& blob, const byte* buf, uint32_t len)
void append(Blob& blob, const byte* buf, size_t len)
{
if (len != 0) {
assert(buf != 0);

@ -158,17 +158,17 @@ namespace Exiv2 {
long Iptcdatum::typeSize() const
{
return TypeInfo::typeSize(typeId());
return static_cast<long>(TypeInfo::typeSize(typeId()));
}
long Iptcdatum::count() const
size_t Iptcdatum::count() const
{
return value_.get() == nullptr ? 0 : value_->count();
}
long Iptcdatum::size() const
{
return value_.get() == nullptr ? 0 : value_->size();
return value_.get() == nullptr ? 0 : static_cast<long>(value_->size());
}
std::string Iptcdatum::toString() const
@ -505,6 +505,9 @@ namespace Exiv2 {
DataBuf IptcParser::encode(const IptcData& iptcData)
{
if (iptcData.empty())
return {};
DataBuf buf(iptcData.size());
byte *pWrite = buf.data();

@ -35,6 +35,7 @@
#include "safe_op.hpp"
// + standard includes
#include <array>
#include <string>
#include <cstring>
#include <iostream>
@ -283,9 +284,9 @@ static void boxes_check(size_t b,size_t m)
if (data_length > io_->size() - io_->tell()) {
throw Error(kerCorruptedMetadata);
}
DataBuf data(static_cast<long>(data_length));
DataBuf data(data_length);
io_->read(data.data(), data.size());
const long iccLength = data.read_uint32(pad, bigEndian);
const size_t iccLength = data.read_uint32(pad, bigEndian);
// subtracting pad from data.size() is safe:
// data.size() is at least 8 and pad = 3
if (iccLength > data.size() - pad) {
@ -338,7 +339,7 @@ static void boxes_check(size_t b,size_t m)
if (io_->read(reinterpret_cast<byte*>(&uuid), sizeof(uuid)) == sizeof(uuid)) {
DataBuf rawData;
long bufRead;
size_t bufRead;
bool bIsExif = memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid))==0;
bool bIsIPTC = memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid))==0;
bool bIsXMP = memcmp(uuid.uuid, kJp2UuidXmp , sizeof(uuid))==0;
@ -362,12 +363,11 @@ static void boxes_check(size_t b,size_t m)
long pos = (a == b && (a=='I' || a=='M')) ? 0 : -1;
// #1242 Forgive having Exif\0\0 in rawData.pData_
const byte exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
for (long i = 0; pos < 0 && i < rawData.size() - static_cast<long>(sizeof(exifHeader));
i++) {
if (rawData.cmpBytes(i, exifHeader, sizeof(exifHeader)) == 0)
std::array<byte, 6> exifHeader { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
for (size_t i = 0; pos < 0 && i < (rawData.size() - exifHeader.size()); i++) {
if (rawData.cmpBytes(i, exifHeader.data(), exifHeader.size()) == 0)
{
pos = i+sizeof(exifHeader);
pos = static_cast<long>(i+sizeof(exifHeader));
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Reading non-standard UUID-EXIF_bad box in " << io_->path() << std::endl;
#endif
@ -409,7 +409,7 @@ static void boxes_check(size_t b,size_t m)
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead != rawData.size()) throw Error(kerInputDataReadFailed);
if (IptcParser::decode(iptcData_, rawData.c_data(), rawData.size()))
if (IptcParser::decode(iptcData_, rawData.c_data(), static_cast<uint32_t>(rawData.size())))
{
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to decode IPTC metadata." << std::endl;
@ -530,15 +530,14 @@ static void boxes_check(size_t b,size_t m)
DataBuf data(subBox.length - sizeof(box));
io_->read(data.data(), data.size());
if (bPrint) {
out << Internal::stringFormat("%8ld | %8ld | sub:", static_cast<size_t>(address),
static_cast<size_t>(subBox.length))
out << Internal::stringFormat("%8ld | %8ld | sub:", address, subBox.length)
<< toAscii(subBox.type) << " | "
<< Internal::binaryToString(makeSlice(data, 0, std::min(30L, data.size())));
<< Internal::binaryToString(makeSlice(data, 0, std::min(static_cast<size_t>(30), data.size())));
bLF = true;
}
if (subBox.type == kJp2BoxTypeColorHeader) {
long pad = 3; // don't know why there are 3 padding bytes
const size_t pad = 3; // don't know why there are 3 padding bytes
// Bounds-check for the `getULong()` below, which reads 4 bytes, starting at `pad`.
enforce(data.size() >= pad + 4, kerCorruptedMetadata);
@ -548,7 +547,8 @@ static void boxes_check(size_t b,size_t m)
for (int i = 0; i < 3; i++)
out << " " << static_cast<int>(data.read_uint8(i));
}
long iccLength = data.read_uint32(pad, bigEndian);
const size_t iccLength = data.read_uint32(pad, bigEndian);
if (bPrint) {
out << " | iccLength:" << iccLength;
}
@ -583,7 +583,7 @@ static void boxes_check(size_t b,size_t m)
DataBuf rawData;
enforce(box.length >= sizeof(uuid) + sizeof(box), kerCorruptedMetadata);
rawData.alloc(box.length - sizeof(uuid) - sizeof(box));
long bufRead = io_->read(rawData.data(), rawData.size());
const size_t bufRead = io_->read(rawData.data(), rawData.size());
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != rawData.size())
@ -655,10 +655,10 @@ static void boxes_check(size_t b,size_t m)
DataBuf output(boxBuf.size() + iccProfile_.size() + 100); // allocate sufficient space
long outlen = sizeof(Jp2BoxHeader) ; // now many bytes have we written to output?
long inlen = sizeof(Jp2BoxHeader) ; // how many bytes have we read from boxBuf?
enforce(sizeof(Jp2BoxHeader) <= static_cast<size_t>(output.size()), Exiv2::kerCorruptedMetadata);
enforce(sizeof(Jp2BoxHeader) <= output.size(), Exiv2::kerCorruptedMetadata);
auto pBox = reinterpret_cast<const Jp2BoxHeader*>(boxBuf.c_data());
uint32_t length = getLong(reinterpret_cast<const byte*>(&pBox->length), bigEndian);
enforce(length <= static_cast<size_t>(output.size()), Exiv2::kerCorruptedMetadata);
enforce(length <= output.size(), Exiv2::kerCorruptedMetadata);
uint32_t count = sizeof (Jp2BoxHeader);
auto p = boxBuf.c_str();
bool bWroteColor = false ;
@ -694,7 +694,7 @@ static void boxes_check(size_t b,size_t m)
const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid";
uint32_t psize = 15;
newlen = sizeof(newBox) + psize ;
enforce(newlen <= static_cast<size_t>(output.size() - outlen), Exiv2::kerCorruptedMetadata);
enforce(newlen <= output.size() - outlen, Exiv2::kerCorruptedMetadata);
ul2Data(reinterpret_cast<byte*>(&newBox.length), psize, bigEndian);
ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian);
output.copyBytes(outlen ,&newBox ,sizeof(newBox));
@ -702,7 +702,7 @@ static void boxes_check(size_t b,size_t m)
} else {
const char* pad = "\x02\x00\x00";
uint32_t psize = 3;
newlen = sizeof(newBox) + psize + iccProfile_.size();
newlen = sizeof(newBox) + psize + static_cast<uint32_t>(iccProfile_.size());
enforce(newlen <= static_cast<size_t>(output.size() - outlen), Exiv2::kerCorruptedMetadata);
ul2Data(reinterpret_cast<byte*>(&newBox.length), newlen, bigEndian);
ul2Data(reinterpret_cast<byte*>(&newBox.type), newBox.type, bigEndian);
@ -766,11 +766,11 @@ static void boxes_check(size_t b,size_t m)
#endif
// Read chunk header.
bheaderBuf.clear();
long bufRead = io_->read(bheaderBuf.data(), bheaderBuf.size());
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead != bheaderBuf.size()) throw Error(kerInputDataReadFailed);
size_t bufRead = io_->read(bheaderBuf.data(), bheaderBuf.size());
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != bheaderBuf.size())
throw Error(kerInputDataReadFailed);
// Decode box header.
@ -812,7 +812,7 @@ static void boxes_check(size_t b,size_t m)
throw Error(kerFailedToReadImageData);
}
if (bufRead != static_cast<long>(box.length - 8)) {
if (bufRead != (box.length - 8)) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Cannot read source file data" << std::endl;
#endif
@ -828,7 +828,8 @@ static void boxes_check(size_t b,size_t m)
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write JP2Header box (length: " << box.length << ")" << std::endl;
#endif
if (outIo.write(newBuf.data(), newBuf.size()) != newBuf.size()) throw Error(kerImageWriteFailed);
if (outIo.write(newBuf.data(), newBuf.size()) != newBuf.size())
throw Error(kerImageWriteFailed);
// Write all updated metadata here, just after JP2Header.
@ -843,7 +844,7 @@ static void boxes_check(size_t b,size_t m)
rawExif.copyBytes(0, &blob[0], blob.size());
DataBuf boxData(8 + 16 + rawExif.size());
ul2Data(boxDataSize, boxData.size(), Exiv2::bigEndian);
ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), Exiv2::bigEndian);
ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian);
boxData.copyBytes(0, boxDataSize, 4);
boxData.copyBytes(4, boxUUIDtype, 4);
@ -854,7 +855,8 @@ static void boxes_check(size_t b,size_t m)
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Exif metadata (length: "
<< boxData.size() << std::endl;
#endif
if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) throw Error(kerImageWriteFailed);
if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size())
throw Error(kerImageWriteFailed);
}
}
@ -866,7 +868,7 @@ static void boxes_check(size_t b,size_t m)
if (rawIptc.size() > 0)
{
DataBuf boxData(8 + 16 + rawIptc.size());
ul2Data(boxDataSize, boxData.size(), Exiv2::bigEndian);
ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), Exiv2::bigEndian);
ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian);
boxData.copyBytes(0, boxDataSize, 4);
boxData.copyBytes(4, boxUUIDtype, 4);
@ -877,7 +879,8 @@ static void boxes_check(size_t b,size_t m)
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Iptc metadata (length: "
<< boxData.size() << std::endl;
#endif
if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) throw Error(kerImageWriteFailed);
if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size())
throw Error(kerImageWriteFailed);
}
}
@ -894,7 +897,7 @@ static void boxes_check(size_t b,size_t m)
DataBuf xmp(reinterpret_cast<const byte*>(xmpPacket_.data()), static_cast<long>(xmpPacket_.size()));
DataBuf boxData(8 + 16 + xmp.size());
ul2Data(boxDataSize, boxData.size(), Exiv2::bigEndian);
ul2Data(boxDataSize, static_cast<uint32_t>(boxData.size()), Exiv2::bigEndian);
ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian);
boxData.copyBytes(0, boxDataSize, 4);
boxData.copyBytes(4, boxUUIDtype, 4);
@ -905,7 +908,8 @@ static void boxes_check(size_t b,size_t m)
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with XMP metadata (length: "
<< boxData.size() << ")" << std::endl;
#endif
if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size()) throw Error(kerImageWriteFailed);
if (outIo.write(boxData.c_data(), boxData.size()) != boxData.size())
throw Error(kerImageWriteFailed);
}
break;
@ -937,7 +941,8 @@ static void boxes_check(size_t b,size_t m)
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: write Uuid box (length: " << box.length << ")" << std::endl;
#endif
if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size()) throw Error(kerImageWriteFailed);
if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size())
throw Error(kerImageWriteFailed);
}
break;
}
@ -947,7 +952,8 @@ static void boxes_check(size_t b,size_t m)
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::doWriteMetadata: write box (length: " << box.length << ")" << std::endl;
#endif
if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size()) throw Error(kerImageWriteFailed);
if (outIo.write(boxBuf.c_data(), boxBuf.size()) != boxBuf.size())
throw Error(kerImageWriteFailed);
break;
}

@ -41,6 +41,7 @@
#include "fff.h"
// + standard includes
#include <algorithm> // for EOF
#include <cstdio> // for EOF
#include <cstring>
#include <cassert>
@ -99,10 +100,10 @@ namespace Exiv2 {
return inRange(lo1,value,hi1) || inRange(lo2,value,hi2);
}
bool Photoshop::isIrb(const byte* pPsData,
long sizePsData)
bool Photoshop::isIrb(const byte* pPsData, size_t sizePsData)
{
if (sizePsData < 4) return false;
if (sizePsData < 4)
return false;
for (auto&& i : irbId_) {
assert(strlen(i) == 4);
if (memcmp(pPsData, i, 4) == 0)
@ -111,8 +112,7 @@ namespace Exiv2 {
return false;
}
bool Photoshop::valid(const byte* pPsData,
long sizePsData)
bool Photoshop::valid(const byte* pPsData, size_t sizePsData)
{
const byte* record = nullptr;
uint32_t sizeIptc = 0;
@ -121,8 +121,7 @@ namespace Exiv2 {
const byte* pEnd = pPsData + sizePsData;
int ret = 0;
while (pCur < pEnd
&& 0 == (ret = Photoshop::locateIptcIrb(pCur, static_cast<long>(pEnd - pCur),
&record, &sizeHdr, &sizeIptc))) {
&& 0 == (ret = Photoshop::locateIptcIrb(pCur, (pEnd - pCur), &record, &sizeHdr, &sizeIptc))) {
pCur = record + sizeHdr + sizeIptc + (sizeIptc & 1);
}
return ret >= 0;
@ -132,7 +131,7 @@ namespace Exiv2 {
// the format (in particular the header). So it remains to be confirmed
// if this also makes sense for psTag != Photoshop::iptc
int Photoshop::locateIrb(const byte* pPsData,
long sizePsData,
size_t sizePsData,
uint16_t psTag,
const byte** record,
uint32_t *const sizeHdr,
@ -141,8 +140,12 @@ namespace Exiv2 {
assert(record);
assert(sizeHdr);
assert(sizeData);
if (sizePsData < 12) {
return 3;
}
// Used for error checking
long position = 0;
size_t position = 0;
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Photoshop::locateIrb: ";
#endif
@ -168,7 +171,7 @@ namespace Exiv2 {
}
uint32_t dataSize = getULong(pPsData + position, bigEndian);
position += 4;
if (dataSize > static_cast<uint32_t>(sizePsData - position)) {
if (dataSize > (sizePsData - position)) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Warning: "
<< "Invalid Photoshop IRB data size "
@ -206,10 +209,10 @@ namespace Exiv2 {
return -2;
}
return 3;
} // Photoshop::locateIrb
}
int Photoshop::locateIptcIrb(const byte* pPsData,
long sizePsData,
size_t sizePsData,
const byte** record,
uint32_t *const sizeHdr,
uint32_t *const sizeData)
@ -219,7 +222,7 @@ namespace Exiv2 {
}
int Photoshop::locatePreviewIrb(const byte* pPsData,
long sizePsData,
size_t sizePsData,
const byte** record,
uint32_t *const sizeHdr,
uint32_t *const sizeData)
@ -228,11 +231,10 @@ namespace Exiv2 {
record, sizeHdr, sizeData);
}
DataBuf Photoshop::setIptcIrb(const byte* pPsData,
long sizePsData,
const IptcData& iptcData)
DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData)
{
if (sizePsData > 0) assert(pPsData);
if (sizePsData > 0)
assert(pPsData);
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "IRB block at the beginning of Photoshop::setIptcIrb\n";
if (sizePsData == 0) std::cerr << " None.\n";
@ -243,36 +245,35 @@ namespace Exiv2 {
uint32_t sizeHdr = 0;
DataBuf rc;
// Safe to call with zero psData.size_
if (0 > Photoshop::locateIptcIrb(pPsData, sizePsData,
&record, &sizeHdr, &sizeIptc)) {
if (0 > Photoshop::locateIptcIrb(pPsData, sizePsData, &record, &sizeHdr, &sizeIptc)) {
return rc;
}
Blob psBlob;
const auto sizeFront = static_cast<uint32_t>(record - pPsData);
const auto sizeFront = static_cast<size_t>(record - pPsData);
// Write data before old record.
if (sizePsData > 0 && sizeFront > 0) {
append(psBlob, pPsData, sizeFront);
}
// Write new iptc record if we have it
DataBuf rawIptc = IptcParser::encode(iptcData);
if (rawIptc.size() > 0) {
byte tmpBuf[12];
std::memcpy(tmpBuf, Photoshop::irbId_[0], 4);
us2Data(tmpBuf + 4, iptc_, bigEndian);
if (!rawIptc.empty()) {
std::array<byte, 12> tmpBuf;
std::copy_n(Photoshop::irbId_[0], 4, tmpBuf.data());
us2Data(tmpBuf.data() + 4, iptc_, bigEndian);
tmpBuf[6] = 0;
tmpBuf[7] = 0;
ul2Data(tmpBuf + 8, rawIptc.size(), bigEndian);
append(psBlob, tmpBuf, 12);
ul2Data(tmpBuf.data() + 8, static_cast<uint32_t>(rawIptc.size()), bigEndian);
append(psBlob, tmpBuf.data(), 12);
append(psBlob, rawIptc.c_data(), rawIptc.size());
// Data is padded to be even (but not included in size)
if (rawIptc.size() & 1) psBlob.push_back(0x00);
if (rawIptc.size() & 1)
psBlob.push_back(0x00);
}
// Write existing stuff after record,
// skip the current and all remaining IPTC blocks
long pos = sizeFront;
while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos,
&record, &sizeHdr, &sizeIptc)) {
const long newPos = static_cast<long>(record - pPsData);
size_t pos = sizeFront;
while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos, &record, &sizeHdr, &sizeIptc)) {
const auto newPos = static_cast<size_t>(record - pPsData);
// Copy data up to the IPTC IRB
if (newPos > pos) {
append(psBlob, pPsData + pos, newPos - pos);
@ -285,15 +286,16 @@ namespace Exiv2 {
}
// Data is rounded to be even
if (!psBlob.empty())
rc = DataBuf(&psBlob[0], static_cast<long>(psBlob.size()));
rc = DataBuf(&psBlob[0], psBlob.size());
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "IRB block at the end of Photoshop::setIptcIrb\n";
if (rc.size() == 0) std::cerr << " None.\n";
if (rc.empty())
std::cerr << " None.\n";
else hexdump(std::cerr, rc.c_data(), rc.size());
#endif
return rc;
} // Photoshop::setIptcIrb
}
bool JpegBase::markerHasLength(byte marker) {
return (marker >= sof0_ && marker <= sof15_) ||
@ -306,7 +308,7 @@ namespace Exiv2 {
}
JpegBase::JpegBase(ImageType type, BasicIo::UniquePtr io, bool create,
const byte initData[], long dataSize)
const byte initData[], size_t dataSize)
: Image(type, mdExif | mdIptc | mdXmp | mdComment, std::move(io))
{
if (create) {
@ -314,7 +316,7 @@ namespace Exiv2 {
}
}
int JpegBase::initImage(const byte initData[], long dataSize)
int JpegBase::initImage(const byte initData[], size_t dataSize)
{
if (io_->open() != 0) {
return 4;
@ -369,17 +371,16 @@ namespace Exiv2 {
while (marker != sos_ && marker != eoi_ && search > 0) {
// 2-byte buffer for reading the size.
byte sizebuf[2];
uint16_t size = 0;
uint16_t size = 0; // Size of the segment, including the 2-byte size field
if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian);
// `size` is the size of the segment, including the 2-byte size field
// that we just read.
enforce(size >= 2, kerFailedToReadImageData);
}
// Read the rest of the segment.
DataBuf buf(size);
/// \todo check if it makes sense to check for size
if (size > 0) {
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2);
@ -424,7 +425,7 @@ namespace Exiv2 {
// Append to psBlob
append(psBlob, buf.c_data(16), size - 16);
// Check whether psBlob is complete
if (!psBlob.empty() && Photoshop::valid(&psBlob[0], static_cast<long>(psBlob.size()))) {
if (!psBlob.empty() && Photoshop::valid(&psBlob[0], psBlob.size())) {
--search;
foundCompletePsData = true;
}
@ -467,7 +468,7 @@ namespace Exiv2 {
<< std::endl ;
#endif
// #1286 profile can be padded
long icc_size = size-2-14;
size_t icc_size = size-2-14;
if (chunk==1 && chunks==1) {
enforce(s <= static_cast<uint32_t>(icc_size), kerInvalidIccProfile);
icc_size = s;
@ -509,8 +510,7 @@ namespace Exiv2 {
const byte* pCur = &psBlob[0];
const byte* pEnd = pCur + psBlob.size();
while ( pCur < pEnd
&& 0 == Photoshop::locateIptcIrb(pCur, static_cast<long>(pEnd - pCur),
&record, &sizeHdr, &sizeIptc)) {
&& 0 == Photoshop::locateIptcIrb(pCur, pEnd - pCur, &record, &sizeHdr, &sizeIptc)) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
#endif
@ -526,7 +526,7 @@ namespace Exiv2 {
#endif
iptcData_.clear();
}
} // psBlob.size() > 0
}
if (rc != 0) {
#ifndef SUPPRESS_WARNINGS
@ -621,8 +621,7 @@ namespace Exiv2 {
assert(markerHasLength(marker));
assert(size >= 2); // Because this marker has a length field.
// http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf p75
const std::string signature =
string_from_unterminated(buf.c_str(2), size - 2);
const std::string signature = string_from_unterminated(buf.c_str(2), size - 2);
// 728 rmills@rmillsmbp:~/gnu/exiv2/ttt $ exiv2 -pS test/data/exiv2-bug922.jpg
// STRUCTURE OF JPEG FILE: test/data/exiv2-bug922.jpg
@ -848,13 +847,35 @@ namespace Exiv2 {
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
}
IoCloser closer(*io_);
BasicIo::UniquePtr tempIo(new MemIo);
assert (tempIo.get() != 0);
auto tempIo = std::make_unique<MemIo>();
doWriteMetadata(*tempIo); // may throw
io_->close();
io_->transfer(*tempIo); // may throw
} // JpegBase::writeMetadata
}
DataBuf JpegBase::readNextSegment(byte marker)
{
// 2-byte buffer for reading the size.
byte sizebuf[2];
uint16_t size = 0;
if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian);
// `size` is the size of the segment, including the 2-byte size field
// that we just read.
enforce(size >= 2, kerFailedToReadImageData);
}
// Read the rest of the segment.
DataBuf buf(size);
if (size > 0) {
assert(size >= 2); // enforced above
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2);
}
return buf;
}
void JpegBase::doWriteMetadata(BasicIo& outIo)
{
@ -900,47 +921,28 @@ namespace Exiv2 {
// to insert after it. But if app0 comes after com, app1 and app13 then
// don't bother.
while (marker != sos_ && marker != eoi_ && search < 6) {
// 2-byte buffer for reading the size.
byte sizebuf[2];
uint16_t size = 0;
if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian);
// `size` is the size of the segment, including the 2-byte size field
// that we just read.
enforce(size >= 2, kerFailedToReadImageData);
}
// Read the rest of the segment.
DataBuf buf(size);
if (size > 0) {
assert(size >= 2); // enforced above
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2);
}
DataBuf buf = readNextSegment(marker);
if (marker == app0_) {
assert(markerHasLength(marker));
assert(size >= 2); // Because this marker has a length field.
insertPos = count + 1;
} else if (skipApp1Exif == notfound &&
marker == app1_ &&
size >= 8 && // prevent out-of-bounds read in memcmp on next line
buf.size() >= 8 && // prevent out-of-bounds read in memcmp on next line
buf.cmpBytes(2, exifId_, 6) == 0) {
skipApp1Exif = count;
++search;
if (size > 8) {
rawExif.alloc(size - 8);
rawExif.copyBytes(0, buf.c_data(8), size - 8);
if (buf.size() > 8) {
rawExif.alloc(buf.size() - 8);
rawExif.copyBytes(0, buf.c_data(8), buf.size() - 8);
}
} else if (skipApp1Xmp == notfound &&
marker == app1_ &&
size >= 31 && // prevent out-of-bounds read in memcmp on next line
buf.size() >= 31 && // prevent out-of-bounds read in memcmp on next line
buf.cmpBytes(2, xmpId_, 29) == 0) {
skipApp1Xmp = count;
++search;
} else if (marker == app2_ &&
size >= 13 && // prevent out-of-bounds read in memcmp on next line
buf.size() >= 13 && // prevent out-of-bounds read in memcmp on next line
buf.cmpBytes(2, iccId_, 11) == 0) {
skipApp2Icc.push_back(count);
if (!foundIccData) {
@ -949,21 +951,19 @@ namespace Exiv2 {
}
} else if (!foundCompletePsData &&
marker == app13_ &&
size >= 16 && // prevent out-of-bounds read in memcmp on next line
buf.size() >= 16 && // prevent out-of-bounds read in memcmp on next line
buf.cmpBytes(2, Photoshop::ps3Id_, 14) == 0) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Found APP13 Photoshop PS3 segment\n";
#endif
skipApp13Ps3.push_back(count);
// Append to psBlob
append(psBlob, buf.c_data(16), size - 16);
append(psBlob, buf.c_data(16), buf.size() - 16);
// Check whether psBlob is complete
if (!psBlob.empty() && Photoshop::valid(&psBlob[0], static_cast<long>(psBlob.size()))) {
if (!psBlob.empty() && Photoshop::valid(&psBlob[0], psBlob.size())) {
foundCompletePsData = true;
}
} else if (marker == com_ && skipCom == notfound) {
assert(markerHasLength(marker));
assert(size >= 2); // Because this marker has a length field.
// Jpegs can have multiple comments, but for now only handle
// the first one (most jpegs only have one anyway).
skipCom = count;
@ -1014,24 +1014,7 @@ namespace Exiv2 {
// potential to change segment ordering (which is allowed).
// Segments are erased if there is no assigned metadata.
while (marker != sos_ && search > 0) {
// 2-byte buffer for reading the size.
byte sizebuf[2];
uint16_t size = 0;
if (markerHasLength(marker)) {
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
size = getUShort(sizebuf, bigEndian);
// `size` is the size of the segment, including the 2-byte size field
// that we just read.
enforce(size >= 2, kerFailedToReadImageData);
}
// Read the rest of the segment.
DataBuf buf(size);
if (size > 0) {
assert(size >= 2); // enforced above
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
buf.copyBytes(0, sizebuf, 2);
}
DataBuf buf = readNextSegment(marker);
if (insertPos == count) {
// Write Exif data first so that - if there is no app0 - we
@ -1051,20 +1034,20 @@ namespace Exiv2 {
exifSize = blob.size();
}
if (exifSize > 0) {
byte tmpBuf[10];
std::array<byte, 10> tmpBuf;
// Write APP1 marker, size of APP1 field, Exif id and Exif data
tmpBuf[0] = 0xff;
tmpBuf[1] = app1_;
if (exifSize > 0xffff - 8)
throw Error(kerTooLargeJpegSegment, "Exif");
us2Data(tmpBuf + 2, static_cast<uint16_t>(exifSize + 8), bigEndian);
std::memcpy(tmpBuf + 4, exifId_, 6);
if (outIo.write(tmpBuf, 10) != 10)
us2Data(tmpBuf.data() + 2, static_cast<uint16_t>(exifSize + 8), bigEndian);
std::memcpy(tmpBuf.data() + 4, exifId_, 6);
if (outIo.write(tmpBuf.data(), 10) != 10)
throw Error(kerImageWriteFailed);
// Write new Exif data buffer
if (outIo.write(pExifData, static_cast<long>(exifSize)) != static_cast<long>(exifSize))
if (outIo.write(pExifData, exifSize) != exifSize)
throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
@ -1080,21 +1063,21 @@ namespace Exiv2 {
}
}
if (!xmpPacket_.empty()) {
byte tmpBuf[33];
std::array<byte, 33> tmpBuf;
// Write APP1 marker, size of APP1 field, XMP id and XMP packet
tmpBuf[0] = 0xff;
tmpBuf[1] = app1_;
if (xmpPacket_.size() > 0xffff - 31)
throw Error(kerTooLargeJpegSegment, "XMP");
us2Data(tmpBuf + 2, static_cast<uint16_t>(xmpPacket_.size() + 31), bigEndian);
std::memcpy(tmpBuf + 4, xmpId_, 29);
if (outIo.write(tmpBuf, 33) != 33)
us2Data(tmpBuf.data() + 2, static_cast<uint16_t>(xmpPacket_.size() + 31), bigEndian);
std::memcpy(tmpBuf.data() + 4, xmpId_, 29);
if (outIo.write(tmpBuf.data(), 33) != 33)
throw Error(kerImageWriteFailed);
// Write new XMP packet
if (outIo.write(reinterpret_cast<const byte*>(xmpPacket_.data()),
static_cast<long>(xmpPacket_.size())) != static_cast<long>(xmpPacket_.size()))
xmpPacket_.size()) != xmpPacket_.size())
throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
@ -1102,29 +1085,29 @@ namespace Exiv2 {
}
if (iccProfileDefined()) {
byte tmpBuf[4];
std::array<byte, 4> tmpBuf;
// Write APP2 marker, size of APP2 field, and IccProfile
// See comments in readMetadata() about the ICC embedding specification
tmpBuf[0] = 0xff;
tmpBuf[1] = app2_;
const long chunk_size = 256 * 256 - 40; // leave bytes for marker, header and padding
long size = iccProfile_.size();
size_t size = iccProfile_.size();
assert(size > 0); // Because iccProfileDefined() == true
if (size >= 255 * chunk_size)
throw Error(kerTooLargeJpegSegment, "IccProfile");
const long chunks = 1 + (size - 1) / chunk_size;
const size_t chunks = 1 + (size - 1) / chunk_size;
assert(chunks <= 255); // Because size < 255 * chunk_size
for (long chunk = 0; chunk < chunks; chunk++) {
long bytes = size > chunk_size ? chunk_size : size; // bytes to write
for (size_t chunk = 0; chunk < chunks; chunk++) {
size_t bytes = size > chunk_size ? chunk_size : size; // bytes to write
size -= bytes;
// write JPEG marker (2 bytes)
if (outIo.write(tmpBuf, 2) != 2)
if (outIo.write(tmpBuf.data(), 2) != 2)
throw Error(kerImageWriteFailed); // JPEG Marker
// write length (2 bytes). length includes the 2 bytes for the length
us2Data(tmpBuf + 2, static_cast<uint16_t>(2 + 14 + bytes), bigEndian);
if (outIo.write(tmpBuf + 2, 2) != 2)
us2Data(tmpBuf.data() + 2, static_cast<uint16_t>(2 + 14 + bytes), bigEndian);
if (outIo.write(tmpBuf.data() + 2, 2) != 2)
throw Error(kerImageWriteFailed); // JPEG Length
// write the ICC_PROFILE header (14 bytes)
@ -1144,14 +1127,14 @@ namespace Exiv2 {
if (foundCompletePsData || iptcData_.count() > 0) {
// Set the new IPTC IRB, keeps existing IRBs but removes the
// IPTC block if there is no new IPTC data to write
DataBuf newPsData = Photoshop::setIptcIrb(!psBlob.empty() ? &psBlob[0] : nullptr,
static_cast<long>(psBlob.size()), iptcData_);
DataBuf newPsData = Photoshop::setIptcIrb(!psBlob.empty() ? psBlob.data() : nullptr,
psBlob.size(), iptcData_);
const long maxChunkSize = 0xffff - 16;
const byte* chunkStart = newPsData.c_data();
const byte* chunkEnd = newPsData.c_data(newPsData.size());
const byte* chunkEnd = newPsData.empty() ? nullptr : newPsData.c_data(newPsData.size()-1);
while (chunkStart < chunkEnd) {
// Determine size of next chunk
long chunkSize = static_cast<long>(chunkEnd - chunkStart);
size_t chunkSize = (chunkEnd + 1 - chunkStart);
if (chunkSize > maxChunkSize) {
chunkSize = maxChunkSize;
// Don't break at a valid IRB boundary
@ -1164,12 +1147,12 @@ namespace Exiv2 {
}
// Write APP13 marker, chunk size, and ps3Id
byte tmpBuf[18];
std::array<byte, 18> tmpBuf;
tmpBuf[0] = 0xff;
tmpBuf[1] = app13_;
us2Data(tmpBuf + 2, static_cast<uint16_t>(chunkSize + 16), bigEndian);
std::memcpy(tmpBuf + 4, Photoshop::ps3Id_, 14);
if (outIo.write(tmpBuf, 18) != 18)
us2Data(tmpBuf.data() + 2, static_cast<uint16_t>(chunkSize + 16), bigEndian);
std::memcpy(tmpBuf.data() + 4, Photoshop::ps3Id_, 14);
if (outIo.write(tmpBuf.data(), 18) != 18)
throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
@ -1187,19 +1170,19 @@ namespace Exiv2 {
}
if (comPos == count) {
if (!comment_.empty()) {
byte tmpBuf[4];
std::array<byte, 4> tmpBuf;
// Write COM marker, size of comment, and string
tmpBuf[0] = 0xff;
tmpBuf[1] = com_;
if (comment_.length() > 0xffff - 3)
throw Error(kerTooLargeJpegSegment, "JPEG comment");
us2Data(tmpBuf + 2, static_cast<uint16_t>(comment_.length() + 3), bigEndian);
us2Data(tmpBuf.data() + 2, static_cast<uint16_t>(comment_.length() + 3), bigEndian);
if (outIo.write(tmpBuf, 4) != 4)
if (outIo.write(tmpBuf.data(), 4) != 4)
throw Error(kerImageWriteFailed);
if (outIo.write(reinterpret_cast<byte*>(const_cast<char*>(comment_.data())),
static_cast<long>(comment_.length())) != static_cast<long>(comment_.length()))
comment_.length()) != comment_.length())
throw Error(kerImageWriteFailed);
if (outIo.putb(0) == EOF)
throw Error(kerImageWriteFailed);
@ -1217,13 +1200,13 @@ namespace Exiv2 {
std::find(skipApp2Icc.begin(), skipApp2Icc.end(), count) != skipApp2Icc.end() || skipCom == count) {
--search;
} else {
byte tmpBuf[2];
std::array<byte, 2> tmpBuf;
// Write marker and a copy of the segment.
tmpBuf[0] = 0xff;
tmpBuf[1] = marker;
if (outIo.write(tmpBuf, 2) != 2)
if (outIo.write(tmpBuf.data(), 2) != 2)
throw Error(kerImageWriteFailed);
if (outIo.write(buf.c_data(), size) != size)
if (outIo.write(buf.c_data(), buf.size()) != buf.size())
throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
@ -1246,7 +1229,7 @@ namespace Exiv2 {
throw Error(kerImageWriteFailed);
DataBuf buf(4096);
long readSize = 0;
size_t readSize = 0;
while ((readSize = io_->read(buf.data(), buf.size()))) {
if (outIo.write(buf.c_data(), readSize) != readSize)
throw Error(kerImageWriteFailed);

@ -241,7 +241,7 @@ namespace Exiv2 {
uint32_t OlympusMnHeader::size() const
{
return header_.size();
return static_cast<uint32_t>(header_.size());
}
uint32_t OlympusMnHeader::ifdOffset() const
@ -283,7 +283,7 @@ namespace Exiv2 {
uint32_t Olympus2MnHeader::size() const
{
return header_.size();
return static_cast<uint32_t>(header_.size());
}
uint32_t Olympus2MnHeader::ifdOffset() const
@ -331,7 +331,7 @@ namespace Exiv2 {
uint32_t FujiMnHeader::size() const
{
return header_.size();
return static_cast<uint32_t>(header_.size());
}
uint32_t FujiMnHeader::ifdOffset() const
@ -470,12 +470,11 @@ namespace Exiv2 {
assert(buf_.size() >= 10);
ioWrapper.write(buf_.c_data(), 10);
// Todo: This removes any gap between the header and
// makernote IFD. The gap should be copied too.
/// \todo: This removes any gap between the header and makernote IFD. The gap should be copied too.
TiffHeader th(byteOrder);
DataBuf buf = th.write();
ioWrapper.write(buf.c_data(), buf.size());
return 10 + buf.size();
return 10 + static_cast<uint32_t>(buf.size());
} // Nikon3MnHeader::write
void Nikon3MnHeader::setByteOrder(ByteOrder byteOrder)
@ -542,7 +541,7 @@ namespace Exiv2 {
uint32_t PentaxDngMnHeader::size() const
{
return header_.size();
return static_cast<uint32_t>(header_.size());
}
uint32_t PentaxDngMnHeader::baseOffset(uint32_t mnOffset) const
@ -589,7 +588,7 @@ namespace Exiv2 {
uint32_t PentaxMnHeader::size() const
{
return header_.size();
return static_cast<uint32_t>(header_.size());
}
uint32_t PentaxMnHeader::ifdOffset() const
@ -1163,7 +1162,7 @@ namespace Exiv2 {
}
buf.alloc(size);
buf.copyBytes(0, pData, buf.size());
ncrypt(buf.data(nci->start_), buf.size() - nci->start_, count, serial);
ncrypt(buf.data(nci->start_), static_cast<uint32_t>(buf.size()) - nci->start_, count, serial);
return buf;
}

@ -141,7 +141,7 @@ namespace Exiv2 {
iptcData_,
xmpData_,
buf.c_data(),
buf.size());
static_cast<uint32_t>(buf.size()));
setByteOrder(bo);
} // MrwImage::readMetadata

@ -1400,8 +1400,8 @@ namespace Exiv2 {
}
char ch;
int size = value.size();
for (int i = 0; i < size && ((ch = static_cast<char>(value.toInt64(i))) != '\0'); i++) {
size_t size = value.size();
for (size_t i = 0; i < size && ((ch = static_cast<char>(value.toInt64(i))) != '\0'); i++) {
os << ch;
}
return os;

@ -183,9 +183,9 @@ namespace Exiv2 {
ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end());
}
std::unique_ptr<TiffHeaderBase> header(new OrfHeader(byteOrder));
OrfHeader header(byteOrder);
return TiffParserWorker::encode(io, pData, size, ed, iptcData, xmpData, Tag::root, TiffMapping::findEncoder,
header.get(), nullptr);
&header, nullptr);
}
// *************************************************************************

@ -659,19 +659,18 @@ namespace Exiv2 {
{
if(value.size()>0 && value.typeId() == undefined)
{
for(long i=0; i< value.size(); i++)
for(size_t i=0; i< value.size(); i++)
{
if(value.toInt64(i)==0)
{
break;
};
}
os << static_cast<char>(value.toInt64(i));
};
}
return os;
}
return os << value;
;
} // PanasonicMakerNote::printPanasonicText
// Manometer Pressure

@ -134,14 +134,17 @@ namespace Exiv2 {
std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n";
#endif
if (size < 0 || static_cast<size_t>(size) > io_->size()) throw Error(kerInputDataReadFailed);
if (size == 0) return;
if (size < 0 || static_cast<size_t>(size) > io_->size())
throw Error(kerInputDataReadFailed);
if (size == 0)
return;
DataBuf imgData(size);
imgData.clear();
long bufRead = io_->read(imgData.data(), imgData.size());
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead != imgData.size()) throw Error(kerInputDataReadFailed);
const size_t bufRead = io_->read(imgData.data(), imgData.size());
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != imgData.size())
throw Error(kerInputDataReadFailed);
auto image = Exiv2::ImageFactory::open(imgData.c_data(), imgData.size());
image->readMetadata();
@ -212,7 +215,7 @@ namespace Exiv2 {
if (outIo.putb(mnb) == EOF) throw Error(kerImageWriteFailed);
// Write new Header size.
uint32_t newHeaderSize = header.size() + imgSize;
uint32_t newHeaderSize = static_cast<uint32_t>(header.size()) + imgSize;
DataBuf buffer(4);
buffer.copyBytes(0, &newHeaderSize, 4);
byteSwap_(buffer,0,bSwap_);
@ -228,15 +231,17 @@ namespace Exiv2 {
#endif
// Write Header data.
if (outIo.write(header.c_data(), header.size()) != header.size()) throw Error(kerImageWriteFailed);
if (outIo.write(header.c_data(), header.size()) != header.size())
throw Error(kerImageWriteFailed);
// Write new metadata byte array.
if (outIo.write(imgBuf.c_data(), imgBuf.size()) != imgBuf.size()) throw Error(kerImageWriteFailed);
if (outIo.write(imgBuf.c_data(), imgBuf.size()) != imgBuf.size())
throw Error(kerImageWriteFailed);
// Copy the rest of PGF image data.
DataBuf buf(4096);
long readSize = 0;
size_t readSize = 0;
while ((readSize=io_->read(buf.data(), buf.size())))
{
if (outIo.write(buf.c_data(), readSize) != readSize) throw Error(kerImageWriteFailed);
@ -264,9 +269,11 @@ namespace Exiv2 {
uint32_t PgfImage::readPgfHeaderSize(BasicIo& iIo) const
{
DataBuf buffer(4);
long bufRead = iIo.read(buffer.data(), buffer.size());
if (iIo.error()) throw Error(kerFailedToReadImageData);
if (bufRead != buffer.size()) throw Error(kerInputDataReadFailed);
const size_t bufRead = iIo.read(buffer.data(), buffer.size());
if (iIo.error())
throw Error(kerFailedToReadImageData);
if (bufRead != buffer.size())
throw Error(kerInputDataReadFailed);
int headerSize = static_cast<int>(byteSwap_(buffer, 0, bSwap_));
if (headerSize <= 0 ) throw Error(kerNoImageInInputData);
@ -281,9 +288,11 @@ namespace Exiv2 {
DataBuf PgfImage::readPgfHeaderStructure(BasicIo& iIo, uint32_t& width, uint32_t& height) const
{
DataBuf header(16);
long bufRead = iIo.read(header.data(), header.size());
if (iIo.error()) throw Error(kerFailedToReadImageData);
if (bufRead != header.size()) throw Error(kerInputDataReadFailed);
size_t bufRead = iIo.read(header.data(), header.size());
if (iIo.error())
throw Error(kerFailedToReadImageData);
if (bufRead != header.size())
throw Error(kerInputDataReadFailed);
DataBuf work(8); // don't disturb the binary data - doWriteMetadata reuses it
work.copyBytes(0,header.c_data(),8);

@ -56,7 +56,7 @@ PNG tags : http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG
*/
namespace
{
constexpr int nullSeparators = 2;
constexpr size_t nullSeparators = 2;
}
// *****************************************************************************
@ -101,24 +101,18 @@ namespace Exiv2
DataBuf PngChunk::keyTXTChunk(const DataBuf& data, bool stripHeader)
{
// From a tEXt, zTXt, or iTXt chunk, we get the keyword which is null terminated.
const int offset = stripHeader ? 8 : 0;
const size_t offset = stripHeader ? 8ul : 0ul;
if (data.size() <= offset)
throw Error(kerFailedToReadImageData);
// Search for null char until the end of the DataBuf
const byte* dataPtr = data.c_data();
int keysize = offset;
while (keysize < data.size() && dataPtr[keysize] != 0) {
keysize++;
}
if (keysize == data.size())
auto it = std::find(data.cbegin() + offset, data.cend(), 0);
if (it == data.cend())
throw Error(kerFailedToReadImageData);
return DataBuf(dataPtr + offset, keysize - offset);
return DataBuf(data.c_data() + offset, std::distance(data.cbegin(), it)- offset);
}
DataBuf PngChunk::parseTXTChunk(const DataBuf& data, int keysize, TxtChunkType type)
DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkType type)
{
DataBuf arr;
@ -139,22 +133,22 @@ namespace Exiv2
// compressed string after the compression technique spec
const byte* compressedText = data.c_data(keysize + nullSeparators);
long compressedTextSize = data.size() - keysize - nullSeparators;
size_t compressedTextSize = data.size() - keysize - nullSeparators;
enforce(compressedTextSize < data.size(), kerCorruptedMetadata);
zlibUncompress(compressedText, compressedTextSize, arr);
zlibUncompress(compressedText, static_cast<uint32_t>(compressedTextSize), arr);
} else if (type == tEXt_Chunk) {
enforce(data.size() >= Safe::add(keysize, 1), Exiv2::kerCorruptedMetadata);
enforce(data.size() >= Safe::add(keysize, static_cast<size_t>(1)), Exiv2::kerCorruptedMetadata);
// Extract a non-compressed Latin-1 text chunk
// the text comes after the key, but isn't null terminated
const byte* text = data.c_data(keysize + 1);
long textsize = data.size() - keysize - 1;
size_t textsize = data.size() - keysize - 1;
arr = DataBuf(text, textsize);
} else if (type == iTXt_Chunk) {
enforce(data.size() >= Safe::add(keysize, 3), Exiv2::kerCorruptedMetadata);
const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size()), '\0');
enforce(data.size() > Safe::add(keysize, static_cast<size_t>(3)), Exiv2::kerCorruptedMetadata);
const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size()-1), '\0');
enforce(nullCount >= nullSeparators, Exiv2::kerCorruptedMetadata);
// Extract a deflate compressed or uncompressed UTF-8 text chunk
@ -169,21 +163,19 @@ namespace Exiv2
// language description string after the compression technique spec
const size_t languageTextMaxSize = data.size() - keysize - 3;
std::string languageText =
string_from_unterminated(data.c_str(Safe::add(keysize, 3)), languageTextMaxSize);
std::string languageText = string_from_unterminated(data.c_str(keysize+3), languageTextMaxSize);
const size_t languageTextSize = languageText.size();
enforce(static_cast<unsigned long>(data.size()) >=
Safe::add(static_cast<size_t>(Safe::add(keysize, 4)), languageTextSize),
Exiv2::kerCorruptedMetadata);
enforce(data.size() >= Safe::add(Safe::add(keysize, static_cast<size_t>(4)), languageTextSize),
Exiv2::kerCorruptedMetadata);
// translated keyword string after the language description
std::string translatedKeyText = string_from_unterminated(
data.c_str(keysize + 3 + languageTextSize + 1), data.size() - (keysize + 3 + languageTextSize + 1));
const auto translatedKeyTextSize = static_cast<unsigned int>(translatedKeyText.size());
const size_t translatedKeyTextSize = translatedKeyText.size();
if ((compressionFlag == 0x00) || (compressionFlag == 0x01 && compressionMethod == 0x00)) {
enforce(Safe::add(static_cast<unsigned int>(keysize + 3 + languageTextSize + 1),
Safe::add(translatedKeyTextSize, 1U)) <= static_cast<size_t>(data.size()),
enforce(Safe::add(keysize + 3 + languageTextSize + 1,
Safe::add(translatedKeyTextSize, static_cast<size_t>(1))) <= data.size(),
Exiv2::kerCorruptedMetadata);
const byte* text = data.c_data(keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1);
@ -195,8 +187,6 @@ namespace Exiv2
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n";
#endif
arr.alloc(textsize);
arr = DataBuf(text, textsize);
} else if (compressionFlag == 0x01 && compressionMethod == 0x00) {
// then it's a zlib compressed iTXt chunk
@ -224,7 +214,7 @@ namespace Exiv2
return arr;
}
void PngChunk::parseChunkContent(Image* pImage, const byte* key, long keySize, const DataBuf& arr)
void PngChunk::parseChunkContent(Image* pImage, const byte* key, size_t keySize, const DataBuf& arr)
{
// We look if an ImageMagick EXIF raw profile exist.
@ -232,16 +222,16 @@ namespace Exiv2
(memcmp("Raw profile type exif", key, 21) == 0 || memcmp("Raw profile type APP1", key, 21) == 0) &&
pImage->exifData().empty()) {
DataBuf exifData = readRawProfile(arr, false);
long length = exifData.size();
size_t length = exifData.size();
if (length > 0) {
if (length >= 6) { // length should have at least the size of exifHeader
// Find the position of Exif header in bytes array.
const std::array<byte,6> exifHeader {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
size_t pos = std::numeric_limits<size_t>::max();
const byte exifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
long pos = -1;
for (long i = 0; i < length - static_cast<long>(sizeof(exifHeader)); i++) {
if (exifData.cmpBytes(i, exifHeader, sizeof(exifHeader)) == 0) {
/// \todo Find substring inside an string
for (size_t i = 0; i < length - exifHeader.size(); i++) {
if (exifData.cmpBytes(i, exifHeader.data(), exifHeader.size()) == 0) {
pos = i;
break;
}
@ -249,14 +239,14 @@ namespace Exiv2
// If found it, store only these data at from this place.
if (pos != -1) {
if (pos != std::numeric_limits<size_t>::max()) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngChunk::parseChunkContent: Exif header found at position " << pos
<< "\n";
#endif
pos = pos + sizeof(exifHeader);
ByteOrder bo = TiffParser::decode(pImage->exifData(), pImage->iptcData(), pImage->xmpData(),
exifData.c_data(pos), length - pos);
exifData.c_data(pos), static_cast<uint32_t>(length - pos));
pImage->setByteOrder(bo);
} else {
#ifndef SUPPRESS_WARNINGS
@ -277,10 +267,9 @@ namespace Exiv2
uint32_t sizeIptc = 0;
uint32_t sizeHdr = 0;
const byte* pEnd = psData.c_data(psData.size());
const byte* pEnd = psData.c_data(psData.size()-1);
const byte* pCur = psData.c_data();
while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, static_cast<long>(pEnd - pCur), &record,
&sizeHdr, &sizeIptc)) {
while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, pEnd - pCur, &record, &sizeHdr, &sizeIptc)) {
if (sizeIptc) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
@ -298,7 +287,8 @@ namespace Exiv2
pImage->clearIptcData();
}
// If there is no IRB, try to decode the complete chunk data
if (iptcBlob.empty() && IptcParser::decode(pImage->iptcData(), psData.c_data(), psData.size())) {
if (iptcBlob.empty() && IptcParser::decode(pImage->iptcData(), psData.c_data(),
static_cast<uint32_t>(psData.size()))) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to decode IPTC metadata.\n";
#endif
@ -311,7 +301,7 @@ namespace Exiv2
if (keySize >= 20 && memcmp("Raw profile type xmp", key, 20) == 0 && pImage->xmpData().empty()) {
DataBuf xmpBuf = readRawProfile(arr, false);
long length = xmpBuf.size();
size_t length = xmpBuf.size();
if (length > 0) {
std::string& xmpPacket = pImage->xmpPacket();
@ -534,15 +524,16 @@ namespace Exiv2
DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt)
{
if (text.size() <= 1) {
return DataBuf();
}
DataBuf info;
unsigned char unhex[103] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
if (text.size() == 0) {
return DataBuf();
}
if (iTXt) {
info.alloc(text.size());
@ -551,7 +542,7 @@ namespace Exiv2
}
const char* sp = text.c_str(1); // current byte (space pointer)
const char* eot = text.c_str(text.size()); // end of text
const char* eot = text.c_str(text.size()-1); // end of text
if (sp >= eot) {
return DataBuf();
@ -578,15 +569,14 @@ namespace Exiv2
}
// Parse the length.
long length = 0;
size_t length = 0;
while ('0' <= *sp && *sp <= '9') {
// Compute the new length using unsigned long, so that we can
// check for overflow.
const unsigned long newlength = (10 * static_cast<unsigned long>(length)) + (*sp - '0');
if (newlength > static_cast<unsigned long>(std::numeric_limits<long>::max())) {
// Compute the new length using unsigned long, so that we can check for overflow.
const size_t newlength = (10 * length) + (*sp - '0');
if (newlength > std::numeric_limits<size_t>::max()) {
return DataBuf(); // Integer overflow.
}
length = static_cast<long>(newlength);
length = newlength;
sp++;
if (sp == eot) {
return DataBuf();
@ -597,7 +587,7 @@ namespace Exiv2
return DataBuf();
}
enforce(length <= (eot - sp) / 2, Exiv2::kerCorruptedMetadata);
enforce(length <= static_cast<size_t>(eot - sp) / 2, Exiv2::kerCorruptedMetadata);
// Allocate space
if (length == 0) {
@ -616,9 +606,9 @@ namespace Exiv2
// Copy profile, skipping white space and column 1 "=" signs
unsigned char* dp = info.data(); // decode pointer
unsigned int nibbles = length * 2;
size_t nibbles = length * 2;
for (long i = 0; i < static_cast<long>(nibbles); i++) {
for (size_t i = 0; i < nibbles; i++) {
enforce(sp < eot, Exiv2::kerCorruptedMetadata);
while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f') {
if (*sp == '\0') {

@ -113,9 +113,7 @@ namespace Exiv2 {
@brief Parse PNG Text chunk to determine type and extract content.
Supported Chunk types are tTXt, zTXt, and iTXt.
*/
static DataBuf parseTXTChunk(const DataBuf& data,
int keysize,
TxtChunkType type);
static DataBuf parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkType type);
/*!
@brief Parse PNG chunk contents to extract metadata container and assign it to image.
@ -126,7 +124,7 @@ namespace Exiv2 {
Xmp packet generated by Adobe ==> Image Xmp metadata.
Description string ==> Image Comments.
*/
static void parseChunkContent(Image* pImage, const byte* key, long keySize, const DataBuf& arr);
static void parseChunkContent(Image* pImage, const byte* key, size_t keySize, const DataBuf& arr);
/*!
@brief Return a compressed (zTXt) or uncompressed (tEXt) PNG ASCII text chunk
@ -157,9 +155,7 @@ namespace Exiv2 {
/*!
@brief Wrapper around zlib to uncompress a PNG chunk content.
*/
static void zlibUncompress(const byte* compressedText,
unsigned int compressedTextSize,
DataBuf& arr);
static void zlibUncompress(const byte* compressedText, unsigned int compressedTextSize, DataBuf& arr);
/*!
@brief Wrapper around zlib to compress a PNG chunk content.

@ -62,7 +62,7 @@ namespace
inline bool compare(const char* str, const Exiv2::DataBuf& buf, size_t length)
{
assert(strlen(str) <= length);
const long minlen = std::min(static_cast<long>(length), buf.size());
const auto minlen = std::min(length, buf.size());
return buf.cmpBytes(0, str, minlen) == 0;
}
} // namespace
@ -108,7 +108,7 @@ namespace Exiv2 {
result.alloc(uncompressedLen);
zlibResult = uncompress(result.data(),&uncompressedLen,bytes,length);
// if result buffer is large than necessary, redo to fit perfectly.
if (zlibResult == Z_OK && static_cast<long>(uncompressedLen) < result.size()) {
if (zlibResult == Z_OK && uncompressedLen < result.size()) {
result.reset();
result.alloc(uncompressedLen);
@ -240,16 +240,17 @@ namespace Exiv2 {
out << " address | chunk | length | data | checksum" << std::endl;
}
const long imgSize = static_cast<long>(io_->size());
const size_t imgSize = io_->size();
DataBuf cheaderBuf(8);
while( !io_->eof() && ::strcmp(chType,"IEND") ) {
size_t address = io_->tell();
cheaderBuf.clear();
long bufRead = io_->read(cheaderBuf.data(), cheaderBuf.size());
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead != cheaderBuf.size()) throw Error(kerInputDataReadFailed);
size_t bufRead = io_->read(cheaderBuf.data(), cheaderBuf.size());
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != cheaderBuf.size())
throw Error(kerInputDataReadFailed);
// Decode chunk data length.
const uint32_t dataOffset = cheaderBuf.read_uint32(0, Exiv2::bigEndian);
@ -261,14 +262,14 @@ namespace Exiv2 {
long restore = io_->tell();
if( restore == -1
|| dataOffset > uint32_t(0x7FFFFFFF)
|| static_cast<long>(dataOffset) > imgSize - restore
|| dataOffset > imgSize - restore
){
throw Exiv2::Error(kerFailedToReadImageData);
}
DataBuf buff(dataOffset);
bufRead = io_->read(buff.data(),dataOffset);
enforce(bufRead == static_cast<long>(dataOffset), kerFailedToReadImageData);
enforce(bufRead == dataOffset, kerFailedToReadImageData);
io_->seek(restore, BasicIo::beg);
// format output
@ -320,11 +321,11 @@ namespace Exiv2 {
if( bDump ) {
DataBuf dataBuf;
enforce(static_cast<uint64_t>(dataOffset) < static_cast<unsigned long>(std::numeric_limits<long>::max()), kerFailedToReadImageData);
DataBuf data(static_cast<long>(dataOffset) + 1);
enforce(dataOffset < std::numeric_limits<uint32_t>::max(), kerFailedToReadImageData);
DataBuf data(dataOffset + 1ul);
data.write_uint8(dataOffset, 0);
bufRead = io_->read(data.data(), static_cast<long>(dataOffset));
enforce(bufRead == static_cast<long>(dataOffset), kerFailedToReadImageData);
bufRead = io_->read(data.data(), dataOffset);
enforce(bufRead == dataOffset, kerFailedToReadImageData);
io_->seek(restore, BasicIo::beg);
size_t name_l = std::strlen(data.c_str()) +
1; // leading string length
@ -336,10 +337,10 @@ namespace Exiv2 {
// decode the chunk
bool bGood = false;
if ( tEXt ) {
bGood = tEXtToDataBuf(data.c_data(name_l), static_cast<unsigned long>(dataOffset - name_l), dataBuf);
bGood = tEXtToDataBuf(data.c_data(name_l), static_cast<long>(dataOffset - name_l), dataBuf);
}
if ( zTXt || iCCP ) {
bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast<unsigned long>(dataOffset - name_l - 1), dataBuf); // +1 = 'compressed' flag
bGood = zlibToDataBuf(data.c_data(name_l + 1), static_cast<long>(dataOffset - name_l - 1), dataBuf); // +1 = 'compressed' flag
}
if ( iTXt ) {
bGood = (3 <= dataOffset) && (start < dataOffset-3); // good if not a nul chunk
@ -363,7 +364,7 @@ namespace Exiv2 {
if ( parsedBuf.size() ) {
if ( bExif ) {
// create memio object with the data, then print the structure
MemIo p(parsedBuf.c_data(6),parsedBuf.size()-6);
MemIo p(parsedBuf.c_data(6), parsedBuf.size()-6);
printTiffStructure(p,out,option,depth);
}
if ( bIptc ) {
@ -401,7 +402,8 @@ namespace Exiv2 {
}
}
io_->seek(dataOffset+4, BasicIo::cur);// jump past checksum
if (io_->error()) throw Error(kerFailedToReadImageData);
if (io_->error())
throw Error(kerFailedToReadImageData);
}
}
}
@ -411,7 +413,7 @@ namespace Exiv2 {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngImage::readMetadata: Position: " << io.tell() << std::endl;
#endif
long bufRead = io.read(buffer.data(), buffer.size());
const size_t bufRead = io.read(buffer.data(), buffer.size());
if (io.error()) {
throw Error(kerFailedToReadImageData);
}
@ -435,12 +437,11 @@ namespace Exiv2 {
}
clearMetadata();
const long imgSize = static_cast<long>(io_->size());
const size_t imgSize = io_->size();
DataBuf cheaderBuf(8); // Chunk header: 4 bytes (data size) + 4 bytes (chunk type).
while(!io_->eof())
{
cheaderBuf.clear();
readChunk(cheaderBuf, *io_); // Read chunk header.
// Decode chunk data length.
@ -448,7 +449,7 @@ namespace Exiv2 {
long pos = io_->tell();
if (pos == -1 ||
chunkLength > uint32_t(0x7FFFFFFF) ||
static_cast<long>(chunkLength) > imgSize - pos) {
chunkLength > imgSize - pos) {
throw Exiv2::Error(kerFailedToReadImageData);
}
@ -484,7 +485,7 @@ namespace Exiv2 {
iptcData(),
xmpData(),
chunkData.c_data(),
chunkData.size());
static_cast<uint32_t>(chunkData.size()));
setByteOrder(bo);
} else if (chunkType == "iCCP") {
// The ICC profile name can vary from 1-79 characters.
@ -540,8 +541,10 @@ namespace Exiv2 {
void PngImage::doWriteMetadata(BasicIo& outIo)
{
if (!io_->isopen()) throw Error(kerInputDataReadFailed);
if (!outIo.isopen()) throw Error(kerImageWriteFailed);
if (!io_->isopen())
throw Error(kerInputDataReadFailed);
if (!outIo.isopen())
throw Error(kerImageWriteFailed);
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngImage::doWriteMetadata: Writing PNG file " << io_->path() << "\n";
@ -553,31 +556,34 @@ namespace Exiv2 {
}
// Write PNG Signature.
if (outIo.write(pngSignature, 8) != 8) throw Error(kerImageWriteFailed);
if (outIo.write(pngSignature, 8) != 8)
throw Error(kerImageWriteFailed);
DataBuf cheaderBuf(8); // Chunk header : 4 bytes (data size) + 4 bytes (chunk type).
while(!io_->eof())
{
// Read chunk header.
cheaderBuf.clear();
long bufRead = io_->read(cheaderBuf.data(), 8);
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead != 8) throw Error(kerInputDataReadFailed);
size_t bufRead = io_->read(cheaderBuf.data(), 8);
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != 8)
throw Error(kerInputDataReadFailed);
// Decode chunk data length.
uint32_t dataOffset = cheaderBuf.read_uint32(0, Exiv2::bigEndian);
if (dataOffset > 0x7FFFFFFF) throw Exiv2::Error(kerFailedToReadImageData);
if (dataOffset > 0x7FFFFFFF)
throw Exiv2::Error(kerFailedToReadImageData);
// Read whole chunk : Chunk header + Chunk data (not fixed size - can be null) + CRC (4 bytes).
DataBuf chunkBuf(8 + dataOffset + 4); // Chunk header (8 bytes) + Chunk data + CRC (4 bytes).
chunkBuf.copyBytes(0, cheaderBuf.c_data(), 8); // Copy header.
bufRead = io_->read(chunkBuf.data(8), dataOffset + 4); // Extract chunk data + CRC
if (io_->error()) throw Error(kerFailedToReadImageData);
if (bufRead != static_cast<long>(dataOffset) + 4L)
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != static_cast<size_t>(dataOffset) + 4)
throw Error(kerInputDataReadFailed);
char szChunk[5];
@ -601,15 +607,15 @@ namespace Exiv2 {
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngImage::doWriteMetadata: Write IHDR chunk (length: " << dataOffset << ")\n";
#endif
if (outIo.write(chunkBuf.data(), chunkBuf.size()) != chunkBuf.size()) throw Error(kerImageWriteFailed);
if (outIo.write(chunkBuf.data(), chunkBuf.size()) != chunkBuf.size())
throw Error(kerImageWriteFailed);
// Write all updated metadata here, just after IHDR.
if (!comment_.empty())
{
// Update Comment data to a new PNG chunk
std::string chunk = PngChunk::makeMetadataChunk(comment_, mdComment);
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), static_cast<long>(chunk.size())) !=
static_cast<long>(chunk.size())) {
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), chunk.size()) != chunk.size()) {
throw Error(kerImageWriteFailed);
}
}
@ -624,8 +630,7 @@ namespace Exiv2 {
std::string rawExif = std::string(exifHeader, 6) +
std::string(reinterpret_cast<const char*>(&blob[0]), blob.size());
std::string chunk = PngChunk::makeMetadataChunk(rawExif, mdExif);
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), static_cast<long>(chunk.size())) !=
static_cast<long>(chunk.size())) {
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), chunk.size()) != chunk.size()) {
throw Error(kerImageWriteFailed);
}
}
@ -639,8 +644,7 @@ namespace Exiv2 {
{
std::string rawIptc(newPsData.c_str(), newPsData.size());
std::string chunk = PngChunk::makeMetadataChunk(rawIptc, mdIptc);
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), static_cast<long>(chunk.size())) !=
static_cast<long>(chunk.size())) {
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), chunk.size()) != chunk.size()) {
throw Error(kerImageWriteFailed);
}
}
@ -648,9 +652,9 @@ namespace Exiv2 {
if ( iccProfileDefined() ) {
DataBuf compressed;
if ( zlibToCompressed(iccProfile_.c_data(),iccProfile_.size(),compressed) ) {
if ( zlibToCompressed(iccProfile_.c_data(), static_cast<long>(iccProfile_.size()), compressed) ) {
const auto nameLength = static_cast<uint32_t>(profileName_.size());
const uint32_t chunkLength = nameLength + 2 + compressed.size() ;
const uint32_t chunkLength = nameLength + 2 + static_cast<uint32_t>(compressed.size());
byte length[4];
ul2Data (length,chunkLength,bigEndian);
@ -659,7 +663,7 @@ namespace Exiv2 {
tmp = crc32(tmp, typeICCP, 4);
tmp = crc32(tmp, (const Bytef*)profileName_.data(), nameLength);
tmp = crc32(tmp, nullComp, 2);
tmp = crc32(tmp, compressed.c_data(), compressed.size());
tmp = crc32(tmp, compressed.c_data(), static_cast<uint32_t>(compressed.size()));
byte crc[4];
ul2Data(crc, tmp, bigEndian);
@ -689,22 +693,23 @@ namespace Exiv2 {
if (!xmpPacket_.empty()) {
// Update XMP data to a new PNG chunk
std::string chunk = PngChunk::makeMetadataChunk(xmpPacket_, mdXmp);
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), static_cast<long>(chunk.size())) !=
static_cast<long>(chunk.size())) {
if (outIo.write(reinterpret_cast<const byte*>(chunk.data()), chunk.size()) !=
chunk.size()) {
throw Error(kerImageWriteFailed);
}
}
} else if (!strcmp(szChunk, "tEXt") || !strcmp(szChunk, "zTXt") || !strcmp(szChunk, "iTXt") ||
!strcmp(szChunk, "iCCP")) {
DataBuf key = PngChunk::keyTXTChunk(chunkBuf, true);
if (compare("Raw profile type exif", key, 21) ||
if (key.empty() == false && (
compare("Raw profile type exif", key, 21) ||
compare("Raw profile type APP1", key, 21) ||
compare("Raw profile type iptc", key, 21) ||
compare("Raw profile type xmp", key, 20) ||
compare("XML:com.adobe.xmp", key, 17) ||
compare("icc", key, 3) || // see test/data/imagemagick.png
compare("ICC", key, 3) ||
compare("Description", key, 11))
compare("Description", key, 11)))
{
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PngImage::doWriteMetadata: strip " << szChunk
@ -725,7 +730,8 @@ namespace Exiv2 {
std::cout << "Exiv2::PngImage::doWriteMetadata: copy " << szChunk
<< " chunk (length: " << dataOffset << ")" << std::endl;
#endif
if (outIo.write(chunkBuf.c_data(), chunkBuf.size()) != chunkBuf.size()) throw Error(kerImageWriteFailed);
if (outIo.write(chunkBuf.c_data(), chunkBuf.size()) != chunkBuf.size())
throw Error(kerImageWriteFailed);
}
}

@ -140,7 +140,7 @@ namespace {
uint32_t height_;
//! Preview image size in bytes
uint32_t size_;
size_t size_;
//! True if the source image contains a preview image of given type
bool valid_;
@ -197,7 +197,7 @@ namespace {
static const Param param_[];
//! Offset value
uint32_t offset_;
size_t offset_;
};
//! Function to create new LoaderExifJpeg
@ -424,7 +424,7 @@ namespace {
if (nativePreview_.filter_.empty()) {
size_ = nativePreview_.size_;
} else {
size_ = getData().size();
size_ = static_cast<uint32_t>(getData().size());
}
}
@ -496,11 +496,15 @@ namespace {
bool LoaderNative::readDimensions()
{
if (!valid()) return false;
if (width_ != 0 || height_ != 0) return true;
if (!valid())
return false;
if (width_ != 0 || height_ != 0)
return true;
const DataBuf data = getData();
if (data.size() == 0) return false;
if (data.empty())
return false;
try {
auto image = ImageFactory::open(data.c_data(), data.size());
if (!image)
@ -618,7 +622,8 @@ namespace {
size_ = pos->size(); // direct data
}
if (size_ == 0) return;
if (size_ == 0)
return;
valid_ = true;
}
@ -644,7 +649,7 @@ namespace {
if (pos != image_.exifData().end()) {
DataBuf buf = pos->dataArea(); // indirect data
if (buf.size() == 0) { // direct data
if (buf.empty()) { // direct data
buf = DataBuf(pos->size());
pos->copy(buf.data(), invalidByteOrder);
}
@ -658,10 +663,12 @@ namespace {
bool LoaderExifDataJpeg::readDimensions()
{
if (!valid()) return false;
if (!valid())
return false;
DataBuf buf = getData();
if (buf.size() == 0) return false;
if (buf.empty())
return false;
try {
auto image = ImageFactory::open(buf.c_data(), buf.size());
@ -685,14 +692,16 @@ namespace {
{
const ExifData &exifData = image_.exifData();
int offsetCount = 0;
size_t offsetCount = 0;
ExifData::const_iterator pos;
// check if the group_ contains a preview image
if (param_[parIdx].checkTag_) {
pos = exifData.findKey(ExifKey(param_[parIdx].checkTag_));
if (pos == exifData.end()) return;
if (param_[parIdx].checkValue_ && pos->toString() != param_[parIdx].checkValue_) return;
if (pos == exifData.end())
return;
if (param_[parIdx].checkValue_ && pos->toString() != param_[parIdx].checkValue_)
return;
}
pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".StripOffsets"));
@ -703,20 +712,24 @@ namespace {
}
else {
pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".TileOffsets"));
if (pos == exifData.end()) 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()) return;
if (offsetCount != pos->value().count()) return;
for (int i = 0; i < offsetCount; i++) {
size_ += pos->toUint32(i);
if (pos == exifData.end())
return;
if (offsetCount != pos->value().count())
return;
for (size_t i = 0; i < offsetCount; i++) {
size_ += pos->toUint32(static_cast<long>(i));
}
if (size_ == 0) return;
if (size_ == 0)
return;
pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".ImageWidth"));
if (pos != exifData.end() && pos->count() > 0) {
@ -728,7 +741,8 @@ namespace {
height_ = pos->toUint32();
}
if (width_ == 0 || height_ == 0) return;
if (width_ == 0 || height_ == 0)
return;
valid_ = true;
}
@ -797,7 +811,7 @@ namespace {
enforce(size_ <= static_cast<uint32_t>(io.size()), kerCorruptedMetadata);
DataBuf buf(size_);
uint32_t idxBuf = 0;
for (long i = 0; i < sizes.count(); i++) {
for (size_t i = 0; i < sizes.count(); i++) {
uint32_t offset = dataValue.toUint32(i);
uint32_t size = sizes.toUint32(i);
@ -843,15 +857,20 @@ namespace {
}
auto imageDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":image"));
if (imageDatum == xmpData.end()) return;
if (imageDatum == xmpData.end())
return;
auto formatDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":format"));
if (formatDatum == xmpData.end()) return;
if (formatDatum == xmpData.end())
return;
auto widthDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":width"));
if (widthDatum == xmpData.end()) return;
if (widthDatum == xmpData.end())
return;
auto heightDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":height"));
if (heightDatum == xmpData.end()) return;
if (heightDatum == xmpData.end())
return;
if (formatDatum->toString() != "JPEG") return;
if (formatDatum->toString() != "JPEG")
return;
width_ = widthDatum->toUint32();
height_ = heightDatum->toUint32();
@ -875,7 +894,8 @@ namespace {
DataBuf LoaderXmpJpeg::getData() const
{
if (!valid()) return DataBuf();
if (!valid())
return DataBuf();
return DataBuf(preview_.c_data(), preview_.size());
}
@ -937,11 +957,13 @@ namespace {
if (decodeBase64Table[static_cast<unsigned char>(src[srcPos])] != invalid)
validSrcSize++;
}
if (validSrcSize > ULONG_MAX / 3) return DataBuf(); // avoid integer overflow
if (validSrcSize > ULONG_MAX / 3)
return DataBuf(); // avoid integer overflow
const unsigned long destSize = (validSrcSize * 3) / 4;
// allocate dest buffer
if (destSize > LONG_MAX) return DataBuf(); // avoid integer overflow
if (destSize > LONG_MAX)
return DataBuf(); // avoid integer overflow
DataBuf dest(static_cast<long>(destSize));
// decode
@ -971,7 +993,7 @@ namespace {
return DataBuf();
}
const byte *imageData = src.c_data(colorTableSize);
const long imageDataSize = src.size() - colorTableSize;
const long imageDataSize = static_cast<long>(src.size()) - colorTableSize;
const bool rle = (imageDataSize >= 3 && imageData[0] == 'R' && imageData[1] == 'L' && imageData[2] == 'E');
std::string dest;
for (long i = rle ? 3 : 0; i < imageDataSize;) {
@ -1005,7 +1027,7 @@ namespace {
DataBuf makePnm(uint32_t width, uint32_t height, const DataBuf &rgb)
{
const long expectedSize = static_cast<long>(width) * static_cast<long>(height) * 3L;
const size_t expectedSize = width * height * 3UL;
if (rgb.size() != expectedSize) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Invalid size of preview data. Expected " << expectedSize << " bytes, got " << rgb.size() << " bytes.\n";
@ -1037,13 +1059,14 @@ namespace Exiv2 {
PreviewImage& PreviewImage::operator=(const PreviewImage& rhs)
{
if (this == &rhs) return *this;
if (this == &rhs)
return *this;
properties_ = rhs.properties_;
preview_ = DataBuf(rhs.pData(), rhs.size());
return *this;
}
long PreviewImage::writeFile(const std::string& path) const
size_t PreviewImage::writeFile(const std::string& path) const
{
std::string name = path + extension();
// Todo: Creating a DataBuf here unnecessarily copies the memory
@ -1063,7 +1086,7 @@ namespace Exiv2 {
uint32_t PreviewImage::size() const
{
return preview_.size();
return static_cast<uint32_t>(preview_.size());
}
std::string PreviewImage::mimeType() const
@ -1105,7 +1128,7 @@ namespace Exiv2 {
if (loader && loader->readDimensions()) {
PreviewProperties props = loader->getProperties();
DataBuf buf = loader->getData(); // #16 getPreviewImage()
props.size_ = buf.size(); // update the size
props.size_ = static_cast<uint32_t>(buf.size()); // update the size
list.push_back(props) ;
}
}

@ -4186,19 +4186,20 @@ namespace Exiv2 {
prefix_ = prefix;
}
XmpKey::XmpKey(const std::string& key) : p_(new Impl)
XmpKey::XmpKey(const std::string& key) : p_(std::make_unique<Impl>())
{
p_->decomposeKey(key);
}
XmpKey::XmpKey(const std::string& prefix, const std::string& property) : p_(new Impl(prefix, property))
XmpKey::XmpKey(const std::string& prefix, const std::string& property)
: p_(std::make_unique<Impl>(prefix, property))
{
}
XmpKey::~XmpKey() = default;
XmpKey::XmpKey(const XmpKey& rhs)
: p_(new Impl(*rhs.p_))
: p_(std::make_unique<Impl>(*rhs.p_))
{
}

@ -146,7 +146,8 @@ namespace Exiv2 {
// Ensure that this is the correct image type
if (!isPsdType(*io_, false))
{
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
throw Error(kerNotAnImage, "Photoshop");
}
clearMetadata();
@ -248,8 +249,9 @@ namespace Exiv2 {
{
DataBuf rawIPTC(resourceSize);
io_->read(rawIPTC.data(), rawIPTC.size());
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (IptcParser::decode(iptcData_, rawIPTC.c_data(), rawIPTC.size())) {
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
if (IptcParser::decode(iptcData_, rawIPTC.c_data(), static_cast<uint32_t>(rawIPTC.size()))) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to decode IPTC metadata.\n";
#endif
@ -262,7 +264,8 @@ namespace Exiv2 {
{
DataBuf rawExif(resourceSize);
io_->read(rawExif.data(), rawExif.size());
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
ByteOrder bo = ExifParser::decode(exifData_, rawExif.c_data(), rawExif.size());
setByteOrder(bo);
if (rawExif.size() > 0 && byteOrder() == invalidByteOrder) {
@ -278,7 +281,8 @@ namespace Exiv2 {
{
DataBuf xmpPacket(resourceSize);
io_->read(xmpPacket.data(), xmpPacket.size());
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
xmpPacket_.assign(xmpPacket.c_str(), xmpPacket.size());
if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
#ifndef SUPPRESS_WARNINGS
@ -323,7 +327,8 @@ namespace Exiv2 {
if (nativePreview.size_ > 0 && nativePreview.position_ >= 0) {
io_->seek(static_cast<long>(nativePreview.size_), BasicIo::cur);
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
if (format == 1) {
nativePreview.filter_ = "";
@ -360,8 +365,10 @@ namespace Exiv2 {
void PsdImage::doWriteMetadata(BasicIo& outIo)
{
if (!io_->isopen()) throw Error(kerInputDataReadFailed);
if (!outIo.isopen()) throw Error(kerImageWriteFailed);
if (!io_->isopen())
throw Error(kerInputDataReadFailed);
if (!outIo.isopen())
throw Error(kerImageWriteFailed);
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::PsdImage::doWriteMetadata: Writing PSD file " << io_->path() << "\n";
@ -370,7 +377,8 @@ namespace Exiv2 {
// Ensure that this is the correct image type
if (!isPsdType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(kerInputDataReadFailed);
if (io_->error() || io_->eof())
throw Error(kerInputDataReadFailed);
throw Error(kerNoImageInInputData);
}
@ -381,47 +389,54 @@ namespace Exiv2 {
// Get Photoshop header from original file
byte psd_head[26];
if (io_->read(psd_head, 26) != 26) throw Error(kerNotAnImage, "Photoshop");
if (io_->read(psd_head, 26) != 26)
throw Error(kerNotAnImage, "Photoshop");
// Write Photoshop header data out to new PSD file
if (outIo.write(psd_head, 26) != 26) throw Error(kerImageWriteFailed);
if (outIo.write(psd_head, 26) != 26)
throw Error(kerImageWriteFailed);
// Read colorDataLength from original PSD
if (io_->read(buf, 4) != 4) throw Error(kerNotAnImage, "Photoshop");
if (io_->read(buf, 4) != 4)
throw Error(kerNotAnImage, "Photoshop");
uint32_t colorDataLength = getULong(buf, bigEndian);
// Write colorDataLength
ul2Data(buf, colorDataLength, bigEndian);
if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << std::dec << "colorDataLength: " << colorDataLength << "\n";
#endif
// Copy colorData
uint32_t readTotal = 0;
size_t readTotal = 0;
while (readTotal < colorDataLength) {
long toRead = static_cast<long>(colorDataLength - readTotal) < lbuf.size()
? static_cast<long>(colorDataLength - readTotal)
: lbuf.size();
size_t toRead = (colorDataLength - readTotal) < lbuf.size()
? static_cast<size_t>(colorDataLength) - readTotal
: lbuf.size();
if (io_->read(lbuf.data(), toRead) != toRead)
throw Error(kerNotAnImage, "Photoshop");
readTotal += toRead;
if (outIo.write(lbuf.c_data(), toRead) != toRead)
throw Error(kerImageWriteFailed);
}
if (outIo.error()) throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
uint32_t resLenOffset = io_->tell(); // remember for later update
// Read length of all resource blocks from original PSD
if (io_->read(buf, 4) != 4) throw Error(kerNotAnImage, "Photoshop");
if (io_->read(buf, 4) != 4)
throw Error(kerNotAnImage, "Photoshop");
uint32_t oldResLength = getULong(buf, bigEndian);
uint32_t newResLength = 0;
// Write oldResLength (will be updated later)
ul2Data(buf, oldResLength, bigEndian);
if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << std::dec << "oldResLength: " << oldResLength << "\n";
@ -435,7 +450,8 @@ namespace Exiv2 {
bool exifDone = false;
bool xmpDone = false;
while (oldResLength > 0) {
if (io_->read(buf, 8) != 8) throw Error(kerNotAnImage, "Photoshop");
if (io_->read(buf, 8) != 8)
throw Error(kerNotAnImage, "Photoshop");
// read resource type and ID
uint32_t resourceType = getULong(buf, bigEndian);
@ -451,11 +467,12 @@ namespace Exiv2 {
// read rest of resource name, plus any padding
DataBuf resName(256);
if ( io_->read(resName.data(), adjResourceNameLen)
!= static_cast<long>(adjResourceNameLen)) throw Error(kerNotAnImage, "Photoshop");
if (io_->read(resName.data(), adjResourceNameLen) != adjResourceNameLen)
throw Error(kerNotAnImage, "Photoshop");
// read resource size (actual length w/o padding!)
if (io_->read(buf, 4) != 4) throw Error(kerNotAnImage, "Photoshop");
if (io_->read(buf, 4) != 4)
throw Error(kerNotAnImage, "Photoshop");
uint32_t resourceSize = getULong(buf, bigEndian);
uint32_t pResourceSize = (resourceSize + 1) & ~1; // padded resource size
@ -493,25 +510,30 @@ namespace Exiv2 {
#endif
// Copy resource block to new PSD file
ul2Data(buf, resourceType, bigEndian);
if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
us2Data(buf, resourceId, bigEndian);
if (outIo.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
// Write resource name as Pascal string
buf[0] = resourceNameLength & 0x00ff;
if (outIo.write(buf, 1) != 1) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 1) != 1)
throw Error(kerImageWriteFailed);
buf[0] = resourceNameFirstChar;
if (outIo.write(buf, 1) != 1) throw Error(kerImageWriteFailed);
if ( outIo.write(resName.c_data(), adjResourceNameLen)
!= static_cast<long>(adjResourceNameLen)) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 1) != 1)
throw Error(kerImageWriteFailed);
if (outIo.write(resName.c_data(), adjResourceNameLen) != static_cast<size_t>(adjResourceNameLen))
throw Error(kerImageWriteFailed);
ul2Data(buf, resourceSize, bigEndian);
if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
readTotal = 0;
while (readTotal < pResourceSize) {
/// \todo almost same code as in lines 403-410. Factor out & reuse!
long toRead = static_cast<long>(pResourceSize - readTotal) < lbuf.size()
size_t toRead = (pResourceSize - readTotal) < lbuf.size()
? static_cast<long>(pResourceSize - readTotal)
: lbuf.size();
: static_cast<long>(lbuf.size());
if (io_->read(lbuf.data(), toRead) != toRead) {
throw Error(kerNotAnImage, "Photoshop");
}
@ -519,7 +541,8 @@ namespace Exiv2 {
if (outIo.write(lbuf.c_data(), toRead) != toRead)
throw Error(kerImageWriteFailed);
}
if (outIo.error()) throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
newResLength += pResourceSize + adjResourceNameLen + 12;
}
@ -548,11 +571,13 @@ namespace Exiv2 {
io_->populateFakeData();
// Copy remaining data
long readSize = 0;
size_t readSize = 0;
while ((readSize=io_->read(lbuf.data(), lbuf.size()))) {
if (outIo.write(lbuf.c_data(), readSize) != readSize) throw Error(kerImageWriteFailed);
if (outIo.write(lbuf.c_data(), readSize) != readSize)
throw Error(kerImageWriteFailed);
}
if (outIo.error()) throw Error(kerImageWriteFailed);
if (outIo.error())
throw Error(kerImageWriteFailed);
// Update length of resources
#ifdef EXIV2_DEBUG_MESSAGES
@ -560,7 +585,8 @@ namespace Exiv2 {
#endif
outIo.seek(resLenOffset, BasicIo::beg);
ul2Data(buf, newResLength, bigEndian);
if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (outIo.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
} // PsdImage::doWriteMetadata
@ -576,20 +602,26 @@ namespace Exiv2 {
std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_IPTC_NAA << "\n";
std::cerr << std::dec << "Writing IPTC_NAA: size: " << rawIptc.size() << "\n";
#endif
if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 4) != 4) throw Error(kerImageWriteFailed);
if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 4) != 4)
throw Error(kerImageWriteFailed);
us2Data(buf, kPhotoshopResourceID_IPTC_NAA, bigEndian);
if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
if (out.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
us2Data(buf, 0, bigEndian); // NULL resource name
if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
ul2Data(buf, rawIptc.size(), bigEndian);
if (out.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (out.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
ul2Data(buf, static_cast<uint32_t>(rawIptc.size()), bigEndian);
if (out.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
// Write encoded Iptc data
if (out.write(rawIptc.c_data(), rawIptc.size()) != rawIptc.size()) throw Error(kerImageWriteFailed);
resLength += rawIptc.size() + 12;
if (out.write(rawIptc.c_data(), rawIptc.size()) != rawIptc.size())
throw Error(kerImageWriteFailed);
resLength += static_cast<uint32_t>(rawIptc.size()) + 12;
if (rawIptc.size() & 1) // even padding
{
buf[0] = 0;
if (out.write(buf, 1) != 1) throw Error(kerImageWriteFailed);
if (out.write(buf, 1) != 1)
throw Error(kerImageWriteFailed);
resLength++;
}
}
@ -616,20 +648,26 @@ namespace Exiv2 {
std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_ExifInfo << "\n";
std::cerr << std::dec << "Writing ExifInfo: size: " << blob.size() << "\n";
#endif
if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 4) != 4) throw Error(kerImageWriteFailed);
if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 4) != 4)
throw Error(kerImageWriteFailed);
us2Data(buf, kPhotoshopResourceID_ExifInfo, bigEndian);
if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
if (out.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
us2Data(buf, 0, bigEndian); // NULL resource name
if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
if (out.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
ul2Data(buf, static_cast<uint32_t>(blob.size()), bigEndian);
if (out.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (out.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
// Write encoded Exif data
if (out.write(&blob[0], static_cast<long>(blob.size())) != static_cast<long>(blob.size())) throw Error(kerImageWriteFailed);
if (out.write(&blob[0], blob.size()) != blob.size())
throw Error(kerImageWriteFailed);
resLength += static_cast<long>(blob.size()) + 12;
if (blob.size() & 1) // even padding
{
buf[0] = 0;
if (out.write(buf, 1) != 1) throw Error(kerImageWriteFailed);
if (out.write(buf, 1) != 1)
throw Error(kerImageWriteFailed);
resLength++;
}
}
@ -660,22 +698,28 @@ namespace Exiv2 {
std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_XMPPacket << "\n";
std::cerr << std::dec << "Writing XMPPacket: size: " << xmpPacket.size() << "\n";
#endif
if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 4) != 4) throw Error(kerImageWriteFailed);
if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 4) != 4)
throw Error(kerImageWriteFailed);
us2Data(buf, kPhotoshopResourceID_XMPPacket, bigEndian);
if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
if (out.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
us2Data(buf, 0, bigEndian); // NULL resource name
if (out.write(buf, 2) != 2) throw Error(kerImageWriteFailed);
if (out.write(buf, 2) != 2)
throw Error(kerImageWriteFailed);
ul2Data(buf, static_cast<uint32_t>(xmpPacket.size()), bigEndian);
if (out.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
if (out.write(buf, 4) != 4)
throw Error(kerImageWriteFailed);
// Write XMPPacket
if (out.write(reinterpret_cast<const byte*>(xmpPacket.data()), static_cast<long>(xmpPacket.size()))
!= static_cast<long>(xmpPacket.size())) throw Error(kerImageWriteFailed);
if (out.error()) throw Error(kerImageWriteFailed);
if (out.write(reinterpret_cast<const byte*>(xmpPacket.data()), xmpPacket.size()) != xmpPacket.size())
throw Error(kerImageWriteFailed);
if (out.error())
throw Error(kerImageWriteFailed);
resLength += static_cast<uint32_t>(xmpPacket.size()) + 12;
if (xmpPacket.size() & 1) // even padding
{
buf[0] = 0;
if (out.write(buf, 1) != 1) throw Error(kerImageWriteFailed);
if (out.write(buf, 1) != 1)
throw Error(kerImageWriteFailed);
resLength++;
}
}

@ -86,14 +86,15 @@ namespace Exiv2 {
// not supported
throw(Error(kerInvalidSettingForImage, "Image comment", "RAF"));
}
void RafImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
if (io_->open() != 0) {
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
}
// Ensure this is the correct image type
if (!isRafType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
throw Error(kerNotAnImage, "RAF");
}
@ -159,7 +160,7 @@ namespace Exiv2 {
address = io_->tell();
DataBuf unknown(20);
io_->read(unknown.data(),unknown.size());
io_->read(unknown.data(), unknown.size());
{
out << Internal::indent(depth)
<< Internal::stringFormat(format,address, 20)
@ -286,21 +287,26 @@ namespace Exiv2 {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Reading RAF file " << io_->path() << "\n";
#endif
if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError());
if (io_->open() != 0)
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
IoCloser closer(*io_);
// Ensure that this is the correct image type
if (!isRafType(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
throw Error(kerNotAnImage, "RAF");
}
clearMetadata();
if (io_->seek(84,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
if (io_->seek(84,BasicIo::beg) != 0)
throw Error(kerFailedToReadImageData);
byte jpg_img_offset [4];
if (io_->read(jpg_img_offset, 4) != 4) throw Error(kerFailedToReadImageData);
if (io_->read(jpg_img_offset, 4) != 4)
throw Error(kerFailedToReadImageData);
byte jpg_img_length [4];
if (io_->read(jpg_img_length, 4) != 4) throw Error(kerFailedToReadImageData);
if (io_->read(jpg_img_length, 4) != 4)
throw Error(kerFailedToReadImageData);
uint32_t jpg_img_off_u32 = Exiv2::getULong(jpg_img_offset, bigEndian);
uint32_t jpg_img_len_u32 = Exiv2::getULong(jpg_img_length, bigEndian);
@ -319,9 +325,12 @@ namespace Exiv2 {
enforce(jpg_img_len >= 12, kerCorruptedMetadata);
DataBuf buf(jpg_img_len - 12);
if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0)
throw Error(kerFailedToReadImageData);
io_->read(buf.data(), buf.size());
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
io_->seek(0,BasicIo::beg); // rewind
@ -329,7 +338,7 @@ namespace Exiv2 {
iptcData_,
xmpData_,
buf.c_data(),
buf.size());
static_cast<uint32_t>(buf.size()));
exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian);
exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian);
@ -338,22 +347,27 @@ namespace Exiv2 {
// parse the tiff
byte readBuff[4];
if (io_->seek(100, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
if (io_->read(readBuff, 4) != 4 ) throw Error(kerFailedToReadImageData);
if (io_->seek(100, BasicIo::beg) != 0)
throw Error(kerFailedToReadImageData);
if (io_->read(readBuff, 4) != 4 )
throw Error(kerFailedToReadImageData);
uint32_t tiffOffset = Exiv2::getULong(readBuff, bigEndian);
if (io_->read(readBuff, 4) != 4) throw Error(kerFailedToReadImageData);
if (io_->read(readBuff, 4) != 4)
throw Error(kerFailedToReadImageData);
uint32_t tiffLength = Exiv2::getULong(readBuff, bigEndian);
// sanity check. Does tiff lie inside the file?
enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), kerCorruptedMetadata);
if (io_->seek(tiffOffset, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
if (io_->seek(tiffOffset, BasicIo::beg) != 0)
throw Error(kerFailedToReadImageData);
// Check if this really is a tiff and then call the tiff parser.
// Check is needed because some older models just embed a raw bitstream.
// For those files we skip the parsing step.
if (io_->read(readBuff, 4) != 4) { throw Error(kerFailedToReadImageData); }
// For those files we skip the parsing step.
if (io_->read(readBuff, 4) != 4) {
throw Error(kerFailedToReadImageData); }
io_->seek(-4, BasicIo::cur);
if (memcmp(readBuff, "\x49\x49\x2A\x00", 4) == 0 ||
memcmp(readBuff, "\x4D\x4D\x00\x2A", 4) == 0)
@ -367,7 +381,7 @@ namespace Exiv2 {
iptcData_,
xmpData_,
tiff.c_data(),
tiff.size());
static_cast<uint32_t>(tiff.size()));
}
}
} // RafImage::readMetadata

@ -295,7 +295,7 @@ namespace Exiv2 {
}
ExifKey::ExifKey(uint16_t tag, const std::string& groupName)
: p_(new Impl)
: p_(std::make_unique<Impl>())
{
IfdId ifdId = groupId(groupName);
// Todo: Test if this condition can be removed
@ -311,7 +311,7 @@ namespace Exiv2 {
}
ExifKey::ExifKey(const TagInfo& ti)
: p_(new Impl)
: p_(std::make_unique<Impl>())
{
auto ifdId = static_cast<IfdId>(ti.ifdId_);
if (!Internal::isExifIfd(ifdId) && !Internal::isMakerIfd(ifdId)) {
@ -322,13 +322,13 @@ namespace Exiv2 {
}
ExifKey::ExifKey(const std::string& key)
: p_(new Impl)
: p_(std::make_unique<Impl>())
{
p_->decomposeKey(key);
}
ExifKey::ExifKey(const ExifKey& rhs)
: p_(new Impl(*rhs.p_))
: p_(std::make_unique<Impl>(*rhs.p_))
{
}

@ -2601,7 +2601,7 @@ namespace Exiv2 {
{
uint16_t bit = 0;
uint16_t comma = 0;
for (long i = 0; i < value.count(); i++ ) { // for each element in value array
for (size_t i = 0; i < value.count(); i++ ) { // for each element in value array
auto bits = static_cast<uint16_t>(value.toInt64(i));
for (uint16_t b = 0; b < 16; ++b) { // for every bit
if (bits & (1 << b)) {
@ -2949,7 +2949,7 @@ namespace Exiv2 {
std::ostream& print0x9101(std::ostream& os, const Value& value, const ExifData*)
{
for (long i = 0; i < value.count(); ++i) {
for (size_t i = 0; i < value.count(); ++i) {
const auto l = value.toInt64(i);
switch (l) {
case 0: break;

@ -344,7 +344,7 @@ namespace Exiv2 {
return os;
}
for (int i=0; i< value.count(); i++) {
for (size_t i=0; i< value.count(); i++) {
if (i != 0)
os << ", ";
const TagVocabulary* td = find(array, value.toString(i));

@ -56,14 +56,14 @@ namespace Exiv2 {
&& key.g_ == group_;
}
IoWrapper::IoWrapper(BasicIo& io, const byte* pHeader, long size, OffsetWriter* pow)
IoWrapper::IoWrapper(BasicIo& io, const byte* pHeader, size_t size, OffsetWriter* pow)
: io_(io), pHeader_(pHeader), size_(size), wroteHeader_(false), pow_(pow)
{
if (pHeader_ == nullptr || size_ == 0)
wroteHeader_ = true;
}
long IoWrapper::write(const byte* pData, long wcount)
size_t IoWrapper::write(const byte* pData, size_t wcount)
{
if (!wroteHeader_ && wcount > 0) {
io_.write(pHeader_, size_);
@ -319,7 +319,7 @@ namespace Exiv2 {
{
storage_ = buf;
pData_ = buf->data();
size_ = buf->size();
size_ = static_cast<uint32_t>(buf->size());
}
void TiffEntryBase::setData(byte* pData, uint32_t size,
@ -336,7 +336,7 @@ namespace Exiv2 {
{
if (value.get() == nullptr)
return;
uint32_t newSize = value->size();
size_t newSize = value->size();
if (newSize > size_) {
setData(std::make_shared<DataBuf>(newSize));
}
@ -392,14 +392,14 @@ namespace Exiv2 {
return;
}
uint32_t size = 0;
for (long i = 0; i < pSize->count(); ++i) {
for (size_t i = 0; i < pSize->count(); ++i) {
size += pSize->toUint32(i);
}
auto offset = pValue()->toUint32(0);
// Todo: Remove limitation of JPEG writer: strips must be contiguous
// Until then we check: last offset + last size - first offset == size?
if ( pValue()->toUint32(pValue()->count()-1)
+ pSize->toUint32(pSize->count()-1)
if ( pValue()->toUint32(static_cast<long>(pValue()->count())-1)
+ pSize->toUint32(static_cast<long>(pSize->count())-1)
- offset != size) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Directory " << groupName(group())
@ -449,7 +449,7 @@ namespace Exiv2 {
#endif
return;
}
for (long i = 0; i < pValue()->count(); ++i) {
for (size_t i = 0; i < pValue()->count(); ++i) {
const auto offset = pValue()->toUint32(i);
const byte* pStrip = pData + baseOffset + offset;
const auto size = pSize->toUint32(i);
@ -525,7 +525,7 @@ namespace Exiv2 {
uint32_t ArrayDef::size(uint16_t tag, IfdId group) const
{
TypeId typeId = toTypeId(tiffType_, tag, group);
return count_ * TypeInfo::typeSize(typeId);
return static_cast<uint32_t>(count_ * TypeInfo::typeSize(typeId));
}
bool TiffBinaryArray::initialize(IfdId group)
@ -985,7 +985,7 @@ namespace Exiv2 {
uint32_t TiffEntryBase::doCount() const
{
return count_;
return static_cast<uint32_t>(count_);
}
uint32_t TiffMnEntry::doCount() const
@ -1019,7 +1019,7 @@ namespace Exiv2 {
if (elements_.empty()) return 0;
TypeId typeId = toTypeId(tiffType(), tag(), group());
long typeSize = TypeInfo::typeSize(typeId);
size_t typeSize = TypeInfo::typeSize(typeId);
if (0 == typeSize) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Directory " << groupName(group())
@ -1097,7 +1097,7 @@ namespace Exiv2 {
}
// Also add the size of data, but only if needed
if (isRootDir) {
uint32_t sd = component->sizeData();
uint32_t sd = static_cast<uint32_t>(component->sizeData());
sd += sd & 1; // Align data to word boundary
sizeData += sd;
}
@ -1124,7 +1124,7 @@ namespace Exiv2 {
sv += sv & 1; // Align value to word boundary
valueIdx += sv;
}
uint32_t sd = component->sizeData();
uint32_t sd = static_cast<uint32_t>(component->sizeData());
sd += sd & 1; // Align data to word boundary
dataIdx += sd;
}
@ -1154,7 +1154,7 @@ namespace Exiv2 {
idx += sv;
valueIdx += sv;
}
uint32_t sd = component->sizeData();
uint32_t sd = static_cast<uint32_t>(component->sizeData());
sd += sd & 1; // Align data to word boundary
dataIdx += sd;
}
@ -1227,7 +1227,7 @@ namespace Exiv2 {
DataBuf buf(pValue_->size());
pValue_->copy(buf.data(), byteOrder);
ioWrapper.write(buf.c_data(), buf.size());
return buf.size();
return static_cast<uint32_t>(buf.size());
} // TiffEntryBase::doWrite
uint32_t TiffEntryBase::writeOffset(byte* buf,
@ -1260,7 +1260,8 @@ namespace Exiv2 {
uint32_t dataIdx,
uint32_t& /*imageIdx*/)
{
if (!pValue() || pValue()->count() == 0) return 0;
if (!pValue() || pValue()->count() == 0)
return 0;
DataBuf buf(pValue()->size());
uint32_t idx = 0;
@ -1274,7 +1275,7 @@ namespace Exiv2 {
byteOrder);
}
ioWrapper.write(buf.c_data(), buf.size());
return buf.size();
return static_cast<uint32_t>(buf.size());
} // TiffDataEntry::doWrite
uint32_t TiffImageEntry::doWrite(IoWrapper& ioWrapper,
@ -1293,8 +1294,7 @@ namespace Exiv2 {
<< std::setfill('0') << std::hex << tag() << std::dec
<< ": Writing offset " << o2 << "\n";
#endif
DataBuf buf(static_cast<long>(strips_.size()) * 4);
buf.clear();
DataBuf buf(strips_.size() * 4);
uint32_t idx = 0;
for (auto&& strip : strips_) {
idx += writeOffset(buf.data(idx), o2, tiffType(), byteOrder);
@ -1306,7 +1306,7 @@ namespace Exiv2 {
}
}
ioWrapper.write(buf.c_data(), buf.size());
return buf.size();
return static_cast<uint32_t>(buf.size());
} // TiffImageEntry::doWrite
uint32_t TiffSubIfd::doWrite(IoWrapper& ioWrapper,
@ -1316,7 +1316,7 @@ namespace Exiv2 {
uint32_t dataIdx,
uint32_t& /*imageIdx*/)
{
DataBuf buf(static_cast<long>(ifds_.size()) * 4);
DataBuf buf(ifds_.size() * 4);
uint32_t idx = 0;
// Sort IFDs by group, needed if image data tags were copied first
std::sort(ifds_.begin(), ifds_.end(), cmpGroupLt);
@ -1325,7 +1325,7 @@ namespace Exiv2 {
dataIdx += ifd->size();
}
ioWrapper.write(buf.c_data(), buf.size());
return buf.size();
return static_cast<uint32_t>(buf.size());
} // TiffSubIfd::doWrite
uint32_t TiffMnEntry::doWrite(IoWrapper& ioWrapper,
@ -1376,7 +1376,7 @@ namespace Exiv2 {
// Some array entries need to have the size in the first element
if (cfg()->hasSize_) {
byte buf[4];
long elSize = TypeInfo::typeSize(toTypeId(cfg()->elTiffType_, 0, cfg()->group_));
size_t elSize = TypeInfo::typeSize(toTypeId(cfg()->elTiffType_, 0, cfg()->group_));
switch (elSize) {
case 2:
idx += us2Data(buf, size(), byteOrder);
@ -1416,7 +1416,7 @@ namespace Exiv2 {
mio.write(buf.c_data(), buf.size());
}
}
ioWrapper.write(mio.mmap(), static_cast<uint32_t>(mio.size()));
ioWrapper.write(mio.mmap(), mio.size());
return idx;
} // TiffBinaryArray::doWrite
@ -1429,11 +1429,12 @@ namespace Exiv2 {
uint32_t& /*imageIdx*/)
{
Value const* pv = pValue();
if (!pv || pv->count() == 0) return 0;
if (!pv || pv->count() == 0)
return 0;
DataBuf buf(pv->size());
pv->copy(buf.data(), byteOrder);
ioWrapper.write(buf.c_data(), buf.size());
return buf.size();
return static_cast<uint32_t>(buf.size());
} // TiffBinaryElement::doWrite
uint32_t TiffComponent::writeData(IoWrapper& ioWrapper,
@ -1493,9 +1494,10 @@ namespace Exiv2 {
ioWrapper.write(buf.c_data(), buf.size());
// Align data to word boundary
uint32_t align = (buf.size() & 1);
if (align) ioWrapper.putb(0x0);
if (align)
ioWrapper.putb(0x0);
return buf.size() + align;
return static_cast<uint32_t>(buf.size() + align);
} // TiffDataEntry::doWriteData
uint32_t TiffSubIfd::doWriteData(IoWrapper& ioWrapper,
@ -1587,9 +1589,10 @@ namespace Exiv2 {
uint32_t TiffImageEntry::doWriteImage(IoWrapper& ioWrapper,
ByteOrder /*byteOrder*/) const
{
if ( !pValue() ) throw Error(kerImageWriteFailed); // #1296
if ( !pValue() )
throw Error(kerImageWriteFailed); // #1296
uint32_t len = pValue()->sizeDataArea();
size_t len = pValue()->sizeDataArea();
if (len > 0) {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "TiffImageEntry, Directory " << groupName(group())
@ -1599,8 +1602,9 @@ namespace Exiv2 {
#endif
DataBuf buf = pValue()->dataArea();
ioWrapper.write(buf.c_data(), buf.size());
uint32_t align = len & 1; // Align image data to word boundary
if (align) ioWrapper.putb(0x0);
size_t align = len & 1; // Align image data to word boundary
if (align)
ioWrapper.putb(0x0);
len += align;
}
else {
@ -1622,7 +1626,7 @@ namespace Exiv2 {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << ", len = " << len << " bytes\n";
#endif
return len;
return static_cast<uint32_t>(len);
} // TiffImageEntry::doWriteImage
uint32_t TiffComponent::size() const
@ -1642,7 +1646,7 @@ namespace Exiv2 {
sv += sv & 1; // Align value to word boundary
len += sv;
}
uint32_t sd = component->sizeData();
uint32_t sd = static_cast<uint32_t>(component->sizeData());
sd += sd & 1; // Align data to word boundary
len += sd;
}
@ -1716,65 +1720,67 @@ namespace Exiv2 {
uint32_t TiffBinaryElement::doSize() const
{
if (!pValue()) return 0;
return pValue()->size();
} // TiffBinaryElement::doSize
if (!pValue())
return 0;
return static_cast<uint32_t>(pValue()->size());
}
uint32_t TiffComponent::sizeData() const
size_t TiffComponent::sizeData() const
{
return doSizeData();
} // TiffComponent::sizeData
}
uint32_t TiffDirectory::doSizeData() const
size_t TiffDirectory::doSizeData() const
{
assert(false);
return 0;
} // TiffDirectory::doSizeData
}
uint32_t TiffEntryBase::doSizeData() const
size_t TiffEntryBase::doSizeData() const
{
return 0;
} // TiffEntryBase::doSizeData
}
uint32_t TiffImageEntry::doSizeData() const
size_t TiffImageEntry::doSizeData() const
{
uint32_t len = 0;
size_t len = 0;
// For makernotes, TIFF image data is written to the data area
if (group() > mnId) { // Todo: Fix this hack!!
len = sizeImage();
}
return len;
} // TiffImageEntry::doSizeData
}
uint32_t TiffDataEntry::doSizeData() const
size_t TiffDataEntry::doSizeData() const
{
if (!pValue()) return 0;
return pValue()->sizeDataArea();
} // TiffDataEntry::doSizeData
if (!pValue())
return 0;
return static_cast<uint32_t>(pValue()->sizeDataArea());
}
uint32_t TiffSubIfd::doSizeData() const
size_t TiffSubIfd::doSizeData() const
{
uint32_t len = 0;
for (auto&& ifd : ifds_) {
len += ifd->size();
}
return len;
} // TiffSubIfd::doSizeData
}
uint32_t TiffIfdMakernote::doSizeData() const
size_t TiffIfdMakernote::doSizeData() const
{
assert(false);
return 0;
} // TiffIfdMakernote::doSizeData
}
uint32_t TiffComponent::sizeImage() const
size_t TiffComponent::sizeImage() const
{
return doSizeImage();
} // TiffComponent::sizeImage
}
uint32_t TiffDirectory::doSizeImage() const
size_t TiffDirectory::doSizeImage() const
{
uint32_t len = 0;
size_t len = 0;
for (auto&& component : components_) {
len += component->sizeImage();
}
@ -1782,31 +1788,32 @@ namespace Exiv2 {
len += pNext_->sizeImage();
}
return len;
} // TiffDirectory::doSizeImage
}
uint32_t TiffSubIfd::doSizeImage() const
size_t TiffSubIfd::doSizeImage() const
{
uint32_t len = 0;
size_t len = 0;
for (auto&& ifd : ifds_) {
len += ifd->sizeImage();
}
return len;
} // TiffSubIfd::doSizeImage
uint32_t TiffIfdMakernote::doSizeImage() const
size_t TiffIfdMakernote::doSizeImage() const
{
return ifd_.sizeImage();
} // TiffIfdMakernote::doSizeImage
uint32_t TiffEntryBase::doSizeImage() const
size_t TiffEntryBase::doSizeImage() const
{
return 0;
} // TiffEntryBase::doSizeImage
uint32_t TiffImageEntry::doSizeImage() const
size_t TiffImageEntry::doSizeImage() const
{
if (!pValue()) return 0;
uint32_t len = pValue()->sizeDataArea();
if (!pValue())
return 0;
auto len = pValue()->sizeDataArea();
if (len == 0) {
for (auto&& strip : strips_) {
len += strip.second;
@ -1905,11 +1912,10 @@ namespace {
{
if (curr < tobe) {
Exiv2::DataBuf buf(tobe - curr);
buf.clear();
ioWrapper.write(buf.c_data(), buf.size());
return tobe - curr;
}
return 0;
} // fillGap
}
} // namespace

@ -122,7 +122,7 @@ namespace Exiv2 {
The IO wrapper owns none of the objects passed in so the caller is
responsible to keep them alive.
*/
IoWrapper(BasicIo& io, const byte* pHeader, long size, OffsetWriter* pow);
IoWrapper(BasicIo& io, const byte* pHeader, size_t size, OffsetWriter* pow);
//@}
//! @name Manipulators
@ -133,7 +133,7 @@ namespace Exiv2 {
Writes the TIFF header to the IO, if it hasn't been written yet, followed
by the data passed in the arguments.
*/
long write(const byte* pData, long wcount);
size_t write(const byte* pData, size_t wcount);
/*!
@brief Wraps the corresponding BasicIo::putb() method.
@ -149,7 +149,7 @@ namespace Exiv2 {
// DATA
BasicIo& io_; //! Reference for the IO instance.
const byte* pHeader_; //! Pointer to the header data.
long size_; //! Size of the header data.
size_t size_; //! Size of the header data.
bool wroteHeader_; //! Indicates if the header has been written.
OffsetWriter* pow_; //! Pointer to an offset-writer, if any, or 0
}; // class IoWrapper
@ -289,14 +289,14 @@ namespace Exiv2 {
write(). Components derived from TiffEntryBase implement this
method corresponding to their implementation of writeData().
*/
uint32_t sizeData() const;
size_t sizeData() const;
/*!
@brief Return the size in bytes of the image data of this component
when written to a binary image. This is a support function for
write(). TIFF components implement this method corresponding to
their implementation of writeImage().
*/
uint32_t sizeImage() const;
size_t sizeImage() const;
/*!
@brief Return the unique id of the entry in the image.
*/
@ -346,9 +346,9 @@ namespace Exiv2 {
//! Implements count().
virtual uint32_t doCount() const =0;
//! Implements sizeData().
virtual uint32_t doSizeData() const =0;
virtual size_t doSizeData() const =0;
//! Implements sizeImage().
virtual uint32_t doSizeImage() const =0;
virtual size_t doSizeImage() const =0;
//@}
private:
@ -529,9 +529,9 @@ namespace Exiv2 {
//! Implements size(). Return the size of a standard TIFF entry
uint32_t doSize() const override;
//! Implements sizeData(). Return 0.
uint32_t doSizeData() const override;
size_t doSizeData() const override;
//! Implements sizeImage(). Return 0.
uint32_t doSizeImage() const override;
size_t doSizeImage() const override;
//@}
//! Helper function to write an \em offset to a preallocated binary buffer
@ -552,7 +552,7 @@ namespace Exiv2 {
// DATA
TiffType tiffType_; //!< Field TIFF type
uint32_t count_; //!< The number of values of the indicated type
size_t count_; //!< The number of values of the indicated type
int64_t offset_; //!< Offset to the data area
/*!
Size of the data buffer holding the value in bytes, there is no
@ -717,7 +717,7 @@ namespace Exiv2 {
// Using doWriteImage from base class
// Using doSize() from base class
//! Implements sizeData(). Return the size of the data area.
uint32_t doSizeData() const override;
size_t doSizeData() const override;
// Using doSizeImage from base class
//@}
@ -792,9 +792,9 @@ namespace Exiv2 {
//! Implements size(). Return the size of the strip pointers.
uint32_t doSize() const override;
//! Implements sizeData(). Return the size of the image data area.
uint32_t doSizeData() const override;
size_t doSizeData() const override;
//! Implements sizeImage(). Return the size of the image data area.
uint32_t doSizeImage() const override;
size_t doSizeImage() const override;
//@}
private:
@ -926,12 +926,12 @@ namespace Exiv2 {
@brief This class does not really implement sizeData(), it only has
size(). This method must not be called; it commits suicide.
*/
uint32_t doSizeData() const override;
size_t doSizeData() const override;
/*!
@brief Implements sizeImage(). Return the sum of the image sizes of
all components plus that of the next-IFD, if there is any.
*/
uint32_t doSizeImage() const override;
size_t doSizeImage() const override;
//@}
private:
@ -1015,9 +1015,9 @@ namespace Exiv2 {
//! Implements size(). Return the size of the sub-Ifd pointers.
uint32_t doSize() const override;
//! Implements sizeData(). Return the sum of the sizes of all sub-IFDs.
uint32_t doSizeData() const override;
size_t doSizeData() const override;
//! Implements sizeImage(). Return the sum of the image sizes of all sub-IFDs.
uint32_t doSizeImage() const override;
size_t doSizeImage() const override;
//@}
private:
@ -1228,12 +1228,12 @@ namespace Exiv2 {
@brief This class does not really implement sizeData(), it only has
size(). This method must not be called; it commits suicide.
*/
uint32_t doSizeData() const override;
size_t doSizeData() const override;
/*!
@brief Implements sizeImage(). Return the total image data size of the
makernote IFD.
*/
uint32_t doSizeImage() const override;
size_t doSizeImage() const override;
//@}
private:

@ -194,7 +194,7 @@ namespace Exiv2 {
Exiv2::ExifKey key("Exif.Image.InterColorProfile");
auto pos = exifData_.findKey(key);
if ( pos != exifData_.end() ) {
long size = pos->count() * pos->typeSize();
size_t size = pos->count() * pos->typeSize();
if (size == 0) {
throw Error(kerFailedToReadImageData);
}
@ -234,7 +234,7 @@ namespace Exiv2 {
auto pos = exifData_.findKey(key);
bool found = pos != exifData_.end();
if ( iccProfileDefined() ) {
Exiv2::DataValue value(iccProfile_.c_data(), iccProfile_.size());
Exiv2::DataValue value(iccProfile_.c_data(), static_cast<long>(iccProfile_.size()));
if ( found ) pos->setValue(&value);
else exifData_.add(key,&value);
} else {
@ -247,12 +247,11 @@ namespace Exiv2 {
TiffParser::encode(*io_, pData, size, bo, exifData_, iptcData_, xmpData_); // may throw
} // TiffImage::writeMetadata
ByteOrder TiffParser::decode(
ExifData& exifData,
ByteOrder TiffParser::decode(ExifData& exifData,
IptcData& iptcData,
XmpData& xmpData,
const byte* pData,
uint32_t size
size_t size
)
{
uint32_t root = Tag::root;
@ -269,7 +268,7 @@ namespace Exiv2 {
iptcData,
xmpData,
pData,
size,
static_cast<uint32_t>(size),
root,
TiffMapping::findDecoder);
} // TiffParser::decode
@ -298,9 +297,9 @@ namespace Exiv2 {
ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(filteredIfd)), ed.end());
}
std::unique_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder));
TiffHeader header(byteOrder);
return TiffParserWorker::encode(io, pData, size, ed, iptcData, xmpData, Tag::root, TiffMapping::findEncoder,
header.get(), nullptr);
&header, nullptr);
} // TiffParser::encode
// *************************************************************************

@ -50,7 +50,7 @@ namespace Exiv2 {
false, // Don't concatenate gaps
{ 0, ttUnsignedShort, 1 }
};
//! Canon Camera Settings binary array - definition
constexpr ArrayDef canonCsDef[] = {
{ 46, ttUnsignedShort, 3 } // Exif.CanonCs.Lens
@ -259,7 +259,7 @@ namespace Exiv2 {
{ 0, ttSignedLong, 1 }
};
//! Canon RawBurst Info binary array - configuration
@ -1303,13 +1303,13 @@ namespace Exiv2 {
{ Tag::root, fujiId, exifId, 0x927c },
{ Tag::root, canonId, exifId, 0x927c },
{ Tag::root, canonCsId, canonId, 0x0001 },
{ Tag::root, canonSiId, canonId, 0x0004 },
{ Tag::root, canonSiId, canonId, 0x0004 },
{ Tag::root, canonPaId, canonId, 0x0005 },
{ Tag::root, canonCfId, canonId, 0x000f },
{ Tag::root, canonPiId, canonId, 0x0012 },
{ Tag::root, canonTiId, canonId, 0x0035 },
{ Tag::root, canonFiId, canonId, 0x0093 },
{ Tag::root, canonPrId, canonId, 0x00a0 },
{ Tag::root, canonPrId, canonId, 0x00a0 },
{ Tag::root, canonAfMiAdjId, canonId, 0x4013 },
{ Tag::root, canonVigCor2Id, canonId, 0x4016 },
{ Tag::root, canonLiOpId, canonId, 0x4018 },
@ -1676,7 +1676,7 @@ namespace Exiv2 {
{ 0x0012, canonId, EXV_SIMPLE_BINARY_ARRAY(canonPiCfg) },
{ 0x0035, canonId, EXV_SIMPLE_BINARY_ARRAY(canonTiCfg) },
{ 0x0093, canonId, EXV_BINARY_ARRAY(canonFiCfg, canonFiDef) },
{ 0x00a0, canonId, EXV_SIMPLE_BINARY_ARRAY(canonPrCfg) },
{ 0x00a0, canonId, EXV_SIMPLE_BINARY_ARRAY(canonPrCfg) },
{ 0x4013, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAfMiAdjCfg) },
// { 0x4015, canonId, EXV_SIMPLE_BINARY_ARRAY(canonVigCorCfg) },
{ 0x4016, canonId, EXV_SIMPLE_BINARY_ARRAY(canonVigCor2Cfg) },
@ -1684,9 +1684,9 @@ namespace Exiv2 {
{ 0x4019, canonId, EXV_SIMPLE_BINARY_ARRAY(canonLeCfg) },
{ 0x4020, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAmCfg) },
{ 0x4021, canonId, EXV_SIMPLE_BINARY_ARRAY(canonMeCfg) },
{ 0x4024, canonId, EXV_SIMPLE_BINARY_ARRAY(canonFilCfg) },
{ 0x4024, canonId, EXV_SIMPLE_BINARY_ARRAY(canonFilCfg) },
{ 0x4025, canonId, EXV_SIMPLE_BINARY_ARRAY(canonHdrCfg) },
{ 0x4028, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAfCCfg) },
{ 0x4028, canonId, EXV_SIMPLE_BINARY_ARRAY(canonAfCCfg) },
{ 0x403f, canonId, EXV_SIMPLE_BINARY_ARRAY(canonRawBCfg) },
{ Tag::next, canonId, ignoreTiffComponent },
{ Tag::all, canonId, newTiffEntry },
@ -2041,7 +2041,7 @@ namespace Exiv2 {
group = ts->parentGroup_;
} while (!(ts->root_ == root && ts->group_ == ifdIdNotSet));
} // TiffCreator::getPath
}
ByteOrder TiffParserWorker::decode(
ExifData& exifData,
@ -2057,7 +2057,7 @@ namespace Exiv2 {
// Create standard TIFF header if necessary
std::unique_ptr<TiffHeaderBase> ph;
if (!pHeader) {
ph = std::unique_ptr<TiffHeaderBase>(new TiffHeader);
ph = std::make_unique<TiffHeader>();
pHeader = ph.get();
}

@ -427,8 +427,7 @@ namespace Exiv2 {
byte const* record = nullptr;
uint32_t sizeHdr = 0;
uint32_t sizeData = 0;
if (0 != Photoshop::locateIptcIrb(pData, size,
&record, &sizeHdr, &sizeData)) {
if (0 != Photoshop::locateIptcIrb(pData, size, &record, &sizeHdr, &sizeData)) {
return;
}
if (0 == IptcParser::decode(iptcData_, record + sizeHdr, sizeData)) {
@ -456,12 +455,13 @@ namespace Exiv2 {
// create vector of signedShorts from unsignedShorts in Exif.Canon.AFInfo
std::vector<int16_t> ints;
std::vector<uint16_t> uint;
for (long i = 0; i < object->pValue()->count(); i++) {
for (size_t i = 0; i < object->pValue()->count(); i++) {
ints.push_back(static_cast<int16_t>(object->pValue()->toInt64(i)));
uint.push_back(static_cast<uint16_t>(object->pValue()->toInt64(i)));
}
// Check this is AFInfo2 (ints[0] = bytes in object)
if ( ints.at(0) != object->pValue()->count()*2 ) return ;
if ( ints.at(0) != static_cast<int16_t>(object->pValue()->count())*2 )
return ;
std::string familyGroup(std::string("Exif.") + groupName(object->group()) + ".");
@ -624,13 +624,12 @@ namespace Exiv2 {
if (rawIptc.size() % 4 != 0) {
// Pad the last unsignedLong value with 0s
buf.alloc((rawIptc.size() / 4) * 4 + 4);
buf.clear();
buf.copyBytes(0, rawIptc.c_data(), rawIptc.size());
}
else {
buf = std::move(rawIptc); // Note: This resets rawIptc
}
value->read(buf.data(), buf.size(), byteOrder_);
value->read(buf.data(), static_cast<long>(buf.size()), byteOrder_);
Exifdatum iptcDatum(iptcNaaKey, value.get());
exifData_.add(iptcDatum);
pos = exifData_.findKey(irbKey); // needed after add()
@ -644,7 +643,7 @@ namespace Exiv2 {
exifData_.erase(pos);
if (irbBuf.size() != 0) {
auto value = Value::create(unsignedByte);
value->read(irbBuf.data(), irbBuf.size(), invalidByteOrder);
value->read(irbBuf.data(), static_cast<long>(irbBuf.size()), invalidByteOrder);
Exifdatum iptcDatum(irbKey, value.get());
exifData_.add(iptcDatum);
}
@ -822,8 +821,10 @@ namespace Exiv2 {
if (object->cfg() == nullptr || !object->decoded())
return;
int32_t size = object->TiffEntryBase::doSize();
if (size == 0) return;
if (!object->initialize(pRoot_)) return;
if (size == 0)
return;
if (!object->initialize(pRoot_))
return;
// Re-encrypt buffer if necessary
CryptFct cryptFct = object->cfg()->cryptFct_;
@ -835,7 +836,7 @@ namespace Exiv2 {
DataBuf buf = cryptFct(object->tag(), pData, size, pRoot_);
if (buf.size() > 0) {
pData = buf.c_data();
size = buf.size();
size = static_cast<int32_t>(buf.size());
}
if (!object->updOrigDataBuf(pData, size)) {
setDirty();
@ -969,7 +970,7 @@ namespace Exiv2 {
{
encodeOffsetEntry(object, datum);
uint32_t sizeDataArea = object->pValue()->sizeDataArea();
size_t sizeDataArea = object->pValue()->sizeDataArea();
if (sizeDataArea > 0 && writeMethod() == wmNonIntrusive) {
#ifdef EXIV2_DEBUG_MESSAGES
@ -992,13 +993,13 @@ namespace Exiv2 {
<< " not found. Writing only one strip.\n";
#endif
object->strips_.clear();
object->strips_.emplace_back(zero, sizeDataArea);
object->strips_.emplace_back(zero, static_cast<uint32_t>(sizeDataArea));
}
else {
uint32_t sizeTotal = 0;
object->strips_.clear();
for (long i = 0; i < pos->count(); ++i) {
uint32_t len = pos->toUint32(i);
for (size_t i = 0; i < pos->count(); ++i) {
uint32_t len = pos->toUint32(static_cast<long>(i));
object->strips_.emplace_back(zero, len);
sizeTotal += len;
}
@ -1510,7 +1511,7 @@ namespace Exiv2 {
p += 2;
TiffType tiffType = getUShort(p, byteOrder());
TypeId typeId = toTypeId(tiffType, object->tag(), object->group());
long typeSize = TypeInfo::typeSize(typeId);
size_t typeSize = TypeInfo::typeSize(typeId);
if (0 == typeSize) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Directory " << groupName(object->group())
@ -1539,7 +1540,7 @@ namespace Exiv2 {
if (count > std::numeric_limits<uint32_t>::max() / typeSize) {
throw Error(kerArithmeticOverflow);
}
uint32_t size = typeSize * count;
uint32_t size = static_cast<uint32_t>(typeSize * count);
uint32_t offset = getLong(p, byteOrder());
byte* pData = p;
if ( size > 4

@ -49,7 +49,7 @@ namespace {
struct TypeInfoTable {
Exiv2::TypeId typeId_; //!< Type id
const char* name_; //!< Name of the type
long size_; //!< Bytes per data entry
size_t size_; //!< Bytes per data entry
//! Comparison operator for \em typeId
bool operator==(Exiv2::TypeId typeId) const
{
@ -111,164 +111,124 @@ namespace Exiv2 {
return tit->typeId_;
}
long TypeInfo::typeSize(TypeId typeId)
size_t TypeInfo::typeSize(TypeId typeId)
{
const TypeInfoTable* tit = find(typeInfoTable, typeId);
if (!tit) return 0;
if (!tit)
return 0;
return tit->size_;
}
DataBuf::DataBuf(DataBuf&& rhs)
: pData_(rhs.pData_), size_(rhs.size_)
{
rhs.pData_ = nullptr;
rhs.size_ = 0;
}
DataBuf::~DataBuf()
{ delete[] pData_; }
DataBuf::DataBuf() : pData_(nullptr), size_(0)
{}
DataBuf::DataBuf(long size) : pData_(new byte[size]()), size_(size)
{}
DataBuf::DataBuf(const byte* pData, long size) : pData_(nullptr), size_(0)
{
if (size > 0) {
pData_ = new byte[size];
std::memcpy(pData_, pData, size);
size_ = size;
}
}
DataBuf::DataBuf(const DataBuf& rhs)
: DataBuf(rhs.pData_, rhs.size_)
DataBuf::DataBuf(size_t size) : pData_(size)
{}
DataBuf& DataBuf::operator=(DataBuf&& rhs)
DataBuf::DataBuf(const byte* pData, size_t size) : pData_(size)
{
if (this == &rhs) return *this;
reset();
std::swap(pData_, rhs.pData_);
std::swap(size_, rhs.size_);
return *this;
std::copy_n(pData, size, pData_.begin());
}
void DataBuf::alloc(long size)
void DataBuf::alloc(size_t size)
{
if (size > size_) {
delete[] pData_;
pData_ = new byte[size];
size_ = size;
}
pData_.resize(size);
}
void DataBuf::resize(long size)
void DataBuf::resize(size_t size)
{
if (size > size_) {
byte* newbuf = new byte[size];
if (size_ > 0) {
memcpy(newbuf, pData_, size_);
}
delete[] pData_;
pData_ = newbuf;
}
size_ = size;
pData_.resize(size);
}
void DataBuf::reset()
{
delete[] pData_;
pData_ = nullptr;
size_ = 0;
}
void DataBuf::clear() {
memset(pData_, 0, size_);
pData_.clear();
}
uint8_t Exiv2::DataBuf::read_uint8(size_t offset) const {
if (offset >= static_cast<size_t>(size_)) {
if (offset >= pData_.size()) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint8");
}
return pData_[offset];
}
void Exiv2::DataBuf::write_uint8(size_t offset, uint8_t x) {
if (offset >= static_cast<size_t>(size_)) {
if (offset >= pData_.size()) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint8");
}
pData_[offset] = x;
}
uint16_t Exiv2::DataBuf::read_uint16(size_t offset, ByteOrder byteOrder) const {
if (size_ < 2 || offset > static_cast<size_t>(size_ - 2)) {
if (pData_.size() < 2 || offset > (pData_.size() - 2)) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint16");
}
return getUShort(&pData_[offset], byteOrder);
}
void Exiv2::DataBuf::write_uint16(size_t offset, uint16_t x, ByteOrder byteOrder) {
if (size_ < 2 || offset > static_cast<size_t>(size_ - 2)) {
if (pData_.size() < 2 || offset > (pData_.size() - 2)) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint16");
}
us2Data(&pData_[offset], x, byteOrder);
}
uint32_t Exiv2::DataBuf::read_uint32(size_t offset, ByteOrder byteOrder) const {
if (size_ < 4 || offset > static_cast<size_t>(size_ - 4)) {
if (pData_.size() < 4 || offset > (pData_.size() - 4)) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint32");
}
return getULong(&pData_[offset], byteOrder);
}
void Exiv2::DataBuf::write_uint32(size_t offset, uint32_t x, ByteOrder byteOrder) {
if (size_ < 4 || offset > static_cast<size_t>(size_ - 4)) {
if (pData_.size() < 4 || offset > (pData_.size() - 4)) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint32");
}
ul2Data(&pData_[offset], x, byteOrder);
}
uint64_t Exiv2::DataBuf::read_uint64(size_t offset, ByteOrder byteOrder) const {
if (size_ < 8 || offset > static_cast<size_t>(size_ - 8)) {
if (pData_.size() < 8 || offset > (pData_.size() - 8)) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::read_uint64");
}
return getULongLong(&pData_[offset], byteOrder);
}
void Exiv2::DataBuf::write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder) {
if (size_ < 8 || offset > static_cast<size_t>(size_ - 8)) {
if (pData_.size() < 8 || offset > (pData_.size() - 8)) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::write_uint64");
}
ull2Data(&pData_[offset], x, byteOrder);
}
void Exiv2::DataBuf::copyBytes(size_t offset, const void* buf, size_t bufsize) {
if (static_cast<size_t>(size_) < bufsize || offset > size_ - bufsize) {
if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::copyBytes");
} if (bufsize > 0) {
memcpy(&pData_[offset], buf, bufsize);
}
memcpy(&pData_[offset], buf, bufsize);
}
int Exiv2::DataBuf::cmpBytes(size_t offset, const void* buf, size_t bufsize) const {
if (static_cast<size_t>(size_) < bufsize || offset > size_ - bufsize) {
if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::cmpBytes");
}
return memcmp(&pData_[offset], buf, bufsize);
}
byte* Exiv2::DataBuf::data(size_t offset) {
if (static_cast<size_t>(size_) < offset) {
/// \todo this first check should be for <= offset
if (pData_.size() < offset) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data");
} else if (pData_.empty() || pData_.size() == offset) {
return nullptr;
}
return &pData_[offset];
}
const byte* Exiv2::DataBuf::c_data(size_t offset) const {
if (static_cast<size_t>(size_) < offset) {
/// \todo this first check should be for <= offset
if (pData_.size() < offset) {
throw std::overflow_error("Overflow in Exiv2::DataBuf::c_data");
} else if (pData_.empty() || pData_.size() == offset) {
return nullptr;
}
return &pData_[offset];
}
@ -283,7 +243,7 @@ namespace Exiv2 {
static void checkDataBufBounds(const DataBuf& buf, size_t end) {
enforce<std::invalid_argument>(end <= static_cast<size_t>(std::numeric_limits<long>::max()),
"end of slice too large to be compared with DataBuf bounds.");
enforce<std::out_of_range>(static_cast<long>(end) <= buf.size(), "Invalid slice bounds specified");
enforce<std::out_of_range>(end <= buf.size(), "Invalid slice bounds specified");
}
Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end)

@ -118,7 +118,7 @@ namespace Exiv2 {
return value;
} // Value::create
int Value::setDataArea(const byte* /*buf*/, long /*len*/)
int Value::setDataArea(const byte* /*buf*/, size_t /*len*/)
{
return -1;
}
@ -131,12 +131,12 @@ namespace Exiv2 {
return os.str();
}
std::string Value::toString(long /*n*/) const
std::string Value::toString(size_t /*n*/) const
{
return toString();
}
long Value::sizeDataArea() const
size_t Value::sizeDataArea() const
{
return 0;
}
@ -158,12 +158,12 @@ namespace Exiv2 {
read(buf, len, byteOrder);
}
long DataValue::count() const
size_t DataValue::count() const
{
return size();
}
int DataValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
int DataValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/)
{
// byteOrder not needed
value_.assign(buf, buf + len);
@ -190,9 +190,9 @@ namespace Exiv2 {
return static_cast<long>(std::copy(value_.begin(), value_.end(), buf) - buf);
}
long DataValue::size() const
size_t DataValue::size() const
{
return static_cast<long>(value_.size());
return value_.size();
}
DataValue* DataValue::clone_() const
@ -210,7 +210,7 @@ namespace Exiv2 {
return os;
}
std::string DataValue::toString(long n) const
std::string DataValue::toString(size_t n) const
{
std::ostringstream os;
os << static_cast<int>(value_.at(n));
@ -218,25 +218,25 @@ namespace Exiv2 {
return os.str();
}
int64_t DataValue::toInt64(long n) const
int64_t DataValue::toInt64(size_t n) const
{
ok_ = true;
return value_.at(n);
}
uint32_t DataValue::toUint32(long n) const
uint32_t DataValue::toUint32(size_t n) const
{
ok_ = true;
return value_.at(n);
}
float DataValue::toFloat(long n) const
float DataValue::toFloat(size_t n) const
{
ok_ = true;
return value_.at(n);
}
Rational DataValue::toRational(long n) const
Rational DataValue::toRational(size_t n) const
{
ok_ = true;
return {value_.at(n), 1};
@ -267,7 +267,7 @@ namespace Exiv2 {
return 0;
}
int StringValueBase::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
int StringValueBase::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/)
{
// byteOrder not needed
if (buf) value_ = std::string(reinterpret_cast<const char*>(buf), len);
@ -285,14 +285,14 @@ namespace Exiv2 {
);
}
long StringValueBase::count() const
size_t StringValueBase::count() const
{
return size();
}
long StringValueBase::size() const
size_t StringValueBase::size() const
{
return static_cast<long>(value_.size());
return value_.size();
}
std::ostream& StringValueBase::write(std::ostream& os) const
@ -300,25 +300,25 @@ namespace Exiv2 {
return os << value_;
}
int64_t StringValueBase::toInt64(long n) const
int64_t StringValueBase::toInt64(size_t n) const
{
ok_ = true;
return value_.at(n);
}
uint32_t StringValueBase::toUint32(long n) const
uint32_t StringValueBase::toUint32(size_t n) const
{
ok_ = true;
return value_.at(n);
}
float StringValueBase::toFloat(long n) const
float StringValueBase::toFloat(size_t n) const
{
ok_ = true;
return value_.at(n);
}
Rational StringValueBase::toRational(long n) const
Rational StringValueBase::toRational(size_t n) const
{
ok_ = true;
return {value_.at(n), 1};
@ -458,7 +458,7 @@ namespace Exiv2 {
return StringValueBase::read(code + c);
}
int CommentValue::read(const byte* buf, long len, ByteOrder byteOrder)
int CommentValue::read(const byte* buf, size_t len, ByteOrder byteOrder)
{
byteOrder_ = byteOrder;
return StringValueBase::read(buf, len, byteOrder);
@ -601,19 +601,17 @@ namespace Exiv2 {
return static_cast<long>(s.size());
}
int XmpValue::read(const byte* buf,
long len,
ByteOrder /*byteOrder*/)
int XmpValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/)
{
std::string s(reinterpret_cast<const char*>(buf), len);
return read(s);
}
long XmpValue::size() const
size_t XmpValue::size() const
{
std::ostringstream os;
write(os);
return static_cast<long>(os.str().size());
return os.str().size();
}
XmpTextValue::XmpTextValue()
@ -667,12 +665,12 @@ namespace Exiv2 {
return UniquePtr(clone_());
}
long XmpTextValue::size() const
size_t XmpTextValue::size() const
{
return static_cast<long>(value_.size());
return value_.size();
}
long XmpTextValue::count() const
size_t XmpTextValue::count() const
{
return size();
}
@ -700,22 +698,22 @@ namespace Exiv2 {
return os << value_;
}
int64_t XmpTextValue::toInt64(long /*n*/) const
int64_t XmpTextValue::toInt64(size_t /*n*/) const
{
return parseInt64(value_, ok_);
}
uint32_t XmpTextValue::toUint32(long /*n*/) const
uint32_t XmpTextValue::toUint32(size_t /*n*/) const
{
return parseUint32(value_, ok_);
}
float XmpTextValue::toFloat(long /*n*/) const
float XmpTextValue::toFloat(size_t /*n*/) const
{
return parseFloat(value_, ok_);
}
Rational XmpTextValue::toRational(long /*n*/) const
Rational XmpTextValue::toRational(size_t /*n*/) const
{
return parseRational(value_, ok_);
}
@ -742,9 +740,9 @@ namespace Exiv2 {
return UniquePtr(clone_());
}
long XmpArrayValue::count() const
size_t XmpArrayValue::count() const
{
return static_cast<long>(value_.size());
return value_.size();
}
std::ostream& XmpArrayValue::write(std::ostream& os) const
@ -756,28 +754,28 @@ namespace Exiv2 {
return os;
}
std::string XmpArrayValue::toString(long n) const
std::string XmpArrayValue::toString(size_t n) const
{
ok_ = true;
return value_.at(n);
}
int64_t XmpArrayValue::toInt64(long n) const
int64_t XmpArrayValue::toInt64(size_t n) const
{
return parseInt64(value_.at(n), ok_);
}
uint32_t XmpArrayValue::toUint32(long n) const
uint32_t XmpArrayValue::toUint32(size_t n) const
{
return parseUint32(value_.at(n), ok_);
}
float XmpArrayValue::toFloat(long n) const
float XmpArrayValue::toFloat(size_t n) const
{
return parseFloat(value_.at(n), ok_);
}
Rational XmpArrayValue::toRational(long n) const
Rational XmpArrayValue::toRational(size_t n) const
{
return parseRational(value_.at(n), ok_);
}
@ -846,9 +844,9 @@ namespace Exiv2 {
return UniquePtr(clone_());
}
long LangAltValue::count() const
size_t LangAltValue::count() const
{
return static_cast<long>(value_.size());
return value_.size();
}
static const std::string x_default = "x-default";
@ -875,7 +873,7 @@ namespace Exiv2 {
return os;
}
std::string LangAltValue::toString(long /*n*/) const
std::string LangAltValue::toString(size_t /*n*/) const
{
return toString(x_default);
}
@ -891,25 +889,25 @@ namespace Exiv2 {
return "";
}
int64_t LangAltValue::toInt64(long /*n*/) const
int64_t LangAltValue::toInt64(size_t /*n*/) const
{
ok_ = false;
return 0;
}
uint32_t LangAltValue::toUint32(long /*n*/) const
uint32_t LangAltValue::toUint32(size_t /*n*/) const
{
ok_ = false;
return 0;
}
float LangAltValue::toFloat(long /*n*/) const
float LangAltValue::toFloat(size_t /*n*/) const
{
ok_ = false;
return 0.0F;
}
Rational LangAltValue::toRational(long /*n*/) const
Rational LangAltValue::toRational(size_t /*n*/) const
{
ok_ = false;
return {0, 0};
@ -933,7 +931,7 @@ namespace Exiv2 {
date_.day = day;
}
int DateValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
int DateValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/)
{
const std::string str(reinterpret_cast<const char*>(buf), len);
return read(str);
@ -986,12 +984,12 @@ namespace Exiv2 {
return date_;
}
long DateValue::count() const
size_t DateValue::count() const
{
return size();
}
long DateValue::size() const
size_t DateValue::size() const
{
return 8;
}
@ -1012,7 +1010,7 @@ namespace Exiv2 {
return os;
}
int64_t DateValue::toInt64(long /*n*/) const
int64_t DateValue::toInt64(size_t /*n*/) const
{
// Range of tm struct is limited to about 1970 to 2038
// This will return -1 if outside that range
@ -1026,7 +1024,7 @@ namespace Exiv2 {
return l;
}
uint32_t DateValue::toUint32(long /*n*/) const
uint32_t DateValue::toUint32(size_t /*n*/) const
{
const int64_t t = toInt64();
if (t < 0 || t > std::numeric_limits<uint32_t>::max()) {
@ -1035,12 +1033,12 @@ namespace Exiv2 {
return static_cast<uint32_t>(t);
}
float DateValue::toFloat(long n) const
float DateValue::toFloat(size_t n) const
{
return static_cast<float>(toInt64(n));
}
Rational DateValue::toRational(long n) const
Rational DateValue::toRational(size_t n) const
{
return {static_cast<int32_t>(toInt64(n)), 1};
}
@ -1062,7 +1060,7 @@ namespace Exiv2 {
time_.tzMinute = tzMinute;
}
int TimeValue::read(const byte* buf, long len, ByteOrder /*byteOrder*/)
int TimeValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/)
{
const std::string str(reinterpret_cast<const char*>(buf), len);
return read(str);
@ -1140,12 +1138,12 @@ namespace Exiv2 {
return time_;
}
long TimeValue::count() const
size_t TimeValue::count() const
{
return size();
}
long TimeValue::size() const
size_t TimeValue::size() const
{
return 11;
}
@ -1174,7 +1172,7 @@ namespace Exiv2 {
return os;
}
int64_t TimeValue::toInt64(long /*n*/) const
int64_t TimeValue::toInt64(size_t /*n*/) const
{
// Returns number of seconds in the day in UTC.
int64_t result = (time_.hour - time_.tzHour) * 60 * 60;
@ -1187,7 +1185,7 @@ namespace Exiv2 {
return result;
}
uint32_t TimeValue::toUint32(long /*n*/) const
uint32_t TimeValue::toUint32(size_t /*n*/) const
{
const int64_t t = toInt64();
if (t < 0 || t > std::numeric_limits<uint32_t>::max()) {
@ -1196,12 +1194,12 @@ namespace Exiv2 {
return static_cast<uint32_t>(t);
}
float TimeValue::toFloat(long n) const
float TimeValue::toFloat(size_t n) const
{
return static_cast<float>(toInt64(n));
}
Rational TimeValue::toRational(long n) const
Rational TimeValue::toRational(size_t n) const
{
return {static_cast<int32_t>(toInt64(n)), 1};
}

@ -411,7 +411,8 @@ namespace Exiv2 {
WEBP_TAG_SIZE)
throw Error(kerImageWriteFailed);
ul2Data(data, static_cast<uint32_t>(iccProfile_.size()), littleEndian);
if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
throw Error(kerImageWriteFailed);
if (outIo.write(iccProfile_.c_data(), iccProfile_.size()) != iccProfile_.size()) {
throw Error(kerImageWriteFailed);
}
@ -444,7 +445,7 @@ namespace Exiv2 {
us2Data(data, static_cast<uint16_t>(blob.size()) + 8, bigEndian);
ul2Data(data, static_cast<uint32_t>(blob.size()), littleEndian);
if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
if (outIo.write(&blob[0], static_cast<long>(blob.size())) != static_cast<long>(blob.size())) {
if (outIo.write(&blob[0], blob.size()) != blob.size()) {
throw Error(kerImageWriteFailed);
}
if (outIo.tell() % 2) {
@ -457,8 +458,7 @@ namespace Exiv2 {
throw Error(kerImageWriteFailed);
ul2Data(data, static_cast<uint32_t>(xmpPacket().size()), littleEndian);
if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
if (outIo.write(reinterpret_cast<const byte*>(xmp.data()), static_cast<long>(xmp.size())) !=
static_cast<long>(xmp.size())) {
if (outIo.write(reinterpret_cast<const byte*>(xmp.data()), xmp.size()) != xmp.size()) {
throw Error(kerImageWriteFailed);
}
if (outIo.tell() % 2) {
@ -526,7 +526,7 @@ namespace Exiv2 {
if ( equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF) && option==kpsRecursive ) {
// create memio object with the payload, then print the structure
MemIo p (payload.c_data(),payload.size());
MemIo p (payload.c_data(), payload.size());
printTiffStructure(p,out,option,depth);
}
@ -561,13 +561,11 @@ namespace Exiv2 {
io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
const uint32_t filesize_u32 =
Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
const uint32_t filesize_u32 = Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
enforce(filesize_u32 <= io_->size(), Exiv2::kerCorruptedMetadata);
// Check that `filesize_u32` is safe to cast to `long`.
enforce(filesize_u32 <= static_cast<size_t>(std::numeric_limits<unsigned int>::max()),
Exiv2::kerCorruptedMetadata);
enforce(filesize_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()), Exiv2::kerCorruptedMetadata);
WebPImage::decodeChunks(static_cast<long>(filesize_u32));
@ -591,8 +589,7 @@ namespace Exiv2 {
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
// Check that `size_u32` is safe to cast to `long`.
enforce(static_cast<uint64_t>(size_u32) <= static_cast<unsigned long>(std::numeric_limits<long>::max()),
Exiv2::kerCorruptedMetadata);
enforce(size_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()), Exiv2::kerCorruptedMetadata);
const long size = static_cast<long>(size_u32);
// Check that `size` is within bounds.
@ -684,26 +681,26 @@ namespace Exiv2 {
byte exifShortHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
byte exifTiffLEHeader[] = { 0x49, 0x49, 0x2A }; // "MM*"
byte exifTiffBEHeader[] = { 0x4D, 0x4D, 0x00, 0x2A }; // "II\0*"
long offset = 0;
size_t offset = 0;
bool s_header = false;
bool le_header = false;
bool be_header = false;
long pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifLongHeader), 4);
long pos = getHeaderOffset(payload.c_data(), static_cast<long>(payload.size()), reinterpret_cast<byte*>(&exifLongHeader), 4);
if (pos == -1) {
pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifLongHeader), 6);
pos = getHeaderOffset(payload.c_data(), static_cast<long>(payload.size()), reinterpret_cast<byte*>(&exifLongHeader), 6);
if (pos != -1) {
s_header = true;
}
}
if (pos == -1) {
pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifTiffLEHeader), 3);
pos = getHeaderOffset(payload.c_data(), static_cast<long>(payload.size()), reinterpret_cast<byte*>(&exifTiffLEHeader), 3);
if (pos != -1) {
le_header = true;
}
}
if (pos == -1) {
pos = getHeaderOffset(payload.c_data(), payload.size(), reinterpret_cast<byte*>(&exifTiffBEHeader), 4);
pos = getHeaderOffset(payload.c_data(), static_cast<long>(payload.size()), reinterpret_cast<byte*>(&exifTiffBEHeader), 4);
if (pos != -1) {
be_header = true;
}
@ -716,7 +713,7 @@ namespace Exiv2 {
offset += 12;
}
const long sizePayload = Safe::add(payload.size(), offset);
const size_t sizePayload = Safe::add(payload.size(), offset);
DataBuf rawExifData(sizePayload);
if (s_header) {
@ -871,7 +868,7 @@ namespace Exiv2 {
/* Handle inject an icc profile right after VP8X chunk */
if (has_icc) {
byte size_buff[WEBP_TAG_SIZE];
ul2Data(size_buff, iccProfile_.size(), littleEndian);
ul2Data(size_buff, static_cast<uint32_t>(iccProfile_.size()), littleEndian);
if (iIo.write(reinterpret_cast<const byte*>(WEBP_CHUNK_HEADER_VP8X), WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
throw Error(kerImageWriteFailed);
if (iIo.write(size_buff, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)

@ -383,14 +383,14 @@ namespace Exiv2 {
return 0;
}
long Xmpdatum::count() const
size_t Xmpdatum::count() const
{
return p_->value_.get() == nullptr ? 0 : p_->value_->count();
}
long Xmpdatum::size() const
{
return p_->value_.get() == nullptr ? 0 : p_->value_->size();
return p_->value_.get() == nullptr ? 0 : static_cast<long>(p_->value_->size());
}
std::string Xmpdatum::toString() const
@ -951,10 +951,10 @@ namespace Exiv2 {
if (i.typeId() == xmpBag || i.typeId() == xmpSeq || i.typeId() == xmpAlt) {
printNode(ns, i.tagName(), "", options);
meta.SetProperty(ns.c_str(), i.tagName().c_str(), nullptr, options);
for (long idx = 0; idx < i.count(); ++idx) {
for (size_t idx = 0; idx < i.count(); ++idx) {
const std::string item = i.tagName() + "[" + toString(idx + 1) + "]";
printNode(ns, item, i.toString(idx), 0);
meta.SetProperty(ns.c_str(), item.c_str(), i.toString(idx).c_str());
printNode(ns, item, i.toString(static_cast<long>(idx)), 0);
meta.SetProperty(ns.c_str(), item.c_str(), i.toString(static_cast<long>(idx)).c_str());
}
continue;
}

@ -79,18 +79,20 @@ namespace Exiv2 {
IoCloser closer(*io_);
// Ensure that this is the correct image type
if (!isXmpType(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
throw Error(kerNotAnImage, "XMP");
}
// Read the XMP packet from the IO stream
std::string xmpPacket;
const long len = 64 * 1024;
byte buf[len];
long l;
size_t l;
while ((l = io_->read(buf, len)) > 0) {
xmpPacket.append(reinterpret_cast<char*>(buf), l);
}
if (io_->error()) throw Error(kerFailedToReadImageData);
if (io_->error())
throw Error(kerFailedToReadImageData);
clearMetadata();
xmpPacket_ = xmpPacket;
if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
@ -179,9 +181,8 @@ namespace Exiv2 {
auto tempIo = std::make_unique<MemIo>();
// Write XMP packet
if ( tempIo->write(reinterpret_cast<const byte*>(xmpPacket_.data()),
static_cast<long>(xmpPacket_.size()))
!= static_cast<long>(xmpPacket_.size())) throw Error(kerImageWriteFailed);
if (tempIo->write(reinterpret_cast<const byte*>(xmpPacket_.data()), xmpPacket_.size()) != xmpPacket_.size())
throw Error(kerImageWriteFailed);
if (tempIo->error()) throw Error(kerImageWriteFailed);
io_->close();
io_->transfer(*tempIo); // may throw

@ -18,7 +18,6 @@ class AdditionOverflowInLoaderExifJpeg(metaclass=system_tests.CaseMeta):
Warning: Directory Image, entry 0x0201: Strip 0 is outside of the data area; ignored.
Warning: Directory Image, entry 0x0201: Strip 7 is outside of the data area; ignored.
Error: Offset of directory Thumbnail, entry 0x0201 is out of bounds: Offset = 0x00000000; truncating the entry
$uncaught_exception $addition_overflow_message
"""
]
retval = [1]
retval = [0]

@ -17,22 +17,22 @@ class PngReadRawProfile(metaclass=system_tests.CaseMeta):
system_tests.path("$data_path/issue_428_poc4.png"),
system_tests.path("$data_path/issue_428_poc5.png"),
system_tests.path("$data_path/issue_428_poc8.png"),
system_tests.path("$data_path/issue_428_poc7.png"),
system_tests.path("$data_path/issue_428_poc2.png"),
system_tests.path("$data_path/issue_428_poc6.png"),
system_tests.path("$data_path/issue_428_poc7.png"),
]
commands = ["$exiv2 " + fname for fname in filenames]
stdout = [""] * len(filenames)
stderr = [ stderr_exception(fname) for fname in filenames[0:5] ]
stderr.append("""$exiv2_exception_message """ + filenames[5] + """:
stderr = [ stderr_exception(fname) for fname in filenames[0:6] ]
stderr.append("""$exiv2_exception_message """ + filenames[6] + """:
$kerInputDataReadFailed
""")
stderr.append("""Error: XMP Toolkit error 201: Error in XMLValidator
Warning: Failed to decode XMP metadata.
""" + stderr_exception(filenames[6]))
stderr.append("""Warning: Failed to decode Exif metadata.
""" + stderr_exception(filenames[7]))
retval = [1] * len(filenames)

@ -30,7 +30,7 @@ TEST(MemIo, isNotAtEofInitially)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_FALSE(io.eof());
}
@ -39,7 +39,7 @@ TEST(MemIo, seekBeyondBufferSizeReturns1AndSetsEofToTrue)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_EQ(1, io.seek(65, BasicIo::beg));
ASSERT_TRUE(io.eof());
}
@ -49,7 +49,7 @@ TEST(MemIo, seekBefore0Returns1ButItDoesNotSetEofToTrue)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_EQ(1, io.seek(-1, BasicIo::beg));
ASSERT_FALSE(io.eof());
}
@ -59,7 +59,7 @@ TEST(MemIo, seekBeyondBoundsDoesNotMoveThePosition)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_EQ(0, io.tell());
ASSERT_EQ(1, io.seek(65, BasicIo::beg));
ASSERT_EQ(0, io.tell());
@ -70,7 +70,7 @@ TEST(MemIo, seekInsideBoundsMoveThePosition)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_EQ(0, io.tell());
ASSERT_EQ(0, io.seek(32, BasicIo::beg));
ASSERT_EQ(32, io.tell());
@ -81,7 +81,7 @@ TEST(MemIo, seekInsideBoundsUsingBeg_resetsThePosition)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
std::vector<std::int64_t> positions {0, 8, 16, 32, 64};
for(auto pos: positions) {
ASSERT_EQ(0, io.seek(pos, BasicIo::beg));
@ -94,7 +94,7 @@ TEST(MemIo, seekInsideBoundsUsingCur_shiftThePosition)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
std::vector<std::int64_t> shifts {4, 4, 8, 16, 32};
std::vector<std::int64_t> positions {4, 8, 16, 32, 64};
for (size_t i = 0; i < shifts.size(); ++i) {
@ -108,7 +108,7 @@ TEST(MemIo, seekToEndPosition_doesNotTriggerEof)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_EQ(0, io.tell());
ASSERT_EQ(0, io.seek(0, BasicIo::end));
ASSERT_EQ(64, io.tell());
@ -120,7 +120,7 @@ TEST(MemIo, seekToEndPositionAndReadTriggersEof)
std::array<byte, 64> buf;
buf.fill(0);
MemIo io(buf.data(), static_cast<long>(buf.size()));
MemIo io(buf.data(), buf.size());
ASSERT_EQ(0, io.seek(0, BasicIo::end));
ASSERT_EQ(64, io.tell());
@ -134,7 +134,7 @@ TEST(MemIo, readEmptyIoReturns0)
{
std::array<byte, 10> buf;
MemIo io;
ASSERT_EQ(0, io.read(buf.data(), static_cast<long>(buf.size())));
ASSERT_EQ(0, io.read(buf.data(), buf.size()));
}
TEST(MemIo, readLessBytesThanAvailableReturnsRequestedBytes)
@ -143,7 +143,7 @@ TEST(MemIo, readLessBytesThanAvailableReturnsRequestedBytes)
buf1.fill(1);
buf2.fill(0);
MemIo io(buf1.data(), static_cast<long>(buf1.size()));
MemIo io(buf1.data(), buf1.size());
ASSERT_EQ(5, io.read(buf2.data(), 5));
}
@ -153,7 +153,7 @@ TEST(MemIo, readSameBytesThanAvailableReturnsRequestedBytes)
buf1.fill(1);
buf2.fill(0);
MemIo io(buf1.data(), static_cast<long>(buf1.size()));
MemIo io(buf1.data(), buf1.size());
ASSERT_EQ(10, io.read(buf2.data(), 10));
}
@ -163,6 +163,6 @@ TEST(MemIo, readMoreBytesThanAvailableReturnsAvailableBytes)
buf1.fill(1);
buf2.fill(0);
MemIo io(buf1.data(), static_cast<long>(buf1.size()));
MemIo io(buf1.data(), buf1.size());
ASSERT_EQ(10, io.read(buf2.data(), 15));
}

@ -113,30 +113,26 @@ TEST(base64encode, encodesValidString)
const std::string original ("This is a unit test");
const std::string expected ("VGhpcyBpcyBhIHVuaXQgdGVzdA==");
size_t encodeLength = ((original.size() + 2) / 3) * 4 + 1;
auto result = new char[encodeLength];
ASSERT_EQ(1, base64encode(original.c_str(), original.size(), result, encodeLength));
ASSERT_STREQ(expected.c_str(), result);
delete [] result;
std::vector<char> result(encodeLength);
ASSERT_EQ(1, base64encode(original.c_str(), original.size(), result.data(), encodeLength));
ASSERT_STREQ(expected.c_str(), result.data());
}
TEST(base64encode, doesNotEncodeWithNotBigEnoughResultSize)
{
const std::string original ("This is a unit test");
size_t encodeLength = (original.size());
auto result = new char[encodeLength];
ASSERT_EQ(0, base64encode(original.c_str(), original.size(), result, encodeLength));
delete [] result;
std::vector<char> result(encodeLength);
ASSERT_EQ(0, base64encode(original.c_str(), original.size(), result.data(), encodeLength));
}
TEST(base64decode, decodesValidString)
{
const std::string original ("VGhpcyBpcyBhIHVuaXQgdGVzdA==");
const std::string expected ("This is a unit test");
auto result = new char[original.size()];
ASSERT_EQ(static_cast<long>(expected.size()),
base64decode(original.c_str(), result, original.size()));
ASSERT_STREQ(expected.c_str(), result);
delete [] result;
std::vector<char> result(original.size());
ASSERT_EQ(static_cast<long>(expected.size()), base64decode(original.c_str(), result.data(), original.size()));
ASSERT_STREQ(expected.c_str(), result.data());
}
TEST(AUri, parsesAndDecoreUrl)

@ -62,7 +62,6 @@ TEST(DataBuf, allocatesDataWithNonEmptyConstructor)
TEST(DataBuf, read_write_endianess)
{
DataBuf buf(4 + 1 + 2 + 4 + 8);
buf.clear();
// Big endian.
buf.write_uint8(4, 0x01);

Loading…
Cancel
Save