Update .clang-format file & apply clang-format to whole project

main
Luis Díaz Más 3 years ago
parent 0641a5f539
commit 30bf563f4d

@ -1,41 +1,20 @@
---
# Indentation for all files
ColumnLimit: 120
IndentWidth: 4
TabWidth: 4
UseTab: Never
# C++ Options
Language: Cpp
Standard: c++17
BasedOnStyle: Google
# Useful for sorting the project inclusions and standard library inclusions separately
IncludeBlocks: Preserve
AccessModifierOffset: -4
ContinuationIndentWidth: 4
# Constructor initializers better formatted in presence of preprocessor conditions (see image.cpp)
BreakConstructorInitializers: AfterColon
AllowAllConstructorInitializersOnNextLine: true
# break braces for most of the cases (except conditionals and loops)
BreakBeforeBraces: Custom
BraceWrapping:
AfterStruct: true
AfterClass: true
AfterFunction: true
AfterControlStatement: false
AfterEnum: true
AfterNamespace: true
# Do not allow SingleLine statements (to improve coverage statistics)
AllowShortFunctionsOnASingleLine: None
AllowShortBlocksOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
Cpp11BracedListStyle: true
...

File diff suppressed because it is too large Load Diff

@ -12,38 +12,36 @@
#define ACTIONS_HPP_
// *****************************************************************************
#include "exiv2app.hpp"
#include <unordered_map>
#include "exiv2app.hpp"
// *****************************************************************************
// class declarations
namespace Exiv2 {
class ExifData;
class Image;
class Metadatum;
class PreviewImage;
}
class ExifData;
class Image;
class Metadatum;
class PreviewImage;
} // namespace Exiv2
// *****************************************************************************
// namespace extensions
/// @brief Contains all action classes (task subclasses).
namespace Action {
//! Enumerates all tasks
enum TaskType { none, adjust, print, rename, erase, extract, insert,
modify, fixiso, fixcom };
//! Enumerates all tasks
enum TaskType { none, adjust, print, rename, erase, extract, insert, modify, fixiso, fixcom };
// *****************************************************************************
// class definitions
/*!
/*!
@brief Abstract base class for all concrete actions.
Task provides a simple interface that actions must implement and a few
commonly used helpers.
*/
class Task {
class Task {
public:
//! Shortcut for an auto pointer.
using UniquePtr = std::unique_ptr<Task>;
@ -56,30 +54,31 @@ namespace Action {
/// @brief Application interface to perform a task.
/// @param path Path of the file to process.
/// @return 0 if successful.
virtual int run(const std::string& path) =0;
virtual int run(const std::string& path) = 0;
bool setBinary(bool b)
{
bool setBinary(bool b) {
bool bResult = binary_;
binary_ = b;
return bResult ;
return bResult;
}
bool binary() { return binary_ ; }
bool binary() {
return binary_;
}
private:
//! copy binary_ from command-line params to task
bool binary_ {false} ;
}; // class Task
bool binary_{false};
}; // class Task
/*!
/*!
@brief Task factory.
Creates an instance of the task of the requested type. The factory is
implemented as a singleton, which can be accessed only through the static
member function instance().
*/
class TaskFactory {
*/
class TaskFactory {
public:
/*!
@brief Get access to the task factory.
@ -111,10 +110,10 @@ namespace Action {
//! List of task types and corresponding prototypes.
std::unordered_map<TaskType, Task::UniquePtr> registry_;
};
};
//! %Print the Exif (or other metadata) of a file to stdout
class Print : public Task {
//! %Print the Exif (or other metadata) of a file to stdout
class Print : public Task {
public:
~Print() override = default;
int run(const std::string& path) override;
@ -143,9 +142,7 @@ namespace Action {
data. A line break is printed only if a label is provided.
@return 1 if a line was written, 0 if the key was not found.
*/
int printTag(const Exiv2::ExifData& exifData,
const std::string& key,
const std::string& label ="") const;
int printTag(const Exiv2::ExifData& exifData, const std::string& key, const std::string& label = "") const;
//! Type for an Exiv2 Easy access function
using EasyAccessFct = Exiv2::ExifData::const_iterator (*)(const Exiv2::ExifData& ed);
/*!
@ -153,45 +150,41 @@ namespace Action {
data. A line break is printed only if a label is provided.
@return 1 if a line was written, 0 if the information was not found.
*/
int printTag(const Exiv2::ExifData& exifData,
EasyAccessFct easyAccessFct,
const std::string& label ="",
EasyAccessFct easyAccessFctFallback =NULL) const;
int printTag(const Exiv2::ExifData& exifData, EasyAccessFct easyAccessFct, const std::string& label = "",
EasyAccessFct easyAccessFctFallback = NULL) const;
private:
std::string path_;
int align_{0}; // for the alignment of the summary output
};
};
/// @brief %Rename a file to its metadata creation timestamp, in the specified format.
class Rename : public Task {
/// @brief %Rename a file to its metadata creation timestamp, in the specified format.
class Rename : public Task {
public:
~Rename() override = default;
int run(const std::string& path) override;
Task::UniquePtr clone() const override;
}; // class Rename
}; // class Rename
//! %Adjust the Exif (or other metadata) timestamps
class Adjust : public Task {
//! %Adjust the Exif (or other metadata) timestamps
class Adjust : public Task {
public:
~Adjust() override = default;
int run(const std::string& path) override;
Task::UniquePtr clone() const override;
private:
int adjustDateTime(Exiv2::ExifData& exifData,
const std::string& key,
const std::string& path) const;
int adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, const std::string& path) const;
long adjustment_ {0};
long yearAdjustment_ {0};
long monthAdjustment_ {0};
long dayAdjustment_ {0};
long adjustment_{0};
long yearAdjustment_{0};
long monthAdjustment_{0};
long dayAdjustment_{0};
}; // class Adjust
}; // class Adjust
/// @brief %Erase the entire exif data or only the thumbnail section.
class Erase : public Task {
/// @brief %Erase the entire exif data or only the thumbnail section.
class Erase : public Task {
public:
~Erase() override = default;
int run(const std::string& path) override;
@ -217,10 +210,10 @@ namespace Action {
private:
std::string path_;
};
};
/// @brief %Extract the entire exif data or only the thumbnail section.
class Extract : public Task {
/// @brief %Extract the entire exif data or only the thumbnail section.
class Extract : public Task {
public:
~Extract() override = default;
int run(const std::string& path) override;
@ -247,10 +240,10 @@ namespace Action {
private:
std::string path_;
};
};
/// @brief %Insert the Exif data from corresponding *.exv files.
class Insert : public Task {
/// @brief %Insert the Exif data from corresponding *.exv files.
class Insert : public Task {
public:
~Insert() override = default;
int run(const std::string& path) override;
@ -264,20 +257,20 @@ namespace Action {
static int insertThumbnail(const std::string& path);
/// @brief Insert an XMP packet from a xmpPath into file \em path.
static int insertXmpPacket(const std::string& path,const std::string& xmpPath) ;
static int insertXmpPacket(const std::string& path, const std::string& xmpPath);
/// @brief Insert xmp from a DataBuf into file \em path.
static int insertXmpPacket(const std::string& path, const Exiv2::DataBuf& xmpBlob, bool usePacket = false);
/// @brief Insert an ICC profile from iccPath into file \em path.
static int insertIccProfile(const std::string& path,const std::string& iccPath) ;
static int insertIccProfile(const std::string& path, const std::string& iccPath);
/// @brief Insert an ICC profile from binary DataBuf into file \em path.
static int insertIccProfile(const std::string& path, Exiv2::DataBuf&& iccProfileBlob);
};
};
/// @brief %Modify the Exif data according to the commands in the modification table.
class Modify : public Task {
/// @brief %Modify the Exif data according to the commands in the modification table.
class Modify : public Task {
public:
Modify() = default;
~Modify() override = default;
@ -295,10 +288,10 @@ namespace Action {
static void delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd);
//! Register an XMP namespace according to \em modifyCmd
static void regNamespace(const ModifyCmd& modifyCmd);
};
};
/// @brief %Copy ISO settings from any of the Nikon makernotes to the regular Exif tag, Exif.Photo.ISOSpeedRatings.
class FixIso : public Task {
/// @brief %Copy ISO settings from any of the Nikon makernotes to the regular Exif tag, Exif.Photo.ISOSpeedRatings.
class FixIso : public Task {
public:
~FixIso() override = default;
int run(const std::string& path) override;
@ -306,19 +299,20 @@ namespace Action {
private:
std::string path_;
};
};
/// @brief Fix the character encoding of Exif UNICODE user comments.
///
/// Decodes the comment using the auto-detected or specified character encoding and writes it back in UCS-2.
class FixCom : public Task {
/// @brief Fix the character encoding of Exif UNICODE user comments.
///
/// Decodes the comment using the auto-detected or specified character encoding and writes it back in UCS-2.
class FixCom : public Task {
public:
~FixCom() override = default;
int run(const std::string& path) override;
Task::UniquePtr clone() const override;
private:
std::string path_;
};
};
} // namespace Action

@ -1,12 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include <climits>
#include <cstdlib>
namespace Util
{
bool strtol(const char* nptr, long& n)
{
namespace Util {
bool strtol(const char* nptr, long& n) {
if (!nptr || *nptr == '\0')
return false;
char* endptr = nullptr;
@ -17,6 +15,6 @@ namespace Util
return false;
n = tmp;
return true;
}
}
} // namespace Util

@ -4,12 +4,12 @@
#define APP_UTILS_HPP_
namespace Util {
/*!
/*!
@brief Convert a C string to a long value, which is returned in n.
Returns true if the conversion is successful, else false.
n is not modified if the conversion is unsuccessful. See strtol(2).
*/
bool strtol(const char* nptr, long& n);
bool strtol(const char* nptr, long& n);
} // namespace Util
#endif // #ifndef UTILS_HPP_

File diff suppressed because it is too large Load Diff

@ -12,13 +12,13 @@
// included header files
#include <exiv2/exiv2.hpp>
#include "types.hpp"
#include "getopt.hpp"
#include "types.hpp"
// + standard includes
#include <set>
#include <iostream>
#include <regex>
#include <set>
// *****************************************************************************
// class definitions
@ -29,18 +29,14 @@ enum CmdId { invalidCmdId, add, set, del, reg };
// enum MetadataId { invalidMetadataId, iptc, exif, xmp };
//! Metadata identifiers
// mdNone=0, mdExif=1, mdIptc=2, mdComment=4, mdXmp=8
enum MetadataId { invalidMetadataId = Exiv2::mdNone
, iptc = Exiv2::mdIptc
, exif = Exiv2::mdExif
, xmp = Exiv2::mdXmp
} ;
enum MetadataId { invalidMetadataId = Exiv2::mdNone, iptc = Exiv2::mdIptc, exif = Exiv2::mdExif, xmp = Exiv2::mdXmp };
//! Structure for one parsed modification command
struct ModifyCmd {
//! C'tor
ModifyCmd() :
cmdId_(invalidCmdId), metadataId_(invalidMetadataId),
typeId_(Exiv2::invalidTypeId), explicitType_(false) {}
cmdId_(invalidCmdId), metadataId_(invalidMetadataId), typeId_(Exiv2::invalidTypeId), explicitType_(false) {
}
CmdId cmdId_; //!< Command identifier
std::string key_; //!< Exiv2 key string
MetadataId metadataId_; //!< Metadata identifier
@ -93,10 +89,10 @@ struct CmdIdAndString {
*/
class Params : public Util::Getopt {
private:
private:
std::string optstring_;
public:
public:
//! Container for command files
using CmdFiles = std::vector<std::string>;
//! Container for commands from the command line
@ -118,16 +114,7 @@ public:
Params(const Params& rhs) = delete;
//! Enumerates print modes
enum PrintMode {
pmSummary,
pmList,
pmComment,
pmPreview,
pmStructure,
pmXMP,
pmIccProfile,
pmRecursive
};
enum PrintMode { pmSummary, pmList, pmComment, pmPreview, pmStructure, pmXMP, pmIccProfile, pmRecursive };
//! Individual items to print, bitmap
enum PrintItem {
@ -157,7 +144,7 @@ public:
ctIccProfile = 128,
ctXmpRaw = 256,
ctStdInOut = 512,
ctIptcRaw =1024
ctIptcRaw = 1024
};
//! Enumerates the policies to handle existing files in rename action
@ -209,18 +196,17 @@ public:
Exiv2::DataBuf stdinBuf; //!< DataBuf with the binary bytes from stdin
private:
private:
bool first_;
Params();
private:
private:
//! @name Helpers
//@{
int setLogLevel(const std::string& optarg);
int evalGrep( const std::string& optarg);
int evalKey( const std::string& optarg);
int evalGrep(const std::string& optarg);
int evalKey(const std::string& optarg);
int evalRename(int opt, const std::string& optarg);
int evalAdjust(const std::string& optarg);
int evalYodAdjust(const Yod& yod, const std::string& optarg);
@ -232,7 +218,7 @@ private:
int evalModify(int opt, const std::string& optarg);
//@}
public:
public:
/*!
@brief Call Getopt::getopt() with optstring, to initiate command line
argument parsing, perform consistency checks after all command line
@ -252,10 +238,10 @@ public:
int nonoption(const std::string& argv) override;
//! Print a minimal usage note to an output stream.
void usage(std::ostream& os =std::cout) const;
void usage(std::ostream& os = std::cout) const;
//! Print further usage explanations to an output stream.
void help(std::ostream& os =std::cout) const;
void help(std::ostream& os = std::cout) const;
//! Print version information to an output stream.
static void version(bool verbose = false, std::ostream& os = std::cout);

@ -10,15 +10,14 @@
namespace fs = std::filesystem;
namespace Util {
// https://raw.githubusercontent.com/skeeto/getopt/master/getopt.h
int optind = 0;
int opterr = 1;
int optopt;
int optpos = 1;
const char* optarg;
// https://raw.githubusercontent.com/skeeto/getopt/master/getopt.h
int optind = 0;
int opterr = 1;
int optopt;
int optpos = 1;
const char* optarg;
/* A minimal POSIX getopt() implementation in ANSI C
/* A minimal POSIX getopt() implementation in ANSI C
*
* This is free and unencumbered software released into the public domain.
*
@ -29,9 +28,8 @@ namespace Util {
* Ref: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html
*/
int getopt(int argc, char * const argv[], const char *optstring)
{
const char *arg;
int getopt(int argc, char* const argv[], const char* optstring) {
const char* arg;
(void)argc;
/* Reset? */
@ -48,7 +46,7 @@ namespace Util {
if (!arg || arg[0] != '-' || !isalnum(arg[1])) {
return -1;
}
const char *opt = strchr(optstring, arg[optpos]);
const char* opt = strchr(optstring, arg[optpos]);
optopt = arg[optpos];
if (!opt) {
if (opterr && *optstring != ':')
@ -77,27 +75,24 @@ namespace Util {
optpos = 1;
}
return optopt;
}
}
// *****************************************************************************
// class Getopt
Getopt::Getopt()
: errcnt_(0)
{
}
Getopt::Getopt() : errcnt_(0) {
}
int Getopt::getopt(int argc, char* const argv[], const std::string& optstring)
{
int Getopt::getopt(int argc, char* const argv[], const std::string& optstring) {
progname_ = fs::path(argv[0]).filename().string();
Util::optind = 0; // reset the Util::Getopt scanner
for (;!errcnt_;) {
for (; !errcnt_;) {
int c = Util::getopt(argc, argv, optstring.c_str());
if (c == -1) {
break;
}
errcnt_ += option(c, Util::optarg ? Util::optarg : "", Util::optopt);
if (c == '?' ) {
if (c == '?') {
break;
}
}
@ -106,11 +101,10 @@ namespace Util {
}
return errcnt_;
}
}
int Getopt::nonoption(const std::string& /*argv*/)
{
int Getopt::nonoption(const std::string& /*argv*/) {
return 0;
}
}
} // namespace Util

@ -6,19 +6,18 @@
#include <string>
namespace Util {
extern int optind;
extern int opterr;
extern int optopt;
extern int optpos;
extern const char* optarg;
extern int optind ;
extern int opterr ;
extern int optopt ;
extern int optpos ;
extern const char* optarg;
int getopt(int argc, char* const argv[], const char* optstring);
int getopt(int argc, char * const argv[], const char *optstring);
// *********************************************************************
// class definitions
// *********************************************************************
// class definitions
/*!
/*!
@brief Parse the command line options of a program.
A wrapper around the POSIX %getopt(3) function. Parses the command line
@ -27,7 +26,7 @@ namespace Util {
remaining non-option parameters are passed to the virtual nonoption()
method.
*/
class Getopt {
class Getopt {
public:
//! Default constructor.
Getopt();
@ -86,15 +85,19 @@ namespace Util {
virtual int nonoption(const std::string& argv);
//! Program name (argv[0])
const std::string& progname() const { return progname_; }
const std::string& progname() const {
return progname_;
}
//! Total number of errors returned by calls to option()
int errcnt() const { return errcnt_; }
int errcnt() const {
return errcnt_;
}
private:
std::string progname_;
int errcnt_;
};
};
}; // namespace Util

@ -4,8 +4,7 @@
extern int __cdecl main();
int wmain(int argc, wchar_t* argv[])
{
int wmain(int argc, wchar_t* argv[]) {
char** args;
int nbytes = (int)(sizeof(char*) * (argc + 1));
HANDLE heap = GetProcessHeap();
@ -17,7 +16,7 @@ int wmain(int argc, wchar_t* argv[])
args[0] = (char*)(args + argc + 1);
for (int i = 0; i < argc; ++i)
args[i+1] = args[i] + WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, args[i], nbytes, NULL, NULL);
args[i + 1] = args[i] + WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, args[i], nbytes, NULL, NULL);
args[argc] = NULL;
@ -26,12 +25,11 @@ int wmain(int argc, wchar_t* argv[])
return argc;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
(void) hInstance;
(void) hPrevInstance;
(void) lpCmdLine;
(void) nCmdShow;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
(void)hInstance;
(void)hPrevInstance;
(void)lpCmdLine;
(void)nCmdShow;
int argc;
wchar_t** argv;

@ -1,10 +1,10 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <iomanip>
#include <iostream>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Invalid files generate a lot of warnings, so switch off logging.
Exiv2::LogMsg::setLevel(Exiv2::LogMsg::mute);
@ -16,8 +16,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size) {
try {
Exiv2::DataBuf data_copy(data, size);
Exiv2::Image::UniquePtr image =
Exiv2::ImageFactory::open(data_copy.c_data(), size);
Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(data_copy.c_data(), size);
assert(image.get() != 0);
image->readMetadata();
@ -43,7 +42,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size) {
image->writeMetadata();
} catch(...) {
} catch (...) {
// Exiv2 throws an exception if the metadata is invalid.
}

@ -22,18 +22,17 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief An interface for simple binary IO.
Designed to have semantics and names similar to those of C style FILE*
operations. Subclasses should all behave the same so that they can be
interchanged.
*/
class EXIV2API BasicIo {
class EXIV2API BasicIo {
public:
//! BasicIo auto_ptr type
using UniquePtr = std::unique_ptr<BasicIo>;
@ -80,7 +79,7 @@ namespace Exiv2 {
@return Number of bytes written to IO source successfully;<BR>
0 if failure;
*/
virtual size_t write(const byte* data, size_t 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
@ -90,7 +89,7 @@ namespace Exiv2 {
@return Number of bytes written to IO source successfully;<BR>
0 if failure;
*/
virtual size_t 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.
@ -122,7 +121,7 @@ namespace Exiv2 {
@return Number of bytes read from IO source successfully;<BR>
0 if failure;
*/
virtual size_t read(byte* buf, size_t 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.
@ -133,7 +132,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, size_t 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.
@ -154,7 +153,7 @@ namespace Exiv2 {
invalidated by the method.
@throw Error In case of failure
*/
virtual void transfer(BasicIo& src) = 0;
virtual void transfer(BasicIo &src) = 0;
/*!
@brief Move the current IO position.
@param offset Number of bytes to move the position relative
@ -184,14 +183,14 @@ namespace Exiv2 {
@return A pointer to the mapped area.
@throw Error In case of failure.
*/
virtual byte* mmap(bool isWriteable =false) =0;
virtual byte *mmap(bool isWriteable = false) = 0;
/*!
@brief Remove a mapping established with mmap(). If the mapped area
is writeable, this ensures that changes are written back.
@return 0 if successful;<BR>
Nonzero if failure;
*/
virtual int munmap() =0;
virtual int munmap() = 0;
//@}
@ -209,18 +208,18 @@ namespace Exiv2 {
-1 if failure;
*/
virtual size_t size() const = 0;
//!Returns true if the IO source is open, otherwise false.
//! Returns true if the IO source is open, otherwise false.
virtual bool isopen() const = 0;
//!Returns 0 if the IO source is in a valid state, otherwise nonzero.
//! Returns 0 if the IO source is in a valid state, otherwise nonzero.
virtual int error() const = 0;
//!Returns true if the IO position has reached the end, otherwise false.
//! Returns true if the IO position has reached the end, otherwise false.
virtual bool eof() const = 0;
/*!
@brief Return the path to the IO resource. Often used to form
comprehensive error messages where only a BasicIo instance is
available.
*/
virtual const std::string& path() const noexcept =0;
virtual const std::string &path() const noexcept = 0;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
@ -234,49 +233,55 @@ namespace Exiv2 {
/*!
@brief this is allocated and populated by mmap()
*/
byte* bigBlock_{};
byte *bigBlock_{};
//@}
}; // class BasicIo
}; // class BasicIo
/*!
/*!
@brief Utility class that closes a BasicIo instance upon destruction.
Meant to be used as a stack variable in functions that need to
ensure BasicIo instances get closed. Useful when functions return
errors from many locations.
*/
class EXIV2API IoCloser {
class EXIV2API IoCloser {
public:
//! @name Creators
//@{
//! Constructor, takes a BasicIo reference
explicit IoCloser(BasicIo& bio) : bio_(bio) {}
explicit IoCloser(BasicIo &bio) : bio_(bio) {
}
//! Destructor, closes the BasicIo reference
virtual ~IoCloser() { close(); }
virtual ~IoCloser() {
close();
}
//@}
//! @name Manipulators
//@{
//! Close the BasicIo if it is open
void close() { if (bio_.isopen()) bio_.close(); }
void close() {
if (bio_.isopen())
bio_.close();
}
//@}
// DATA
//! The BasicIo reference
BasicIo& bio_;
BasicIo &bio_;
// Not implemented
//! Copy constructor
IoCloser(const IoCloser&) = delete;
IoCloser(const IoCloser &) = delete;
//! Assignment operator
IoCloser& operator=(const IoCloser&) = delete;
}; // class IoCloser
IoCloser &operator=(const IoCloser &) = delete;
}; // class IoCloser
/*!
/*!
@brief Provides binary file IO by implementing the BasicIo
interface.
*/
class EXIV2API FileIo : public BasicIo {
class EXIV2API FileIo : public BasicIo {
public:
//! @name Creators
//@{
@ -286,7 +291,7 @@ namespace Exiv2 {
therefore never fails.
@param path The full path of a file
*/
explicit FileIo(const std::string& path);
explicit FileIo(const std::string &path);
//! Destructor. Flushes and closes an open file.
~FileIo() override;
@ -307,7 +312,7 @@ namespace Exiv2 {
@return 0 if successful;<BR>
Nonzero if failure.
*/
int open(const std::string& mode);
int open(const std::string &mode);
/*!
@brief Open the file using the default access mode of "rb".
This method can also be used to "reopen" a file which will flush
@ -332,7 +337,7 @@ namespace Exiv2 {
@return Number of bytes written to the file successfully;<BR>
0 if failure;
*/
size_t write(const byte* data, size_t 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
@ -342,7 +347,7 @@ namespace Exiv2 {
@return Number of bytes written to the file successfully;<BR>
0 if failure;
*/
size_t 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.
@ -374,7 +379,7 @@ namespace Exiv2 {
@return Number of bytes read from the file successfully;<BR>
0 if failure;
*/
size_t read(byte* buf, size_t 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.
@ -400,7 +405,7 @@ namespace Exiv2 {
invalidated by the method.
@throw Error In case of failure
*/
void transfer(BasicIo& src) override;
void transfer(BasicIo &src) override;
int seek(int64_t offset, Position pos) override;
@ -415,7 +420,7 @@ namespace Exiv2 {
@return A pointer to the mapped area.
@throw Error In case of failure.
*/
byte* mmap(bool isWriteable = false) override;
byte *mmap(bool isWriteable = false) override;
/*!
@brief Remove a mapping established with mmap(). If the mapped area is
writeable, this ensures that changes are written back to the
@ -427,7 +432,7 @@ namespace Exiv2 {
/*!
@brief close the file source and set a new path.
*/
virtual void setPath(const std::string& path);
virtual void setPath(const std::string &path);
//@}
//! @name Accessors
@ -452,7 +457,7 @@ namespace Exiv2 {
//! Returns true if the file position has reached the end, otherwise false.
bool eof() const override;
//! Returns the path of the file
const std::string& path() const noexcept override;
const std::string &path() const noexcept override;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
@ -466,18 +471,18 @@ namespace Exiv2 {
// NOT IMPLEMENTED
//! Copy constructor
FileIo(FileIo& rhs) = delete;
FileIo(FileIo &rhs) = delete;
//! Assignment operator
FileIo& operator=(const FileIo& rhs) = delete;
FileIo &operator=(const FileIo &rhs) = delete;
private:
// Pimpl idiom
class Impl;
std::unique_ptr<Impl> p_;
}; // class FileIo
}; // class FileIo
/*!
/*!
@brief Provides binary IO on blocks of memory by implementing the BasicIo
interface. A copy-on-write implementation ensures that the data passed
in is only copied when necessary, i.e., as soon as data is written to
@ -489,7 +494,7 @@ namespace Exiv2 {
creating a specialized readonly class or changing this one to
have a readonly mode.
*/
class EXIV2API MemIo : public BasicIo {
class EXIV2API MemIo : public BasicIo {
public:
//! @name Creators
//@{
@ -502,7 +507,7 @@ namespace Exiv2 {
@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, size_t size);
MemIo(const byte *data, size_t size);
//! Destructor. Releases all managed memory
~MemIo() override;
//@}
@ -531,7 +536,7 @@ namespace Exiv2 {
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
size_t write(const byte* data, size_t 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
@ -542,7 +547,7 @@ namespace Exiv2 {
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
size_t 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.
@ -574,7 +579,7 @@ namespace Exiv2 {
@return Number of bytes read from the memory block successfully;<BR>
0 if failure;
*/
size_t read(byte* buf, size_t 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.
@ -597,7 +602,7 @@ namespace Exiv2 {
invalidated by the method.
@throw Error In case of failure
*/
void transfer(BasicIo& src) override;
void transfer(BasicIo &src) override;
int seek(int64_t offset, Position pos) override;
@ -609,7 +614,7 @@ namespace Exiv2 {
returned pointer remains valid and allocated as long as the
MemIo object exists.
*/
byte* mmap(bool /*isWriteable*/ = false) override;
byte *mmap(bool /*isWriteable*/ = false) override;
int munmap() override;
//@}
@ -626,14 +631,14 @@ namespace Exiv2 {
-1 if failure;
*/
size_t size() const override;
//!Always returns true
//! Always returns true
bool isopen() const override;
//!Always returns 0
//! Always returns 0
int error() const override;
//!Returns true if the IO position has reached the end, otherwise false.
//! Returns true if the IO position has reached the end, otherwise false.
bool eof() const override;
//! Returns a dummy path, indicating that memory access is used
const std::string& path() const noexcept override;
const std::string &path() const noexcept override;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
@ -648,27 +653,27 @@ namespace Exiv2 {
// NOT IMPLEMENTED
//! Copy constructor
MemIo(MemIo& rhs) = delete;
MemIo(MemIo &rhs) = delete;
//! Assignment operator
MemIo& operator=(const MemIo& rhs) = delete;
MemIo &operator=(const MemIo &rhs) = delete;
private:
// Pimpl idiom
class Impl;
std::unique_ptr<Impl> p_;
}; // class MemIo
}; // class MemIo
/*!
/*!
@brief Provides binary IO for the data from stdin and data uri path.
*/
#if EXV_XPATH_MEMIO
class EXIV2API XPathIo : public MemIo {
class EXIV2API XPathIo : public MemIo {
public:
//! @name Creators
//@{
//! Default constructor
XPathIo(const std::string& path);
XPathIo(const std::string &path);
//@}
private:
/*!
@ -681,10 +686,10 @@ namespace Exiv2 {
@param path The data uri.
@throw Error if no base64 data in path.
*/
void ReadDataUri(const std::string& path);
}; // class XPathIo
void ReadDataUri(const std::string &path);
}; // class XPathIo
#else
class EXIV2API XPathIo : public FileIo {
class EXIV2API XPathIo : public FileIo {
public:
/*!
@brief The extension of the temporary file which is created when getting input data
@ -700,7 +705,7 @@ namespace Exiv2 {
//! @name Creators
//@{
//! Default constructor that reads data from stdin/data uri path and writes them to the temp file.
explicit XPathIo(const std::string& orgPath);
explicit XPathIo(const std::string &orgPath);
//! Destructor. Releases all managed memory and removes the temp file.
~XPathIo() override;
@ -712,7 +717,7 @@ namespace Exiv2 {
@brief Change the name of the temp file and make it untemporary before
calling the method of superclass FileIo::transfer.
*/
void transfer(BasicIo& src) override;
void transfer(BasicIo &src) override;
//@}
@ -724,23 +729,22 @@ namespace Exiv2 {
@return the name of the new file.
@throw Error if it fails.
*/
static std::string writeDataToFile(const std::string& orgPath);
static std::string writeDataToFile(const std::string &orgPath);
//@}
private:
// True if the file is a temporary file and it should be deleted in destructor.
bool isTemp_;
std::string tempFilePath_;
}; // class XPathIo
}; // class XPathIo
#endif
/*!
/*!
@brief Provides remote binary file IO by implementing the BasicIo interface. This is an
abstract class. The logics for remote access are implemented in HttpIo, CurlIo, SshIo which
are the derived classes of RemoteIo.
*/
class EXIV2API RemoteIo : public BasicIo {
*/
class EXIV2API RemoteIo : public BasicIo {
public:
//! Destructor. Releases all managed memory.
RemoteIo();
@ -770,7 +774,7 @@ namespace Exiv2 {
@brief Not support this method.
@return 0 means failure
*/
size_t write(const byte* data, size_t 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.
@ -785,7 +789,7 @@ namespace Exiv2 {
@note The write access is only supported by http, https, ssh.
*/
size_t write(BasicIo& src) override;
size_t write(BasicIo &src) override;
/*!
@brief Not support
@ -819,7 +823,7 @@ namespace Exiv2 {
@return Number of bytes read from the memory block successfully;<BR>
0 if failure;
*/
size_t read(byte* buf, size_t 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.
@ -843,7 +847,7 @@ namespace Exiv2 {
@note The write access is only supported by http, https, ssh.
*/
void transfer(BasicIo& src) override;
void transfer(BasicIo &src) override;
int seek(int64_t offset, Position pos) override;
@ -851,7 +855,7 @@ namespace Exiv2 {
@brief Not support
@return NULL
*/
byte* mmap(bool /*isWriteable*/ = false) override;
byte *mmap(bool /*isWriteable*/ = false) override;
/*!
@brief Not support
@return 0
@ -871,14 +875,14 @@ namespace Exiv2 {
-1 if failure;
*/
size_t size() const override;
//!Returns true if the memory area is allocated.
//! Returns true if the memory area is allocated.
bool isopen() const override;
//!Always returns 0
//! Always returns 0
int error() const override;
//!Returns true if the IO position has reached the end, otherwise false.
//! Returns true if the IO position has reached the end, otherwise false.
bool eof() const override;
//!Returns the URL of the file.
const std::string& path() const noexcept override;
//! Returns the URL of the file.
const std::string &path() const noexcept override;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
@ -892,17 +896,16 @@ namespace Exiv2 {
//@}
protected:
// Pimpl idiom
class Impl;
//! Pointer to implementation
std::unique_ptr<Impl> p_;
}; // class RemoteIo
}; // class RemoteIo
/*!
/*!
@brief Provides the http read/write access for the RemoteIo.
*/
class EXIV2API HttpIo : public RemoteIo {
*/
class EXIV2API HttpIo : public RemoteIo {
public:
//! @name Creators
//@{
@ -915,25 +918,25 @@ namespace Exiv2 {
divided into the memory blocks. These blocks are populated
on demand from the server, so it avoids copying the complete file.
*/
explicit HttpIo(const std::string& url, size_t blockSize = 1024);
explicit HttpIo(const std::string &url, size_t blockSize = 1024);
// NOT IMPLEMENTED
//! Copy constructor
HttpIo(HttpIo& rhs) = delete;
HttpIo(HttpIo &rhs) = delete;
//! Assignment operator
HttpIo& operator=(const HttpIo& rhs) = delete;
HttpIo &operator=(const HttpIo &rhs) = delete;
private:
// Pimpl idiom
class HttpImpl;
};
};
#ifdef EXV_USE_CURL
/*!
/*!
@brief Provides the http, https read/write access and ftp read access for the RemoteIo.
This class is based on libcurl.
*/
class EXIV2API CurlIo : public RemoteIo {
*/
class EXIV2API CurlIo : public RemoteIo {
public:
//! @name Creators
//@{
@ -946,53 +949,53 @@ namespace Exiv2 {
on demand from the server, so it avoids copying the complete file.
@throw Error if it is unable to init curl pointer.
*/
explicit CurlIo(const std::string& url, size_t blockSize = 0);
explicit CurlIo(const std::string &url, size_t blockSize = 0);
/*!
@brief Write access is only available for some protocols. This method
will call RemoteIo::write(const byte* data, long wcount) if the write
access is available for the protocol. Otherwise, it throws the Error.
*/
size_t write(const byte* data, size_t 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.
*/
size_t write(BasicIo& src) override;
size_t write(BasicIo &src) override;
// NOT IMPLEMENTED
//! Copy constructor
CurlIo(CurlIo& rhs) = delete;
CurlIo(CurlIo &rhs) = delete;
//! Assignment operator
CurlIo& operator=(const CurlIo& rhs) = delete;
CurlIo &operator=(const CurlIo &rhs) = delete;
protected:
// Pimpl idiom
class CurlImpl;
};
};
#endif
// *****************************************************************************
// template, inline and free functions
/*!
/*!
@brief Read file \em path into a DataBuf, which is returned.
@return Buffer containing the file.
@throw Error In case of failure.
*/
EXIV2API DataBuf readFile(const std::string& path);
/*!
EXIV2API DataBuf readFile(const std::string &path);
/*!
@brief Write DataBuf \em buf to file \em path.
@return Return the number of bytes written.
@throw Error In case of failure.
*/
EXIV2API size_t 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
*/
EXIV2API size_t curlWriter(char* data, size_t size, size_t nmemb, std::string* writerData);
*/
EXIV2API size_t curlWriter(char *data, size_t size, size_t nmemb, std::string *writerData);
#endif
} // namespace Exiv2
#endif // #ifndef BASICIO_HPP_

@ -12,18 +12,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
EXIV2API bool enableBMFF(bool enable = true);
namespace Exiv2 {
EXIV2API bool enableBMFF(bool enable = true);
}
#ifdef EXV_ENABLE_BMFF
namespace Exiv2
{
struct Iloc
{
explicit Iloc(uint32_t ID = 0, uint32_t start = 0, uint32_t length = 0)
: ID_(ID), start_(start), length_(length){};
namespace Exiv2 {
struct Iloc {
explicit Iloc(uint32_t ID = 0, uint32_t start = 0, uint32_t length = 0) : ID_(ID), start_(start), length_(length){};
virtual ~Iloc() = default;
uint32_t ID_;
@ -31,16 +27,15 @@ namespace Exiv2
uint32_t length_;
std::string toString() const;
}; // class Iloc
}; // class Iloc
// *****************************************************************************
// class definitions
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access BMFF images.
*/
class EXIV2API BmffImage : public Image
{
class EXIV2API BmffImage : public Image {
public:
//! @name Creators
//@{
@ -70,7 +65,7 @@ namespace Exiv2
@
*/
void parseTiff(uint32_t root_tag, uint64_t length);
void parseTiff(uint32_t root_tag, uint64_t length,uint64_t start);
void parseTiff(uint32_t root_tag, uint64_t length, uint64_t start);
//@}
//@{
@ -80,7 +75,7 @@ namespace Exiv2
@param start offset in file
@
*/
void parseXmp(uint64_t length,uint64_t start);
void parseXmp(uint64_t length, uint64_t start);
//@}
//@{
@ -96,14 +91,8 @@ namespace Exiv2
@param relative_position Location of the start of image data in the file,
relative to the current file position indicator.
*/
void parseCr3Preview(DataBuf &data,
std::ostream &out,
bool bTrace,
uint8_t version,
size_t width_offset,
size_t height_offset,
size_t size_offset,
size_t relative_position);
void parseCr3Preview(DataBuf& data, std::ostream& out, bool bTrace, uint8_t version, size_t width_offset,
size_t height_offset, size_t size_offset, size_t relative_position);
//@}
//! @name Manipulators
@ -133,11 +122,9 @@ namespace Exiv2
@return address of next box
@warning This function should only be called by readMetadata()
*/
long boxHandler(std::ostream& out, Exiv2::PrintStructureOption option,
const long pbox_end, int depth);
std::string indent(int i)
{
return std::string(2*i,' ');
long boxHandler(std::ostream& out, Exiv2::PrintStructureOption option, const long pbox_end, int depth);
std::string indent(int i) {
return std::string(2 * i, ' ');
}
uint32_t fileType_{0};
@ -159,21 +146,21 @@ namespace Exiv2
static bool fullBox(uint32_t box);
static std::string uuidName(Exiv2::DataBuf& uuid);
}; // class BmffImage
}; // class BmffImage
// *****************************************************************************
// template, inline and free functions
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new BMFF instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newBmffInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newBmffInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a BMFF image.
EXIV2API bool isBmffType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a BMFF image.
EXIV2API bool isBmffType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // EXV_ENABLE_BMFF

@ -17,15 +17,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access Windows bitmaps. This is just a stub - we only
read width and height.
*/
class EXIV2API BmpImage : public Image {
class EXIV2API BmpImage : public Image {
public:
//! @name NOT Implemented
//@{
@ -73,22 +72,22 @@ namespace Exiv2 {
//@{
std::string mimeType() const override;
//@}
}; // class BmpImage
}; // class BmpImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new BmpImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newBmpInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newBmpInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Windows Bitmap image.
EXIV2API bool isBmpType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a Windows Bitmap image.
EXIV2API bool isBmpType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -17,32 +17,32 @@
///// Start of platform macros /////////
#if defined(__MINGW32__) || defined(__MINGW64__)
# ifndef __MING__
# define __MING__ 1
# endif
# ifndef __MINGW__
# define __MINGW__ 1
# endif
#ifndef __MING__
#define __MING__ 1
#endif
#ifndef __MINGW__
#define __MINGW__ 1
#endif
#endif
#ifndef __CYGWIN__
# if defined(__CYGWIN32__) || defined(__CYGWIN64__)
# define __CYGWIN__ 1
# endif
#if defined(__CYGWIN32__) || defined(__CYGWIN64__)
#define __CYGWIN__ 1
#endif
#endif
#ifndef __LITTLE_ENDIAN__
# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define __LITTLE_ENDIAN__ 1
# endif
# endif
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__ 1
#endif
#endif
#endif
#ifndef __LITTLE_ENDIAN__
# if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW__)
# define __LITTLE_ENDIAN__ 1
# endif
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW__)
#define __LITTLE_ENDIAN__ 1
#endif
#endif
/*
@ -50,25 +50,25 @@
you must -library=stdcxx4 along with these inclusions below
*/
#if defined(OS_SOLARIS)
# include <string.h>
# include <strings.h>
# include <math.h>
# if defined(__cplusplus)
# include <ios>
# include <fstream>
# endif
#include <math.h>
#include <string.h>
#include <strings.h>
#if defined(__cplusplus)
#include <fstream>
#include <ios>
#endif
#endif
///// End of platform macros /////////
///// Path separator macros /////
#ifndef EXV_SEPARATOR_STR
# if defined(WIN32) && !defined(__CYGWIN__)
# define EXV_SEPARATOR_STR "\\"
# define EXV_SEPARATOR_CHR '\\'
# else
# define EXV_SEPARATOR_STR "/"
# define EXV_SEPARATOR_CHR '/'
# endif
#if defined(WIN32) && !defined(__CYGWIN__)
#define EXV_SEPARATOR_STR "\\"
#define EXV_SEPARATOR_CHR '\\'
#else
#define EXV_SEPARATOR_STR "/"
#define EXV_SEPARATOR_CHR '/'
#endif
#endif
//////////////////////////////////////

@ -24,40 +24,39 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class IptcData;
class XmpData;
class ExifData;
class IptcData;
class XmpData;
// *****************************************************************************
// free functions, template and inline definitions
//! Convert (copy) Exif tags to XMP properties.
EXIV2API void copyExifToXmp(const ExifData& exifData, XmpData& xmpData);
//! Convert (move) Exif tags to XMP properties, remove converted Exif tags.
EXIV2API void moveExifToXmp(ExifData& exifData, XmpData& xmpData);
//! Convert (copy) Exif tags to XMP properties.
EXIV2API void copyExifToXmp(const ExifData& exifData, XmpData& xmpData);
//! Convert (move) Exif tags to XMP properties, remove converted Exif tags.
EXIV2API void moveExifToXmp(ExifData& exifData, XmpData& xmpData);
//! Convert (copy) XMP properties to Exif tags.
EXIV2API void copyXmpToExif(const XmpData& xmpData, ExifData& exifData);
//! Convert (move) XMP properties to Exif tags, remove converted XMP properties.
EXIV2API void moveXmpToExif(XmpData& xmpData, ExifData& exifData);
//! Convert (copy) XMP properties to Exif tags.
EXIV2API void copyXmpToExif(const XmpData& xmpData, ExifData& exifData);
//! Convert (move) XMP properties to Exif tags, remove converted XMP properties.
EXIV2API void moveXmpToExif(XmpData& xmpData, ExifData& exifData);
//! Detect which metadata are newer and perform a copy in appropriate direction.
EXIV2API void syncExifWithXmp(ExifData& exifData, XmpData& xmpData);
//! Detect which metadata are newer and perform a copy in appropriate direction.
EXIV2API void syncExifWithXmp(ExifData& exifData, XmpData& xmpData);
//! Convert (copy) IPTC datasets to XMP properties.
EXIV2API void copyIptcToXmp(const IptcData& iptcData, XmpData& xmpData, const char* iptcCharset = nullptr);
//! Convert (move) IPTC datasets to XMP properties, remove converted IPTC datasets.
EXIV2API void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData, const char* iptcCharset = nullptr);
//! Convert (copy) IPTC datasets to XMP properties.
EXIV2API void copyIptcToXmp(const IptcData& iptcData, XmpData& xmpData, const char* iptcCharset = nullptr);
//! Convert (move) IPTC datasets to XMP properties, remove converted IPTC datasets.
EXIV2API void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData, const char* iptcCharset = nullptr);
//! Convert (copy) XMP properties to IPTC datasets.
EXIV2API void copyXmpToIptc(const XmpData& xmpData, IptcData& iptcData);
//! Convert (move) XMP properties to IPTC tags, remove converted XMP properties.
EXIV2API void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData);
//! Convert (copy) XMP properties to IPTC datasets.
EXIV2API void copyXmpToIptc(const XmpData& xmpData, IptcData& iptcData);
//! Convert (move) XMP properties to IPTC tags, remove converted XMP properties.
EXIV2API void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData);
/*!
/*!
@brief Convert character encoding of \em str from \em from to \em to.
If the function succeeds, \em str contains the result string.
@ -91,7 +90,7 @@ namespace Exiv2 {
understood by \c iconv_open(3).
@return Return \c true if the conversion was successful, else \c false.
*/
EXIV2API bool convertStringCharset(std::string& str, const char* from, const char* to);
EXIV2API bool convertStringCharset(std::string& str, const char* from, const char* to);
} // namespace Exiv2

@ -17,15 +17,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Canon CR2 images. Exif metadata
is supported directly, IPTC is read from the Exif data, if present.
*/
class EXIV2API Cr2Image : public Image {
class EXIV2API Cr2Image : public Image {
public:
//! @name Creators
//@{
@ -80,56 +79,44 @@ namespace Exiv2 {
Cr2Image& operator=(const Cr2Image& rhs) = delete;
//@}
}; // class Cr2Image
}; // class Cr2Image
/*!
/*!
@brief Stateless parser class for data in CR2 format. Images use this
class to decode and encode CR2 data.
See class TiffParser for details.
*/
class EXIV2API Cr2Parser {
class EXIV2API Cr2Parser {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
with data in CR2 format to the provided metadata containers.
See TiffParser::decode().
*/
static ByteOrder decode(
ExifData& exifData,
IptcData& iptcData,
XmpData& xmpData,
const byte* pData,
size_t size
);
static ByteOrder decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size);
/*!
@brief Encode metadata from the provided metadata to CR2 format.
See TiffParser::encode().
*/
static WriteMethod encode(BasicIo& io,
const byte* pData,
size_t size,
ByteOrder byteOrder,
const ExifData& exifData,
const IptcData& iptcData,
const XmpData& xmpData
);
static WriteMethod encode(BasicIo& io, const byte* pData, size_t size, ByteOrder byteOrder, const ExifData& exifData,
const IptcData& iptcData, const XmpData& xmpData);
}; // class Cr2Parser
}; // class Cr2Parser
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new Cr2Image instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newCr2Instance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newCr2Instance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a CR2 image.
EXIV2API bool isCr2Type(BasicIo& iIo, bool advance);
//! Check if the file iIo is a CR2 image.
EXIV2API bool isCr2Type(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -3,7 +3,8 @@
/*!
@brief Class CrwImage to access Canon CRW images.<BR>
References:<BR>
<a href="http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html">The Canon RAW (CRW) File Format</a> by Phil Harvey
<a href="http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html">The Canon RAW (CRW) File Format</a> by
Phil Harvey
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 28-Aug-05, ahu: created
@ -20,20 +21,19 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class IptcData;
class ExifData;
class IptcData;
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Canon CRW images. Only Exif metadata and a
comment are supported. CRW format does not contain IPTC metadata.
*/
class EXIV2API CrwImage : public Image {
class EXIV2API CrwImage : public Image {
public:
//! @name Creators
//@{
@ -81,12 +81,12 @@ namespace Exiv2 {
CrwImage& operator=(const CrwImage& rhs) = delete;
//@}
}; // class CrwImage
}; // class CrwImage
/*!
/*!
Stateless parser class for Canon CRW images (Ciff format).
*/
class EXIV2API CrwParser {
*/
class EXIV2API CrwParser {
public:
/*!
@brief Decode metadata from a Canon CRW image in data buffer \em pData
@ -118,28 +118,24 @@ namespace Exiv2 {
@throw Error If the metadata from the CRW image cannot be encoded.
*/
static void encode(Blob& blob,
const byte* pData,
size_t size,
const CrwImage* pCrwImage
);
static void encode(Blob& blob, const byte* pData, size_t size, const CrwImage* pCrwImage);
}; // class CrwParser
}; // class CrwParser
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new CrwImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newCrwInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newCrwInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a CRW image.
EXIV2API bool isCrwType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a CRW image.
EXIV2API bool isCrwType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -16,19 +16,18 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
//! Details of an IPTC record.
struct EXIV2API RecordInfo {
//! Details of an IPTC record.
struct EXIV2API RecordInfo {
uint16_t recordId_; //!< Record id
const char* name_; //!< Record name (one word)
const char* desc_; //!< Record description
};
};
//! Details of an IPTC dataset.
struct EXIV2API DataSet {
//! Details of an IPTC dataset.
struct EXIV2API DataSet {
uint16_t number_; //!< Dataset number
const char* name_; //!< Dataset name
const char* title_; //!< Dataset title or label
@ -40,10 +39,10 @@ namespace Exiv2 {
TypeId type_; //!< Exiv2 default type
uint16_t recordId_; //!< Record id
const char* photoshop_; //!< Photoshop string
}; // struct DataSet
}; // struct DataSet
//! IPTC dataset reference, implemented as a static class.
class EXIV2API IptcDataSets {
//! IPTC dataset reference, implemented as a static class.
class EXIV2API IptcDataSets {
public:
/*!
@name Record identifiers
@ -237,12 +236,12 @@ namespace Exiv2 {
static const DataSet* const records_[];
}; // class IptcDataSets
}; // class IptcDataSets
/*!
/*!
@brief Concrete keys for IPTC metadata.
*/
class EXIV2API IptcKey : public Key {
class EXIV2API IptcKey : public Key {
public:
//! Shortcut for an %IptcKey auto pointer.
using UniquePtr = std::unique_ptr<IptcKey>;
@ -271,7 +270,6 @@ namespace Exiv2 {
~IptcKey() override = default;
//@}
//! @name Accessors
//@{
std::string key() const override;
@ -317,18 +315,18 @@ namespace Exiv2 {
uint16_t record_; //!< Record value
std::string key_; //!< Key
}; // class IptcKey
}; // class IptcKey
/*!
/*!
@brief typedef for string:string map
*/
using Dictionary = std::map<std::string, std::string>;
using Dictionary = std::map<std::string, std::string>;
// *****************************************************************************
// free functions
// *****************************************************************************
// free functions
//! Output operator for dataSet
EXIV2API std::ostream& operator<<(std::ostream& os, const DataSet& dataSet);
//! Output operator for dataSet
EXIV2API std::ostream& operator<<(std::ostream& os, const DataSet& dataSet);
} // namespace Exiv2

@ -15,79 +15,78 @@
#include "exif.hpp"
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class ExifData;
//! Return the orientation of the image
EXIV2API ExifData::const_iterator orientation(const ExifData& ed);
//! Return the ISO speed used to shoot the image
EXIV2API ExifData::const_iterator isoSpeed(const ExifData& ed);
//! Return the date and time when the original image data was generated
EXIV2API ExifData::const_iterator dateTimeOriginal(const ExifData& ed);
//! Return the flash bias value
EXIV2API ExifData::const_iterator flashBias(const ExifData& ed);
//! Return the exposure mode setting
EXIV2API ExifData::const_iterator exposureMode(const ExifData& ed);
//! Return the scene mode setting
EXIV2API ExifData::const_iterator sceneMode(const ExifData& ed);
//! Return the macro mode setting
EXIV2API ExifData::const_iterator macroMode(const ExifData& ed);
//! Return the image quality setting
EXIV2API ExifData::const_iterator imageQuality(const ExifData& ed);
//! Return the white balance setting
EXIV2API ExifData::const_iterator whiteBalance(const ExifData& ed);
//! Return the name of the lens used
EXIV2API ExifData::const_iterator lensName(const ExifData& ed);
//! Return the saturation level
EXIV2API ExifData::const_iterator saturation(const ExifData& ed);
//! Return the sharpness level
EXIV2API ExifData::const_iterator sharpness(const ExifData& ed);
//! Return the contrast level
EXIV2API ExifData::const_iterator contrast(const ExifData& ed);
//! Return the scene capture type
EXIV2API ExifData::const_iterator sceneCaptureType(const ExifData& ed);
//! Return the metering mode setting
EXIV2API ExifData::const_iterator meteringMode(const ExifData& ed);
//! Return the camera make
EXIV2API ExifData::const_iterator make(const ExifData& ed);
//! Return the camera model
EXIV2API ExifData::const_iterator model(const ExifData& ed);
//! Return the exposure time
EXIV2API ExifData::const_iterator exposureTime(const ExifData& ed);
//! Return the F number
EXIV2API ExifData::const_iterator fNumber(const ExifData& ed);
//! Return the shutter speed value
EXIV2API ExifData::const_iterator shutterSpeedValue(const ExifData& ed);
//! Return the aperture value
EXIV2API ExifData::const_iterator apertureValue(const ExifData& ed);
//! Return the brightness value
EXIV2API ExifData::const_iterator brightnessValue(const ExifData& ed);
//! Return the exposure bias value
EXIV2API ExifData::const_iterator exposureBiasValue(const ExifData& ed);
//! Return the max aperture value
EXIV2API ExifData::const_iterator maxApertureValue(const ExifData& ed);
//! Return the subject distance
EXIV2API ExifData::const_iterator subjectDistance(const ExifData& ed);
//! Return the kind of light source
EXIV2API ExifData::const_iterator lightSource(const ExifData& ed);
//! Return the status of flash
EXIV2API ExifData::const_iterator flash(const ExifData& ed);
//! Return the camera serial number
EXIV2API ExifData::const_iterator serialNumber(const ExifData& ed);
//! Return the focal length setting
EXIV2API ExifData::const_iterator focalLength(const ExifData& ed);
//! Return the subject location and area
EXIV2API ExifData::const_iterator subjectArea(const ExifData& ed);
//! Return the flash energy
EXIV2API ExifData::const_iterator flashEnergy(const ExifData& ed);
//! Return the exposure index
EXIV2API ExifData::const_iterator exposureIndex(const ExifData& ed);
//! Return the image sensor type
EXIV2API ExifData::const_iterator sensingMethod(const ExifData& ed);
//! Return the AF point
EXIV2API ExifData::const_iterator afPoint(const ExifData& ed);
//! Return the orientation of the image
EXIV2API ExifData::const_iterator orientation(const ExifData& ed);
//! Return the ISO speed used to shoot the image
EXIV2API ExifData::const_iterator isoSpeed(const ExifData& ed);
//! Return the date and time when the original image data was generated
EXIV2API ExifData::const_iterator dateTimeOriginal(const ExifData& ed);
//! Return the flash bias value
EXIV2API ExifData::const_iterator flashBias(const ExifData& ed);
//! Return the exposure mode setting
EXIV2API ExifData::const_iterator exposureMode(const ExifData& ed);
//! Return the scene mode setting
EXIV2API ExifData::const_iterator sceneMode(const ExifData& ed);
//! Return the macro mode setting
EXIV2API ExifData::const_iterator macroMode(const ExifData& ed);
//! Return the image quality setting
EXIV2API ExifData::const_iterator imageQuality(const ExifData& ed);
//! Return the white balance setting
EXIV2API ExifData::const_iterator whiteBalance(const ExifData& ed);
//! Return the name of the lens used
EXIV2API ExifData::const_iterator lensName(const ExifData& ed);
//! Return the saturation level
EXIV2API ExifData::const_iterator saturation(const ExifData& ed);
//! Return the sharpness level
EXIV2API ExifData::const_iterator sharpness(const ExifData& ed);
//! Return the contrast level
EXIV2API ExifData::const_iterator contrast(const ExifData& ed);
//! Return the scene capture type
EXIV2API ExifData::const_iterator sceneCaptureType(const ExifData& ed);
//! Return the metering mode setting
EXIV2API ExifData::const_iterator meteringMode(const ExifData& ed);
//! Return the camera make
EXIV2API ExifData::const_iterator make(const ExifData& ed);
//! Return the camera model
EXIV2API ExifData::const_iterator model(const ExifData& ed);
//! Return the exposure time
EXIV2API ExifData::const_iterator exposureTime(const ExifData& ed);
//! Return the F number
EXIV2API ExifData::const_iterator fNumber(const ExifData& ed);
//! Return the shutter speed value
EXIV2API ExifData::const_iterator shutterSpeedValue(const ExifData& ed);
//! Return the aperture value
EXIV2API ExifData::const_iterator apertureValue(const ExifData& ed);
//! Return the brightness value
EXIV2API ExifData::const_iterator brightnessValue(const ExifData& ed);
//! Return the exposure bias value
EXIV2API ExifData::const_iterator exposureBiasValue(const ExifData& ed);
//! Return the max aperture value
EXIV2API ExifData::const_iterator maxApertureValue(const ExifData& ed);
//! Return the subject distance
EXIV2API ExifData::const_iterator subjectDistance(const ExifData& ed);
//! Return the kind of light source
EXIV2API ExifData::const_iterator lightSource(const ExifData& ed);
//! Return the status of flash
EXIV2API ExifData::const_iterator flash(const ExifData& ed);
//! Return the camera serial number
EXIV2API ExifData::const_iterator serialNumber(const ExifData& ed);
//! Return the focal length setting
EXIV2API ExifData::const_iterator focalLength(const ExifData& ed);
//! Return the subject location and area
EXIV2API ExifData::const_iterator subjectArea(const ExifData& ed);
//! Return the flash energy
EXIV2API ExifData::const_iterator flashEnergy(const ExifData& ed);
//! Return the exposure index
EXIV2API ExifData::const_iterator exposureIndex(const ExifData& ed);
//! Return the image sensor type
EXIV2API ExifData::const_iterator sensingMethod(const ExifData& ed);
//! Return the AF point
EXIV2API ExifData::const_iterator afPoint(const ExifData& ed);
} // namespace Exiv2

@ -4,10 +4,14 @@
@file epsimage.hpp
@brief EPS image.
<br>References:
<br>[1] <a href="http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf">Adobe PostScript Language Document Structuring Conventions Specification, Version 3.0</a>, September 1992
<br>[2] <a href="http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf">Adobe Encapsulated PostScript File Format Specification, Version 3.0</a>, May 1992
<br>[3] <a href="http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf">Adobe XMP Specification Part 3: Storage in Files</a>, July 2010
<br>[4] <a href="http://groups.google.com/group/adobe.illustrator.windows/msg/0a9d7b1244b59062">Re: Thumbnail data format in ai file</a>, Dec 2003
<br>[1] <a href="http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf">Adobe PostScript
Language Document Structuring Conventions Specification, Version 3.0</a>, September 1992 <br>[2] <a
href="http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf">Adobe Encapsulated PostScript File Format
Specification, Version 3.0</a>, May 1992 <br>[3] <a
href="http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart3.pdf">Adobe XMP Specification
Part 3: Storage in Files</a>, July 2010 <br>[4] <a
href="http://groups.google.com/group/adobe.illustrator.windows/msg/0a9d7b1244b59062">Re: Thumbnail data format in ai
file</a>, Dec 2003
@author Michael Ulbrich (mul)
<a href="mailto:mul@rentapacs.de">mul@rentapacs.de</a>
@author Volker Grabsch (vog)
@ -25,16 +29,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access EPS images.
*/
class EXIV2API EpsImage : public Image {
class EXIV2API EpsImage : public Image {
public:
//! @name Creators
//@{
@ -79,22 +81,22 @@ namespace Exiv2
EpsImage& operator=(const EpsImage& rhs) = delete;
//@}
}; // class EpsImage
}; // class EpsImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new EpsImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newEpsInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newEpsInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a EPS image.
EXIV2API bool isEpsType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a EPS image.
EXIV2API bool isEpsType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -22,12 +22,11 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
// *****************************************************************************
// class definitions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class for a log message, used by the library. Applications can set
the log level and provide a customer log message handler (callback
function).
@ -54,8 +53,7 @@ namespace Exiv2
Caveat: The entire log message is not processed in this case. So don't
make that call any logic that always needs to be executed.
*/
class EXIV2API LogMsg
{
class EXIV2API LogMsg {
public:
//! Prevent copy-construction: not implemented.
LogMsg(const LogMsg&) = delete;
@ -65,14 +63,7 @@ namespace Exiv2
@brief Defined log levels. To suppress all log messages, either set the
log level to \c mute or set the log message handler to 0.
*/
enum Level
{
debug = 0,
info = 1,
warn = 2,
error = 3,
mute = 4
};
enum Level { debug = 0, info = 1, warn = 2, error = 3, mute = 4 };
/*!
@brief Type for a log message handler function. The function receives
the log level and message and can process it in an application
@ -127,7 +118,7 @@ namespace Exiv2
// Holds the log message until it is passed to the message handler
std::ostringstream os_;
}; // class LogMsg
}; // class LogMsg
// Macros for simple access
//! Shorthand to create a temp debug log message object and return its ostringstream
@ -153,18 +144,16 @@ namespace Exiv2
#pragma warning(disable : 4275)
#endif
//! Generalised toString function
template <typename charT, typename T>
std::basic_string<charT> toBasicString(const T& arg)
{
//! Generalised toString function
template <typename charT, typename T>
std::basic_string<charT> toBasicString(const T& arg) {
std::basic_ostringstream<charT> os;
os << arg;
return os.str();
}
}
//! Complete list of all Exiv2 error codes
enum class ErrorCode
{
//! Complete list of all Exiv2 error codes
enum class ErrorCode {
kerSuccess = 0,
kerGeneralError,
kerErrorMessage,
@ -230,14 +219,13 @@ namespace Exiv2
kerMallocFailed,
kerErrorCount,
};
};
/*!
/*!
@brief Simple error class used for exceptions. An output operator is
provided to print errors to a stream.
*/
class EXIV2API Error : public std::exception
{
class EXIV2API Error : public std::exception {
public:
//! @name Creators
//@{
@ -246,27 +234,24 @@ namespace Exiv2
//! Constructor taking an error code and one argument
template <typename A>
Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1))
{
Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1)) {
setMsg(1);
}
//! Constructor taking an error code and two arguments
template <typename A, typename B>
Error(ErrorCode code, const A& arg1, const B& arg2)
: code_(code), arg1_(toBasicString<char>(arg1)), arg2_(toBasicString<char>(arg2))
{
Error(ErrorCode code, const A& arg1, const B& arg2) :
code_(code), arg1_(toBasicString<char>(arg1)), arg2_(toBasicString<char>(arg2)) {
setMsg(2);
}
//! Constructor taking an error code and three arguments
template <typename A, typename B, typename C>
Error(ErrorCode code, const A& arg1, const B& arg2, const C& arg3)
: code_(code),
Error(ErrorCode code, const A& arg1, const B& arg2, const C& arg3) :
code_(code),
arg1_(toBasicString<char>(arg1)),
arg2_(toBasicString<char>(arg2)),
arg3_(toBasicString<char>(arg3))
{
arg3_(toBasicString<char>(arg3)) {
setMsg(3);
}
@ -297,13 +282,12 @@ namespace Exiv2
const std::string arg2_; //!< Second argument
const std::string arg3_; //!< Third argument
std::string msg_; //!< Complete error message
}; // class BasicError
}; // class BasicError
//! %Error output operator
inline std::ostream& operator<<(std::ostream& os, const Error& error)
{
//! %Error output operator
inline std::ostream& operator<<(std::ostream& os, const Error& error) {
return os << error.what();
}
}
#ifdef _MSC_VER
#pragma warning(default : 4275)

@ -27,20 +27,21 @@
The <b>libexiv2</b> API consists of the objects of this namespace.
*/
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class ExifData;
// *****************************************************************************
// class definitions
/*!
/*!
@brief An Exif metadatum, consisting of an ExifKey and a Value and
methods to manipulate these.
*/
class EXIV2API Exifdatum : public Metadatum {
template<typename T> friend Exifdatum& setValue(Exifdatum&, const T&);
class EXIV2API Exifdatum : public Metadatum {
template <typename T>
friend Exifdatum& setValue(Exifdatum&, const T&);
public:
//! @name Creators
//@{
@ -199,9 +200,9 @@ namespace Exiv2 {
ExifKey::UniquePtr key_; //!< Key
Value::UniquePtr value_; //!< Value
}; // class Exifdatum
}; // class Exifdatum
/*!
/*!
@brief Access to a Exif %thumbnail image. This class provides higher level
accessors to the thumbnail image that is optionally embedded in IFD1
of the Exif data. These methods do not write to the Exif metadata.
@ -212,7 +213,7 @@ namespace Exiv2 {
class only provides access to the Exif thumbnail as specified in the
Exif standard.
*/
class EXIV2API ExifThumbC {
class EXIV2API ExifThumbC {
public:
//! @name Creators
//@{
@ -254,9 +255,9 @@ namespace Exiv2 {
// DATA
const ExifData& exifData_; //!< Const reference to the Exif metadata.
}; // class ExifThumb
}; // class ExifThumb
/*!
/*!
@brief Access and modify an Exif %thumbnail image. This class implements
manipulators to set and erase the thumbnail image that is optionally
embedded in IFD1 of the Exif data. Accessors are provided by the
@ -267,7 +268,7 @@ namespace Exiv2 {
class only provides access to the Exif thumbnail as specified in the
Exif standard.
*/
class EXIV2API ExifThumb : public ExifThumbC {
class EXIV2API ExifThumb : public ExifThumbC {
public:
//! @name Creators
//@{
@ -351,12 +352,12 @@ namespace Exiv2 {
// DATA
ExifData& exifData_; //!< Reference to the related Exif metadata.
}; // class ExifThumb
}; // class ExifThumb
//! Container type to hold all metadata
using ExifMetadata = std::list<Exifdatum>;
//! Container type to hold all metadata
using ExifMetadata = std::list<Exifdatum>;
/*!
/*!
@brief A container for Exif data. This is a top-level class of the %Exiv2
library. The container holds Exifdatum objects.
@ -367,8 +368,8 @@ namespace Exiv2 {
- write Exif data to JPEG files
- extract Exif metadata to files, insert from these files
- extract and delete Exif thumbnail (JPEG and TIFF thumbnails)
*/
class EXIV2API ExifData {
*/
class EXIV2API ExifData {
public:
//! ExifMetadata iterator type
using iterator = ExifMetadata::iterator;
@ -424,9 +425,13 @@ namespace Exiv2 {
//! Sort metadata by tag
void sortByTag();
//! Begin of the metadata
iterator begin() { return exifMetadata_.begin(); }
iterator begin() {
return exifMetadata_.begin();
}
//! End of the metadata
iterator end() { return exifMetadata_.end(); }
iterator end() {
return exifMetadata_.end();
}
/*!
@brief Find the first Exifdatum with the given \em key, return an
iterator to it.
@ -437,32 +442,40 @@ namespace Exiv2 {
//! @name Accessors
//@{
//! Begin of the metadata
const_iterator begin() const { return exifMetadata_.begin(); }
const_iterator begin() const {
return exifMetadata_.begin();
}
//! End of the metadata
const_iterator end() const { return exifMetadata_.end(); }
const_iterator end() const {
return exifMetadata_.end();
}
/*!
@brief Find the first Exifdatum with the given \em key, return a const
iterator to it.
*/
const_iterator findKey(const ExifKey& key) const;
//! Return true if there is no Exif metadata
bool empty() const { return exifMetadata_.empty(); }
bool empty() const {
return exifMetadata_.empty();
}
//! Get the number of metadata entries
size_t count() const { return exifMetadata_.size(); }
size_t count() const {
return exifMetadata_.size();
}
//@}
private:
// DATA
ExifMetadata exifMetadata_;
}; // class ExifData
}; // class ExifData
/*!
/*!
@brief Stateless parser class for Exif data. Images use this class to
decode and encode binary Exif data.
@note Encode is lossy and is not the inverse of decode.
*/
class EXIV2API ExifParser {
class EXIV2API ExifParser {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
@ -516,13 +529,7 @@ namespace Exiv2 {
@return Write method used.
*/
static WriteMethod encode(
Blob& blob,
const byte* pData,
size_t size,
ByteOrder byteOrder,
const ExifData& exifData
);
static WriteMethod encode(Blob& blob, const byte* pData, size_t size, ByteOrder byteOrder, const ExifData& exifData);
/*!
@brief Encode metadata from the provided metadata to Exif format.
@ -543,16 +550,11 @@ namespace Exiv2 {
@param byteOrder Byte order to use.
@param exifData Exif metadata container.
*/
static void encode(
Blob& blob,
ByteOrder byteOrder,
const ExifData& exifData
)
{
static void encode(Blob& blob, ByteOrder byteOrder, const ExifData& exifData) {
encode(blob, nullptr, 0, byteOrder, exifData);
}
}; // class ExifParser
}; // class ExifParser
} // namespace Exiv2

@ -5,14 +5,14 @@
// *****************************************************************************
// included header files
#include "exiv2/config.h"
#include "exiv2/datasets.hpp"
#include "exiv2/basicio.hpp"
#include "exiv2/bmffimage.hpp"
#include "exiv2/bmpimage.hpp"
#include "exiv2/config.h"
#include "exiv2/convert.hpp"
#include "exiv2/cr2image.hpp"
#include "exiv2/crwimage.hpp"
#include "exiv2/datasets.hpp"
#include "exiv2/easyaccess.hpp"
#include "exiv2/epsimage.hpp"
#include "exiv2/error.hpp"
@ -49,4 +49,4 @@
#include "exiv2/xmp_exiv2.hpp"
#include "exiv2/xmpsidecar.hpp"
#endif//ifndef EXIV2_HPP_
#endif // ifndef EXIV2_HPP_

@ -3,58 +3,43 @@
#ifndef FUTILS_HPP_
#define FUTILS_HPP_
#include "exiv2lib_export.h"
#include "config.h"
#include "exiv2lib_export.h"
#include <string>
// namespace extensions
namespace Exiv2
{
//! the name of environmental variables.
enum EnVar
{
envHTTPPOST = 0,
envTIMEOUT = 1
};
//! the collection of protocols.
enum Protocol
{
pFile = 0,
pHttp,
pFtp,
pHttps,
pSftp,
pFileUri,
pDataUri,
pStdin
};
// *********************************************************************
// free functions
/*!
namespace Exiv2 {
//! the name of environmental variables.
enum EnVar { envHTTPPOST = 0, envTIMEOUT = 1 };
//! the collection of protocols.
enum Protocol { pFile = 0, pHttp, pFtp, pHttps, pSftp, pFileUri, pDataUri, pStdin };
// *********************************************************************
// free functions
/*!
@brief Return the value of environmental variable.
@param[in] var The name of environmental variable. Must be a member of the enumeration @ref EnVar.
@return the value of environmental variable. If it's empty, the default value is returned.
@throws std::out_of_range when an unexpected EnVar is given as input.
*/
EXIV2API std::string getEnv(int env_var);
EXIV2API std::string getEnv(int env_var);
/*!
/*!
@brief Encode the input url.
@param str The url needs encoding.
@return the url-encoded version of str.
@note Source: http://www.geekhideout.com/urlcode.shtml
@todo This function can probably be hidden into the implementation details
*/
EXIV2API std::string urlencode(std::string_view str);
EXIV2API std::string urlencode(std::string_view str);
/*!
/*!
@brief Like urlencode(char* str) but accept the input url in the std::string and modify it.
@todo This function can probably be hidden into the implementation details
*/
EXIV2API void urldecode(std::string& str);
EXIV2API void urldecode(std::string& str);
/*!
/*!
@brief Encode in base64 the data in data_buf and put the resulting string in result.
@param data_buf The data need to encode
@param dataLength Size in bytes of the in buffer
@ -65,9 +50,9 @@ namespace Exiv2
@note Source: http://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64
*/
EXIV2API int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize);
EXIV2API int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize);
/*!
/*!
@brief Decode base64 data and put the resulting string in out.
@param in The data need to decode.
@param out The container for the result, it should be large enough to contain the result.
@ -76,16 +61,16 @@ namespace Exiv2
@note Source: https://github.com/davidgaleano/libwebsockets/blob/master/lib/base64-decode.c
*/
EXIV2API size_t base64decode(const char* in, char* out, size_t out_size);
EXIV2API size_t base64decode(const char* in, char* out, size_t out_size);
/*!
/*!
@brief Return the protocol of the path.
@param path The path of file to extract the protocol.
@return the protocol of the path.
*/
EXIV2API Protocol fileProtocol(const std::string& path);
EXIV2API Protocol fileProtocol(const std::string& path);
/*!
/*!
@brief Test if a file exists.
@param path Name of file to verify.
@ -97,18 +82,18 @@ namespace Exiv2
and its type, see stat(2). <b>errno</b> is left unchanged
in case of an error.
*/
EXIV2API bool fileExists(const std::string& path);
EXIV2API bool fileExists(const std::string& path);
/*!
/*!
@brief Return a system error message and the error code (errno).
See %strerror(3).
*/
EXIV2API std::string strError();
EXIV2API std::string strError();
//! @brief Return the path of the current process.
EXIV2API std::string getProcessPath();
//! @brief Return the path of the current process.
EXIV2API std::string getProcessPath();
/*!
/*!
@brief A container for URL components. It also provides the method to parse a
URL to get the protocol, host, path, port, querystring, username, password.
@ -116,8 +101,7 @@ namespace Exiv2
@todo This class can probably be hidden from the API
*/
class Uri
{
class Uri {
public:
// DATA
std::string QueryString; //!< URL query string
@ -133,7 +117,7 @@ namespace Exiv2
/// @brief Decode the url components.
static void EXIV2API Decode(Uri& uri);
};
};
} // namespace Exiv2

@ -12,15 +12,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw GIF images. Exif/IPTC metadata are supported
directly.
*/
class EXIV2API GifImage : public Image {
class EXIV2API GifImage : public Image {
public:
//! @name NOT Implemented
//@{
@ -77,22 +76,22 @@ namespace Exiv2 {
std::string mimeType() const override;
//@}
}; // class GifImage
}; // class GifImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new GifImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newGifInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newGifInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a GIF image.
EXIV2API bool isGifType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a GIF image.
EXIV2API bool isGifType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -7,16 +7,15 @@
#include "datasets.hpp"
namespace Exiv2 {
/*!
/*!
@brief execute an HTTP request
@param request - a Dictionary of headers to send to server
@param response - a Dictionary of response headers (dictionary is filled by the response)
@param errors - a String with an error
@return Server response 200 = OK, 404 = Not Found etc...
*/
EXIV2API int http(Exiv2::Dictionary& request,Exiv2::Dictionary& response,std::string& errors);
}
*/
EXIV2API int http(Exiv2::Dictionary& request, Exiv2::Dictionary& response, std::string& errors);
} // namespace Exiv2
#endif

@ -9,36 +9,35 @@
// included header files
#include "basicio.hpp"
#include "exif.hpp"
#include "iptc.hpp"
#include "image_types.hpp"
#include "iptc.hpp"
#include "xmp_exiv2.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
//! Native preview information. This is meant to be used only by the PreviewManager.
struct NativePreview {
//! Native preview information. This is meant to be used only by the PreviewManager.
struct NativePreview {
size_t position_; //!< Position
size_t size_; //!< Size
size_t width_; //!< Width
size_t height_; //!< Height
std::string filter_; //!< Filter
std::string mimeType_; //!< MIME type
};
};
//! List of native previews. This is meant to be used only by the PreviewManager.
using NativePreviewList = std::vector<NativePreview>;
//! List of native previews. This is meant to be used only by the PreviewManager.
using NativePreviewList = std::vector<NativePreview>;
/*!
/*!
@brief Options for printStructure
*/
enum PrintStructureOption { kpsNone, kpsBasic, kpsXMP, kpsRecursive, kpsIccProfile, kpsIptcErase };
enum PrintStructureOption { kpsNone, kpsBasic, kpsXMP, kpsRecursive, kpsIccProfile, kpsIptcErase };
/*!
/*!
@brief Abstract base class defining the interface for an image. This is
the top-level interface to the Exiv2 library.
@ -48,7 +47,7 @@ namespace Exiv2 {
ImageFactory method. The Image class can then be used to to read, write,
and save metadata.
*/
class EXIV2API Image {
class EXIV2API Image {
public:
//! Image auto_ptr type
using UniquePtr = std::unique_ptr<Image>;
@ -74,7 +73,7 @@ namespace Exiv2 {
@warning This function is not thread safe and intended for exiv2 -pS for debugging.
@warning You may need to put the stream into binary mode (see src/actions.cpp)
*/
virtual void printStructure(std::ostream& out, PrintStructureOption option =kpsNone, int depth=0);
virtual void printStructure(std::ostream& out, PrintStructureOption option = kpsNone, int depth = 0);
/*!
@brief Read all metadata supported by a specific image format from the
image. Before this method is called, the image metadata will be
@ -88,7 +87,7 @@ namespace Exiv2 {
data is not valid (does not look like data of the specific image
type).
*/
virtual void readMetadata() =0;
virtual void readMetadata() = 0;
/*!
@brief Write metadata back to the image.
@ -101,7 +100,7 @@ namespace Exiv2 {
@throw Error if the operation fails
*/
virtual void writeMetadata() =0;
virtual void writeMetadata() = 0;
/*!
@brief Assign new Exif data. The new Exif data is not written
to the image until the writeMetadata() method is called.
@ -191,7 +190,7 @@ namespace Exiv2 {
@param iccProfile DataBuf containing profile (binary)
@param bTestValid - tests that iccProfile contains credible data
*/
virtual void setIccProfile(DataBuf&& iccProfile,bool bTestValid=true);
virtual void setIccProfile(DataBuf&& iccProfile, bool bTestValid = true);
/*!
@brief Erase iccProfile. the profile is not removed from
the actual image until the writeMetadata() method is called.
@ -200,15 +199,16 @@ namespace Exiv2 {
/*!
@brief Returns the status of the ICC profile in the image instance
*/
virtual bool iccProfileDefined()
{
virtual bool iccProfileDefined() {
return iccProfile_.size() != 0;
}
/*!
@brief return iccProfile
*/
virtual const DataBuf& iccProfile() const { return iccProfile_; }
virtual const DataBuf& iccProfile() const {
return iccProfile_;
}
/*!
@brief Copy all existing metadata from source Image. The data is
@ -293,12 +293,13 @@ namespace Exiv2 {
@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).
*/
void printTiffStructure(BasicIo& io,std::ostream& out, PrintStructureOption option,int depth,size_t offset=0);
void printTiffStructure(BasicIo& io, std::ostream& out, PrintStructureOption option, int depth, size_t offset = 0);
/*!
@brief Print out the structure of a TIFF IFD
*/
void printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option, size_t start, bool bSwap, char c, int depth);
void printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option, size_t start, bool bSwap,
char c, int depth);
/*!
@brief is the host platform bigEndian
@ -324,9 +325,9 @@ namespace Exiv2 {
static uint64_t byteSwap(uint64_t value, bool bSwap);
static uint32_t byteSwap(uint32_t value, bool bSwap);
static uint16_t byteSwap(uint16_t value, bool bSwap);
static uint16_t byteSwap2(const DataBuf& buf,size_t offset,bool bSwap) ;
static uint32_t byteSwap4(const DataBuf& buf,size_t offset,bool bSwap) ;
static uint64_t byteSwap8(const DataBuf& buf,size_t offset,bool bSwap) ;
static uint16_t byteSwap2(const DataBuf& buf, size_t offset, bool bSwap);
static uint32_t byteSwap4(const DataBuf& buf, size_t offset, bool bSwap);
static uint64_t byteSwap8(const DataBuf& buf, size_t offset, bool bSwap);
//@}
@ -352,7 +353,7 @@ namespace Exiv2 {
and thus they all have MIME type "image/tiff", although a more
specific MIME type may exist (e.g., "image/x-nikon-nef").
*/
virtual std::string mimeType() const =0;
virtual std::string mimeType() const = 0;
/*!
@brief Return the pixel width of the image.
*/
@ -439,14 +440,15 @@ namespace Exiv2 {
//@}
//! set type support for this image format
void setTypeSupported(ImageType imageType, uint16_t supportedMetadata)
{
void setTypeSupported(ImageType imageType, uint16_t supportedMetadata) {
imageType_ = imageType;
supportedMetadata_ = supportedMetadata;
}
//! set type support for this image format
ImageType imageType() const { return imageType_; }
ImageType imageType() const {
return imageType_;
}
//! @name NOT implemented
//@{
@ -479,26 +481,27 @@ namespace Exiv2 {
// DATA
ImageType imageType_; //!< Image type
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
bool writeXmpFromPacket_;//!< Determines the source when writing XMP
bool writeXmpFromPacket_; //!< Determines the source when writing XMP
ByteOrder byteOrder_; //!< Byte order
std::map<int,std::string> tags_; //!< Map of tags
std::map<int, std::string> tags_; //!< Map of tags
bool init_; //!< Flag marking if map of tags needs to be initialized
}; // class Image
}; // class Image
//! Type for function pointer that creates new Image instances
using NewInstanceFct = Image::UniquePtr (*)(BasicIo::UniquePtr io, bool create);
//! Type for function pointer that checks image types
using IsThisTypeFct = bool (*)(BasicIo& iIo, bool advance);
//! Type for function pointer that creates new Image instances
using NewInstanceFct = Image::UniquePtr (*)(BasicIo::UniquePtr io, bool create);
//! Type for function pointer that checks image types
using IsThisTypeFct = bool (*)(BasicIo& iIo, bool advance);
/*!
/*!
@brief Returns an Image instance of the specified type.
The factory is implemented as a static class.
*/
class EXIV2API ImageFactory {
*/
class EXIV2API ImageFactory {
friend bool Image::good() const;
public:
/*!
@brief Create the appropriate class type implemented BasicIo based on the protocol of the input.
@ -659,13 +662,13 @@ namespace Exiv2 {
ImageFactory(const ImageFactory& rhs) = delete;
//@}
}; // class ImageFactory
}; // class ImageFactory
// *****************************************************************************
// 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, size_t len);
//! Append \em len bytes pointed to by \em buf to \em blob.
EXIV2API void append(Exiv2::Blob& blob, const byte* buf, size_t len);
} // namespace Exiv2

@ -3,11 +3,9 @@
#ifndef IMAGE_TYPES_H
#define IMAGE_TYPES_H
namespace Exiv2
{
/// Supported Image Formats
enum class ImageType
{
namespace Exiv2 {
/// Supported Image Formats
enum class ImageType {
none,
arw,
bigtiff,
@ -36,7 +34,7 @@ namespace Exiv2
tiff,
webp,
xmp, ///< XMP sidecar files
};
};
} // namespace Exiv2
#endif // IMAGE_TYPES_H

@ -17,7 +17,6 @@
#include <string>
namespace Exiv2 {
#ifndef __INI_H__
#define __INI_H__
@ -72,8 +71,7 @@ int ini_parse_file(FILE* file, ini_handler handler, void* user);
@return 0 on success
*/
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
void* user);
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, void* user);
/*! @brief Nonzero to allow multi-line value parsing, in the style of Python's
configparser. If allowed, ini_parse() will call the handler with the same
@ -122,13 +120,11 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
#endif /* __INI_H__ */
/*! @brief Read an INI file into easy-to-access name/value pairs. (Note that I've gone
for simplicity here rather than speed, but it should be pretty decent.)
*/
class EXIV2API INIReader
{
public:
class EXIV2API INIReader {
public:
/*! @brief Construct INIReader and parse given filename. See ini.h for more info
about the parsing.
*/
@ -184,7 +180,7 @@ public:
*/
bool GetBoolean(const std::string& section, const std::string& name, bool default_value);
private:
private:
int _error; //!< status
std::map<std::string, std::string> _values; //!< values from file
static std::string MakeKey(const std::string& section,

@ -11,27 +11,26 @@
#include "exiv2lib_export.h"
// included header files
#include "metadatum.hpp"
#include "datasets.hpp"
#include "metadatum.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class ExifData;
// *****************************************************************************
// class definitions
/*!
/*!
@brief An IPTC metadatum ("dataset"), consisting of an IptcKey and a
Value and methods to manipulate these.
This is referred in the standard as a property.
*/
class EXIV2API Iptcdatum : public Metadatum {
class EXIV2API Iptcdatum : public Metadatum {
public:
//! @name Creators
//@{
@ -135,12 +134,12 @@ namespace Exiv2 {
IptcKey::UniquePtr key_; //!< Key
Value::UniquePtr value_; //!< Value
}; // class Iptcdatum
}; // class Iptcdatum
//! Container type to hold all metadata
using IptcMetadata = std::vector<Iptcdatum>;
//! Container type to hold all metadata
using IptcMetadata = std::vector<Iptcdatum>;
/*!
/*!
@brief A container for IPTC data. This is a top-level class of the %Exiv2 library.
Provide high-level access to the IPTC data of an image:
@ -149,8 +148,8 @@ namespace Exiv2 {
- add, modify and delete metadata
- write IPTC data to JPEG files
- extract IPTC metadata to files, insert from these files
*/
class EXIV2API IptcData {
*/
class EXIV2API IptcData {
public:
//! IptcMetadata iterator type
using iterator = IptcMetadata::iterator;
@ -195,15 +194,21 @@ namespace Exiv2 {
/*!
@brief Delete all Iptcdatum instances resulting in an empty container.
*/
void clear() { iptcMetadata_.clear(); }
void clear() {
iptcMetadata_.clear();
}
//! Sort metadata by key
void sortByKey();
//! Sort metadata by tag (aka dataset)
void sortByTag();
//! Begin of the metadata
iterator begin() { return iptcMetadata_.begin(); }
iterator begin() {
return iptcMetadata_.begin();
}
//! End of the metadata
iterator end() { return iptcMetadata_.end(); }
iterator end() {
return iptcMetadata_.end();
}
/*!
@brief Find the first Iptcdatum with the given key, return an iterator
to it.
@ -213,16 +218,19 @@ namespace Exiv2 {
@brief Find the first Iptcdatum with the given record and dataset it,
return a const iterator to it.
*/
iterator findId(uint16_t dataset,
uint16_t record = IptcDataSets::application2);
iterator findId(uint16_t dataset, uint16_t record = IptcDataSets::application2);
//@}
//! @name Accessors
//@{
//! Begin of the metadata
const_iterator begin() const { return iptcMetadata_.begin(); }
const_iterator begin() const {
return iptcMetadata_.begin();
}
//! End of the metadata
const_iterator end() const { return iptcMetadata_.end(); }
const_iterator end() const {
return iptcMetadata_.end();
}
/*!
@brief Find the first Iptcdatum with the given key, return a const
iterator to it.
@ -232,34 +240,37 @@ namespace Exiv2 {
@brief Find the first Iptcdatum with the given record and dataset
number, return a const iterator to it.
*/
const_iterator findId(uint16_t dataset,
uint16_t record = IptcDataSets::application2) const;
const_iterator findId(uint16_t dataset, uint16_t record = IptcDataSets::application2) const;
//! Return true if there is no IPTC metadata
bool empty() const { return count() == 0; }
bool empty() const {
return count() == 0;
}
//! Get the number of metadata entries
size_t count() const { return iptcMetadata_.size(); }
size_t count() const {
return iptcMetadata_.size();
}
//! @brief Return the exact size of all contained IPTC metadata
size_t size() const;
//! @brief Return the metadata charset name or 0
const char *detectCharset() const;
const char* detectCharset() const;
//! @brief dump iptc formatted binary data (used by printStructure kpsRecursive)
static void printStructure(std::ostream& out, const Slice<byte*>& bytes,uint32_t depth);
static void printStructure(std::ostream& out, const Slice<byte*>& bytes, uint32_t depth);
//@}
private:
// DATA
IptcMetadata iptcMetadata_;
}; // class IptcData
}; // class IptcData
/*!
/*!
@brief Stateless parser class for IPTC data. Images use this class to
decode and encode binary IPTC data.
*/
class EXIV2API IptcParser {
class EXIV2API IptcParser {
public:
/*!
@brief Decode binary IPTC data in IPTC IIM4 format from a buffer \em pData
@ -288,7 +299,7 @@ namespace Exiv2 {
// Constant data
static const byte marker_; // Dataset marker
}; // class IptcParser
}; // class IptcParser
} // namespace Exiv2

@ -11,16 +11,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access JPEG-2000 images.
*/
class EXIV2API Jp2Image : public Image {
class EXIV2API Jp2Image : public Image {
public:
//! @name Creators
//@{
@ -52,7 +50,7 @@ namespace Exiv2
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;
void printStructure(std::ostream &out, PrintStructureOption option, int depth) override;
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
@ -69,9 +67,9 @@ namespace Exiv2
//! @name NOT Implemented
//@{
//! Copy constructor
Jp2Image(const Jp2Image& rhs) = delete;
Jp2Image(const Jp2Image &rhs) = delete;
//! Assignment operator
Jp2Image& operator=(const Jp2Image& rhs) = delete;
Jp2Image &operator=(const Jp2Image &rhs) = delete;
private:
/*!
@ -81,32 +79,32 @@ namespace Exiv2
@return 4 if opening or writing to the associated BasicIo fails
*/
void doWriteMetadata(BasicIo& outIo);
void doWriteMetadata(BasicIo &outIo);
/*!
@brief reformats the Jp2Header to store iccProfile
@param oldData DataBufRef to data in the file.
@param newData DataBufRef with updated data
*/
void encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf);
void encodeJp2Header(const DataBuf &boxBuf, DataBuf &outBuf);
//@}
}; // class Jp2Image
}; // class Jp2Image
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new Jp2Image instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newJp2Instance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newJp2Instance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a JPEG-2000 image.
EXIV2API bool isJp2Type(BasicIo& iIo, bool advance);
//! Check if the file iIo is a JPEG-2000 image.
EXIV2API bool isJp2Type(BasicIo &iIo, bool advance);
} // namespace Exiv2

@ -9,21 +9,20 @@
#include <array>
// included header files
#include "image.hpp"
#include "error.hpp"
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Helper class, has methods to deal with %Photoshop "Information
Resource Blocks" (IRBs).
*/
struct EXIV2API Photoshop {
struct EXIV2API Photoshop {
// Todo: Public for now
static constexpr std::array<const char*, 4> irbId_{"8BIM", "AgHg", "DCSR", "PHUT"}; //!< %Photoshop IRB markers
inline static const char* ps3Id_ = "Photoshop 3.0\0"; //!< %Photoshop marker
@ -66,28 +65,18 @@ namespace Exiv2 {
3 if no data for psTag was found in pPsData;<BR>
-2 if the pPsData buffer does not contain valid data.
*/
static int locateIrb(const byte *pPsData,
size_t sizePsData,
uint16_t psTag,
const byte **record,
uint32_t *const sizeHdr,
uint32_t *const sizeData);
static int locateIrb(const byte* pPsData, size_t sizePsData, uint16_t psTag, const byte** record,
uint32_t* const sizeHdr, uint32_t* const sizeData);
/*!
@brief Forwards to locateIrb() with \em psTag = \em iptc_
*/
static int locateIptcIrb(const byte *pPsData,
size_t sizePsData,
const byte **record,
uint32_t *const sizeHdr,
uint32_t *const sizeData);
static int locateIptcIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t* const sizeHdr,
uint32_t* const sizeData);
/*!
@brief Forwards to locatePreviewIrb() with \em psTag = \em preview_
*/
static int locatePreviewIrb(const byte *pPsData,
size_t sizePsData,
const byte **record,
uint32_t *const sizeHdr,
uint32_t *const sizeData);
static int locatePreviewIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t* const sizeHdr,
uint32_t* const sizeData);
/*!
@brief Set the new IPTC IRB, keeps existing IRBs but removes the
IPTC block if there is no new IPTC data to write.
@ -99,12 +88,12 @@ namespace Exiv2 {
*/
static DataBuf setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData);
}; // class Photoshop
}; // class Photoshop
/*!
/*!
@brief Abstract helper base class to access JPEG images.
*/
class EXIV2API JpegBase : public Image {
class EXIV2API JpegBase : public Image {
public:
//! @name Manipulators
//@{
@ -144,11 +133,7 @@ namespace Exiv2 {
valid image of the calling subclass.
@param dataSize Size of initData in bytes.
*/
JpegBase(ImageType type,
BasicIo::UniquePtr io,
bool create,
const byte initData[],
size_t dataSize);
JpegBase(ImageType type, BasicIo::UniquePtr io, bool create, const byte initData[], size_t dataSize);
//@}
//! @name Accessors
@ -172,7 +157,7 @@ namespace Exiv2 {
@return true if the data matches the type of this class;<BR>
false if the data does not match
*/
virtual bool isThisType(BasicIo& iIo, bool advance) const =0;
virtual bool isThisType(BasicIo& iIo, bool advance) const = 0;
//@}
//! @name Manipulators
@ -183,7 +168,7 @@ namespace Exiv2 {
@return 0 if successful;<BR>
4 if the output file can not be written to
*/
virtual int writeHeader(BasicIo& oIo) const =0;
virtual int writeHeader(BasicIo& oIo) const = 0;
//@}
// Constant Data
@ -267,13 +252,14 @@ namespace Exiv2 {
@return true if the marker is followed by a non-zero payload
*/
static bool markerHasLength(byte marker);
}; // class JpegBase
}; // class JpegBase
/*!
/*!
@brief Class to access JPEG images
*/
class EXIV2API JpegImage : public JpegBase {
class EXIV2API JpegImage : public JpegBase {
friend EXIV2API bool isJpegType(BasicIo& iIo, bool advance);
public:
//! @name Creators
//@{
@ -329,11 +315,12 @@ namespace Exiv2 {
// Constant data
static const byte soi_; // SOI marker
static const byte blank_[]; // Minimal Jpeg image
}; // class JpegImage
}; // class JpegImage
//! Helper class to access %Exiv2 files
class EXIV2API ExvImage : public JpegBase {
//! Helper class to access %Exiv2 files
class EXIV2API ExvImage : public JpegBase {
friend EXIV2API bool isExvType(BasicIo& iIo, bool advance);
public:
//! @name Creators
//@{
@ -382,29 +369,29 @@ namespace Exiv2 {
static constexpr char exiv2Id_[] = "Exiv2"; // EXV identifier
static constexpr byte blank_[] = {0xff, 0x01, 'E', 'x', 'i', 'v', '2', 0xff, 0xd9}; // Minimal exiv2 file
}; // class ExvImage
}; // class ExvImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new JpegImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newJpegInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a JPEG image.
EXIV2API bool isJpegType(BasicIo& iIo, bool advance);
/*!
EXIV2API Image::UniquePtr newJpegInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a JPEG image.
EXIV2API bool isJpegType(BasicIo& iIo, bool advance);
/*!
@brief Create a new ExvImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newExvInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is an EXV file
EXIV2API bool isExvType(BasicIo& iIo, bool advance);
EXIV2API Image::UniquePtr newExvInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is an EXV file
EXIV2API bool isExvType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -12,19 +12,18 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class ExifData;
// *****************************************************************************
// class definitions
/*!
/*!
@brief Abstract base class defining the %Key of a metadatum.
Keys are used to identify and group metadata.
*/
class EXIV2API Key {
*/
class EXIV2API Key {
public:
//! Shortcut for a %Key auto pointer.
using UniquePtr = std::unique_ptr<Key>;
@ -43,17 +42,17 @@ namespace Exiv2 {
key is not necessarily unique, e.g., an ExifData may contain
multiple metadata with the same key.
*/
virtual std::string key() const =0;
virtual std::string key() const = 0;
//! Return an identifier for the type of metadata (the first part of the key)
virtual const char* familyName() const =0;
virtual const char* familyName() const = 0;
//! Return the name of the group (the second part of the key)
virtual std::string groupName() const =0;
virtual std::string groupName() const = 0;
//! Return the name of the tag (which is also the third part of the key)
virtual std::string tagName() const =0;
virtual std::string tagName() const = 0;
//! Return a label for the tag
virtual std::string tagLabel() const =0;
virtual std::string tagLabel() const = 0;
//! Return the tag number
virtual uint16_t tag() const =0;
virtual uint16_t tag() const = 0;
/*!
@brief Return an auto-pointer to a copy of itself (deep copy).
The caller owns this copy and the auto-pointer ensures that it
@ -66,7 +65,9 @@ namespace Exiv2 {
the output operator for %Key,
operator<<(std::ostream &os, const Key &key).
*/
std::ostream& write(std::ostream& os) const { return os << key(); }
std::ostream& write(std::ostream& os) const {
return os << key();
}
//@}
protected:
@ -81,21 +82,20 @@ namespace Exiv2 {
private:
//! Internal virtual copy constructor.
virtual Key* clone_() const =0;
virtual Key* clone_() const = 0;
}; // class Key
}; // class Key
//! Output operator for Key types
inline std::ostream& operator<<(std::ostream& os, const Key& key)
{
//! Output operator for Key types
inline std::ostream& operator<<(std::ostream& os, const Key& key) {
return key.write(os);
}
}
/*!
/*!
@brief Abstract base class defining the interface to access information
related to one metadata tag.
*/
class EXIV2API Metadatum {
class EXIV2API Metadatum {
public:
//! @name Creators
//@{
@ -113,14 +113,14 @@ namespace Exiv2 {
@brief Set the value. This method copies (clones) the value pointed
to by pValue.
*/
virtual void setValue(const Value* pValue) =0;
virtual void setValue(const Value* pValue) = 0;
/*!
@brief Set the value to the string buf.
Uses Value::read(const std::string& buf). If the metadatum does
not have a value yet, then one is created. See subclasses for
more details. Return 0 if the value was read successfully.
*/
virtual int setValue(const std::string& buf) =0;
virtual int setValue(const std::string& buf) = 0;
//@}
//! @name Accessors
@ -142,7 +142,7 @@ namespace Exiv2 {
@param byteOrder Applicable byte order (little or big endian).
@return Number of characters written.
*/
virtual size_t copy(byte* buf, ByteOrder byteOrder) const =0;
virtual size_t copy(byte* buf, ByteOrder byteOrder) const = 0;
/*!
@brief Write the interpreted value to an output stream, return
the stream.
@ -171,57 +171,57 @@ namespace Exiv2 {
is not necessarily unique, e.g., an ExifData object may
contain multiple metadata with the same key.
*/
virtual std::string key() const =0;
virtual std::string key() const = 0;
//! Return the name of the metadata family (which is also the first part of the key)
virtual const char* familyName() const =0;
virtual const char* familyName() const = 0;
//! Return the name of the metadata group (which is also the second part of the key)
virtual std::string groupName() const =0;
virtual std::string groupName() const = 0;
//! Return the name of the tag (which is also the third part of the key)
virtual std::string tagName() const =0;
virtual std::string tagName() const = 0;
//! Return a label for the tag
virtual std::string tagLabel() const =0;
virtual std::string tagLabel() const = 0;
//! Return the tag
virtual uint16_t tag() const =0;
virtual uint16_t tag() const = 0;
//! Return the type id of the value
virtual TypeId typeId() const =0;
virtual TypeId typeId() const = 0;
//! Return the name of the type
virtual const char* typeName() const =0;
virtual const char* typeName() const = 0;
//! Return the size in bytes of one component of this type
virtual size_t typeSize() const =0;
virtual size_t typeSize() const = 0;
//! Return the number of components in the value
virtual size_t count() const =0;
virtual size_t count() const = 0;
//! Return the size of the value in bytes
virtual size_t size() const =0;
virtual size_t size() const = 0;
//! Return the value as a string.
virtual std::string toString() const =0;
virtual std::string toString() const = 0;
/*!
@brief Return the <EM>n</EM>-th component of the value converted to
a string. The behaviour of the method is undefined if there
is no <EM>n</EM>-th component.
*/
virtual std::string toString(size_t n) const =0;
virtual std::string toString(size_t n) const = 0;
/*!
@brief Return the <EM>n</EM>-th component of the value converted to int64_t.
The return value is -1 if the value is not set and the behaviour
of the method is undefined if there is no <EM>n</EM>-th component.
*/
virtual int64_t toInt64(size_t n =0) const =0;
virtual int64_t toInt64(size_t n = 0) const = 0;
/*!
@brief Return the <EM>n</EM>-th component of the value converted to uint32_t.
*/
uint32_t toUint32(size_t n =0) const;
uint32_t toUint32(size_t n = 0) const;
/*!
@brief Return the <EM>n</EM>-th component of the value converted to float.
The return value is -1 if the value is not set and the behaviour
of the method is undefined if there is no <EM>n</EM>-th component.
*/
virtual float toFloat(size_t n =0) const =0;
virtual float toFloat(size_t n = 0) const = 0;
/*!
@brief Return the <EM>n</EM>-th component of the value converted to Rational.
The return value is -1/1 if the value is not set and the behaviour
of the method is undefined if there is no <EM>n</EM>-th component.
*/
virtual Rational toRational(size_t n =0) const =0;
virtual Rational toRational(size_t n = 0) const = 0;
/*!
@brief Return an auto-pointer to a copy (clone) of the value. The
caller owns this copy and the auto-poiner ensures that it will
@ -235,7 +235,7 @@ namespace Exiv2 {
@return An auto-pointer containing a pointer to a copy (clone) of the
value, 0 if the value is not set.
*/
virtual Value::UniquePtr getValue() const =0;
virtual Value::UniquePtr getValue() const = 0;
/*!
@brief Return a constant reference to the value.
@ -249,7 +249,7 @@ namespace Exiv2 {
@return A constant reference to the value.
@throw Error if the value is not set.
*/
virtual const Value& value() const =0;
virtual const Value& value() const = 0;
//@}
protected:
@ -262,27 +262,26 @@ namespace Exiv2 {
Metadatum& operator=(const Metadatum& rhs) = default;
//@}
}; // class Metadatum
}; // class Metadatum
/*!
/*!
@brief Output operator for Metadatum types, writing the interpreted
tag value.
*/
inline std::ostream& operator<<(std::ostream& os, const Metadatum& md)
{
inline std::ostream& operator<<(std::ostream& os, const Metadatum& md) {
return md.write(os);
}
}
/*!
/*!
@brief Compare two metadata by tag. Return true if the tag of metadatum
lhs is less than that of rhs.
*/
EXIV2API bool cmpMetadataByTag(const Metadatum& lhs, const Metadatum& rhs);
/*!
EXIV2API bool cmpMetadataByTag(const Metadatum& lhs, const Metadatum& rhs);
/*!
@brief Compare two metadata by key. Return true if the key of metadatum
lhs is less than that of rhs.
*/
EXIV2API bool cmpMetadataByKey(const Metadatum& lhs, const Metadatum& rhs);
EXIV2API bool cmpMetadataByKey(const Metadatum& lhs, const Metadatum& rhs);
} // namespace Exiv2

@ -12,15 +12,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Minolta MRW images. Exif metadata is supported
directly, IPTC is read from the Exif data, if present.
*/
class EXIV2API MrwImage : public Image {
class EXIV2API MrwImage : public Image {
public:
//! @name NOT Implemented
//@{
@ -81,22 +80,22 @@ namespace Exiv2 {
uint32_t pixelWidth() const override;
uint32_t pixelHeight() const override;
//@}
}; // class MrwImage
}; // class MrwImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new MrwImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newMrwInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newMrwInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a MRW image.
EXIV2API bool isMrwType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a MRW image.
EXIV2API bool isMrwType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -12,15 +12,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Olympus ORF images. Exif metadata is supported
directly, IPTC is read from the Exif data, if present.
*/
class EXIV2API OrfImage : public TiffImage {
class EXIV2API OrfImage : public TiffImage {
public:
//! @name NOT Implemented
//@{
@ -68,50 +67,43 @@ namespace Exiv2 {
uint32_t pixelWidth() const override;
uint32_t pixelHeight() const override;
//@}
}; // class OrfImage
}; // class OrfImage
/*!
/*!
@brief Stateless parser class for data in ORF format. Images use this
class to decode and encode ORF data.
See class TiffParser for details.
*/
class EXIV2API OrfParser {
class EXIV2API OrfParser {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
with data in ORF format to the provided metadata containers.
See TiffParser::decode().
*/
static ByteOrder decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData,
size_t size);
static ByteOrder decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size);
/*!
@brief Encode metadata from the provided metadata to ORF format.
See TiffParser::encode().
*/
static WriteMethod encode(BasicIo& io,
const byte* pData,
size_t size,
ByteOrder byteOrder,
const ExifData& exifData,
const IptcData& iptcData,
const XmpData& xmpData
);
}; // class OrfParser
static WriteMethod encode(BasicIo& io, const byte* pData, size_t size, ByteOrder byteOrder, const ExifData& exifData,
const IptcData& iptcData, const XmpData& xmpData);
}; // class OrfParser
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new OrfImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newOrfInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newOrfInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is an ORF image.
EXIV2API bool isOrfType(BasicIo& iIo, bool advance);
//! Check if the file iIo is an ORF image.
EXIV2API bool isOrfType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -11,17 +11,15 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access PGF images. Exif and IPTC metadata are supported
directly.
*/
class EXIV2API PgfImage : public Image {
class EXIV2API PgfImage : public Image {
public:
//! @name Creators
//@{
@ -51,8 +49,7 @@ namespace Exiv2
//! @name Accessors
//@{
std::string mimeType() const override
{
std::string mimeType() const override {
return "image/pgf";
}
//@}
@ -82,22 +79,22 @@ namespace Exiv2
DataBuf readPgfHeaderStructure(BasicIo& iIo, uint32_t& width, uint32_t& height) const;
//@}
}; // class PgfImage
}; // class PgfImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new PgfImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newPgfInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newPgfInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a PGF image.
EXIV2API bool isPgfType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a PGF image.
EXIV2API bool isPgfType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -11,17 +11,15 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access PNG images. Exif and IPTC metadata are supported
directly.
*/
class EXIV2API PngImage : public Image {
class EXIV2API PngImage : public Image {
public:
//! @name Creators
//@{
@ -82,22 +80,22 @@ namespace Exiv2
std::string profileName_;
}; // class PngImage
}; // class PngImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new PngImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newPngInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newPngInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a PNG image.
EXIV2API bool isPngType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a PNG image.
EXIV2API bool isPngType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -11,33 +11,31 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// *****************************************************************************
// class definitions
//! Type of preview image.
using PreviewId = int;
//! Type of preview image.
using PreviewId = int;
/*!
/*!
@brief Preview image properties.
*/
struct EXIV2API PreviewProperties
{
struct EXIV2API PreviewProperties {
std::string mimeType_; //!< Preview image mime type.
std::string extension_; //!< Preview image extension.
size_t size_; //!< Preview image size in bytes.
size_t width_; //!< Preview image width in pixels or 0 for unknown width.
size_t height_; //!< Preview image height in pixels or 0 for unknown height.
PreviewId id_; //!< Identifies type of preview image.
};
};
//! Container type to hold all preview images metadata.
using PreviewPropertiesList = std::vector<PreviewProperties>;
//! Container type to hold all preview images metadata.
using PreviewPropertiesList = std::vector<PreviewProperties>;
/*!
/*!
@brief Class that holds preview image properties and data buffer.
*/
class EXIV2API PreviewImage {
class EXIV2API PreviewImage {
friend class PreviewManager;
public:
@ -110,12 +108,12 @@ namespace Exiv2 {
PreviewProperties properties_; //!< Preview image properties
DataBuf preview_; //!< Preview image data
}; // class PreviewImage
}; // class PreviewImage
/*!
/*!
@brief Class for extracting preview images from image metadata.
*/
class EXIV2API PreviewManager {
class EXIV2API PreviewManager {
public:
//! @name Constructors
//@{
@ -140,7 +138,7 @@ namespace Exiv2 {
private:
const Image& image_;
}; // class PreviewManager
}; // class PreviewManager
} // namespace Exiv2
#endif // #ifndef PREVIEW_HPP_

@ -7,25 +7,24 @@
#include "exiv2lib_export.h"
// included header files
#include "datasets.hpp"
#include <mutex>
#include "datasets.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class XmpKey;
class XmpKey;
// *****************************************************************************
// class definitions
//! Category of an XMP property
enum XmpCategory { xmpInternal, xmpExternal };
//! Category of an XMP property
enum XmpCategory { xmpInternal, xmpExternal };
//! Information about one XMP property.
struct EXIV2API XmpPropertyInfo {
//! Information about one XMP property.
struct EXIV2API XmpPropertyInfo {
//! Comparison operator for name
bool operator==(const std::string& name) const;
@ -35,10 +34,10 @@ namespace Exiv2 {
TypeId typeId_; //!< Exiv2 default type for the property
XmpCategory xmpCategory_; //!< Category (internal or external)
const char* desc_; //!< Property description
};
};
//! Structure mapping XMP namespaces and (preferred) prefixes.
struct EXIV2API XmpNsInfo {
//! Structure mapping XMP namespaces and (preferred) prefixes.
struct EXIV2API XmpNsInfo {
//! For comparison with prefix
struct Prefix {
//! Constructor.
@ -62,10 +61,10 @@ namespace Exiv2 {
const char* prefix_; //!< (Preferred) prefix
const XmpPropertyInfo* xmpPropertyInfo_; //!< List of known properties
const char* desc_; //!< Brief description of the namespace
};
};
//! XMP property reference, implemented as a static class.
class EXIV2API XmpProperties {
//! XMP property reference, implemented as a static class.
class EXIV2API XmpProperties {
//! Prevent construction: not implemented.
XmpProperties();
//! Prevent copy-construction: not implemented.
@ -156,9 +155,7 @@ namespace Exiv2 {
static void printProperties(std::ostream& os, const std::string& prefix);
//! Interpret and print the value of an XMP property
static std::ostream& printProperty(std::ostream& os,
const std::string& key,
const Value& value);
static std::ostream& printProperty(std::ostream& os, const std::string& key, const Value& value);
/*!
@brief Register namespace \em ns with preferred prefix \em prefix.
@ -212,13 +209,12 @@ namespace Exiv2 {
*/
static void registeredNamespaces(Exiv2::Dictionary& nsDict);
}; // class XmpProperties
}; // class XmpProperties
/*!
/*!
@brief Concrete keys for XMP metadata.
*/
class EXIV2API XmpKey : public Key
{
class EXIV2API XmpKey : public Key {
public:
//! Shortcut for an %XmpKey auto pointer.
using UniquePtr = std::unique_ptr<XmpKey>;
@ -285,13 +281,13 @@ namespace Exiv2 {
struct Impl;
std::unique_ptr<Impl> p_;
}; // class XmpKey
}; // class XmpKey
// *****************************************************************************
// free functions
// *****************************************************************************
// free functions
//! Output operator for property info
EXIV2API std::ostream& operator<<(std::ostream& os, const XmpPropertyInfo& propertyInfo);
//! Output operator for property info
EXIV2API std::ostream& operator<<(std::ostream& os, const XmpPropertyInfo& propertyInfo);
} // namespace Exiv2

@ -12,14 +12,13 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Photoshop images.
*/
class EXIV2API PsdImage : public Image {
class EXIV2API PsdImage : public Image {
public:
//! @name NOT Implemented
//@{
@ -93,22 +92,22 @@ namespace Exiv2 {
uint32_t writeXmpData(const XmpData& xmpData, BasicIo& out) const;
//@}
}; // class PsdImage
}; // class PsdImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new PsdImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newPsdInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newPsdInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Photoshop image.
EXIV2API bool isPsdType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a Photoshop image.
EXIV2API bool isPsdType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -12,15 +12,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Fujifilm RAF images. Exif metadata is
supported directly, IPTC is read from the Exif data, if present.
*/
class EXIV2API RafImage : public Image {
class EXIV2API RafImage : public Image {
public:
//! @name Creators
//@{
@ -83,22 +82,22 @@ namespace Exiv2 {
RafImage& operator=(const RafImage& rhs) = delete;
//@}
}; // class RafImage
}; // class RafImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new RafImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newRafInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newRafInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a RAF image.
EXIV2API bool isRafType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a RAF image.
EXIV2API bool isRafType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -12,16 +12,15 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw Panasonic RW2 images. Exif metadata is
supported directly, IPTC and XMP are read from the Exif data, if
present.
*/
class EXIV2API Rw2Image : public Image {
class EXIV2API Rw2Image : public Image {
public:
//! @name Creators
//@{
@ -81,43 +80,38 @@ namespace Exiv2 {
Rw2Image& operator=(const Rw2Image& rhs) = delete;
//@}
}; // class Rw2Image
}; // class Rw2Image
/*!
/*!
@brief Stateless parser class for data in RW2 format. Images use this
class to decode and encode RW2 data. Only decoding is currently
implemented. See class TiffParser for details.
*/
class EXIV2API Rw2Parser {
class EXIV2API Rw2Parser {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
with data in RW2 format to the provided metadata containers.
See TiffParser::decode().
*/
static ByteOrder decode(ExifData& exifData,
IptcData& iptcData,
XmpData& xmpData,
const byte* pData,
size_t size
);
static ByteOrder decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size);
}; // class Rw2Parser
}; // class Rw2Parser
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new Rw2Image instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newRw2Instance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newRw2Instance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a RW2 image.
EXIV2API bool isRw2Type(BasicIo& iIo, bool advance);
//! Check if the file iIo is a RW2 image.
EXIV2API bool isRw2Type(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -8,20 +8,16 @@
#include <iterator>
#include <stdexcept>
namespace Exiv2
{
namespace Internal
{
/*!
namespace Exiv2 {
namespace Internal {
/*!
* Common base class of all slice implementations.
*
* Implements only the most basic functions, which do not require any
* knowledge about the stored data.
*/
struct SliceBase
{
inline SliceBase(size_t begin, size_t end) : begin_(begin), end_(end)
{
struct SliceBase {
inline SliceBase(size_t begin, size_t end) : begin_(begin), end_(end) {
if (begin >= end) {
throw std::out_of_range("Begin must be smaller than end");
}
@ -30,8 +26,7 @@ namespace Exiv2
/*!
* Return the number of elements in the slice.
*/
inline size_t size() const noexcept
{
inline size_t size() const noexcept {
// cannot underflow, as we know that begin < end
return end_ - begin_;
}
@ -43,8 +38,7 @@ namespace Exiv2
* @throw std::out_of_range when `index` will access an element
* outside of the slice
*/
inline void rangeCheck(size_t index) const
{
inline void rangeCheck(size_t index) const {
if (index >= size()) {
throw std::out_of_range("Index outside of the slice");
}
@ -55,9 +49,9 @@ namespace Exiv2
* container/array stored in storage_
*/
const size_t begin_, end_;
};
};
/*!
/*!
* @brief This class provides the public-facing const-qualified methods
* of a slice.
*
@ -83,9 +77,8 @@ namespace Exiv2
* - Must provide appropriate typedefs for iterator, const_iterator and
* value_type
*/
template <template <typename data_type> class storage_type, typename data_type>
struct ConstSliceBase : SliceBase
{
template <template <typename data_type> class storage_type, typename data_type>
struct ConstSliceBase : SliceBase {
using iterator = typename storage_type<data_type>::iterator;
using const_iterator = typename storage_type<data_type>::const_iterator;
using value_type = typename storage_type<data_type>::value_type;
@ -95,9 +88,7 @@ namespace Exiv2
* otherwise an exception is thrown. Also forwards all parameters to
* the constructor of storage_
*/
ConstSliceBase(data_type& data, size_t begin, size_t end)
: SliceBase(begin, end), storage_(data, begin, end)
{
ConstSliceBase(data_type& data, size_t begin, size_t end) : SliceBase(begin, end), storage_(data, begin, end) {
}
/*!
@ -106,8 +97,7 @@ namespace Exiv2
*
* @throw std::out_of_range when index is out of bounds of the slice
*/
const value_type& at(size_t index) const
{
const value_type& at(size_t index) const {
rangeCheck(index);
// we know: begin_ < end <= size() <= SIZE_T_MAX
// and: index < end - begin
@ -119,16 +109,14 @@ namespace Exiv2
/*!
* Obtain a constant iterator to the first element in the slice.
*/
const_iterator cbegin() const noexcept
{
const_iterator cbegin() const noexcept {
return storage_.unsafeGetIteratorAt(begin_);
}
/*!
* Obtain a constant iterator to the first beyond the slice.
*/
const_iterator cend() const noexcept
{
const_iterator cend() const noexcept {
return storage_.unsafeGetIteratorAt(end_);
}
@ -141,8 +129,7 @@ namespace Exiv2
* mutable_slice_base.
*/
template <typename slice_type>
slice_type subSlice(size_t begin, size_t end) const
{
slice_type subSlice(size_t begin, size_t end) const {
this->rangeCheck(begin);
// end == size() is a legal value, since end is the first
// element beyond the slice
@ -163,16 +150,15 @@ namespace Exiv2
* Stores a reference to the actual data.
*/
storage_type<data_type> storage_;
};
};
/*!
/*!
* This class provides all public-facing non-const-qualified methods of
* slices. It only re-implements the const-qualified versions as
* non-const.
*/
template <template <typename> class storage_type, typename data_type>
struct MutableSliceBase : public ConstSliceBase<storage_type, data_type>
{
template <template <typename> class storage_type, typename data_type>
struct MutableSliceBase : public ConstSliceBase<storage_type, data_type> {
using iterator = typename ConstSliceBase<storage_type, data_type>::iterator;
using const_iterator = typename ConstSliceBase<storage_type, data_type>::const_iterator;
using value_type = typename ConstSliceBase<storage_type, data_type>::value_type;
@ -182,9 +168,8 @@ namespace Exiv2
*
* @todo use using once we have C++11
*/
MutableSliceBase(data_type& data, size_t begin, size_t end)
: ConstSliceBase<storage_type, data_type>(data, begin, end)
{
MutableSliceBase(data_type& data, size_t begin, size_t end) :
ConstSliceBase<storage_type, data_type>(data, begin, end) {
}
/*!
@ -193,30 +178,26 @@ namespace Exiv2
*
* @throw std::out_of_range when index is out of bounds of the slice
*/
value_type& at(size_t index)
{
value_type& at(size_t index) {
this->rangeCheck(index);
return this->storage_.unsafeAt(this->begin_ + index);
}
const value_type& at(size_t index) const
{
const value_type& at(size_t index) const {
return base_type::at(index);
}
/*!
* Obtain an iterator to the first element in the slice.
*/
iterator begin() noexcept
{
iterator begin() noexcept {
return this->storage_.unsafeGetIteratorAt(this->begin_);
}
/*!
* Obtain an iterator to the first element beyond the slice.
*/
iterator end() noexcept
{
iterator end() noexcept {
return this->storage_.unsafeGetIteratorAt(this->end_);
}
@ -238,8 +219,7 @@ namespace Exiv2
* the appropriate `slice<const T>` and call its `subSlice() const`,
* which returns the correct type.
*/
ConstSliceBase<storage_type, const data_type> to_const_base() const noexcept
{
ConstSliceBase<storage_type, const data_type> to_const_base() const noexcept {
return ConstSliceBase<storage_type, const data_type>(this->storage_.data_, this->begin_, this->end_);
}
@ -254,8 +234,7 @@ namespace Exiv2
* mutable_slice_base.
*/
template <typename slice_type>
slice_type subSlice(size_t begin, size_t end)
{
slice_type subSlice(size_t begin, size_t end) {
this->rangeCheck(begin);
// end == size() is a legal value, since end is the first
// element beyond the slice
@ -271,16 +250,15 @@ namespace Exiv2
}
return slice_type(this->storage_.data_, new_begin, new_end);
}
};
};
/*!
/*!
* Implementation of the storage concept for STL-containers.
*
* @tparam container Type of the STL-container.
*/
template <typename container>
struct ContainerStorage
{
template <typename container>
struct ContainerStorage {
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
@ -291,8 +269,7 @@ namespace Exiv2
* @throw std::out_of_range when end is larger than the container's
* size.
*/
ContainerStorage(container& data, size_t /* begin*/, size_t end) : data_(data)
{
ContainerStorage(container& data, size_t /* begin*/, size_t end) : data_(data) {
if (end > data.size()) {
throw std::out_of_range("Invalid input parameters to slice");
}
@ -304,13 +281,11 @@ namespace Exiv2
*
* @throw whatever container::at() throws
*/
const value_type& unsafeAt(size_t index) const
{
const value_type& unsafeAt(size_t index) const {
return data_.at(index);
}
value_type& unsafeAt(size_t index)
{
value_type& unsafeAt(size_t index) {
return data_.at(index);
}
@ -320,8 +295,7 @@ namespace Exiv2
*
* @throw whatever container::begin() and std::advance() throw
*/
iterator unsafeGetIteratorAt(size_t index)
{
iterator unsafeGetIteratorAt(size_t index) {
// we are screwed if the container got changed => try to catch it
assert(index <= data_.size());
@ -330,8 +304,7 @@ namespace Exiv2
return it;
}
const_iterator unsafeGetIteratorAt(size_t index) const
{
const_iterator unsafeGetIteratorAt(size_t index) const {
assert(index <= data_.size());
const_iterator it = data_.begin();
@ -340,19 +313,18 @@ namespace Exiv2
}
container& data_;
};
};
/*!
/*!
* @brief Implementation of the storage concept for slices of C arrays.
*
* @tparam storage_type Type as which the C-array should be stored. Use
* this parameter to save constant arrays as `const` and mutable ones as
* non-`const`.
*/
template <typename storage_type>
struct PtrSliceStorage
{
using value_type = std::remove_cv_t<std::remove_pointer_t<storage_type> >;
template <typename storage_type>
struct PtrSliceStorage {
using value_type = std::remove_cv_t<std::remove_pointer_t<storage_type>>;
using iterator = value_type*;
using const_iterator = const value_type*;
@ -362,8 +334,7 @@ namespace Exiv2
*
* @throw std::invalid_argument when ptr is `NULL`
*/
PtrSliceStorage(storage_type ptr, size_t /*begin*/, size_t /*end*/) : data_(ptr)
{
PtrSliceStorage(storage_type ptr, size_t /*begin*/, size_t /*end*/) : data_(ptr) {
if (!ptr) {
throw std::invalid_argument("Null pointer passed to slice constructor");
}
@ -375,13 +346,11 @@ namespace Exiv2
*
* @throw nothing
*/
value_type& unsafeAt(size_t index) noexcept
{
value_type& unsafeAt(size_t index) noexcept {
return data_[index];
}
const value_type& unsafeAt(size_t index) const noexcept
{
const value_type& unsafeAt(size_t index) const noexcept {
return data_[index];
}
@ -391,22 +360,20 @@ namespace Exiv2
*
* @throw nothing
*/
iterator unsafeGetIteratorAt(size_t index) noexcept
{
iterator unsafeGetIteratorAt(size_t index) noexcept {
return data_ + index;
}
const_iterator unsafeGetIteratorAt(size_t index) const noexcept
{
const_iterator unsafeGetIteratorAt(size_t index) const noexcept {
return data_ + index;
}
storage_type data_;
};
};
} // namespace Internal
} // namespace Internal
/*!
/*!
* @brief Slice (= view) for STL containers.
*
* This is a very simple implementation of slices (i.e. views of sub-arrays)
@ -450,9 +417,8 @@ namespace Exiv2
* @tparam container A STL container type, like vector or array. Must support
* array-like access via the `at()` method.
*/
template <typename container>
struct Slice : public Internal::MutableSliceBase<Internal::ContainerStorage, container>
{
template <typename container>
struct Slice : public Internal::MutableSliceBase<Internal::ContainerStorage, container> {
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
@ -475,9 +441,8 @@ namespace Exiv2
* than `begin` (they cannot be equal) it is impossible to construct a
* slice with zero length.
*/
Slice(container& cont, size_t begin, size_t end)
: Internal::MutableSliceBase<Internal::ContainerStorage, container>(cont, begin, end)
{
Slice(container& cont, size_t begin, size_t end) :
Internal::MutableSliceBase<Internal::ContainerStorage, container>(cont, begin, end) {
}
/*!
@ -489,47 +454,41 @@ namespace Exiv2
*
* @throw std::out_of_range when begin or end are invalid
*/
Slice subSlice(size_t begin, size_t end)
{
return Internal::MutableSliceBase<Internal::ContainerStorage, container>::template subSlice<Slice>(begin,
end);
Slice subSlice(size_t begin, size_t end) {
return Internal::MutableSliceBase<Internal::ContainerStorage, container>::template subSlice<Slice>(begin, end);
}
/*!
* Constructs a new constant subSlice. Behaves otherwise exactly like
* the non-const version.
*/
Slice<const container> subSlice(size_t begin, size_t end) const
{
return this->to_const_base().template subSlice<Slice<const container> >(begin, end);
Slice<const container> subSlice(size_t begin, size_t end) const {
return this->to_const_base().template subSlice<Slice<const container>>(begin, end);
}
};
};
/*!
/*!
* @brief Specialization of slices for constant containers.
*/
template <typename container>
struct Slice<const container> : public Internal::ConstSliceBase<Internal::ContainerStorage, const container>
{
template <typename container>
struct Slice<const container> : public Internal::ConstSliceBase<Internal::ContainerStorage, const container> {
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
using value_type = std::remove_cv_t<typename container::value_type>;
Slice(const container& cont, size_t begin, size_t end)
: Internal::ConstSliceBase<Internal::ContainerStorage, const container>(cont, begin, end)
{
Slice(const container& cont, size_t begin, size_t end) :
Internal::ConstSliceBase<Internal::ContainerStorage, const container>(cont, begin, end) {
}
Slice subSlice(size_t begin, size_t end) const
{
Slice subSlice(size_t begin, size_t end) const {
return Internal::ConstSliceBase<Internal::ContainerStorage,
const container>::template subSlice<Slice<const container> >(begin, end);
const container>::template subSlice<Slice<const container>>(begin, end);
}
};
};
/*!
/*!
* Specialization of slices for constant C-arrays.
*
* These have exactly the same interface as the slices for STL-containers,
@ -537,9 +496,8 @@ namespace Exiv2
* a proper bounds check! It can only verify that you didn't accidentally
* swap begin and end!
*/
template <typename T>
struct Slice<const T*> : public Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*>
{
template <typename T>
struct Slice<const T*> : public Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*> {
/*!
* Constructor.
*
@ -552,99 +510,86 @@ namespace Exiv2
* Please note that the constructor has no way how to verify that
* `begin` and `end` are not out of bounds of the provided array!
*/
Slice(const T* ptr, size_t begin, size_t end)
: Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*>(ptr, begin, end)
{
Slice(const T* ptr, size_t begin, size_t end) :
Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*>(ptr, begin, end) {
// TODO: use using in C++11
}
Slice<const T*> subSlice(size_t begin, size_t end) const
{
return Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*>::template subSlice<Slice<const T*> >(
begin, end);
Slice<const T*> subSlice(size_t begin, size_t end) const {
return Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*>::template subSlice<Slice<const T*>>(begin,
end);
}
};
};
/*!
/*!
* Specialization of slices for (mutable) C-arrays.
*/
template <typename T>
struct Slice<T*> : public Internal::MutableSliceBase<Internal::PtrSliceStorage, T*>
{
Slice(T* ptr, size_t begin, size_t end)
: Internal::MutableSliceBase<Internal::PtrSliceStorage, T*>(ptr, begin, end)
{
template <typename T>
struct Slice<T*> : public Internal::MutableSliceBase<Internal::PtrSliceStorage, T*> {
Slice(T* ptr, size_t begin, size_t end) : Internal::MutableSliceBase<Internal::PtrSliceStorage, T*>(ptr, begin, end) {
// TODO: use using in C++11
}
Slice<T*> subSlice(size_t begin, size_t end)
{
return Internal::MutableSliceBase<Internal::PtrSliceStorage, T*>::template subSlice<Slice<T*> >(begin, end);
Slice<T*> subSlice(size_t begin, size_t end) {
return Internal::MutableSliceBase<Internal::PtrSliceStorage, T*>::template subSlice<Slice<T*>>(begin, end);
}
Slice<const T*> subSlice(size_t begin, size_t end) const
{
return this->to_const_base().template subSlice<Slice<const T*> >(begin, end);
Slice<const T*> subSlice(size_t begin, size_t end) const {
return this->to_const_base().template subSlice<Slice<const T*>>(begin, end);
}
};
};
/*!
/*!
* @brief Return a new slice with the given bounds.
*
* Convenience wrapper around the slice's constructor for automatic template
* parameter deduction.
*/
template <typename T>
inline Slice<T> makeSlice(T& cont, size_t begin, size_t end)
{
template <typename T>
inline Slice<T> makeSlice(T& cont, size_t begin, size_t end) {
return Slice<T>(cont, begin, end);
}
}
/*!
/*!
* Overload of makeSlice for slices of C-arrays.
*/
template <typename T>
inline Slice<T*> makeSlice(T* ptr, size_t begin, size_t end)
{
template <typename T>
inline Slice<T*> makeSlice(T* ptr, size_t begin, size_t end) {
return Slice<T*>(ptr, begin, end);
}
}
/*!
/*!
* @brief Return a new slice spanning the whole container.
*/
template <typename container>
inline Slice<container> makeSlice(container& cont)
{
template <typename container>
inline Slice<container> makeSlice(container& cont) {
return Slice<container>(cont, 0, cont.size());
}
}
/*!
/*!
* @brief Return a new slice spanning from begin until the end of the
* container.
*/
template <typename container>
inline Slice<container> makeSliceFrom(container& cont, size_t begin)
{
template <typename container>
inline Slice<container> makeSliceFrom(container& cont, size_t begin) {
return Slice<container>(cont, begin, cont.size());
}
}
/*!
/*!
* @brief Return a new slice spanning until `end`.
*/
template <typename container>
inline Slice<container> makeSliceUntil(container& cont, size_t end)
{
template <typename container>
inline Slice<container> makeSliceUntil(container& cont, size_t end) {
return Slice<container>(cont, 0, end);
}
}
/*!
/*!
* Overload of makeSliceUntil for pointer based slices.
*/
template <typename T>
inline Slice<T*> makeSliceUntil(T* ptr, size_t end)
{
template <typename T>
inline Slice<T*> makeSliceUntil(T* ptr, size_t end) {
return Slice<T*>(ptr, 0, end);
}
}
} // namespace Exiv2

@ -12,27 +12,26 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class ExifKey;
class Value;
struct TagInfo;
class ExifData;
class ExifKey;
class Value;
struct TagInfo;
// *****************************************************************************
// type definitions
//! Type for a function pointer for functions interpreting the tag value
using PrintFct = std::ostream& (*)(std::ostream&, const Value&, const ExifData* pExifData);
//! A function returning a tag list.
using TagListFct = const TagInfo* (*)();
//! Type for a function pointer for functions interpreting the tag value
using PrintFct = std::ostream& (*)(std::ostream&, const Value&, const ExifData* pExifData);
//! A function returning a tag list.
using TagListFct = const TagInfo* (*)();
// *****************************************************************************
// class definitions
// *****************************************************************************
// class definitions
//! The details of an Exif group. Groups include IFDs and binary arrays.
struct EXIV2API GroupInfo {
//! The details of an Exif group. Groups include IFDs and binary arrays.
struct EXIV2API GroupInfo {
struct GroupName;
bool operator==(int ifdId) const; //!< Comparison operator for IFD id
bool operator==(const GroupName& groupName) const; //!< Comparison operator for group name
@ -40,16 +39,16 @@ namespace Exiv2 {
const char* ifdName_; //!< IFD name
const char* groupName_; //!< Group name, unique for each group.
TagListFct tagList_; //!< Tag list
};
};
//! Search key to find a GroupInfo by its group name.
struct EXIV2API GroupInfo::GroupName {
//! Search key to find a GroupInfo by its group name.
struct EXIV2API GroupInfo::GroupName {
explicit GroupName(std::string groupName);
std::string g_; //!< Group name
};
};
//! Tag information
struct EXIV2API TagInfo {
//! Tag information
struct EXIV2API TagInfo {
uint16_t tag_; //!< Tag
const char* name_; //!< One word tag label
const char* title_; //!< Tag title
@ -59,10 +58,10 @@ namespace Exiv2 {
TypeId typeId_; //!< Type id
int16_t count_; //!< The number of values (not bytes!), 0=any, -1=count not known.
PrintFct printFct_; //!< Pointer to tag print function
}; // struct TagInfo
}; // struct TagInfo
//! Access to Exif group and tag lists and misc. tag reference methods, implemented as a static class.
class EXIV2API ExifTags {
//! Access to Exif group and tag lists and misc. tag reference methods, implemented as a static class.
class EXIV2API ExifTags {
public:
//! Prevent construction: not implemented.
ExifTags() = delete;
@ -98,12 +97,12 @@ namespace Exiv2 {
*/
static bool isExifGroup(const std::string& groupName);
}; // class ExifTags
}; // class ExifTags
/*!
/*!
@brief Concrete keys for Exif metadata and access to Exif tag reference data.
*/
class EXIV2API ExifKey : public Key {
class EXIV2API ExifKey : public Key {
public:
//! Shortcut for an %ExifKey auto pointer.
using UniquePtr = std::unique_ptr<ExifKey>;
@ -181,13 +180,13 @@ namespace Exiv2 {
struct Impl;
std::unique_ptr<Impl> p_;
}; // class ExifKey
}; // class ExifKey
// *****************************************************************************
// free functions
//! Output operator for TagInfo
EXIV2API std::ostream& operator<<(std::ostream& os, const TagInfo& ti);
//! Output operator for TagInfo
EXIV2API std::ostream& operator<<(std::ostream& os, const TagInfo& ti);
} // namespace Exiv2

@ -11,15 +11,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access raw TARGA images. This is just a stub - we only
read width and height.
*/
class EXIV2API TgaImage : public Image {
class EXIV2API TgaImage : public Image {
public:
//! @name NOT Implemented
//@{
@ -76,22 +75,22 @@ namespace Exiv2 {
std::string mimeType() const override;
//@}
}; // class TgaImage
}; // class TgaImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new TgaImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newTgaInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newTgaInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Targa v2 image.
EXIV2API bool isTgaType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a Targa v2 image.
EXIV2API bool isTgaType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -12,15 +12,14 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access TIFF images. Exif metadata is
supported directly, IPTC is read from the Exif data, if present.
*/
class EXIV2API TiffImage : public Image {
class EXIV2API TiffImage : public Image {
public:
//! @name Creators
//@{
@ -90,14 +89,14 @@ namespace Exiv2 {
mutable uint32_t pixelWidthPrimary_; //!< Width of the primary image in pixels
mutable uint32_t pixelHeightPrimary_; //!< Height of the primary image in pixels
}; // class TiffImage
}; // class TiffImage
/*!
/*!
@brief Stateless parser class for data in TIFF format. Images use this
class to decode and encode TIFF data. It is a wrapper of the
internal class Internal::TiffParserWorker.
*/
class EXIV2API TiffParser {
class EXIV2API TiffParser {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
@ -112,13 +111,7 @@ namespace Exiv2 {
@return Byte order in which the data is encoded.
*/
static ByteOrder decode(
ExifData& exifData,
IptcData& iptcData,
XmpData& xmpData,
const byte* pData,
size_t size
);
static ByteOrder decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size);
/*!
@brief Encode metadata from the provided metadata to TIFF format.
@ -152,31 +145,25 @@ namespace Exiv2 {
@return Write method used.
*/
static WriteMethod encode(BasicIo& io,
const byte* pData,
size_t size,
ByteOrder byteOrder,
const ExifData& exifData,
const IptcData& iptcData,
const XmpData& xmpData
);
static WriteMethod encode(BasicIo& io, const byte* pData, size_t size, ByteOrder byteOrder, const ExifData& exifData,
const IptcData& iptcData, const XmpData& xmpData);
}; // class TiffParser
}; // class TiffParser
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new TiffImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newTiffInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newTiffInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a TIFF image.
EXIV2API bool isTiffType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a TIFF image.
EXIV2API bool isTiffType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -29,56 +29,55 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// type definitions
// *****************************************************************************
// type definitions
//! 1 byte unsigned integer type.
using byte = uint8_t;
//! 1 byte unsigned integer type.
using byte = uint8_t;
//! 8 byte unsigned rational type.
using URational = std::pair<uint32_t, uint32_t>;
//! 8 byte signed rational type.
using Rational = std::pair<int32_t, int32_t>;
//! 8 byte unsigned rational type.
using URational = std::pair<uint32_t, uint32_t>;
//! 8 byte signed rational type.
using Rational = std::pair<int32_t, int32_t>;
//! Type to express the byte order (little or big endian)
enum ByteOrder {
//! Type to express the byte order (little or big endian)
enum ByteOrder {
invalidByteOrder,
littleEndian,
bigEndian,
};
};
//! Type to indicate write method used by TIFF parsers
enum WriteMethod {
//! Type to indicate write method used by TIFF parsers
enum WriteMethod {
wmIntrusive,
wmNonIntrusive,
};
};
//! An identifier for each type of metadata
enum MetadataId {
//! An identifier for each type of metadata
enum MetadataId {
mdNone = 0,
mdExif = 1,
mdIptc = 2,
mdComment = 4,
mdXmp = 8,
mdIccProfile = 16,
};
};
//! An identifier for each mode of metadata support
enum AccessMode {
//! An identifier for each mode of metadata support
enum AccessMode {
amNone = 0,
amRead = 1,
amWrite = 2,
amReadWrite = 3,
};
};
/*!
/*!
@brief %Exiv2 value type identifiers.
Used primarily as identifiers when creating %Exiv2 Value instances.
See Value::create. 0x0000 to 0xffff are reserved for TIFF (Exif) types.
*/
enum TypeId {
enum TypeId {
unsignedByte = 1, //!< Exif BYTE type, 8-bit unsigned integer.
asciiString = 2, //!< Exif ASCII type, 8-bit byte.
unsignedShort = 3, //!< Exif SHORT type, 16-bit (2-byte) unsigned integer.
@ -107,16 +106,16 @@ namespace Exiv2 {
langAlt = 0x10009, //!< XMP language alternative type.
invalidTypeId = 0x1fffe, //!< Invalid type id.
lastTypeId = 0x1ffff //!< Last type id.
};
};
//! Container for binary data
using Blob = std::vector<byte>;
//! Container for binary data
using Blob = std::vector<byte>;
// *****************************************************************************
// class definitions
// *****************************************************************************
// class definitions
//! Type information lookup functions. Implemented as a static class.
class EXIV2API TypeInfo {
//! Type information lookup functions. Implemented as a static class.
class EXIV2API TypeInfo {
public:
//! Prevent construction: not implemented.
TypeInfo() = delete;
@ -131,15 +130,15 @@ namespace Exiv2 {
static TypeId typeId(const std::string& typeName);
//! Return the size in bytes of one element of this type
static size_t typeSize(TypeId typeId);
};
};
/*!
/*!
@brief Utility class containing a character array. All it does is to take
care of memory allocation and deletion. Its primary use is meant to
be as a stack variable in functions that need a temporary data
buffer.
*/
struct EXIV2API DataBuf {
struct EXIV2API DataBuf {
//! @name Creators
//@{
//! Default constructor
@ -170,12 +169,22 @@ namespace Exiv2 {
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(); }
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();
}
size_t size() const { return pData_.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);
@ -204,13 +213,15 @@ 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(); }
bool empty() const {
return pData_.empty();
}
private:
std::vector<byte> pData_;
};
};
/*!
/*!
* @brief Create a new Slice from a DataBuf given the bounds.
*
* @param[in] begin, end Bounds of the new Slice. `begin` must be smaller
@ -221,125 +232,125 @@ namespace Exiv2 {
* @throw std::invalid_argument when `end` is larger than `LONG_MAX` or
* anything that the constructor of @ref Slice throws
*/
EXIV2API Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end);
EXIV2API Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end);
//! Overload of makeSlice for `const DataBuf`, returning an immutable Slice
EXIV2API Slice<const byte*> makeSlice(const DataBuf& buf, size_t begin, size_t end);
//! Overload of makeSlice for `const DataBuf`, returning an immutable Slice
EXIV2API Slice<const byte*> makeSlice(const DataBuf& buf, size_t begin, size_t end);
// *****************************************************************************
// free functions
// *****************************************************************************
// free functions
//! Read a 2 byte unsigned short value from the data buffer
EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
//! Read a 2 byte unsigned short value from a Slice
template <typename T>
uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder) {
//! Read a 2 byte unsigned short value from the data buffer
EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
//! Read a 2 byte unsigned short value from a Slice
template <typename T>
uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder) {
if (byteOrder == littleEndian) {
return static_cast<byte>(buf.at(1)) << 8 | static_cast<byte>(buf.at(0));
}
return static_cast<byte>(buf.at(0)) << 8 | static_cast<byte>(buf.at(1));
}
//! Read a 4 byte unsigned long value from the data buffer
EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
//! Read a 8 byte unsigned long value from the data buffer
EXIV2API uint64_t getULongLong(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte unsigned rational value from the data buffer
EXIV2API URational getURational(const byte* buf, ByteOrder byteOrder);
//! Read a 2 byte signed short value from the data buffer
EXIV2API int16_t getShort(const byte* buf, ByteOrder byteOrder);
//! Read a 4 byte signed long value from the data buffer
EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte signed rational value from the data buffer
EXIV2API Rational getRational(const byte* buf, ByteOrder byteOrder);
//! Read a 4 byte single precision floating point value (IEEE 754 binary32) from the data buffer
EXIV2API float getFloat(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte double precision floating point value (IEEE 754 binary64) from the data buffer
EXIV2API double getDouble(const byte* buf, ByteOrder byteOrder);
//! Output operator for our fake rational
EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r);
//! Input operator for our fake rational
EXIV2API std::istream& operator>>(std::istream& is, Rational& r);
//! Output operator for our fake unsigned rational
EXIV2API std::ostream& operator<<(std::ostream& os, const URational& r);
//! Input operator for our fake unsigned rational
EXIV2API std::istream& operator>>(std::istream& is, URational& r);
}
//! Read a 4 byte unsigned long value from the data buffer
EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
//! Read a 8 byte unsigned long value from the data buffer
EXIV2API uint64_t getULongLong(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte unsigned rational value from the data buffer
EXIV2API URational getURational(const byte* buf, ByteOrder byteOrder);
//! Read a 2 byte signed short value from the data buffer
EXIV2API int16_t getShort(const byte* buf, ByteOrder byteOrder);
//! Read a 4 byte signed long value from the data buffer
EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte signed rational value from the data buffer
EXIV2API Rational getRational(const byte* buf, ByteOrder byteOrder);
//! Read a 4 byte single precision floating point value (IEEE 754 binary32) from the data buffer
EXIV2API float getFloat(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte double precision floating point value (IEEE 754 binary64) from the data buffer
EXIV2API double getDouble(const byte* buf, ByteOrder byteOrder);
//! Output operator for our fake rational
EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r);
//! Input operator for our fake rational
EXIV2API std::istream& operator>>(std::istream& is, Rational& r);
//! Output operator for our fake unsigned rational
EXIV2API std::ostream& operator<<(std::ostream& os, const URational& r);
//! Input operator for our fake unsigned rational
EXIV2API std::istream& operator>>(std::istream& is, URational& r);
/*!
/*!
@brief Convert an unsigned short to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder);
/*!
EXIV2API long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder);
/*!
@brief Convert an unsigned long to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder);
/*!
EXIV2API long ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder);
/*!
@brief Convert an uint64_t to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long ull2Data(byte* buf, uint64_t l, ByteOrder byteOrder);
/*!
EXIV2API long ull2Data(byte* buf, uint64_t l, ByteOrder byteOrder);
/*!
@brief Convert an unsigned rational to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long ur2Data(byte* buf, URational l, ByteOrder byteOrder);
/*!
EXIV2API long ur2Data(byte* buf, URational l, ByteOrder byteOrder);
/*!
@brief Convert a signed short to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long s2Data(byte* buf, int16_t s, ByteOrder byteOrder);
/*!
EXIV2API long s2Data(byte* buf, int16_t s, ByteOrder byteOrder);
/*!
@brief Convert a signed long to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long l2Data(byte* buf, int32_t l, ByteOrder byteOrder);
/*!
EXIV2API long l2Data(byte* buf, int32_t l, ByteOrder byteOrder);
/*!
@brief Convert a signed rational to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API long r2Data(byte* buf, Rational l, ByteOrder byteOrder);
/*!
EXIV2API long r2Data(byte* buf, Rational l, ByteOrder byteOrder);
/*!
@brief Convert a single precision floating point (IEEE 754 binary32) float
to data, write the data to the buffer, return number of bytes written.
*/
EXIV2API long f2Data(byte* buf, float f, ByteOrder byteOrder);
/*!
EXIV2API long f2Data(byte* buf, float f, ByteOrder byteOrder);
/*!
@brief Convert a double precision floating point (IEEE 754 binary64) double
to data, write the data to the buffer, return number of bytes written.
*/
EXIV2API long d2Data(byte* buf, double d, ByteOrder byteOrder);
EXIV2API long d2Data(byte* buf, double d, ByteOrder byteOrder);
/*!
/*!
@brief Print len bytes from buf in hex and ASCII format to the given
stream, prefixed with the position in the buffer adjusted by
offset.
*/
EXIV2API void hexdump(std::ostream& os, const byte* buf, size_t len, size_t offset = 0);
EXIV2API void hexdump(std::ostream& os, const byte* buf, size_t len, size_t offset = 0);
/*!
/*!
@brief Return true if str is a hex number starting with prefix followed
by size hex digits, false otherwise. If size is 0, any number of
digits is allowed and all are checked.
*/
EXIV2API bool isHex(const std::string& str, size_t size = 0, const std::string& prefix = "");
EXIV2API bool isHex(const std::string& str, size_t size = 0, const std::string& prefix = "");
/*!
/*!
@brief Converts a string in the form "%Y:%m:%d %H:%M:%S", e.g.,
"2007:05:24 12:31:55" to broken down time format,
returns 0 if successful, else 1.
*/
EXIV2API int exifTime(const char* buf, struct tm* tm);
EXIV2API int exifTime(const char* buf, struct tm* tm);
/*!
/*!
@brief Translate a string using the gettext framework. This wrapper hides
all the implementation details from the interface.
*/
EXIV2API const char* exvGettext(const char* str);
EXIV2API const char* exvGettext(const char* str);
/*!
/*!
@brief Return a \em int64_t set to the value represented by \em s.
Besides strings that represent \em int64_t values, the function also
@ -350,10 +361,10 @@ namespace Exiv2 {
@param ok Output variable indicating the success of the operation.
@return Returns the \em int64_t value represented by \em s and sets \em ok
to \c true if the conversion was successful or \c false if not.
*/
EXIV2API int64_t parseInt64(const std::string& s, bool& ok);
*/
EXIV2API int64_t parseInt64(const std::string& s, bool& ok);
/*!
/*!
@brief Return a \em uint32_t set to the value represented by \em s.
Besides strings that represent \em uint32_t values, the function also
@ -364,10 +375,10 @@ namespace Exiv2 {
@param ok Output variable indicating the success of the operation.
@return Returns the \em uint32_t value represented by \em s and sets \em ok
to \c true if the conversion was successful or \c false if not.
*/
EXIV2API uint32_t parseUint32(const std::string& s, bool& ok);
*/
EXIV2API uint32_t parseUint32(const std::string& s, bool& ok);
/*!
/*!
@brief Return a \em float set to the value represented by \em s.
Besides strings that represent \em float values, the function also
@ -378,10 +389,10 @@ namespace Exiv2 {
@param ok Output variable indicating the success of the operation.
@return Returns the \em float value represented by \em s and sets \em ok
to \c true if the conversion was successful or \c false if not.
*/
EXIV2API float parseFloat(const std::string& s, bool& ok);
*/
EXIV2API float parseFloat(const std::string& s, bool& ok);
/*!
/*!
@brief Return a \em Rational set to the value represented by \em s.
Besides strings that represent \em Rational values, the function also
@ -394,21 +405,21 @@ namespace Exiv2 {
@param ok Output variable indicating the success of the operation.
@return Returns the \em Rational value represented by \em s and sets \em ok
to \c true if the conversion was successful or \c false if not.
*/
EXIV2API Rational parseRational(const std::string& s, bool& ok);
*/
EXIV2API Rational parseRational(const std::string& s, bool& ok);
/*!
/*!
@brief Very simple conversion of a \em float to a \em Rational.
Test it with the values that you expect and check the implementation
to see if this is really what you want!
*/
EXIV2API Rational floatToRationalCast(float f);
EXIV2API Rational floatToRationalCast(float f);
// *****************************************************************************
// template and inline definitions
// *****************************************************************************
// template and inline definitions
/*!
/*!
@brief Find an element that matches \em key in the array \em src.
Designed to be used with lookup tables as shown in the example below.
@ -451,22 +462,22 @@ namespace Exiv2 {
return 0;
}
@endcode
*/
template <typename T, typename K, int N>
const T* find(T (&src)[N], const K& key) {
*/
template <typename T, typename K, int N>
const T* find(T (&src)[N], const K& key) {
const T* rc = std::find(src, src + N, key);
return rc == src + N ? nullptr : rc;
}
}
//! Utility function to convert the argument of any type to a string
template <typename T>
std::string toString(const T& arg) {
//! Utility function to convert the argument of any type to a string
template <typename T>
std::string toString(const T& arg) {
std::ostringstream os;
os << arg;
return os.str();
}
}
/*!
/*!
@brief Utility function to convert a string to a value of type \c T.
The string representation of the value must match that recognized by
@ -477,28 +488,29 @@ namespace Exiv2 {
@return Returns the converted value and sets \em ok to \c true if the
conversion was successful or \c false if not.
*/
template <typename T>
T stringTo(const std::string& s, bool& ok) {
template <typename T>
T stringTo(const std::string& s, bool& ok) {
std::istringstream is(s);
T tmp = T();
ok = bool(is >> tmp);
std::string rest;
is >> std::skipws >> rest;
if (!rest.empty()) ok = false;
if (!rest.empty())
ok = false;
return tmp;
}
}
/*!
/*!
@brief Specialization of stringTo(const std::string& s, bool& ok) for \em bool.
Handles the same string values as the XMP SDK. Converts the string to lowercase
and returns \c true if it is "true", "t" or "1", and \c false if it is
"false", "f" or "0".
*/
template <>
bool stringTo<bool>(const std::string& s, bool& ok);
template <>
bool stringTo<bool>(const std::string& s, bool& ok);
/*!
/*!
@brief Return the greatest common denominator of n and m.
(Implementation from Boost rational.hpp)
@ -506,8 +518,8 @@ namespace Exiv2 {
value in using const IntType& as we would only need to make a copy
anyway...
*/
template <typename IntType>
IntType gcd(IntType n, IntType m) {
template <typename IntType>
IntType gcd(IntType n, IntType m) {
// Avoid repeated construction
IntType zero(0);
@ -528,12 +540,14 @@ namespace Exiv2 {
// positive value (the standard guarantees this for built-in types,
// and we require it of user-defined types).
for (;;) {
if (m == zero) return n;
if (m == zero)
return n;
n %= m;
if (n == zero) return m;
if (n == zero)
return m;
m %= n;
}
}
}
} // namespace Exiv2

File diff suppressed because it is too large Load Diff

@ -9,21 +9,19 @@
// *****************************************************************************
// included header files
// + standard includes
#include <vector>
#include <regex>
#include <vector>
/*!
@brief Make an integer version number for comparison from a major, minor and
a patch version number.
*/
#define EXIV2_MAKE_VERSION(major,minor,patch) \
(((major) << 16) | ((minor) << 8) | (patch))
#define EXIV2_MAKE_VERSION(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch))
/*!
@brief The %Exiv2 version number of the library used at compile-time as
an integer number for easy comparison.
*/
#define EXIV2_VERSION \
EXIV2_MAKE_VERSION(EXIV2_MAJOR_VERSION,EXIV2_MINOR_VERSION,EXIV2_PATCH_VERSION)
#define EXIV2_VERSION EXIV2_MAKE_VERSION(EXIV2_MAJOR_VERSION, EXIV2_MINOR_VERSION, EXIV2_PATCH_VERSION)
/*!
@brief Macro to test the version the %Exiv2 library at compile-time.
@ -68,45 +66,42 @@
#endif
@endcode
*/
#define EXIV2_TEST_VERSION(major,minor,patch) \
( EXIV2_VERSION >= EXIV2_MAKE_VERSION(major,minor,patch) )
#define EXIV2_TEST_VERSION(major, minor, patch) (EXIV2_VERSION >= EXIV2_MAKE_VERSION(major, minor, patch))
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
/*!
/*!
@brief Return the version of %Exiv2 available at runtime as an integer.
*/
EXIV2API int versionNumber();
/*!
*/
EXIV2API int versionNumber();
/*!
@brief Return the version string Example: "0.25.0" (major.minor.patch)
*/
EXIV2API std::string versionString();
/*!
*/
EXIV2API std::string versionString();
/*!
@brief Return the version of %Exiv2 as hex string of fixed length 6.
*/
EXIV2API std::string versionNumberHexString();
*/
EXIV2API std::string versionNumberHexString();
/*!
/*!
@brief Return the version of %Exiv2 as "C" string eg "0.27.0.2".
*/
EXIV2API const char* version();
*/
EXIV2API const char* version();
/*!
/*!
@brief Test the version of the available %Exiv2 library at runtime. Return
true if it is the same as or newer than the passed-in version.
Versions are denoted using a triplet of integers: \em major.minor.patch .
The fourth version number is designated a "tweak" an used by Release Candidates
*/
EXIV2API bool testVersion(int major, int minor, int patch);
/*!
*/
EXIV2API bool testVersion(int major, int minor, int patch);
/*!
@brief dumpLibraryInfo implements the exiv2 option --version --verbose
used by exiv2 test suite to inspect libraries loaded at run-time
*/
EXIV2API void dumpLibraryInfo(std::ostream& os,const std::vector<std::regex>& keys);
EXIV2API void dumpLibraryInfo(std::ostream& os, const std::vector<std::regex>& keys);
} // namespace Exiv2
#endif // VERSION_HPP_

@ -12,15 +12,13 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access WEBP video files.
*/
class EXIV2API WebPImage:public Image
{
class EXIV2API WebPImage : public Image {
public:
//! @name Creators
//@{
@ -68,11 +66,9 @@ namespace Exiv2 {
//@{
static long getHeaderOffset(const byte* data, long data_size, const byte* header, long header_size);
static bool equalsWebPTag(Exiv2::DataBuf& buf, const char* str);
void debugPrintHex(byte *data, long size);
void debugPrintHex(byte* data, long size);
void decodeChunks(long filesize);
void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif,
bool has_alpha, bool has_icc, int width,
int height);
void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_alpha, bool has_icc, int width, int height);
static const byte WEBP_PAD_ODD;
static const int WEBP_TAG_SIZE;
@ -89,22 +85,22 @@ namespace Exiv2 {
static const char* const WEBP_CHUNK_HEADER_EXIF;
static const char* const WEBP_CHUNK_HEADER_XMP;
}; //Class WebPImage
}; // Class WebPImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new WebPImage instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newWebPInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newWebPInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a WebP Video.
EXIV2API bool isWebPType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a WebP Video.
EXIV2API bool isWebPType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -13,19 +13,18 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class ExifData;
// *****************************************************************************
// class definitions
/*!
/*!
@brief Information related to an XMP property. An XMP metadatum consists
of an XmpKey and a Value and provides methods to manipulate these.
*/
class EXIV2API Xmpdatum : public Metadatum {
class EXIV2API Xmpdatum : public Metadatum {
public:
//! @name Creators
//@{
@ -71,7 +70,7 @@ namespace Exiv2 {
@brief Assign a \em value of any type with an output operator
to the %Xmpdatum. Calls operator=(const std::string&).
*/
template<typename T>
template <typename T>
Xmpdatum& operator=(const T& value);
/*!
@brief Assign Value \em value to the %Xmpdatum.
@ -130,12 +129,12 @@ namespace Exiv2 {
struct Impl;
std::unique_ptr<Impl> p_;
}; // class Xmpdatum
}; // class Xmpdatum
//! Container type to hold all metadata
using XmpMetadata = std::vector<Xmpdatum>;
//! Container type to hold all metadata
using XmpMetadata = std::vector<Xmpdatum>;
/*!
/*!
@brief A container for XMP data. This is a top-level class of
the %Exiv2 library.
@ -144,8 +143,8 @@ namespace Exiv2 {
- access metadata through keys and standard C++ iterators
- add, modify and delete metadata
- serialize XMP data to an XML block
*/
class EXIV2API XmpData {
*/
class EXIV2API XmpData {
public:
//! Default constructor
XmpData() = default;
@ -224,30 +223,41 @@ namespace Exiv2 {
long count() const;
//! are we to use the packet?
bool usePacket() const { return usePacket_; } ;
bool usePacket() const {
return usePacket_;
};
//! set usePacket_
bool usePacket(bool b) { bool r = usePacket_; usePacket_=b ; return r; };
bool usePacket(bool b) {
bool r = usePacket_;
usePacket_ = b;
return r;
};
//! setPacket
void setPacket(const std::string& xmpPacket) { xmpPacket_ = xmpPacket ; usePacket(false); };
void setPacket(const std::string& xmpPacket) {
xmpPacket_ = xmpPacket;
usePacket(false);
};
// ! getPacket
const std::string& xmpPacket() const { return xmpPacket_ ; };
const std::string& xmpPacket() const {
return xmpPacket_;
};
//@}
private:
// DATA
XmpMetadata xmpMetadata_;
std::string xmpPacket_ ;
std::string xmpPacket_;
bool usePacket_{};
}; // class XmpData
}; // class XmpData
/*!
/*!
@brief Stateless parser class for XMP packets. Images use this
class to parse and serialize XMP packets. The parser uses
the XMP toolkit to do the job.
*/
class EXIV2API XmpParser {
class EXIV2API XmpParser {
public:
//! Options to control the format of the serialized XMP packet.
enum XmpFormatFlags {
@ -272,8 +282,7 @@ namespace Exiv2 {
2 if the XMP toolkit failed to initialize;<BR>
3 if the XMP toolkit failed and raised an XMP_Error
*/
static int decode( XmpData& xmpData,
const std::string& xmpPacket);
static int decode(XmpData& xmpData, const std::string& xmpPacket);
/*!
@brief Encode (serialize) XMP metadata from \em xmpData into a
string xmpPacket. The XMP packet returned in the string
@ -291,10 +300,8 @@ namespace Exiv2 {
2 if the XMP toolkit failed to initialize;<BR>
3 if the XMP toolkit failed and raised an XMP_Error
*/
static int encode( std::string& xmpPacket,
const XmpData& xmpData,
uint16_t formatFlags =useCompactFormat,
uint32_t padding =0);
static int encode(std::string& xmpPacket, const XmpData& xmpData, uint16_t formatFlags = useCompactFormat,
uint32_t padding = 0);
/*!
@brief Lock/unlock function type
@ -370,8 +377,7 @@ namespace Exiv2 {
/*!
@brief Register a namespace with the XMP Toolkit.
*/
static void registerNs(const std::string& ns,
const std::string& prefix);
static void registerNs(const std::string& ns, const std::string& prefix);
/*!
@brief Delete a namespace from the XMP Toolkit.
@ -391,27 +397,24 @@ namespace Exiv2 {
friend class XmpProperties; // permit XmpProperties -> registerNs() and registeredNamespaces()
}; // class XmpParser
}; // class XmpParser
// *****************************************************************************
// free functions, template and inline definitions
inline Xmpdatum& Xmpdatum::operator=(const char* value)
{
inline Xmpdatum& Xmpdatum::operator=(const char* value) {
return Xmpdatum::operator=(std::string(value));
}
}
inline Xmpdatum& Xmpdatum::operator=(const bool& value)
{
inline Xmpdatum& Xmpdatum::operator=(const bool& value) {
return operator=(value ? "True" : "False");
}
}
template<typename T>
Xmpdatum& Xmpdatum::operator=(const T& value)
{
template <typename T>
Xmpdatum& Xmpdatum::operator=(const T& value) {
setValue(Exiv2::toString(value));
return *this;
}
}
} // namespace Exiv2

@ -12,14 +12,13 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
/*!
@brief Class to access XMP sidecar files. They contain only XMP metadata.
*/
class EXIV2API XmpSidecar : public Image {
class EXIV2API XmpSidecar : public Image {
public:
//! @name Creators
//@{
@ -66,22 +65,22 @@ namespace Exiv2 {
Exiv2::Dictionary dates_;
}; // class XmpSidecar
}; // class XmpSidecar
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new XmpSidecar instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newXmpInstance(BasicIo::UniquePtr io, bool create);
EXIV2API Image::UniquePtr newXmpInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is an XMP sidecar file.
EXIV2API bool isXmpType(BasicIo& iIo, bool advance);
//! Check if the file iIo is an XMP sidecar file.
EXIV2API bool isXmpType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -57,7 +57,7 @@ target_include_directories(getopt-test PRIVATE
${CMAKE_SOURCE_DIR}/app
) # To find getopt.hpp
add_executable( metacopy metacopy.cpp ../app/getopt.cpp)
add_executable( metacopy metacopy.cpp metacopy.hpp ../app/getopt.cpp)
list(APPEND APPLICATIONS metacopy)
target_include_directories(metacopy PRIVATE
${CMAKE_SOURCE_DIR}/app

File diff suppressed because it is too large Load Diff

@ -23,74 +23,70 @@ THE SOFTWARE.
#define Jzon_h__
#ifndef JzonAPI
# ifdef _WINDLL
# define JzonAPI __declspec(dllimport)
# elif defined(__GNUC__) && (__GNUC__ >= 4)
# define JzonAPI __attribute__ ((visibility("default")))
# else
# define JzonAPI
# endif
#ifdef _WINDLL
#define JzonAPI __declspec(dllimport)
#elif defined(__GNUC__) && (__GNUC__ >= 4)
#define JzonAPI __attribute__((visibility("default")))
#else
#define JzonAPI
#endif
#endif
#include <string>
#include <vector>
#include <queue>
#include <iterator>
#include <queue>
#include <stdexcept>
#include <string>
#include <vector>
namespace Jzon
{
class Node;
class Value;
class Object;
class Array;
using NamedNode = std::pair<std::string, Node&>;
using NamedNodePtr = std::pair<std::string, Node*>;
class TypeException : public std::logic_error
{
namespace Jzon {
class Node;
class Value;
class Object;
class Array;
using NamedNode = std::pair<std::string, Node &>;
using NamedNodePtr = std::pair<std::string, Node *>;
class TypeException : public std::logic_error {
public:
TypeException() : std::logic_error("A Node was used as the wrong type")
{}
};
class NotFoundException : public std::out_of_range
{
TypeException() : std::logic_error("A Node was used as the wrong type") {
}
};
class NotFoundException : public std::out_of_range {
public:
NotFoundException() : std::out_of_range("The node could not be found")
{}
};
NotFoundException() : std::out_of_range("The node could not be found") {
}
};
struct Format
{
struct Format {
bool newline;
bool spacing;
bool useTabs;
unsigned int indentSize;
};
static const Format StandardFormat = { true, true, true, 1 };
static const Format NoFormat = { false, false, false, 0 };
};
static const Format StandardFormat = {true, true, true, 1};
static const Format NoFormat = {false, false, false, 0};
class JzonAPI Node
{
class JzonAPI Node {
friend class Object;
friend class Array;
public:
enum Type
{
T_OBJECT,
T_ARRAY,
T_VALUE
};
enum Type { T_OBJECT, T_ARRAY, T_VALUE };
Node() noexcept = default;
virtual ~Node() noexcept = default;
virtual Type GetType() const = 0;
inline bool IsObject() const { return (GetType() == T_OBJECT); }
inline bool IsArray() const { return (GetType() == T_ARRAY); }
inline bool IsValue() const { return (GetType() == T_VALUE); }
inline bool IsObject() const {
return (GetType() == T_OBJECT);
}
inline bool IsArray() const {
return (GetType() == T_ARRAY);
}
inline bool IsValue() const {
return (GetType() == T_VALUE);
}
Object &AsObject();
const Object &AsObject() const;
@ -99,38 +95,57 @@ namespace Jzon
Value &AsValue();
const Value &AsValue() const;
virtual inline bool IsNull() const { return false; }
virtual inline bool IsString() const { return false; }
virtual inline bool IsNumber() const { return false; }
virtual inline bool IsBool() const { return false; }
virtual inline bool IsNull() const {
return false;
}
virtual inline bool IsString() const {
return false;
}
virtual inline bool IsNumber() const {
return false;
}
virtual inline bool IsBool() const {
return false;
}
virtual std::string ToString() const { throw TypeException(); }
virtual int ToInt() const { throw TypeException(); }
virtual float ToFloat() const { throw TypeException(); }
virtual double ToDouble() const { throw TypeException(); }
virtual bool ToBool() const { throw TypeException(); }
virtual std::string ToString() const {
throw TypeException();
}
virtual int ToInt() const {
throw TypeException();
}
virtual float ToFloat() const {
throw TypeException();
}
virtual double ToDouble() const {
throw TypeException();
}
virtual bool ToBool() const {
throw TypeException();
}
virtual bool Has(const std::string &/*name*/) const { throw TypeException(); }
virtual size_t GetCount() const { return 0; }
virtual Node &Get(const std::string &/*name*/) const { throw TypeException(); }
virtual Node &Get(size_t /*index*/) const { throw TypeException(); }
virtual bool Has(const std::string & /*name*/) const {
throw TypeException();
}
virtual size_t GetCount() const {
return 0;
}
virtual Node &Get(const std::string & /*name*/) const {
throw TypeException();
}
virtual Node &Get(size_t /*index*/) const {
throw TypeException();
}
static Type DetermineType(const std::string &json);
protected:
virtual Node *GetCopy() const = 0;
};
};
class JzonAPI Value : public Node
{
class JzonAPI Value : public Node {
public:
enum ValueType
{
VT_NULL,
VT_STRING,
VT_NUMBER,
VT_BOOL
};
enum ValueType { VT_NULL, VT_STRING, VT_NUMBER, VT_BOOL };
Value();
Value(const Value &rhs);
@ -147,20 +162,16 @@ namespace Jzon
Type GetType() const override;
ValueType GetValueType() const;
inline bool IsNull() const override
{
inline bool IsNull() const override {
return (type == VT_NULL);
}
inline bool IsString() const override
{
inline bool IsString() const override {
return (type == VT_STRING);
}
inline bool IsNumber() const override
{
inline bool IsNumber() const override {
return (type == VT_NUMBER);
}
inline bool IsBool() const override
{
inline bool IsBool() const override {
return (type == VT_BOOL);
}
@ -201,43 +212,70 @@ namespace Jzon
private:
std::string valueStr;
ValueType type;
};
};
static const Value null;
static const Value null;
class JzonAPI Object : public Node
{
class JzonAPI Object : public Node {
public:
class iterator : public std::iterator<std::input_iterator_tag, NamedNode>
{
class iterator : public std::iterator<std::input_iterator_tag, NamedNode> {
public:
iterator(NamedNodePtr *o) : p(o) {}
iterator(const iterator &it) : p(it.p) {}
iterator(NamedNodePtr *o) : p(o) {
}
iterator(const iterator &it) : p(it.p) {
}
iterator &operator++() { ++p; return *this; }
iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
iterator &operator++() {
++p;
return *this;
}
iterator operator++(int) {
iterator tmp(*this);
operator++();
return tmp;
}
bool operator==(const iterator &rhs) { return p == rhs.p; }
bool operator!=(const iterator &rhs) { return p != rhs.p; }
bool operator==(const iterator &rhs) {
return p == rhs.p;
}
bool operator!=(const iterator &rhs) {
return p != rhs.p;
}
NamedNode operator*() { return NamedNode(p->first, *p->second); }
NamedNode operator*() {
return NamedNode(p->first, *p->second);
}
private:
NamedNodePtr *p;
};
class const_iterator : public std::iterator<std::input_iterator_tag, const NamedNode>
{
class const_iterator : public std::iterator<std::input_iterator_tag, const NamedNode> {
public:
const_iterator(const NamedNodePtr *o) : p(o) {}
const_iterator(const const_iterator &it) : p(it.p) {}
const_iterator(const NamedNodePtr *o) : p(o) {
}
const_iterator(const const_iterator &it) : p(it.p) {
}
const_iterator &operator++() { ++p; return *this; }
const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
const_iterator &operator++() {
++p;
return *this;
}
const_iterator operator++(int) {
const_iterator tmp(*this);
operator++();
return tmp;
}
bool operator==(const const_iterator &rhs) { return p == rhs.p; }
bool operator!=(const const_iterator &rhs) { return p != rhs.p; }
bool operator==(const const_iterator &rhs) {
return p == rhs.p;
}
bool operator!=(const const_iterator &rhs) {
return p != rhs.p;
}
const NamedNode operator*() { return NamedNode(p->first, *p->second); }
const NamedNode operator*() {
return NamedNode(p->first, *p->second);
}
private:
const NamedNodePtr *p;
@ -271,41 +309,68 @@ namespace Jzon
private:
using ChildList = std::vector<NamedNodePtr>;
ChildList children;
};
};
class JzonAPI Array : public Node
{
class JzonAPI Array : public Node {
public:
class iterator : public std::iterator<std::input_iterator_tag, Node>
{
class iterator : public std::iterator<std::input_iterator_tag, Node> {
public:
iterator(Node **o) : p(o) {}
iterator(const iterator &it) : p(it.p) {}
iterator(Node **o) : p(o) {
}
iterator(const iterator &it) : p(it.p) {
}
iterator &operator++() { ++p; return *this; }
iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
iterator &operator++() {
++p;
return *this;
}
iterator operator++(int) {
iterator tmp(*this);
operator++();
return tmp;
}
bool operator==(const iterator &rhs) { return p == rhs.p; }
bool operator!=(const iterator &rhs) { return p != rhs.p; }
bool operator==(const iterator &rhs) {
return p == rhs.p;
}
bool operator!=(const iterator &rhs) {
return p != rhs.p;
}
Node &operator*() { return **p; }
Node &operator*() {
return **p;
}
private:
Node **p;
};
class const_iterator : public std::iterator<std::input_iterator_tag, const Node>
{
class const_iterator : public std::iterator<std::input_iterator_tag, const Node> {
public:
const_iterator(const Node *const *o) : p(o) {}
const_iterator(const const_iterator &it) : p(it.p) {}
const_iterator(const Node *const *o) : p(o) {
}
const_iterator(const const_iterator &it) : p(it.p) {
}
const_iterator &operator++() { ++p; return *this; }
const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
const_iterator &operator++() {
++p;
return *this;
}
const_iterator operator++(int) {
const_iterator tmp(*this);
operator++();
return tmp;
}
bool operator==(const const_iterator &rhs) { return p == rhs.p; }
bool operator!=(const const_iterator &rhs) { return p != rhs.p; }
bool operator==(const const_iterator &rhs) {
return p == rhs.p;
}
bool operator!=(const const_iterator &rhs) {
return p != rhs.p;
}
const Node &operator*() { return **p; }
const Node &operator*() {
return **p;
}
private:
const Node *const *p;
@ -338,10 +403,9 @@ namespace Jzon
private:
using ChildList = std::vector<Node *>;
ChildList children;
};
};
class JzonAPI FileWriter
{
class JzonAPI FileWriter {
public:
FileWriter(std::string filename);
~FileWriter() = default;
@ -352,10 +416,9 @@ namespace Jzon
private:
std::string filename;
};
};
class JzonAPI FileReader
{
class JzonAPI FileReader {
public:
FileReader(const std::string &filename);
~FileReader() = default;
@ -372,10 +435,9 @@ namespace Jzon
static bool loadFile(const std::string &filename, std::string &json);
std::string json;
std::string error;
};
};
class JzonAPI Writer
{
class JzonAPI Writer {
public:
Writer(const Node &root, const Format &format = NoFormat);
~Writer();
@ -387,7 +449,8 @@ namespace Jzon
const std::string &GetResult() const;
// Disable assignment operator
Writer &operator=(const Writer&) = delete;
Writer &operator=(const Writer &) = delete;
private:
void writeNode(const Node &node, size_t level);
void writeObject(const Object &node, size_t level);
@ -399,10 +462,9 @@ namespace Jzon
class FormatInterpreter *fi;
const Node &root;
};
};
class JzonAPI Parser
{
class JzonAPI Parser {
public:
Parser(Node &root);
Parser(Node &root, const std::string &json);
@ -414,10 +476,10 @@ namespace Jzon
const std::string &GetError() const;
// Disable assignment operator
Parser &operator=(const Parser&) = delete;
Parser &operator=(const Parser &) = delete;
private:
enum Token
{
enum Token {
T_UNKNOWN,
T_OBJ_BEGIN,
T_OBJ_END,
@ -442,14 +504,14 @@ namespace Jzon
std::size_t jsonSize{0};
std::queue<Token> tokens;
std::queue<std::pair<Value::ValueType, std::string> > data;
std::queue<std::pair<Value::ValueType, std::string>> data;
std::size_t cursor{0};
Node &root;
std::string error;
};
}
};
} // namespace Jzon
#endif // Jzon_h__

@ -3,11 +3,11 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <cassert>
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -67,8 +67,7 @@ try {
std::string date = tag.toString();
date.replace(0, 4, "2000");
tag.setValue(date);
std::cout << "Modified key \"" << tag.key()
<< "\", new value \"" << tag.value() << "\"\n";
std::cout << "Modified key \"" << tag.key() << "\", new value \"" << tag.value() << "\"\n";
// Alternatively, we can use findKey()
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
@ -88,8 +87,7 @@ try {
rv.value_.at(2) = {88, 77};
// Copy the modified value back to the metadatum
pos->setValue(&rv);
std::cout << "Modified key \"" << key
<< "\", new value \"" << pos->value() << "\"\n";
std::cout << "Modified key \"" << key << "\", new value \"" << pos->value() << "\"\n";
// *************************************************************************
// Delete metadata from the Exif data container
@ -97,7 +95,8 @@ try {
// Delete the metadatum at iterator position pos
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
pos = exifData.findKey(key);
if (pos == exifData.end()) throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Key not found");
if (pos == exifData.end())
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Key not found");
exifData.erase(pos);
std::cout << "Deleted key \"" << key << "\"\n";
@ -108,8 +107,8 @@ try {
image->writeMetadata();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}

@ -3,10 +3,10 @@
#include <exiv2/exiv2.hpp>
#ifdef EXV_USE_CURL
#include <curl/curl.h>
#include <curl/curl.h>
#endif
#include <iostream>
#include <cstdlib>
#include <iostream>
void httpcon(const std::string& url, bool useHttp1_0 = false) {
Exiv2::Dictionary response;
@ -19,9 +19,10 @@ void httpcon(const std::string& url, bool useHttp1_0 = false) {
request["server"] = uri.Host;
request["page"] = uri.Path;
request["port"] = uri.Port;
if (!useHttp1_0) request["version"] = "1.1";
if (!useHttp1_0)
request["version"] = "1.1";
int serverCode = Exiv2::http(request,response,errors);
int serverCode = Exiv2::http(request, response, errors);
if (serverCode < 0 || serverCode >= 400 || !errors.empty()) {
throw Exiv2::Error(Exiv2::ErrorCode::kerTiffDirectoryTooLarge, "Server", serverCode);
}
@ -30,7 +31,7 @@ void httpcon(const std::string& url, bool useHttp1_0 = false) {
#ifdef EXV_USE_CURL
void curlcon(const std::string& url, bool useHttp1_0 = false) {
CURL* curl = curl_easy_init();
if(!curl) {
if (!curl) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Unable to init libcurl.");
}
@ -48,19 +49,21 @@ void curlcon(const std::string& url, bool useHttp1_0 = false) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); // debug
if (useHttp1_0) curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
else curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); // debug
if (useHttp1_0)
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
else
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
/* Perform the request, res will get the return code */
CURLcode res = curl_easy_perform(curl);
if(res != CURLE_OK) { // error happened
if (res != CURLE_OK) { // error happened
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, curl_easy_strerror(res));
}
// get return code
long returnCode;
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &returnCode); // get code
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &returnCode); // get code
curl_easy_cleanup(curl);
if (returnCode >= 400 || returnCode < 0) {
@ -69,8 +72,7 @@ void curlcon(const std::string& url, bool useHttp1_0 = false) {
}
#endif
int main(int argc,const char** argv)
{
int main(int argc, const char** argv) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -85,19 +87,20 @@ int main(int argc,const char** argv)
Exiv2::Protocol prot = Exiv2::fileProtocol(url);
bool useHttp1_0 = false;
for ( int a = 1 ; a < argc ; a++ ) {
for (int a = 1; a < argc; a++) {
std::string arg(argv[a]);
if (arg == "-http1_0") useHttp1_0 = true;
if (arg == "-http1_0")
useHttp1_0 = true;
}
bool isOk = false;
try {
#ifdef EXV_USE_CURL
#ifdef EXV_USE_CURL
if (prot == Exiv2::pHttp || prot == Exiv2::pHttps || prot == Exiv2::pFtp) {
curlcon(url, useHttp1_0);
isOk = true;
}
#endif
#endif
if (!isOk && prot == Exiv2::pHttp) {
httpcon(url, useHttp1_0);
isOk = true;
@ -107,8 +110,10 @@ int main(int argc,const char** argv)
return -1;
}
if (!isOk) std::cout << "The protocol is unsupported." << std::endl;
else std::cout << "OK." << std::endl;
if (!isOk)
std::cout << "The protocol is unsupported." << std::endl;
else
std::cout << "OK." << std::endl;
return 0;
}

@ -3,11 +3,11 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <cassert>
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -33,8 +33,8 @@ try {
image->writeMetadata();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Sample program using high-level metadata access functions
#include <cassert>
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <iostream>
using EasyAccessFct = Exiv2::ExifData::const_iterator (*)(const Exiv2::ExifData&);
@ -13,45 +13,43 @@ struct EasyAccess {
EasyAccessFct findFct_;
};
static const EasyAccess easyAccess[] = {
{ "Orientation", Exiv2::orientation },
{ "ISO speed", Exiv2::isoSpeed },
{ "Date & time original", Exiv2::dateTimeOriginal },
{ "Flash bias", Exiv2::flashBias },
{ "Exposure mode", Exiv2::exposureMode },
{ "Scene mode", Exiv2::sceneMode },
{ "Macro mode", Exiv2::macroMode },
{ "Image quality", Exiv2::imageQuality },
{ "White balance", Exiv2::whiteBalance },
{ "Lens name", Exiv2::lensName },
{ "Saturation", Exiv2::saturation },
{ "Sharpness", Exiv2::sharpness },
{ "Contrast", Exiv2::contrast },
{ "Scene capture type", Exiv2::sceneCaptureType },
{ "Metering mode", Exiv2::meteringMode },
{ "Camera make", Exiv2::make },
{ "Camera model", Exiv2::model },
{ "Exposure time", Exiv2::exposureTime },
{ "FNumber", Exiv2::fNumber },
{ "Shutter speed value", Exiv2::shutterSpeedValue },
{ "Aperture value", Exiv2::apertureValue },
{ "Brightness value", Exiv2::brightnessValue },
{ "Exposure bias", Exiv2::exposureBiasValue },
{ "Max aperture value", Exiv2::maxApertureValue },
{ "Subject distance", Exiv2::subjectDistance },
{ "Light source", Exiv2::lightSource },
{ "Flash", Exiv2::flash },
{ "Camera serial number", Exiv2::serialNumber },
{ "Focal length", Exiv2::focalLength },
{ "Subject location/area", Exiv2::subjectArea },
{ "Flash energy", Exiv2::flashEnergy },
{ "Exposure index", Exiv2::exposureIndex },
{ "Sensing method", Exiv2::sensingMethod },
{ "AF point", Exiv2::afPoint }
};
static const EasyAccess easyAccess[] = {{"Orientation", Exiv2::orientation},
{"ISO speed", Exiv2::isoSpeed},
{"Date & time original", Exiv2::dateTimeOriginal},
{"Flash bias", Exiv2::flashBias},
{"Exposure mode", Exiv2::exposureMode},
{"Scene mode", Exiv2::sceneMode},
{"Macro mode", Exiv2::macroMode},
{"Image quality", Exiv2::imageQuality},
{"White balance", Exiv2::whiteBalance},
{"Lens name", Exiv2::lensName},
{"Saturation", Exiv2::saturation},
{"Sharpness", Exiv2::sharpness},
{"Contrast", Exiv2::contrast},
{"Scene capture type", Exiv2::sceneCaptureType},
{"Metering mode", Exiv2::meteringMode},
{"Camera make", Exiv2::make},
{"Camera model", Exiv2::model},
{"Exposure time", Exiv2::exposureTime},
{"FNumber", Exiv2::fNumber},
{"Shutter speed value", Exiv2::shutterSpeedValue},
{"Aperture value", Exiv2::apertureValue},
{"Brightness value", Exiv2::brightnessValue},
{"Exposure bias", Exiv2::exposureBiasValue},
{"Max aperture value", Exiv2::maxApertureValue},
{"Subject distance", Exiv2::subjectDistance},
{"Light source", Exiv2::lightSource},
{"Flash", Exiv2::flash},
{"Camera serial number", Exiv2::serialNumber},
{"Focal length", Exiv2::focalLength},
{"Subject location/area", Exiv2::subjectArea},
{"Flash energy", Exiv2::flashEnergy},
{"Exposure index", Exiv2::exposureIndex},
{"Sensing method", Exiv2::sensingMethod},
{"AF point", Exiv2::afPoint}};
int main(int argc, char **argv)
try {
int main(int argc, char** argv) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -71,17 +69,16 @@ try {
auto pos = ea.findFct_(ed);
std::cout << std::setw(21) << std::left << ea.label_;
if (pos != ed.end()) {
std::cout << " (" << std::setw(35) << pos->key() << ") : "
<< pos->print(&ed) << "\n";
}
else {
std::cout << " (" << std::setw(35) << " " << ") : \n";
std::cout << " (" << std::setw(35) << pos->key() << ") : " << pos->print(&ed) << "\n";
} else {
std::cout << " (" << std::setw(35) << " "
<< ") : \n";
}
}
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}

@ -1,14 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Abstract : Sample program showing how to set the Exif comment of an image, Exif.Photo.UserComment
#include <cassert>
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <cassert>
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -22,7 +22,7 @@ try {
auto image = Exiv2::ImageFactory::open(argv[1]);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
Exiv2::ExifData& exifData = image->exifData();
/*
Exiv2 uses a CommentValue for Exif user comments. The format of the
@ -41,15 +41,13 @@ try {
exifData["Exif.Photo.UserComment"] = "Another undefined Exif comment added with Exiv2";
exifData["Exif.Photo.UserComment"] = "charset=Ascii An ASCII Exif comment added with Exiv2";
std::cout << "Writing user comment '"
<< exifData["Exif.Photo.UserComment"]
<< "' back to the image\n";
std::cout << "Writing user comment '" << exifData["Exif.Photo.UserComment"] << "' back to the image\n";
image->writeMetadata();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}

@ -8,9 +8,8 @@ void print(const std::string& file);
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
int main(int argc, char* const argv[]) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -24,10 +23,10 @@ try {
std::string file(argv[1]);
auto image = Exiv2::ImageFactory::open(file);
assert (image);
assert(image);
image->readMetadata();
Exiv2::ExifData &ed = image->exifData();
Exiv2::ExifData& ed = image->exifData();
if (ed.empty()) {
std::string error = file + ": No Exif data found in the file";
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
@ -40,7 +39,7 @@ try {
ed1["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am";
ed1["Exif.Photo.MeteringMode"] = uint16_t(1);
ed1["Exif.Iop.InteroperabilityIndex"] = "123";
// ed1["Exif.Thumbnail.Orientation"] = uint16_t(2);
// ed1["Exif.Thumbnail.Orientation"] = uint16_t(2);
write(file, ed1);
print(file);
std::cout << "----------------------------------------------\n";
@ -87,40 +86,29 @@ try {
print(file);
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}
}
void write(const std::string& file, Exiv2::ExifData& ed)
{
void write(const std::string& file, Exiv2::ExifData& ed) {
auto image = Exiv2::ImageFactory::open(file);
image->setExifData(ed);
image->writeMetadata();
}
void print(const std::string& file)
{
void print(const std::string& file) {
auto image = Exiv2::ImageFactory::open(file);
image->readMetadata();
Exiv2::ExifData &ed = image->exifData();
Exiv2::ExifData& ed = image->exifData();
auto end = ed.end();
for (auto i = ed.begin(); i != end; ++i) {
std::cout << std::setw(45) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(12) << std::setfill(' ') << std::left
<< i->ifdName() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< i->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->toString()
<< "\n";
std::cout << std::setw(45) << std::setfill(' ') << std::left << i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " " << std::setw(12)
<< std::setfill(' ') << std::left << i->ifdName() << " " << std::setw(9) << std::setfill(' ') << std::left
<< i->typeName() << " " << std::dec << std::setw(3) << std::setfill(' ') << std::right << i->count()
<< " " << std::dec << i->toString() << "\n";
}
}

@ -3,22 +3,15 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <cassert>
#include <iostream>
#include <string>
using format_t = std::map<std::string, int>;
using format_i = format_t::const_iterator;
enum format_e
{
wolf,
csv,
json,
xml
};
void syntax(const char* argv[],format_t& formats)
{
enum format_e { wolf, csv, json, xml };
void syntax(const char* argv[], format_t& formats) {
std::cout << "Usage: " << argv[0] << " file format" << std::endl;
int count = 0;
std::cout << "formats: ";
@ -28,18 +21,19 @@ void syntax(const char* argv[],format_t& formats)
std::cout << std::endl;
}
size_t formatInit(Exiv2::ExifData& exifData)
{
size_t formatInit(Exiv2::ExifData& exifData) {
return std::distance(exifData.begin(), exifData.end());
}
///////////////////////////////////////////////////////////////////////
std::string escapeCSV(Exiv2::ExifData::const_iterator it,bool bValue)
{
std::string result ;
std::string escapeCSV(Exiv2::ExifData::const_iterator it, bool bValue) {
std::string result;
std::ostringstream os;
if ( bValue ) os << it->value() ; else os << it->key() ;
if (bValue)
os << it->value();
else
os << it->key();
std::string s = os.str();
for (auto&& c : s) {
@ -51,46 +45,46 @@ std::string escapeCSV(Exiv2::ExifData::const_iterator it,bool bValue)
return result;
}
std::string formatCSV(Exiv2::ExifData& exifData)
{
std::string formatCSV(Exiv2::ExifData& exifData) {
size_t count = 0;
size_t length = formatInit(exifData);
std::ostringstream result;
for (auto i = exifData.begin(); count++ < length; ++i) {
result << escapeCSV(i,false) << (count != length ? ", " : "" ) ;
result << escapeCSV(i, false) << (count != length ? ", " : "");
}
result << std::endl;
count = 0;
for (auto i = exifData.begin(); count++ < length ; ++i) {
result << escapeCSV(i,true) << (count != length ? ", " : "" ) ;
for (auto i = exifData.begin(); count++ < length; ++i) {
result << escapeCSV(i, true) << (count != length ? ", " : "");
}
return result.str();
}
///////////////////////////////////////////////////////////////////////
std::string formatWolf(Exiv2::ExifData& exifData)
{
std::string formatWolf(Exiv2::ExifData& exifData) {
size_t count = 0;
size_t length = formatInit(exifData);
std::ostringstream result;
result << "{ " << std::endl;
for (auto i = exifData.begin(); count++ < length ; ++i) {
result << " " << i->key() << " -> " << i->value() << (count != length ? "," : "" ) << std::endl ;
for (auto i = exifData.begin(); count++ < length; ++i) {
result << " " << i->key() << " -> " << i->value() << (count != length ? "," : "") << std::endl;
}
result << "}";
return result.str();
}
///////////////////////////////////////////////////////////////////////
std::string escapeJSON(Exiv2::ExifData::const_iterator it,bool bValue=true)
{
std::string result ;
std::string escapeJSON(Exiv2::ExifData::const_iterator it, bool bValue = true) {
std::string result;
std::ostringstream os;
if ( bValue ) os << it->value() ; else os << it->key() ;
if (bValue)
os << it->value();
else
os << it->key();
std::string s = os.str();
for (auto&& c : s) {
@ -103,27 +97,28 @@ std::string escapeJSON(Exiv2::ExifData::const_iterator it,bool bValue=true)
return q + result + q;
}
std::string formatJSON(Exiv2::ExifData& exifData)
{
std::string formatJSON(Exiv2::ExifData& exifData) {
size_t count = 0;
size_t length = formatInit(exifData);
std::ostringstream result;
result << "{" << std::endl ;
for (auto i = exifData.begin(); count++ < length ; ++i) {
result << " " << escapeJSON(i,false) << ":" << escapeJSON(i,true) << ( count != length ? "," : "" ) << std::endl ;
result << "{" << std::endl;
for (auto i = exifData.begin(); count++ < length; ++i) {
result << " " << escapeJSON(i, false) << ":" << escapeJSON(i, true) << (count != length ? "," : "") << std::endl;
}
result << "}";
return result.str();
}
///////////////////////////////////////////////////////////////////////
std::string escapeXML(Exiv2::ExifData::const_iterator it,bool bValue=true)
{
std::string result ;
std::string escapeXML(Exiv2::ExifData::const_iterator it, bool bValue = true) {
std::string result;
std::ostringstream os;
if ( bValue ) os << it->value() ; else os << it->key() ;
if (bValue)
os << it->value();
else
os << it->key();
std::string s = os.str();
for (auto&& c : s) {
@ -137,25 +132,23 @@ std::string escapeXML(Exiv2::ExifData::const_iterator it,bool bValue=true)
return result;
}
std::string formatXML(Exiv2::ExifData& exifData)
{
std::string formatXML(Exiv2::ExifData& exifData) {
size_t count = 0;
size_t length = formatInit(exifData);
std::ostringstream result;
result << "<exif>" << std::endl;
for (auto i = exifData.begin(); count++ < length ; ++i) {
std::string key = escapeXML(i,false);
std::string value = escapeXML(i,true);
result << " <" << key << ">" << value << "<" << key << "/>" << std::endl ;
for (auto i = exifData.begin(); count++ < length; ++i) {
std::string key = escapeXML(i, false);
std::string value = escapeXML(i, true);
result << " <" << key << ">" << value << "<" << key << "/>" << std::endl;
}
result << "</exif>" << std::endl;
return result.str();
}
///////////////////////////////////////////////////////////////////////
int main(int argc,const char* argv[])
{
int main(int argc, const char* argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -164,44 +157,54 @@ int main(int argc,const char* argv[])
format_t formats;
formats["wolf"] = wolf;
formats["csv" ] = csv ;
formats["csv"] = csv;
formats["json"] = json;
formats["xml" ] = xml ;
formats["xml"] = xml;
int result = 0 ;
int result = 0;
if (argc != 3) {
syntax(argv,formats) ;
syntax(argv, formats);
result = 1;
}
const char* file = argv[1];
const char* format = argv[2];
if ( !result && formats.find(format) == formats.end() ) {
if (!result && formats.find(format) == formats.end()) {
std::cout << "Unrecognised format " << format << std::endl;
syntax(argv,formats);
syntax(argv, formats);
result = 2;
}
if ( !result ) try {
if (!result)
try {
auto image = Exiv2::ImageFactory::open(file);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
Exiv2::ExifData& exifData = image->exifData();
switch ( formats.find(format)->second ) {
case wolf : std::cout << formatWolf(exifData) << std::endl; break;
case csv : std::cout << formatCSV (exifData) << std::endl; break;
case json : std::cout << formatJSON(exifData) << std::endl; break;
case xml : std::cout << formatXML (exifData) << std::endl; break;
switch (formats.find(format)->second) {
case wolf:
std::cout << formatWolf(exifData) << std::endl;
break;
case csv:
std::cout << formatCSV(exifData) << std::endl;
break;
case json:
std::cout << formatJSON(exifData) << std::endl;
break;
case xml:
std::cout << formatXML(exifData) << std::endl;
break;
default : std::cout << "*** error: format not implemented yet: " << format << " ***" << std::endl;
default:
std::cout << "*** error: format not implemented yet: " << format << " ***" << std::endl;
result = 3;
break;
}
} catch (Exiv2::Error& e) {
std::cerr << "*** error exiv2 exception '" << e << "' ***" << std::endl;
result = 4;
} catch ( ... ) {
} catch (...) {
std::cerr << "*** error exception" << std::endl;
result = 5;
}

@ -5,15 +5,14 @@
#include <regex>
// copied from src/tiffvisitor_int.cpp
static const Exiv2::TagInfo* findTag(const Exiv2::TagInfo* pList,uint16_t tag)
{
while ( pList->tag_ != 0xffff && pList->tag_ != tag ) pList++;
static const Exiv2::TagInfo* findTag(const Exiv2::TagInfo* pList, uint16_t tag) {
while (pList->tag_ != 0xffff && pList->tag_ != tag)
pList++;
return pList->tag_ != 0xffff ? pList : nullptr;
}
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) {
try {
setlocale(LC_CTYPE, ".utf8");
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
@ -27,15 +26,15 @@ try {
return 1;
}
int rc = 0 ;
int rc = 0;
const char* file = argv[1];
bool bLint = strcmp(file, "--lint") == 0 && argc == 3;
if ( bLint ) file= argv[2];
if (bLint)
file = argv[2];
if ( strcmp(file,"--version") == 0 ) {
if (strcmp(file, "--version") == 0) {
std::vector<std::regex> keys;
Exiv2::dumpLibraryInfo(std::cout,keys);
Exiv2::dumpLibraryInfo(std::cout, keys);
return rc;
}
if (strcmp(file, "--version-test") == 0) {
@ -46,28 +45,27 @@ try {
<< "strlen(Exiv2::version()) " << ::strlen(Exiv2::version()) << std::endl
<< "Exiv2::versionNumber() " << Exiv2::versionNumber() << std::endl
<< "Exiv2::versionString() " << Exiv2::versionString() << std::endl
<< "Exiv2::versionNumberHexString() " << Exiv2::versionNumberHexString() << std::endl
;
<< "Exiv2::versionNumberHexString() " << Exiv2::versionNumberHexString() << std::endl;
// Test the Exiv2 version available at runtime but compile the if-clause only if
// the compile-time version is at least 0.15. Earlier versions didn't have a
// testVersion() function:
#if EXIV2_TEST_VERSION(0,15,0)
if (Exiv2::testVersion(0,13,0)) {
// Test the Exiv2 version available at runtime but compile the if-clause only if
// the compile-time version is at least 0.15. Earlier versions didn't have a
// testVersion() function:
#if EXIV2_TEST_VERSION(0, 15, 0)
if (Exiv2::testVersion(0, 13, 0)) {
std::cout << "Available Exiv2 version is equal to or greater than 0.13\n";
} else {
std::cout << "Installed Exiv2 version is less than 0.13\n";
}
#else
#else
std::cout << "Compile-time Exiv2 version doesn't have Exiv2::testVersion()\n";
#endif
#endif
return rc;
}
auto image = Exiv2::ImageFactory::open(file);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
Exiv2::ExifData& exifData = image->exifData();
if (exifData.empty()) {
std::string error("No Exif data found in file");
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
@ -84,42 +82,34 @@ try {
auto end = exifData.end();
for (auto i = exifData.begin(); i != end; ++i) {
if ( ! bLint ) {
if (!bLint) {
const char* tn = i->typeName();
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< (tn ? tn : "Unknown") << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->toString()
std::cout << std::setw(44) << std::setfill(' ') << std::left << i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left << (tn ? tn : "Unknown") << " " << std::dec
<< std::setw(3) << std::setfill(' ') << std::right << i->count() << " " << std::dec << i->toString()
<< "\n";
} else {
const Exiv2::TagInfo* tagInfo = findTag( Exiv2::ExifTags::tagList(i->groupName()),i->tag() );
if ( tagInfo ) {
const Exiv2::TagInfo* tagInfo = findTag(Exiv2::ExifTags::tagList(i->groupName()), i->tag());
if (tagInfo) {
Exiv2::TypeId type = i->typeId();
if ( type!= tagInfo-> typeId_
&&!(tagInfo->typeId_ == Exiv2::comment && type == Exiv2::undefined) // comment is stored as undefined
&&!(shortLong.find(i->key())!=shortLong.end() &&(type == Exiv2::unsignedShort||type==Exiv2::unsignedLong)) // can be short or long!
if (type != tagInfo->typeId_ &&
!(tagInfo->typeId_ == Exiv2::comment && type == Exiv2::undefined) // comment is stored as undefined
&& !(shortLong.find(i->key()) != shortLong.end() &&
(type == Exiv2::unsignedShort || type == Exiv2::unsignedLong)) // can be short or long!
) {
std::cerr << i->key()
<< " type " << i->typeName() << " (" << type << ")"
<< " expected " << Exiv2::TypeInfo::typeName(tagInfo-> typeId_) << " (" << tagInfo-> typeId_ << ")"
std::cerr << i->key() << " type " << i->typeName() << " (" << type << ")"
<< " expected " << Exiv2::TypeInfo::typeName(tagInfo->typeId_) << " (" << tagInfo->typeId_ << ")"
<< std::endl;
rc=2;
rc = 2;
}
}
}
}
return rc;
}
//catch (std::exception& e) {
//catch (Exiv2::Error& e) {
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
return -1;
}
}

@ -5,8 +5,7 @@
#include <iostream>
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -23,9 +22,9 @@ int main(int argc, char* const argv[])
auto image = Exiv2::ImageFactory::open(file);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
Exiv2::ExifData& exifData = image->exifData();
if ( exifData.empty()) {
if (exifData.empty()) {
std::cerr << "no metadata found in file " << file << std::endl;
exit(2);
}
@ -35,7 +34,7 @@ int main(int argc, char* const argv[])
} catch (Exiv2::Error& e) {
std::cerr << "Caught Exiv2 exception '" << e << "'" << std::endl;
exit(3);
} catch ( ... ) {
} catch (...) {
std::cerr << "Caught a cold!" << std::endl;
exit(4);
}

@ -26,76 +26,79 @@ struct Token {
using Tokens = std::vector<Token>;
// "XMP.xmp.MP.RegionInfo/MPRI:Regions[1]/MPReg:Rectangle"
bool getToken(std::string& in, Token& token, std::set<std::string>* pNS = nullptr)
{
bool getToken(std::string& in, Token& token, std::set<std::string>* pNS = nullptr) {
bool result = false;
bool ns = false;
token.n = "" ;
token.a = false ;
token.i = 0 ;
token.n = "";
token.a = false;
token.i = 0;
while ( !result && in.length() ) {
std::string c = in.substr(0,1);
while (!result && in.length()) {
std::string c = in.substr(0, 1);
char C = c.at(0);
in = in.substr(1,std::string::npos);
if ( in.length() == 0 && C != ']' ) token.n += c;
if ( C == '/' || C == '[' || C == ':' || C == '.' || C == ']' || in.length() == 0 ) {
ns |= C == '/' ;
token.a = C == '[' ;
if ( C == ']' ) token.i = std::atoi(token.n.c_str()); // encoded string first index == 1
result = token.n.length() > 0 ;
in = in.substr(1, std::string::npos);
if (in.length() == 0 && C != ']')
token.n += c;
if (C == '/' || C == '[' || C == ':' || C == '.' || C == ']' || in.length() == 0) {
ns |= C == '/';
token.a = C == '[';
if (C == ']')
token.i = std::atoi(token.n.c_str()); // encoded string first index == 1
result = token.n.length() > 0;
} else {
token.n += c;
}
}
if (ns && pNS) pNS->insert(token.n);
if (ns && pNS)
pNS->insert(token.n);
return result;
}
Jzon::Node& addToTree(Jzon::Node& r1, const Token& token)
{
Jzon::Object object ;
Jzon::Array array ;
Jzon::Node& addToTree(Jzon::Node& r1, const Token& token) {
Jzon::Object object;
Jzon::Array array;
std::string key = token.n ;
size_t index = token.i-1; // array Eg: "History[1]" indexed from 1. Jzon expects 0 based index.
std::string key = token.n;
size_t index = token.i - 1; // array Eg: "History[1]" indexed from 1. Jzon expects 0 based index.
auto& empty = token.a ? static_cast<Jzon::Node&>(array) : static_cast<Jzon::Node&>(object);
if ( r1.IsObject() ) {
if (r1.IsObject()) {
Jzon::Object& o1 = r1.AsObject();
if ( !o1.Has(key) ) o1.Add(key,empty);
if (!o1.Has(key))
o1.Add(key, empty);
return o1.Get(key);
}
if (r1.IsArray()) {
Jzon::Array& a1 = r1.AsArray();
while ( a1.GetCount() <= index ) a1.Add(empty);
while (a1.GetCount() <= index)
a1.Add(empty);
return a1.Get(index);
}
return r1;
}
Jzon::Node& recursivelyBuildTree(Jzon::Node& root,Tokens& tokens,size_t k)
{
return addToTree( k==0 ? root : recursivelyBuildTree(root,tokens,k-1), tokens.at(k) );
Jzon::Node& recursivelyBuildTree(Jzon::Node& root, Tokens& tokens, size_t k) {
return addToTree(k == 0 ? root : recursivelyBuildTree(root, tokens, k - 1), tokens.at(k));
}
// build the json tree for this key. return location and discover the name
Jzon::Node& objectForKey(const std::string& Key, Jzon::Object& root, std::string& name,
std::set<std::string>* pNS = nullptr)
{
std::set<std::string>* pNS = nullptr) {
// Parse the key
Tokens tokens ;
Token token ;
std::string input = Key ; // Example: "XMP.xmp.MP.RegionInfo/MPRI:Regions[1]/MPReg:Rectangle"
while ( getToken(input,token,pNS) ) tokens.push_back(token);
size_t l = tokens.size()-1; // leave leaf name to push()
name = tokens.at(l).n ;
Tokens tokens;
Token token;
std::string input = Key; // Example: "XMP.xmp.MP.RegionInfo/MPRI:Regions[1]/MPReg:Rectangle"
while (getToken(input, token, pNS))
tokens.push_back(token);
size_t l = tokens.size() - 1; // leave leaf name to push()
name = tokens.at(l).n;
// The second token. For example: XMP.dc is a namespace
if ( pNS && tokens.size() > 1 ) pNS->insert(tokens[1].n);
return recursivelyBuildTree(root,tokens,l-1);
if (pNS && tokens.size() > 1)
pNS->insert(tokens[1].n);
return recursivelyBuildTree(root, tokens, l - 1);
#if 0
// recursivelyBuildTree:
@ -110,23 +113,22 @@ Jzon::Node& objectForKey(const std::string& Key, Jzon::Object& root, std::string
#endif
}
bool isObject(std::string& value)
{
bool isObject(std::string& value) {
return value == std::string("type=\"Struct\"");
}
bool isArray(std::string& value)
{
bool isArray(std::string& value) {
return value == "type=\"Seq\"" || value == "type=\"Bag\"" || value == "type=\"Alt\"";
}
#define STORE(node,key,value) \
if (node.IsObject()) node.AsObject().Add(key,value);\
else node.AsArray() .Add( value)
#define STORE(node, key, value) \
if (node.IsObject()) \
node.AsObject().Add(key, value); \
else \
node.AsArray().Add(value)
template <class T>
void push(Jzon::Node& node,const std::string& key,T i)
{
void push(Jzon::Node& node, const std::string& key, T i) {
#define ABORT_IF_I_EMPTY \
if (i->value().size() == 0) { \
return; \
@ -134,16 +136,16 @@ void push(Jzon::Node& node,const std::string& key,T i)
std::string value = i->value().toString();
switch ( i->typeId() ) {
switch (i->typeId()) {
case Exiv2::xmpText:
if ( ::isObject(value) ) {
if (::isObject(value)) {
Jzon::Object v;
STORE(node,key,v);
} else if ( ::isArray(value) ) {
STORE(node, key, v);
} else if (::isArray(value)) {
Jzon::Array v;
STORE(node,key,v);
STORE(node, key, v);
} else {
STORE(node,key,value);
STORE(node, key, value);
}
break;
@ -153,12 +155,12 @@ void push(Jzon::Node& node,const std::string& key,T i)
case Exiv2::signedByte:
case Exiv2::signedShort:
case Exiv2::signedLong:
STORE(node,key,std::atoi(value.c_str()) );
STORE(node, key, std::atoi(value.c_str()));
break;
case Exiv2::tiffFloat:
case Exiv2::tiffDouble:
STORE(node,key,std::atof(value.c_str()) );
STORE(node, key, std::atof(value.c_str()));
break;
case Exiv2::unsignedRational:
@ -166,28 +168,27 @@ void push(Jzon::Node& node,const std::string& key,T i)
ABORT_IF_I_EMPTY
Jzon::Array arr;
Exiv2::Rational rat = i->value().toRational();
arr.Add(rat.first );
arr.Add(rat.first);
arr.Add(rat.second);
STORE(node,key,arr);
STORE(node, key, arr);
} break;
case Exiv2::langAlt: {
ABORT_IF_I_EMPTY
Jzon::Object l ;
Jzon::Object l;
const auto& langs = dynamic_cast<const Exiv2::LangAltValue&>(i->value());
for (auto&& lang : langs.value_) {
l.Add(lang.first, lang.second);
}
Jzon::Object o ;
o.Add("lang",l);
STORE(node,key,o);
}
break;
Jzon::Object o;
o.Add("lang", l);
STORE(node, key, o);
} break;
default:
case Exiv2::date:
case Exiv2::time:
case Exiv2::asciiString :
case Exiv2::asciiString:
case Exiv2::string:
case Exiv2::comment:
case Exiv2::undefined:
@ -197,26 +198,26 @@ void push(Jzon::Node& node,const std::string& key,T i)
case Exiv2::xmpBag:
case Exiv2::xmpSeq:
// http://dev.exiv2.org/boards/3/topics/1367#message-1373
if ( key == "UserComment" ) {
size_t pos = value.find('\0') ;
if ( pos != std::string::npos )
value = value.substr(0,pos);
if (key == "UserComment") {
size_t pos = value.find('\0');
if (pos != std::string::npos)
value = value.substr(0, pos);
}
if ( key == "MakerNote") return;
STORE(node,key,value);
if (key == "MakerNote")
return;
STORE(node, key, value);
break;
}
}
void fileSystemPush(const char* path,Jzon::Node& nfs)
{
void fileSystemPush(const char* path, Jzon::Node& nfs) {
auto& fs = dynamic_cast<Jzon::Object&>(nfs);
fs.Add("path",path);
fs.Add("path", path);
fs.Add("realpath", std::filesystem::absolute(std::filesystem::path(path)).string());
struct stat buf;
memset(&buf,0,sizeof(buf));
stat(path,&buf);
memset(&buf, 0, sizeof(buf));
stat(path, &buf);
fs.Add("st_dev", static_cast<int>(buf.st_dev)); /* ID of device containing file */
fs.Add("st_ino", static_cast<int>(buf.st_ino)); /* inode number */
@ -232,17 +233,16 @@ void fileSystemPush(const char* path,Jzon::Node& nfs)
#if defined(_MSC_VER) || defined(__MINGW__)
size_t blksize = 1024;
size_t blocks = (buf.st_size+blksize-1)/blksize;
size_t blocks = (buf.st_size + blksize - 1) / blksize;
#else
size_t blksize = buf.st_blksize;
size_t blocks = buf.st_blocks ;
size_t blocks = buf.st_blocks;
#endif
fs.Add("st_blksize", static_cast<int>(blksize)); /* blocksize for file system I/O */
fs.Add("st_blocks", static_cast<int>(blocks)); /* number of 512B blocks allocated */
}
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -255,9 +255,10 @@ int main(int argc, char* const argv[])
std::cout << "Option: all | exif | iptc | xmp | filesystem" << std::endl;
return 1;
}
const char* path = argv[argc-1];
const char* opt = argc == 3 ? argv[1] : "-all" ;
while (opt[0] == '-') opt++ ; // skip past leading -'s
const char* path = argv[argc - 1];
const char* opt = argc == 3 ? argv[1] : "-all";
while (opt[0] == '-')
opt++; // skip past leading -'s
char option = opt[0];
Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(path);
@ -266,42 +267,41 @@ int main(int argc, char* const argv[])
Jzon::Object root;
if ( option == 'f' ) { // only report filesystem when requested
const char* Fs="FS";
Jzon::Object fs ;
root.Add(Fs,fs) ;
fileSystemPush(path,root.Get(Fs));
if (option == 'f') { // only report filesystem when requested
const char* Fs = "FS";
Jzon::Object fs;
root.Add(Fs, fs);
fileSystemPush(path, root.Get(Fs));
}
if ( option == 'a' || option == 'e' ) {
Exiv2::ExifData &exifData = image->exifData();
for ( auto i = exifData.begin(); i != exifData.end() ; ++i ) {
std::string name ;
Jzon::Node& object = objectForKey(i->key(),root,name);
push(object,name,i);
if (option == 'a' || option == 'e') {
Exiv2::ExifData& exifData = image->exifData();
for (auto i = exifData.begin(); i != exifData.end(); ++i) {
std::string name;
Jzon::Node& object = objectForKey(i->key(), root, name);
push(object, name, i);
}
}
if ( option == 'a' || option == 'i' ) {
Exiv2::IptcData &iptcData = image->iptcData();
if (option == 'a' || option == 'i') {
Exiv2::IptcData& iptcData = image->iptcData();
for (auto i = iptcData.begin(); i != iptcData.end(); ++i) {
std::string name ;
Jzon::Node& object = objectForKey(i->key(),root,name);
push(object,name,i);
std::string name;
Jzon::Node& object = objectForKey(i->key(), root, name);
push(object, name, i);
}
}
#ifdef EXV_HAVE_XMP_TOOLKIT
if ( option == 'a' || option == 'x' ) {
Exiv2::XmpData &xmpData = image->xmpData();
if ( !xmpData.empty() ) {
#ifdef EXV_HAVE_XMP_TOOLKIT
if (option == 'a' || option == 'x') {
Exiv2::XmpData& xmpData = image->xmpData();
if (!xmpData.empty()) {
// get the xmpData and recursively parse into a Jzon Object
std::set<std::string> namespaces;
for (auto i = xmpData.begin(); i != xmpData.end(); ++i) {
std::string name ;
Jzon::Node& object = objectForKey(i->key(),root,name,&namespaces);
push(object,name,i);
std::string name;
Jzon::Node& object = objectForKey(i->key(), root, name, &namespaces);
push(object, name, i);
}
// get the namespace dictionary from XMP
@ -315,10 +315,10 @@ int main(int argc, char* const argv[])
}
// add xmlns as Xmp.xmlns
root.Get("Xmp").AsObject().Add("xmlns",xmlns);
root.Get("Xmp").AsObject().Add("xmlns", xmlns);
}
}
#endif
#endif
Jzon::Writer writer(root, Jzon::StandardFormat);
writer.Write();

File diff suppressed because it is too large Load Diff

@ -31,14 +31,13 @@
#endif
#include <iostream>
#define Safe(x) (x?x:"unknown")
#define Safe(x) (x ? x : "unknown")
const char* optstring = ":hVvqfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:K:n:Q:";
// *****************************************************************************
// class Params
class Params : public Util::Getopt {
public:
public:
/*!
@brief Call Getopt::getopt() with optstring, to initiate command line
argument parsing, perform consistency checks after all command line
@ -49,38 +48,29 @@ public:
@return 0 if successful, >0 in case of errors.
*/
int getopt(int argc, char** const argv)
{
int getopt(int argc, char** const argv) {
int rc = Util::Getopt::getopt(argc, argv, ::optstring);
std::cout << "Params::getopt()"
<< " rc = " << rc
<< std::endl;
return rc ;
<< " rc = " << rc << std::endl;
return rc;
}
//! Handle options and their arguments.
int option(int opt, const std::string& optarg, int optopt) override
{
int option(int opt, const std::string& optarg, int optopt) override {
std::cout << "Params::option()"
<< " opt = " << opt
<< " optarg = " << optarg
<< " optopt = " << optopt
<< std::endl;
<< " opt = " << opt << " optarg = " << optarg << " optopt = " << optopt << std::endl;
return 0;
}
//! Handle non-option parameters.
int nonoption(const std::string& argv) override
{
int nonoption(const std::string& argv) override {
std::cout << "Params::nonoption()"
<< " " << argv
<< std::endl;
return 0 ;
<< " " << argv << std::endl;
return 0;
}
}; // class Params
int main(int argc, char** const argv)
{
int main(int argc, char** const argv) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -92,38 +82,32 @@ int main(int argc, char** const argv)
#ifdef EXV_HAVE_UNISTD_H
std::cout << "standard getopt()" << std::endl;
do {
n = ::getopt(argc,argv,::optstring);
if ( n >= 0 ) {
n = ::getopt(argc, argv, ::optstring);
if (n >= 0) {
auto N = static_cast<char>(n);
std::cout << n << " = " << N;
} else {
std::cout << n ;
std::cout << n;
}
std::cout << " optind = " << ::optind
<< " opterr = " << ::opterr
<< " optopt = " << ::optopt
<< " optarg = " << Safe(::optarg)
<< std::endl;
} while ( n >= 0 );
std::cout << " optind = " << ::optind << " opterr = " << ::opterr << " optopt = " << ::optopt
<< " optarg = " << Safe(::optarg) << std::endl;
} while (n >= 0);
std::cout << std::endl;
#endif
std::cout << "homemade getopt()" << std::endl;
do {
n = Util::getopt(argc,argv,::optstring);
if ( n >= 0 ) {
n = Util::getopt(argc, argv, ::optstring);
if (n >= 0) {
auto N = static_cast<char>(n);
std::cout << n << " = " << N;
} else {
std::cout << n ;
std::cout << n;
}
std::cout << " optind = " << Util::optind
<< " opterr = " << Util::opterr
<< " optopt = " << Util::optopt
<< " optarg = " << Safe(Util::optarg)
<< std::endl;
std::cout << " optind = " << Util::optind << " opterr = " << Util::opterr << " optopt = " << Util::optopt
<< " optarg = " << Safe(Util::optarg) << std::endl;
} while ( n >= 0 );
} while (n >= 0);
std::cout << std::endl;
// Handle command line arguments
@ -132,4 +116,3 @@ int main(int argc, char** const argv)
return 0;
}

@ -12,34 +12,30 @@ Config loaded from : 'initest.ini' version=6, name=Bob Smith, email=bob@smith.co
#include <exiv2/exiv2.hpp>
#include <iostream>
int main()
{
int main() {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
Exiv2::enableBMFF();
#endif
int result = 0 ;
int result = 0;
const char* ini = "ini-test.ini";
Exiv2::INIReader reader(ini);
if (reader.ParseError() < 0) {
std::cerr << "Can't load '" << ini << "'" << std::endl ;
std::cerr << "Can't load '" << ini << "'" << std::endl;
result = 1;
} else {
std::cout << "Config loaded from : '" << ini << "' "
<< "version=" << reader.GetInteger("protocol", "version", -1)
<< ", name=" << reader.Get("user", "name", "UNKNOWN")
<< ", email=" << reader.Get("user", "email", "UNKNOWN")
<< ", pi=" << reader.GetReal("user", "pi", -1)
<< ", active=" << reader.GetBoolean("user", "active", true)
<< std::endl ;
<< ", email=" << reader.Get("user", "email", "UNKNOWN") << ", pi=" << reader.GetReal("user", "pi", -1)
<< ", active=" << reader.GetBoolean("user", "active", true) << std::endl;
std::cout << "169=" << reader.Get("canon", "169","UNDEFINED")
<< ", 170=" << reader.Get("canon", "170","UNDEFINED")
<< std::endl ;
std::cout << "169=" << reader.Get("canon", "169", "UNDEFINED")
<< ", 170=" << reader.Get("canon", "170", "UNDEFINED") << std::endl;
}
return result ;
return result;
}

@ -3,20 +3,19 @@
#include <iostream>
using Exiv2::byte;
using Exiv2::BasicIo;
using Exiv2::MemIo;
using Exiv2::byte;
using Exiv2::Error;
using Exiv2::FileIo;
using Exiv2::IoCloser;
using Exiv2::Error;
using Exiv2::MemIo;
using Exiv2::strError;
int WriteReadSeek(BasicIo &io);
int WriteReadSeek(BasicIo& io);
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -24,14 +23,14 @@ int main(int argc, char* const argv[])
#endif
try {
if (argc < 4 || argc > 6 ) {
std::cout << "Usage: " << argv[0] << " filein fileout1 fileout2 [remote [blocksize]]\n"
if (argc < 4 || argc > 6) {
std::cout << "Usage: " << argv[0]
<< " filein fileout1 fileout2 [remote [blocksize]]\n"
"copy filein to fileout1 and copy filein to fileout2\n"
"fileout1 and fileout2 are overwritten and should match filein exactly\n"
"\n"
"You may optionally provide the URL of a remote file to be copied to filein\n"
"If you use `remote`, you may optionally provide a blocksize for the copy buffer (default 10k)\n"
;
"If you use `remote`, you may optionally provide a blocksize for the copy buffer (default 10k)\n";
return 1;
}
const char* f0 = argv[1]; // fileIn
@ -40,34 +39,34 @@ int main(int argc, char* const argv[])
const char* fr = argv[4]; // remote file
const char* ba = argv[5]; // block argument
if ( argc >= 5 ) {
int blocksize = argc==6 ? atoi(ba) : 10000;
if (argc >= 5) {
int blocksize = argc == 6 ? atoi(ba) : 10000;
// ensure blocksize is sane
if (blocksize>1024*1024)
blocksize=10000;
if (blocksize > 1024 * 1024)
blocksize = 10000;
std::vector<Exiv2::byte> bytes (blocksize);
std::vector<Exiv2::byte> bytes(blocksize);
// copy fileIn from a remote location.
auto io = Exiv2::ImageFactory::createIo(fr);
if ( io->open() != 0 ) {
if (io->open() != 0) {
Error(Exiv2::ErrorCode::kerFileOpenFailed, io->path(), "rb", strError());
}
FileIo output(f0);
if ( !output.open("wb") ) {
Error(Exiv2::ErrorCode::kerFileOpenFailed, output.path() , "w+b", strError());
if (!output.open("wb")) {
Error(Exiv2::ErrorCode::kerFileOpenFailed, output.path(), "w+b", strError());
}
size_t l = 0;
if ( !bytes.empty() ) {
size_t r ;
while ( (r=io->read(bytes.data(),blocksize)) > 0 ) {
if (!bytes.empty()) {
size_t r;
while ((r = io->read(bytes.data(), blocksize)) > 0) {
l += r;
output.write(bytes.data(),r) ;
output.write(bytes.data(), r);
}
} else {
// read/write byte-wise (#1029)
while ( l++ < io->size() ) {
output.putb(io->getb()) ;
while (l++ < io->size()) {
output.putb(io->getb());
}
}
output.close();
@ -91,16 +90,16 @@ int main(int argc, char* const argv[])
fileOut1.write(memIo1);
// Make sure they are all the same size
if(fileIn.size() != memIo1.size() || memIo1.size() != fileOut1.size()) {
std::cerr << argv[0] <<
": Sizes do not match\n";
if (fileIn.size() != memIo1.size() || memIo1.size() != fileOut1.size()) {
std::cerr << argv[0] << ": Sizes do not match\n";
return 1;
}
// Read writereadseek test on MemIo
MemIo memIo2;
int rc = WriteReadSeek(memIo2);
if (rc != 0) return rc;
if (rc != 0)
return rc;
// Read writereadseek test on FileIo
// Create or overwrite the file, then close it
@ -111,7 +110,8 @@ int main(int argc, char* const argv[])
fileTest.close();
rc = WriteReadSeek(fileTest);
if (rc != 0) return rc;
if (rc != 0)
return rc;
// Another test of reading and writing
fileOut1.seek(0, BasicIo::beg);
@ -123,15 +123,13 @@ int main(int argc, char* const argv[])
size_t readCount = 0;
byte buf[32];
while ((readCount=fileOut1.read(buf, sizeof(buf)))) {
while ((readCount = fileOut1.read(buf, sizeof(buf)))) {
if (memIo2.write(buf, readCount) != readCount) {
std::cerr << argv[0] <<
": MemIo bad write 2\n";
std::cerr << argv[0] << ": MemIo bad write 2\n";
return 13;
}
if (fileOut2.write(buf, readCount) != readCount) {
std::cerr << argv[0] <<
": FileIo bad write 2\n";
std::cerr << argv[0] << ": FileIo bad write 2\n";
return 14;
}
}
@ -143,9 +141,7 @@ int main(int argc, char* const argv[])
}
}
int WriteReadSeek(BasicIo &io)
{
int WriteReadSeek(BasicIo& io) {
byte buf[4096];
const char tester1[] = "this is a little test of MemIo";
const char tester2[] = "Appending this on the end";
@ -172,12 +168,12 @@ int WriteReadSeek(BasicIo &io)
int c = EOF;
std::memset(buf, -1, sizeof(buf));
for (int i = 0; (c=io.getb()) != EOF; ++i) {
for (int i = 0; (c = io.getb()) != EOF; ++i) {
buf[i] = static_cast<byte>(c);
}
// Make sure we got the null back
if(buf[size1-1] != 0) {
if (buf[size1 - 1] != 0) {
std::cerr << ": WRS missing null terminator 1\n";
return 3;
}
@ -227,7 +223,7 @@ int WriteReadSeek(BasicIo &io)
}
// Make sure we got the null back
if(buf[insert + size2 - 1] != 0) {
if (buf[insert + size2 - 1] != 0) {
std::cerr << ": WRS missing null terminator 2\n";
return 11;
}

@ -5,8 +5,7 @@
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -43,8 +42,7 @@ try {
image->writeMetadata();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}

@ -5,8 +5,7 @@
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -21,7 +20,7 @@ try {
auto image = Exiv2::ImageFactory::open(argv[1]);
image->readMetadata();
Exiv2::IptcData &iptcData = image->iptcData();
Exiv2::IptcData& iptcData = image->iptcData();
if (iptcData.empty()) {
std::string error(argv[1]);
error += ": No IPTC data found in the file";
@ -30,26 +29,17 @@ try {
auto end = iptcData.end();
for (auto md = iptcData.begin(); md != end; ++md) {
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< md->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << md->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< md->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< md->count() << " "
<< std::dec << md->value()
<< std::endl;
std::cout << std::setw(44) << std::setfill(' ') << std::left << md->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << md->tag() << " " << std::setw(9)
<< std::setfill(' ') << std::left << md->typeName() << " " << std::dec << std::setw(3)
<< std::setfill(' ') << std::right << md->count() << " " << std::dec << md->value() << std::endl;
}
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return 1;
}
catch (const std::exception& e) {
} catch (const std::exception& e) {
std::cout << "Caught exception: '" << e.what() << "'\n";
return 1;
}

@ -6,15 +6,14 @@
using namespace Exiv2;
bool processLine(const std::string& line, int num, IptcData &iptcData);
void processAdd(const std::string& line, int num, IptcData &iptcData);
void processRemove(const std::string& line, int num, IptcData &iptcData);
void processModify(const std::string& line, int num, IptcData &iptcData);
bool processLine(const std::string& line, int num, IptcData& iptcData);
void processAdd(const std::string& line, int num, IptcData& iptcData);
void processRemove(const std::string& line, int num, IptcData& iptcData);
void processModify(const std::string& line, int num, IptcData& iptcData);
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -22,7 +21,6 @@ int main(int argc, char* const argv[])
#endif
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " image\n";
std::cout << "Commands read from stdin.\n";
@ -44,15 +42,13 @@ int main(int argc, char* const argv[])
image->writeMetadata();
return 0;
}
catch (Error& e) {
} catch (Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}
bool processLine(const std::string& line, int num, IptcData &iptcData)
{
bool processLine(const std::string& line, int num, IptcData& iptcData) {
switch (line.at(0)) {
case 'a':
case 'A':
@ -77,27 +73,24 @@ bool processLine(const std::string& line, int num, IptcData &iptcData)
return true;
}
void processAdd(const std::string& line, int num, IptcData &iptcData)
{
void processAdd(const std::string& line, int num, IptcData& iptcData) {
std::string::size_type keyStart = line.find_first_not_of(" \t", 1);
std::string::size_type keyEnd = line.find_first_of(" \t", keyStart+1);
std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd+1);
std::string::size_type keyEnd = line.find_first_of(" \t", keyStart + 1);
std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd + 1);
if (keyStart == std::string::npos ||
keyEnd == std::string::npos ||
dataStart == std::string::npos) {
if (keyStart == std::string::npos || keyEnd == std::string::npos || dataStart == std::string::npos) {
std::ostringstream os;
os << "Invalid \'a\' command at line " << num;
throw Error(ErrorCode::kerErrorMessage, os.str());
}
std::string key(line.substr(keyStart, keyEnd-keyStart));
std::string key(line.substr(keyStart, keyEnd - keyStart));
IptcKey iptcKey(key);
std::string data(line.substr(dataStart));
// if data starts and ends with quotes, remove them
if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') {
data = data.substr(1, data.size()-2);
if (data.at(0) == '\"' && data.at(data.size() - 1) == '\"') {
data = data.substr(1, data.size() - 2);
}
TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
Value::UniquePtr value = Value::create(type);
@ -109,8 +102,7 @@ void processAdd(const std::string& line, int num, IptcData &iptcData)
}
}
void processRemove(const std::string& line, int num, IptcData &iptcData)
{
void processRemove(const std::string& line, int num, IptcData& iptcData) {
std::string::size_type keyStart = line.find_first_not_of(" \t", 1);
if (keyStart == std::string::npos) {
@ -119,7 +111,7 @@ void processRemove(const std::string& line, int num, IptcData &iptcData)
throw Error(ErrorCode::kerErrorMessage, os.str());
}
const std::string key( line.substr(keyStart) );
const std::string key(line.substr(keyStart));
IptcKey iptcKey(key);
auto iter = iptcData.findKey(iptcKey);
@ -128,27 +120,24 @@ void processRemove(const std::string& line, int num, IptcData &iptcData)
}
}
void processModify(const std::string& line, int num, IptcData &iptcData)
{
void processModify(const std::string& line, int num, IptcData& iptcData) {
std::string::size_type keyStart = line.find_first_not_of(" \t", 1);
std::string::size_type keyEnd = line.find_first_of(" \t", keyStart+1);
std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd+1);
std::string::size_type keyEnd = line.find_first_of(" \t", keyStart + 1);
std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd + 1);
if (keyStart == std::string::npos ||
keyEnd == std::string::npos ||
dataStart == std::string::npos) {
if (keyStart == std::string::npos || keyEnd == std::string::npos || dataStart == std::string::npos) {
std::ostringstream os;
os << "Invalid \'m\' command at line " << num;
throw Error(ErrorCode::kerErrorMessage, os.str());
}
std::string key(line.substr(keyStart, keyEnd-keyStart));
std::string key(line.substr(keyStart, keyEnd - keyStart));
IptcKey iptcKey(key);
std::string data(line.substr(dataStart));
// if data starts and ends with quotes, remove them
if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') {
data = data.substr(1, data.size()-2);
if (data.at(0) == '\"' && data.at(data.size() - 1) == '\"') {
data = data.substr(1, data.size() - 2);
}
TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
Value::UniquePtr value = Value::create(type);
@ -157,8 +146,7 @@ void processModify(const std::string& line, int num, IptcData &iptcData)
auto iter = iptcData.findKey(iptcKey);
if (iter != iptcData.end()) {
iter->setValue(value.get());
}
else {
} else {
int rc = iptcData.add(iptcKey, value.get());
if (rc) {
throw Error(ErrorCode::kerErrorMessage, "Iptc dataset already exists and is not repeatable");

@ -6,8 +6,7 @@
using namespace Exiv2;
int main()
{
int main() {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -185,9 +184,7 @@ int main()
if (rc == 0) {
std::cout << "All " << tc << " testcases passed." << std::endl;
}
else {
} else {
std::cout << rc << " of " << tc << " testcases failed." << std::endl;
}
}

@ -3,12 +3,11 @@
// Test for large (>65535 bytes) IPTC buffer
// ***************************************************************** -*- C++ -*-
#include <exiv2/exiv2.hpp>
#include <cassert>
#include <exiv2/exiv2.hpp>
#include <iostream>
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);

@ -1,17 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <exiv2/exiv2.hpp>
#include <iostream>
// include local header files which are not part of libexiv2
#include "getopt.hpp"
#include "metacopy.hpp"
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
int main(int argc, char* const argv[]) {
try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -56,54 +53,64 @@ try {
try {
writeImg->writeMetadata();
}
catch (const Exiv2::Error&) {
std::cerr << params.progname() <<
": Could not write metadata to (" << params.write_ << ")\n";
} catch (const Exiv2::Error&) {
std::cerr << params.progname() << ": Could not write metadata to (" << params.write_ << ")\n";
return 8;
}
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cerr << "Caught Exiv2 exception '" << e << "'\n";
return 10;
}
}
}
int Params::option(int opt, const std::string& /*optarg*/, int optopt)
{
int Params::option(int opt, const std::string& /*optarg*/, int optopt) {
int rc = 0;
switch (opt) {
case 'h': {help_ = true; break;}
case 'i': {iptc_ = true; break;}
case 'e': {exif_ = true; break;}
case 'c': {comment_ = true; break;}
case 'x': {xmp_ = true; break;}
case 'p': {preserve_ = true; break;}
case 'a':{
iptc_ =true;
exif_ =true;
comment_ =true;
xmp_ =true;
case 'h': {
help_ = true;
break;
}
case ':':{
std::cerr << progname() << ": Option -" << static_cast<char>(optopt)
<< " requires an argument\n";
case 'i': {
iptc_ = true;
break;
}
case 'e': {
exif_ = true;
break;
}
case 'c': {
comment_ = true;
break;
}
case 'x': {
xmp_ = true;
break;
}
case 'p': {
preserve_ = true;
break;
}
case 'a': {
iptc_ = true;
exif_ = true;
comment_ = true;
xmp_ = true;
break;
}
case ':': {
std::cerr << progname() << ": Option -" << static_cast<char>(optopt) << " requires an argument\n";
rc = 1;
break;
}
case '?':{
std::cerr << progname() << ": Unrecognized option -"
<< static_cast<char>(optopt) << "\n";
case '?': {
std::cerr << progname() << ": Unrecognized option -" << static_cast<char>(optopt) << "\n";
rc = 1;
break;
}
default:{
std::cerr << progname()
<< ": getopt returned unexpected character code "
<< std::hex << opt << "\n";
default: {
std::cerr << progname() << ": getopt returned unexpected character code " << std::hex << opt << "\n";
rc = 1;
break;
}
@ -112,32 +119,32 @@ int Params::option(int opt, const std::string& /*optarg*/, int optopt)
return rc;
}
int Params::nonoption(const std::string& argv)
{
int Params::nonoption(const std::string& argv) {
if (!write_.empty()) {
std::cerr << progname() << ": Unexpected extra argument (" << argv << ")\n";
return 1;
}
if (first_) read_ = argv;
else write_ = argv;
if (first_)
read_ = argv;
else
write_ = argv;
first_ = false;
return 0;
}
int Params::getopt(int argc, char* const argv[])
{
int Params::getopt(int argc, char* const argv[]) {
int rc = Util::Getopt::getopt(argc, argv, optstring_);
// Further consistency checks
if (!help_) {
if (rc==0 && read_.empty() ) {
if (rc == 0 && read_.empty()) {
std::cerr << progname() << ": Read and write files must be specified\n";
rc = 1;
}
if (rc==0 && write_.empty() ) {
if (rc == 0 && write_.empty()) {
std::cerr << progname() << ": Write file must be specified\n";
rc = 1;
}
if (preserve_ && iptc_ && exif_ && comment_ && xmp_ ) {
if (preserve_ && iptc_ && exif_ && comment_ && xmp_) {
std::cerr << progname() << ": Option -p has no effect when all metadata types are specified.\n";
rc = 1;
}
@ -145,16 +152,12 @@ int Params::getopt(int argc, char* const argv[])
return rc;
} // Params::getopt
void Params::usage(std::ostream& os) const
{
void Params::usage(std::ostream& os) const {
os << "\nReads and writes raw metadata. Use -h option for help.\n"
<< "Usage: " << progname()
<< " [-iecxaph] readfile writefile\n";
<< "Usage: " << progname() << " [-iecxaph] readfile writefile\n";
}
void Params::help(std::ostream& os) const
{
void Params::help(std::ostream& os) const {
usage(os);
os << "\nOptions:\n"
<< " -i Read Iptc data from readfile and write to writefile.\n"
@ -165,4 +168,3 @@ void Params::help(std::ostream& os) const
<< " -p Preserve existing metadata in writefile if not replaced.\n"
<< " -h Display this help and exit.\n\n";
} // Params::help

@ -1,31 +1,18 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2021 Exiv2 authors
* This program is part of the Exiv2 distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef METACOPY_HPP_
#define METACOPY_HPP_
#include "getopt.hpp"
#include <iostream>
class Params : public Util::Getopt {
private:
private:
std::string optstring_;
bool first_{true};
public:
public:
bool help_{false}; //!< Help option flag.
bool iptc_{false}; //!< Iptc option flag.
bool exif_{false}; //!< Exif option flag.
@ -35,12 +22,11 @@ public:
std::string read_; //!< Source file
std::string write_; //!< Destination file
public:
public:
/*!
@brief Default constructor. Note that optstring_ is initialized here.
*/
Params() : optstring_(":iecxaph")
{
Params() : optstring_(":iecxaph") {
}
/*!
@ -62,10 +48,10 @@ public:
int nonoption(const std::string& argv) override;
//! Print a minimal usage note to an output stream.
void usage(std::ostream& os =std::cout) const;
void usage(std::ostream& os = std::cout) const;
//! Print further usage explanations to an output stream.
void help(std::ostream& os =std::cout) const;
void help(std::ostream& os = std::cout) const;
}; // class Params

@ -7,8 +7,7 @@
using namespace Exiv2;
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -38,7 +37,6 @@ try {
file.close();
return 0;
}
catch (const Error& e) {
} catch (const Error& e) {
std::cout << e << "\n";
}

@ -1,12 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Sample program to extract a Minolta thumbnail from the makernote
#include <exiv2/exiv2.hpp>
#include <cassert>
#include <exiv2/exiv2.hpp>
#include <iostream>
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF

@ -3,13 +3,12 @@
#include <exiv2/exiv2.hpp>
#include <filesystem>
#include <iostream>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -35,8 +34,7 @@ int main(int argc, char* const argv[])
std::string b = p.filename().string();
if (d != dir || b != base) {
std::cout << path << "\t'" << d << "'\t '" << b
<< "'\t ==> Testcase failed\n";
std::cout << path << "\t'" << d << "'\t '" << b << "'\t ==> Testcase failed\n";
}
}

@ -5,8 +5,7 @@
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -25,8 +24,8 @@ try {
Exiv2::PreviewManager loader(*image);
Exiv2::PreviewPropertiesList list = loader.getPreviewProperties();
for (auto&& pos : list) {
std::cout << pos.mimeType_ << " preview, type " << pos.id_ << ", " << pos.size_ << " bytes, " << pos.width_
<< 'x' << pos.height_ << " pixels"
std::cout << pos.mimeType_ << " preview, type " << pos.id_ << ", " << pos.size_ << " bytes, " << pos.width_ << 'x'
<< pos.height_ << " pixels"
<< "\n";
Exiv2::PreviewImage preview = loader.getPreviewImage(pos);
@ -37,8 +36,7 @@ try {
Exiv2::XmpParser::terminate();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}

@ -3,13 +3,12 @@
// It makes some modifications on the metadata of remote file, reads new metadata from that file
// and reset the metadata back to the original status.
#include <cassert>
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -22,10 +21,12 @@ try {
}
bool useCurlFromExiv2TestApps = true;
for ( int a = 1 ; a < argc ; a++ ) {
for (int a = 1; a < argc; a++) {
std::string arg(argv[a]);
if (arg == "--nocurl") useCurlFromExiv2TestApps = false;
else if (arg == "--curl") useCurlFromExiv2TestApps = true;
if (arg == "--nocurl")
useCurlFromExiv2TestApps = false;
else if (arg == "--curl")
useCurlFromExiv2TestApps = true;
}
std::string file(argv[1]);
@ -52,7 +53,7 @@ try {
std::cout << "Print out the new metadata ...\n";
auto readTest = Exiv2::ImageFactory::open(file, useCurlFromExiv2TestApps);
readTest->readMetadata();
Exiv2::ExifData &exifReadData = readTest->exifData();
Exiv2::ExifData& exifReadData = readTest->exifData();
if (exifReadData.empty()) {
std::string error(argv[1]);
error += ": No Exif data found in the file";
@ -61,20 +62,12 @@ try {
auto end = exifReadData.end();
for (auto i = exifReadData.begin(); i != end; ++i) {
const char* tn = i->typeName();
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< (tn ? tn : "Unknown") << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
std::cout << std::setw(44) << std::setfill(' ') << std::left << i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " " << std::setw(9)
<< std::setfill(' ') << std::left << (tn ? tn : "Unknown") << " " << std::dec << std::setw(3)
<< std::setfill(' ') << std::right << i->count() << " " << std::dec << i->value() << "\n";
}
// del, reset the metadata
std::cout << "Reset ...\n";
exifReadData["Exif.Photo.UserComment"] = "Have a nice day"; // AsciiValue
@ -82,26 +75,29 @@ try {
exifReadData["Exif.Image.Copyright"] = "Exiv2.org"; // AsciiValue
key = Exiv2::ExifKey("Exif.Image.Make");
auto pos = exifReadData.findKey(key);
if (pos == exifReadData.end()) throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.Image.Make not found");
if (pos == exifReadData.end())
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.Image.Make not found");
exifReadData.erase(pos);
key = Exiv2::ExifKey("Exif.Image.DateTime");
pos = exifReadData.findKey(key);
if (pos == exifReadData.end()) throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.Image.DateTime not found");
if (pos == exifReadData.end())
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.Image.DateTime not found");
exifReadData.erase(pos);
key = Exiv2::ExifKey("Exif.Canon.OwnerName");
pos = exifReadData.findKey(key);
if (pos == exifReadData.end()) throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.Canon.OwnerName not found");
if (pos == exifReadData.end())
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.Canon.OwnerName not found");
exifReadData.erase(pos);
key = Exiv2::ExifKey("Exif.CanonCs.LensType");
pos = exifReadData.findKey(key);
if (pos == exifReadData.end()) throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.CanonCs.LensType not found");
if (pos == exifReadData.end())
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Exif.CanonCs.LensType not found");
exifReadData.erase(pos);
readTest->setExifData(exifReadData);
readTest->writeMetadata();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}

@ -36,8 +36,7 @@ static constexpr const char* testcases[] = {
"text",
};
int main()
{
int main() {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF

@ -6,8 +6,7 @@
using namespace Exiv2;
int main(int argc, char* argv[])
{
int main(int argc, char* argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -23,7 +22,7 @@ int main(int argc, char* argv[])
case 2: {
std::string item(argv[1]);
if ( item == "--help" ) {
if (item == "--help") {
bHelp = true;
break;
}
@ -39,17 +38,17 @@ int main(int argc, char* argv[])
break;
}
if (item == "all" || item == "ALL" ) {
if (item == "all" || item == "ALL") {
const GroupInfo* groupList = ExifTags::groupList();
if (groupList) {
std::string line;
while (groupList->tagList_) {
std::ostringstream tags;
ExifTags::taglist(tags,groupList->groupName_);
std::istringstream input(tags.str()) ;
ExifTags::taglist(tags, groupList->groupName_);
std::istringstream input(tags.str());
while (std::getline(input, line)) {
std::cout << groupList->groupName_ << "."
<< (item == "all" ? line.substr(0, line.find(',')) : line) << std::endl;
std::cout << groupList->groupName_ << "." << (item == "all" ? line.substr(0, line.find(',')) : line)
<< std::endl;
}
groupList++;
}
@ -57,7 +56,6 @@ int main(int argc, char* argv[])
break;
}
if (item == "Exif") {
ExifTags::taglist(std::cout);
break;
@ -93,15 +91,11 @@ int main(int argc, char* argv[])
rc = EXIT_FAILURE; // assume unhappy ending!
if (item == "--group") {
if ( ExifTags::isExifGroup(name) ) {
ExifTags::taglist(std::cout,name);
if (ExifTags::isExifGroup(name)) {
ExifTags::taglist(std::cout, name);
rc = EXIT_SUCCESS; // result is good
} else {
std::cerr << "warning:"
<< name
<< " is not a valid Exif group name "
<< std::endl
;
std::cerr << "warning:" << name << " is not a valid Exif group name " << std::endl;
const GroupInfo* groupList = ExifTags::groupList();
if (groupList) {
while (rc && groupList->tagList_) {
@ -128,16 +122,18 @@ int main(int argc, char* argv[])
if (rc || bHelp) {
std::cout << "Usage: taglist [--help]" << std::endl
<< " [--group name|" << std::endl
<< " Groups|Exif|Canon|CanonCs|CanonSi|CanonCf|CanonHdr|Fujifilm|Minolta|Nikon1|Nikon2|Nikon3|Olympus|" << std::endl
<< " "
"Groups|Exif|Canon|CanonCs|CanonSi|CanonCf|CanonHdr|Fujifilm|Minolta|Nikon1|Nikon2|Nikon3|Olympus|"
<< std::endl
<< " Panasonic|Pentax|Sigma|Sony|Iptc|" << std::endl
<< " dc|xmp|xmpRights|xmpMM|xmpBJ|xmpTPg|xmpDM|pdf|photoshop|crs|tiff|exif|aux|iptc|all|ALL" << std::endl
<< " dc|xmp|xmpRights|xmpMM|xmpBJ|xmpTPg|xmpDM|pdf|photoshop|crs|tiff|exif|aux|iptc|all|ALL"
<< std::endl
<< " ]" << std::endl
<< "Print Exif tags, MakerNote tags, or Iptc datasets" << std::endl
;
<< "Print Exif tags, MakerNote tags, or Iptc datasets" << std::endl;
}
} catch (Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
rc = EXIT_FAILURE ;
rc = EXIT_FAILURE;
}
return rc;
}

@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// First and very simple TIFF write test.
#include <exiv2/exiv2.hpp>
#include <enforce.hpp>
#include <exiv2/exiv2.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <string>
using namespace Exiv2;
@ -16,8 +16,7 @@ void print(const ExifData& exifData);
void mini1(const char* path);
void mini9(const char* path);
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -34,13 +33,11 @@ try {
mini9(path);
return 0;
}
catch (const Error& e) {
} catch (const Error& e) {
std::cout << e << "\n";
}
void mini1(const char* path)
{
void mini1(const char* path) {
ExifData exifData;
Blob blob;
WriteMethod wm;
@ -69,8 +66,7 @@ void mini1(const char* path)
print(exifData);
}
void mini9(const char* path)
{
void mini9(const char* path) {
TiffImage tiffImage(std::make_unique<FileIo>(path), false);
tiffImage.readMetadata();
@ -89,24 +85,16 @@ void mini9(const char* path)
tiffImage.writeMetadata();
}
void print(const ExifData& exifData)
{
void print(const ExifData& exifData) {
if (exifData.empty()) {
std::string error("No Exif data found in the file");
throw Exiv2::Error(ErrorCode::kerErrorMessage, error);
}
auto end = exifData.end();
for (auto i = exifData.begin(); i != end; ++i) {
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< i->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
std::cout << std::setw(44) << std::setfill(' ') << std::left << i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " " << std::setw(9)
<< std::setfill(' ') << std::left << i->typeName() << " " << std::dec << std::setw(3) << std::setfill(' ')
<< std::right << i->count() << " " << std::dec << i->value() << "\n";
}
}

@ -9,17 +9,13 @@
using namespace Exiv2;
void testCase(const std::string& file1,
const std::string& file2,
const std::string& thumb,
const std::string& key,
void testCase(const std::string& file1, const std::string& file2, const std::string& thumb, const std::string& key,
const std::string& value);
void exifPrint(const ExifData& exifData);
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -27,7 +23,6 @@ int main(int argc, char* const argv[])
#endif
try {
if (argc != 3) {
std::cout << "Usage: write-test file case\n\n"
<< "where case is an integer between 1 and 11\n";
@ -44,79 +39,59 @@ int main(int argc, char* const argv[])
case 1:
std::cerr << "Case 1: ";
std::cerr << "Non-intrusive change to the standard Exif metadata\n";
testCase(testFile, "test1.jpg", "thumb1",
"Exif.Photo.DateTimeOriginal",
"1999:11:22 00:11:22");
testCase(testFile, "test1.jpg", "thumb1", "Exif.Photo.DateTimeOriginal", "1999:11:22 00:11:22");
break;
case 2:
std::cerr << "Case 2: ";
std::cerr << "Non-intrusive change to the makernote metadata\n";
testCase(testFile, "test2.jpg", "thumb2",
"Exif.Canon.OwnerName",
"Chan YeeSend");
testCase(testFile, "test2.jpg", "thumb2", "Exif.Canon.OwnerName", "Chan YeeSend");
break;
case 3:
std::cerr << "Case 3: ";
std::cerr << "Non-intrusive change to the Exif metadata (w/o makernote)\n";
testCase(testFile, "test3.jpg", "thumb3",
"Exif.Photo.DateTimeOriginal",
"1999:11:22 00:11:22");
testCase(testFile, "test3.jpg", "thumb3", "Exif.Photo.DateTimeOriginal", "1999:11:22 00:11:22");
break;
case 4:
std::cerr << "Case 4: ";
std::cerr << "Intrusive change to the standard Exif metadata\n";
testCase(testFile, "test4.jpg", "thumb4",
"Exif.Photo.DateTimeOriginal",
testCase(testFile, "test4.jpg", "thumb4", "Exif.Photo.DateTimeOriginal",
"1999:11:22 00:11:22 and twenty seconds");
break;
case 5:
std::cerr << "Case 5: ";
std::cerr << "Intrusive change to the Canon makernote metadata\n";
testCase(testFile, "test5.jpg", "thumb5",
"Exif.Canon.OwnerName",
"Frau Chan YeeSend und Herr Andreas Huggel");
testCase(testFile, "test5.jpg", "thumb5", "Exif.Canon.OwnerName", "Frau Chan YeeSend und Herr Andreas Huggel");
break;
case 6:
std::cerr << "Case 6: ";
std::cerr << "Intrusive change to the Exif metadata (w/o makernote)\n";
testCase(testFile, "test6.jpg", "thumb6",
"Exif.Photo.DateTimeOriginal",
testCase(testFile, "test6.jpg", "thumb6", "Exif.Photo.DateTimeOriginal",
"1999:11:22 00:11:22 and twenty seconds");
break;
case 7:
std::cerr << "Case 7: ";
std::cerr << "Intrusive change to the Fujifilm makernote metadata\n";
testCase(testFile, "test7.jpg", "thumb7",
"Exif.Fujifilm.Quality",
"Typical Fujifilm Quality");
testCase(testFile, "test7.jpg", "thumb7", "Exif.Fujifilm.Quality", "Typical Fujifilm Quality");
break;
case 8:
std::cerr << "Case 8: ";
std::cerr << "Intrusive change to the Sigma makernote metadata\n";
testCase(testFile, "test8.jpg", "thumb8",
"Exif.Sigma.ResolutionMode",
"Sigma HI resolution");
testCase(testFile, "test8.jpg", "thumb8", "Exif.Sigma.ResolutionMode", "Sigma HI resolution");
break;
case 9:
std::cerr << "Case 9: ";
std::cerr << "Intrusive change to the Nikon1 makernote metadata\n";
testCase(testFile, "test9.jpg", "thumb9",
"Exif.Nikon1.Quality",
"Typical Nikon1 Quality");
testCase(testFile, "test9.jpg", "thumb9", "Exif.Nikon1.Quality", "Typical Nikon1 Quality");
break;
case 10:
std::cerr << "Case 10: ";
std::cerr << "Intrusive change to the Nikon2 makernote metadata\n";
testCase(testFile, "test10.jpg", "thumb10",
"Exif.Nikon2.0x0002",
"Nikon2 Version 2");
testCase(testFile, "test10.jpg", "thumb10", "Exif.Nikon2.0x0002", "Nikon2 Version 2");
break;
case 11:
std::cerr << "Case 11: ";
std::cerr << "Intrusive change to the Nikon3 makernote metadata\n";
testCase(testFile, "test11.jpg", "thumb11",
"Exif.Nikon3.Quality",
"Typical Nikon3 Quality");
testCase(testFile, "test11.jpg", "thumb11", "Exif.Nikon3.Quality", "Typical Nikon3 Quality");
break;
// ToDo: Erase Sigma thumbnail
@ -131,30 +106,25 @@ int main(int argc, char* const argv[])
}
return rc;
}
catch (Error& e) {
} catch (Error& e) {
std::cerr << "Caught Exiv2 exception '" << e << "'\n";
return 1;
}
}
}
// *****************************************************************************
void testCase(const std::string& file1,
const std::string& file2,
const std::string& thumb,
const std::string& key,
const std::string& value)
{
void testCase(const std::string& file1, const std::string& file2, const std::string& thumb, const std::string& key,
const std::string& value) {
ExifKey ek(key);
//Open first image
// Open first image
auto image1 = ImageFactory::open(file1);
// Load existing metadata
std::cerr << "---> Reading file " << file1 << "\n";
image1->readMetadata();
Exiv2::ExifData &ed1 = image1->exifData();
Exiv2::ExifData& ed1 = image1->exifData();
std::cerr << "---> Modifying Exif data\n";
auto pos = ed1.findKey(ek);
if (pos == ed1.end()) {
@ -173,7 +143,7 @@ void testCase(const std::string& file1,
std::cerr << "---> Reading file " << file2 << "\n";
image2->readMetadata();
Exiv2::ExifData &ed2 = image2->exifData();
Exiv2::ExifData& ed2 = image2->exifData();
exifPrint(ed2);
std::cerr << "---> Writing Exif thumbnail to file " << thumb << ".*\n";
@ -183,20 +153,12 @@ void testCase(const std::string& file1,
// *****************************************************************************
void exifPrint(const ExifData& exifData)
{
void exifPrint(const ExifData& exifData) {
auto i = exifData.begin();
for (; i != exifData.end(); ++i) {
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< i->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
std::cout << std::setw(44) << std::setfill(' ') << std::left << i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " " << std::setw(9)
<< std::setfill(' ') << std::left << i->typeName() << " " << std::dec << std::setw(3) << std::setfill(' ')
<< std::right << i->count() << " " << std::dec << i->value() << "\n";
}
}

@ -8,8 +8,7 @@ void print(const std::string& file);
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -23,7 +22,7 @@ int main(int argc, char* const argv[])
}
std::string file(argv[1]);
std::cout <<"----- Some IFD0 tags\n";
std::cout << "----- Some IFD0 tags\n";
Exiv2::ExifData ed1;
ed1["Exif.Image.Model"] = "Test 1";
@ -46,13 +45,13 @@ int main(int argc, char* const argv[])
write(file, ed1);
print(file);
std::cout <<"\n----- One Exif tag\n";
std::cout << "\n----- One Exif tag\n";
Exiv2::ExifData ed2;
ed2["Exif.Photo.DateTimeOriginal"] = "Test 2";
write(file, ed2);
print(file);
std::cout <<"\n----- Canon MakerNote tags\n";
std::cout << "\n----- Canon MakerNote tags\n";
Exiv2::ExifData edMn1;
edMn1["Exif.Image.Make"] = "Canon";
edMn1["Exif.Image.Model"] = "Canon PowerShot S40";
@ -65,7 +64,7 @@ int main(int argc, char* const argv[])
write(file, edMn1);
print(file);
std::cout <<"\n----- Non-intrusive writing of special Canon MakerNote tags\n";
std::cout << "\n----- Non-intrusive writing of special Canon MakerNote tags\n";
auto image = Exiv2::ImageFactory::open(file);
image->readMetadata();
@ -75,7 +74,7 @@ int main(int argc, char* const argv[])
image->writeMetadata();
print(file);
std::cout <<"\n----- One Fujifilm MakerNote tag\n";
std::cout << "\n----- One Fujifilm MakerNote tag\n";
Exiv2::ExifData edMn2;
edMn2["Exif.Image.Make"] = "FUJIFILM";
edMn2["Exif.Image.Model"] = "FinePixS2Pro";
@ -83,7 +82,7 @@ int main(int argc, char* const argv[])
write(file, edMn2);
print(file);
std::cout <<"\n----- One Sigma/Foveon MakerNote tag\n";
std::cout << "\n----- One Sigma/Foveon MakerNote tag\n";
Exiv2::ExifData edMn3;
edMn3["Exif.Image.Make"] = "SIGMA";
edMn3["Exif.Image.Model"] = "SIGMA SD10";
@ -91,7 +90,7 @@ int main(int argc, char* const argv[])
write(file, edMn3);
print(file);
std::cout <<"\n----- One Nikon1 MakerNote tag\n";
std::cout << "\n----- One Nikon1 MakerNote tag\n";
Exiv2::ExifData edMn4;
edMn4["Exif.Image.Make"] = "NIKON";
edMn4["Exif.Image.Model"] = "E990";
@ -99,7 +98,7 @@ int main(int argc, char* const argv[])
write(file, edMn4);
print(file);
std::cout <<"\n----- One Nikon2 MakerNote tag\n";
std::cout << "\n----- One Nikon2 MakerNote tag\n";
Exiv2::ExifData edMn5;
edMn5["Exif.Image.Make"] = "NIKON";
edMn5["Exif.Image.Model"] = "E950";
@ -107,7 +106,7 @@ int main(int argc, char* const argv[])
write(file, edMn5);
print(file);
std::cout <<"\n----- One Nikon3 MakerNote tag\n";
std::cout << "\n----- One Nikon3 MakerNote tag\n";
Exiv2::ExifData edMn6;
edMn6["Exif.Image.Make"] = "NIKON CORPORATION";
edMn6["Exif.Image.Model"] = "NIKON D70";
@ -115,7 +114,7 @@ int main(int argc, char* const argv[])
write(file, edMn6);
print(file);
std::cout <<"\n----- One Olympus MakerNote tag\n";
std::cout << "\n----- One Olympus MakerNote tag\n";
Exiv2::ExifData edMn7;
edMn7["Exif.Image.Make"] = "OLYMPUS CORPORATION";
edMn7["Exif.Image.Model"] = "C8080WZ";
@ -123,7 +122,7 @@ int main(int argc, char* const argv[])
write(file, edMn7);
print(file);
std::cout <<"\n----- One Panasonic MakerNote tag\n";
std::cout << "\n----- One Panasonic MakerNote tag\n";
Exiv2::ExifData edMn8;
edMn8["Exif.Image.Make"] = "Panasonic";
edMn8["Exif.Image.Model"] = "DMC-FZ5";
@ -131,7 +130,7 @@ int main(int argc, char* const argv[])
write(file, edMn8);
print(file);
std::cout <<"\n----- One Sony1 MakerNote tag\n";
std::cout << "\n----- One Sony1 MakerNote tag\n";
Exiv2::ExifData edMn9;
edMn9["Exif.Image.Make"] = "SONY";
edMn9["Exif.Image.Model"] = "DSC-W7";
@ -139,7 +138,7 @@ int main(int argc, char* const argv[])
write(file, edMn9);
print(file);
std::cout <<"\n----- Minolta MakerNote tags\n";
std::cout << "\n----- Minolta MakerNote tags\n";
Exiv2::ExifData edMn10;
edMn10["Exif.Image.Make"] = "Minolta";
edMn10["Exif.Image.Model"] = "A fancy Minolta camera";
@ -153,32 +152,32 @@ int main(int argc, char* const argv[])
write(file, edMn10);
print(file);
std::cout <<"\n----- One IOP tag\n";
std::cout << "\n----- One IOP tag\n";
Exiv2::ExifData ed3;
ed3["Exif.Iop.InteroperabilityIndex"] = "Test 3";
write(file, ed3);
print(file);
std::cout <<"\n----- One GPS tag\n";
std::cout << "\n----- One GPS tag\n";
Exiv2::ExifData ed4;
ed4["Exif.GPSInfo.GPSVersionID"] = "19 20";
write(file, ed4);
print(file);
std::cout <<"\n----- One IFD1 tag\n";
std::cout << "\n----- One IFD1 tag\n";
Exiv2::ExifData ed5;
ed5["Exif.Thumbnail.Artist"] = "Test 5";
write(file, ed5);
print(file);
std::cout <<"\n----- One IOP and one IFD1 tag\n";
std::cout << "\n----- One IOP and one IFD1 tag\n";
Exiv2::ExifData ed6;
ed6["Exif.Iop.InteroperabilityIndex"] = "Test 6 Iop tag";
ed6["Exif.Thumbnail.Artist"] = "Test 6 Ifd1 tag";
write(file, ed6);
print(file);
std::cout <<"\n----- One IFD0 and one IFD1 tag\n";
std::cout << "\n----- One IFD0 and one IFD1 tag\n";
Exiv2::ExifData ed7;
ed7["Exif.Thumbnail.Artist"] = "Test 7";
Exiv2::Value::UniquePtr v5 = Exiv2::Value::create(Exiv2::unsignedShort);
@ -188,42 +187,30 @@ int main(int argc, char* const argv[])
print(file);
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}
}
void write(const std::string& file, Exiv2::ExifData& ed)
{
void write(const std::string& file, Exiv2::ExifData& ed) {
auto image = Exiv2::ImageFactory::open(file);
image->setExifData(ed);
image->writeMetadata();
}
void print(const std::string& file)
{
void print(const std::string& file) {
auto image = Exiv2::ImageFactory::open(file);
image->readMetadata();
Exiv2::ExifData &ed = image->exifData();
Exiv2::ExifData& ed = image->exifData();
auto end = ed.end();
for (auto i = ed.begin(); i != end; ++i) {
std::cout << std::setw(45) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(12) << std::setfill(' ') << std::left
<< i->ifdName() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< i->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
std::cout << std::setw(45) << std::setfill(' ') << std::left << i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << i->tag() << " " << std::setw(12)
<< std::setfill(' ') << std::left << i->ifdName() << " " << std::setw(9) << std::setfill(' ') << std::left
<< i->typeName() << " " << std::dec << std::setw(3) << std::setfill(' ') << std::right << i->count()
<< " " << std::dec << i->value() << "\n";
}
}

@ -4,8 +4,7 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
int main(int argc, char* const argv[])
{
int main(int argc, char* const argv[]) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF

@ -4,8 +4,7 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -32,14 +31,13 @@ try {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
}
for (auto&& md : xmpData) {
std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key() << " " << std::setw(9)
<< std::setfill(' ') << std::left << md.typeName() << " " << std::dec << std::setw(3)
<< std::setfill(' ') << std::right << md.count() << " " << std::dec << md.toString() << std::endl;
std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key() << " " << std::setw(9) << std::setfill(' ')
<< std::left << md.typeName() << " " << std::dec << std::setw(3) << std::setfill(' ') << std::right
<< md.count() << " " << std::dec << md.toString() << std::endl;
}
Exiv2::XmpParser::terminate();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}

@ -4,8 +4,7 @@
#include <exiv2/exiv2.hpp>
#include <iostream>
int main(int argc, char* const argv[])
try {
int main(int argc, char* const argv[]) try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -33,9 +32,9 @@ try {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
}
for (auto&& md : xmpData) {
std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key() << " " << std::setw(9)
<< std::setfill(' ') << std::left << md.typeName() << " " << std::dec << std::setw(3)
<< std::setfill(' ') << std::right << md.count() << " " << std::dec << md.toString() << std::endl;
std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key() << " " << std::setw(9) << std::setfill(' ')
<< std::left << md.typeName() << " " << std::dec << std::setw(3) << std::setfill(' ') << std::right
<< md.count() << " " << std::dec << md.toString() << std::endl;
}
filename += "-new";
std::cerr << "-----> Encoding XMP data to write to " << filename << " <-----\n";
@ -53,8 +52,7 @@ try {
}
Exiv2::XmpParser::terminate();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}

@ -1,24 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Read an XMP from a video or graphic file, parse it and print all (known) properties.
#include <cassert>
#include <exiv2/exiv2.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <string>
int main(int argc, char** argv)
{
int main(int argc, char** argv) {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
Exiv2::enableBMFF();
#endif
try
{
if (argc != 2)
{
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " file\n";
return 1;
}
@ -26,14 +23,13 @@ int main(int argc, char** argv)
auto image = Exiv2::ImageFactory::open(argv[1]);
image->readMetadata();
Exiv2::XmpData &xmpData = image->xmpData();
Exiv2::XmpData& xmpData = image->xmpData();
if (xmpData.empty()) {
std::string error(argv[1]);
error += ": No XMP data found in the file";
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
}
if (xmpData.empty())
{
if (xmpData.empty()) {
std::string error(argv[1]);
error += ": No XMP properties found in the XMP packet";
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
@ -48,11 +44,8 @@ int main(int argc, char** argv)
Exiv2::XmpParser::terminate();
return 0;
}
catch (Exiv2::Error& e)
{
} catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}

@ -7,14 +7,12 @@
#include <cmath>
#include <iostream>
bool isEqual(float a, float b)
{
bool isEqual(float a, float b) {
double d = std::fabs(a - b);
return d < 0.00001;
}
int main()
try {
int main() try {
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#ifdef EXV_ENABLE_BMFF
@ -68,10 +66,10 @@ try {
assert(getv2.ok());
[[maybe_unused]] Exiv2::Rational R = getv2.toRational();
assert(getv2.ok());
assert(isEqual(static_cast<float>(R.first) / R.second, 3.1415f ));
assert(isEqual(static_cast<float>(R.first) / R.second, 3.1415f));
[[maybe_unused]] const Exiv2::Value &getv3 = xmpData["Xmp.dc.three"].value();
assert(isEqual(getv3.toFloat(), 5.0f/7.0f));
assert(isEqual(getv3.toFloat(), 5.0f / 7.0f));
assert(getv3.ok());
assert(getv3.toInt64() == 0); // long(5.0 / 7.0)
assert(getv3.ok());
@ -100,7 +98,8 @@ try {
// Deleting an XMP property
auto pos = xmpData.findKey(Exiv2::XmpKey("Xmp.dc.eight"));
if (pos == xmpData.end()) throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Key not found");
if (pos == xmpData.end())
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Key not found");
xmpData.erase(pos);
// -------------------------------------------------------------------------
@ -187,9 +186,9 @@ try {
// -------------------------------------------------------------------------
// Output XMP properties
for (auto &&md : xmpData) {
std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key() << " " << std::setw(9)
<< std::setfill(' ') << std::left << md.typeName() << " " << std::dec << std::setw(3)
<< std::setfill(' ') << std::right << md.count() << " " << std::dec << md.value() << std::endl;
std::cout << std::setfill(' ') << std::left << std::setw(44) << md.key() << " " << std::setw(9) << std::setfill(' ')
<< std::left << md.typeName() << " " << std::dec << std::setw(3) << std::setfill(' ') << std::right
<< md.count() << " " << std::dec << md.value() << std::endl;
}
// -------------------------------------------------------------------------
@ -204,8 +203,7 @@ try {
Exiv2::XmpParser::terminate();
return 0;
}
catch (Exiv2::Error& e) {
} catch (Exiv2::Error &e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}

File diff suppressed because it is too large Load Diff

@ -5,8 +5,8 @@
#include "basicio.hpp"
#include "config.h"
#include "error.hpp"
#include "enforce.hpp"
#include "error.hpp"
#include "futils.hpp"
#include "image.hpp"
#include "image_int.hpp"
@ -59,59 +59,50 @@
// *****************************************************************************
// class member definitions
#ifdef EXV_ENABLE_BMFF
namespace Exiv2
{
static bool enabled = false;
EXIV2API bool enableBMFF(bool enable)
{
enabled = enable ;
return true ;
}
namespace Exiv2 {
static bool enabled = false;
EXIV2API bool enableBMFF(bool enable) {
enabled = enable;
return true;
}
std::string Iloc::toString() const
{
std::string Iloc::toString() const {
return Internal::stringFormat("ID = %u from,length = %u,%u", ID_, start_, length_);
}
}
BmffImage::BmffImage(BasicIo::UniquePtr io, bool /* create */)
: Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io))
{
} // BmffImage::BmffImage
BmffImage::BmffImage(BasicIo::UniquePtr io, bool /* create */) :
Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io)) {
} // BmffImage::BmffImage
std::string BmffImage::toAscii(long n)
{
std::string BmffImage::toAscii(long n) {
const auto p = reinterpret_cast<const char*>(&n);
std::string result;
for (int i = 0; i < 4; i++) {
char c = p[isBigEndianPlatform() ? i : (3 - i)];
result += (32<=c && c<127) ? c // only allow 7-bit printable ascii
: c==0 ? '_' // show 0 as _
: '.' ; // others .
result += (32 <= c && c < 127) ? c // only allow 7-bit printable ascii
: c == 0 ? '_' // show 0 as _
: '.'; // others .
}
return result;
}
}
bool BmffImage::superBox(uint32_t box)
{
bool BmffImage::superBox(uint32_t box) {
return box == TAG_moov || box == TAG_dinf || box == TAG_iprp || box == TAG_ipco || box == TAG_meta ||
box == TAG_iinf || box == TAG_iloc;
}
}
bool BmffImage::fullBox(uint32_t box)
{
bool BmffImage::fullBox(uint32_t box) {
return box == TAG_meta || box == TAG_iinf || box == TAG_iloc || box == TAG_thmb || box == TAG_prvw;
}
}
static bool skipBox(uint32_t box)
{
static bool skipBox(uint32_t box) {
// Allows boxHandler() to optimise the reading of files by identifying
// box types that we're not interested in. Box types listed here must
// not appear in the cases in switch (box_type) in boxHandler().
return box == TAG_mdat; // mdat is where the main image lives and can be huge
}
}
std::string BmffImage::mimeType() const
{
std::string BmffImage::mimeType() const {
switch (fileType_) {
case TAG_avif:
case TAG_avio:
@ -132,28 +123,25 @@ namespace Exiv2
default:
return "image/generic";
}
}
}
uint32_t BmffImage::pixelWidth() const
{
uint32_t BmffImage::pixelWidth() const {
auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
return imageWidth->toUint32();
}
return pixelWidth_;
}
}
uint32_t BmffImage::pixelHeight() const
{
uint32_t BmffImage::pixelHeight() const {
auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
return imageHeight->toUint32();
}
return pixelHeight_;
}
}
std::string BmffImage::uuidName(Exiv2::DataBuf& uuid)
{
std::string BmffImage::uuidName(Exiv2::DataBuf& uuid) {
const char* uuidCano = "\x85\xC0\xB6\x87\x82\xF\x11\xE0\x81\x11\xF4\xCE\x46\x2B\x6A\x48";
const char* uuidXmp = "\xBE\x7A\xCF\xCB\x97\xA9\x42\xE8\x9C\x71\x99\x94\x91\xE3\xAF\xAC";
const char* uuidCanp = "\xEA\xF4\x2B\x5E\x1C\x98\x4B\x88\xB9\xFB\xB7\xDC\x40\x6E\x4D\x16";
@ -162,24 +150,22 @@ namespace Exiv2
: uuid.cmpBytes(0, uuidCanp, 16) == 0 ? "canp"
: "";
return result;
}
}
long BmffImage::boxHandler(std::ostream& out /* = std::cout*/ ,
Exiv2::PrintStructureOption option /* = kpsNone */,
const long pbox_end,
int depth)
{
long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStructureOption option /* = kpsNone */,
const long pbox_end, int depth) {
long address = io_->tell();
// never visit a box twice!
if ( depth == 0 ) visits_.clear();
if (depth == 0)
visits_.clear();
if (visits_.find(address) != visits_.end() || visits_.size() > visits_max_) {
throw Error(ErrorCode::kerCorruptedMetadata);
}
visits_.insert(address);
bool bTrace = option == kpsBasic || option == kpsRecursive ;
bool bTrace = option == kpsBasic || option == kpsRecursive;
#ifdef EXIV2_DEBUG_MESSAGES
bTrace = true ;
bTrace = true;
#endif
// 8-byte buffer for parsing the box length and type.
@ -196,7 +182,7 @@ namespace Exiv2
uint32_t box_type = getLong(reinterpret_cast<byte*>(&hdrbuf[sizeof(uint32_t)]), endian_);
bool bLF = true;
if ( bTrace ) {
if (bTrace) {
bLF = true;
out << indent(depth) << "Exiv2::BmffImage::boxHandler: " << toAscii(box_type)
<< Internal::stringFormat(" %8ld->%lu ", address, box_length);
@ -248,14 +234,14 @@ namespace Exiv2
case TAG_ftyp: {
enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
fileType_ = data.read_uint32(0, endian_);
if ( bTrace ) {
if (bTrace) {
out << "brand: " << toAscii(fileType_);
}
} break;
// 8.11.6.1
case TAG_iinf: {
if ( bTrace ) {
if (bTrace) {
out << std::endl;
bLF = false;
}
@ -266,7 +252,7 @@ namespace Exiv2
io_->seek(skip, BasicIo::cur);
while (n-- > 0) {
io_->seek(boxHandler(out,option,box_end,depth + 1), BasicIo::beg);
io_->seek(boxHandler(out, option, box_end, depth + 1), BasicIo::beg);
}
} break;
@ -285,13 +271,13 @@ namespace Exiv2
std::string name(str);
if (name.find("Exif") != std::string::npos) { // "Exif" or "ExifExif"
exifID_ = ID;
id=" *** Exif ***";
id = " *** Exif ***";
} else if (name.find("mime\0xmp") != std::string::npos ||
name.find("mime\0application/rdf+xml") != std::string::npos) {
xmpID_ = ID;
id=" *** XMP ***";
id = " *** XMP ***";
}
if ( bTrace ) {
if (bTrace) {
out << Internal::stringFormat("ID = %3d ", ID) << name << " " << id;
}
} break;
@ -300,31 +286,31 @@ namespace Exiv2
case TAG_iprp:
case TAG_ipco:
case TAG_meta: {
if ( bTrace ) {
if (bTrace) {
out << std::endl;
bLF = false;
}
io_->seek(skip, BasicIo::cur);
while (io_->tell() < box_end) {
io_->seek(boxHandler(out,option,box_end,depth + 1), BasicIo::beg);
io_->seek(boxHandler(out, option, box_end, depth + 1), BasicIo::beg);
}
// post-process meta box to recover Exif and XMP
if (box_type == TAG_meta) {
if ( ilocs_.find(exifID_) != ilocs_.end()) {
if (ilocs_.find(exifID_) != ilocs_.end()) {
const Iloc& iloc = ilocs_.find(exifID_)->second;
if ( bTrace ) {
if (bTrace) {
out << indent(depth) << "Exiv2::BMFF Exif: " << iloc.toString() << std::endl;
}
parseTiff(Internal::Tag::root,iloc.length_,iloc.start_);
parseTiff(Internal::Tag::root, iloc.length_, iloc.start_);
}
if ( ilocs_.find(xmpID_) != ilocs_.end()) {
if (ilocs_.find(xmpID_) != ilocs_.end()) {
const Iloc& iloc = ilocs_.find(xmpID_)->second;
if ( bTrace ) {
if (bTrace) {
out << indent(depth) << "Exiv2::BMFF XMP: " << iloc.toString() << std::endl;
}
parseXmp(iloc.length_,iloc.start_);
parseXmp(iloc.length_, iloc.start_);
}
ilocs_.clear() ;
ilocs_.clear();
}
} break;
@ -344,12 +330,11 @@ namespace Exiv2
skip++;
#endif
enforce(data.size() - skip >= (version < 2u ? 2u : 4u), Exiv2::ErrorCode::kerCorruptedMetadata);
uint32_t itemCount = version < 2 ? data.read_uint16(skip, endian_)
: data.read_uint32(skip, endian_);
uint32_t itemCount = version < 2 ? data.read_uint16(skip, endian_) : data.read_uint32(skip, endian_);
skip += version < 2 ? 2 : 4;
if (itemCount && itemCount < box_length / 14 && offsetSize == 4 && lengthSize == 4 &&
((box_length - 16) % itemCount) == 0) {
if ( bTrace ) {
if (bTrace) {
out << std::endl;
bLF = false;
}
@ -359,21 +344,19 @@ namespace Exiv2
skip = base + i * step; // move in 14, 16 or 18 byte steps
enforce(data.size() - skip >= (version > 2u ? 4u : 2u), Exiv2::ErrorCode::kerCorruptedMetadata);
enforce(data.size() - skip >= step, Exiv2::ErrorCode::kerCorruptedMetadata);
uint32_t ID = version > 2 ? data.read_uint32(skip, endian_)
: data.read_uint16(skip, endian_);
uint32_t offset = step==14 || step==16 ? data.read_uint32(skip + step - 8, endian_)
: step== 18 ? data.read_uint32(skip + 4, endian_)
: 0 ;
uint32_t ID = version > 2 ? data.read_uint32(skip, endian_) : data.read_uint16(skip, endian_);
uint32_t offset = step == 14 || step == 16 ? data.read_uint32(skip + step - 8, endian_)
: step == 18 ? data.read_uint32(skip + 4, endian_)
: 0;
uint32_t ldata = data.read_uint32(skip + step - 4, endian_);
if ( bTrace ) {
if (bTrace) {
out << indent(depth)
<< Internal::stringFormat("%8ld | %8ld | ID | %4u | %6u,%6u", address + skip, step,
ID, offset, ldata)
<< Internal::stringFormat("%8ld | %8ld | ID | %4u | %6u,%6u", address + skip, step, ID, offset, ldata)
<< std::endl;
}
// save data for post-processing in meta box
if ( offset && ldata && ID != unknownID_ ) {
if (offset && ldata && ID != unknownID_) {
ilocs_[ID] = Iloc(ID, offset, ldata);
}
}
@ -387,7 +370,7 @@ namespace Exiv2
skip += 4;
uint32_t height = data.read_uint32(skip, endian_);
skip += 4;
if ( bTrace ) {
if (bTrace) {
out << "pixelWidth_, pixelHeight_ = " << Internal::stringFormat("%d, %d", width, height);
}
// HEIC files can have multiple ispe records
@ -402,18 +385,18 @@ namespace Exiv2
case TAG_colr: {
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);
uint8_t approx = data.read_uint8(skip+2);
uint8_t meth = data.read_uint8(skip + 0);
uint8_t prec = data.read_uint8(skip + 1);
uint8_t approx = data.read_uint8(skip + 2);
std::string colour_type = std::string(data.c_str(), 4);
skip+=4;
if ( colour_type == "rICC" || colour_type == "prof" ) {
DataBuf profile(data.c_data(skip),data.size()-skip);
skip += 4;
if (colour_type == "rICC" || colour_type == "prof") {
DataBuf profile(data.c_data(skip), data.size() - skip);
setIccProfile(std::move(profile));
} else if ( meth == 2 && prec == 0 && approx == 0 ) {
} else if (meth == 2 && prec == 0 && approx == 0) {
// JP2000 files have a 3 byte head // 2 0 0 icc......
skip -= 1 ;
DataBuf profile(data.c_data(skip),data.size()-skip);
skip -= 1;
DataBuf profile(data.c_data(skip), data.size() - skip);
setIccProfile(std::move(profile));
}
}
@ -423,21 +406,21 @@ namespace Exiv2
DataBuf uuid(16);
io_->read(uuid.data(), uuid.size());
std::string name = uuidName(uuid);
if ( bTrace ) {
if (bTrace) {
out << " uuidName " << name << std::endl;
bLF = false;
}
if (name == "cano" || name == "canp" ) {
if (name == "cano" || name == "canp") {
if (name == "canp") {
// based on
// https://github.com/lclevy/canon_cr3/blob/7be75d6/parse_cr3.py#L271
io_->seek(8, BasicIo::cur);
}
while (io_->tell() < box_end) {
io_->seek(boxHandler(out,option,box_end,depth + 1), BasicIo::beg);
io_->seek(boxHandler(out, option, box_end, depth + 1), BasicIo::beg);
}
} else if ( name == "xmp" ) {
parseXmp(box_length,io_->tell());
} else if (name == "xmp") {
parseXmp(box_length, io_->tell());
}
} break;
@ -454,18 +437,18 @@ namespace Exiv2
parseTiff(Internal::Tag::cmt4, box_length);
break;
case TAG_exif:
parseTiff(Internal::Tag::root, box_length,address+8);
parseTiff(Internal::Tag::root, box_length, address + 8);
break;
case TAG_xml:
parseXmp(box_length,io_->tell());
parseXmp(box_length, io_->tell());
break;
case TAG_thmb:
switch (version) {
case 0: // JPEG
parseCr3Preview(data, out, bTrace, version, skip, skip+2, skip+4, skip+12);
parseCr3Preview(data, out, bTrace, version, skip, skip + 2, skip + 4, skip + 12);
break;
case 1: // HDR
parseCr3Preview(data, out, bTrace, version, skip+2, skip+4, skip+8, skip+12);
parseCr3Preview(data, out, bTrace, version, skip + 2, skip + 4, skip + 8, skip + 12);
break;
default:
break;
@ -475,23 +458,24 @@ namespace Exiv2
switch (version) {
case 0: // JPEG
case 1: // HDR
parseCr3Preview(data, out, bTrace, version, skip+2, skip+4, skip+8, skip+12);
parseCr3Preview(data, out, bTrace, version, skip + 2, skip + 4, skip + 8, skip + 12);
break;
default:
break;
}
break;
default: break ; /* do nothing */
default:
break; /* do nothing */
}
if (bLF && bTrace) out << std::endl;
if (bLF && bTrace)
out << std::endl;
// return address of next box
return box_end;
}
}
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length,uint64_t start)
{
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length, uint64_t start) {
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
enforce(start <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
@ -500,27 +484,26 @@ namespace Exiv2
// read and parse exif data
long restore = io_->tell();
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() ) {
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 ( 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' )
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 = static_cast<long>(i);
}
if ( punt != eof ) {
if (punt != eof) {
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt),
static_cast<uint32_t>(exif.size()-punt), root_tag,
static_cast<uint32_t>(exif.size() - punt), root_tag,
Internal::TiffMapping::findDecoder);
}
}
io_->seek(restore,BasicIo::beg);
}
io_->seek(restore, BasicIo::beg);
}
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length)
{
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length) {
if (length > 8) {
enforce(length - 8 <= io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
enforce(length - 8 <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
@ -532,28 +515,27 @@ namespace Exiv2
if (bufRead != data.size())
throw Error(ErrorCode::kerInputDataReadFailed);
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(),
data.c_data(), static_cast<uint32_t>(data.size()), root_tag,
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), data.c_data(),
static_cast<uint32_t>(data.size()), root_tag,
Internal::TiffMapping::findDecoder);
}
}
}
void BmffImage::parseXmp(uint64_t length,uint64_t start)
{
void BmffImage::parseXmp(uint64_t length, uint64_t start) {
if (length > 8) {
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
long restore = io_->tell() ;
long restore = io_->tell();
enforce(start <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
io_->seek(static_cast<long>(start),BasicIo::beg);
io_->seek(static_cast<long>(start), BasicIo::beg);
enforce(length < std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
DataBuf xmp(static_cast<size_t>(length+1));
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<size_t>(length)) != length )
if (io_->read(xmp.data(), static_cast<size_t>(length)) != length)
throw Error(ErrorCode::kerInputDataReadFailed);
if ( io_->error() )
if (io_->error())
throw Error(ErrorCode::kerFailedToReadImageData);
try {
Exiv2::XmpParser::decode(xmpData(), std::string(xmp.c_str()));
@ -561,24 +543,16 @@ namespace Exiv2
throw Error(ErrorCode::kerFailedToReadImageData);
}
io_->seek(restore,BasicIo::beg);
}
io_->seek(restore, BasicIo::beg);
}
}
/// \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,
size_t width_offset,
size_t height_offset,
size_t size_offset,
size_t relative_position)
{
/// \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, 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();
enforce(here >= 0 &&
here <= std::numeric_limits<long>::max() - static_cast<long>(relative_position),
enforce(here >= 0 && here <= std::numeric_limits<long>::max() - static_cast<long>(relative_position),
ErrorCode::kerCorruptedMetadata);
NativePreview nativePreview;
nativePreview.position_ = here + static_cast<long>(relative_position);
@ -597,21 +571,17 @@ namespace Exiv2
nativePreviews_.push_back(nativePreview);
if (bTrace) {
out << Internal::stringFormat("width,height,size = %u,%u,%u",
nativePreview.width_,
nativePreview.height_,
out << Internal::stringFormat("width,height,size = %u,%u,%u", nativePreview.width_, nativePreview.height_,
nativePreview.size_);
}
}
}
void BmffImage::setComment(std::string_view /*comment*/)
{
void BmffImage::setComment(std::string_view /*comment*/) {
// bmff files are read-only
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "BMFF"));
}
}
void BmffImage::openOrThrow()
{
void BmffImage::openOrThrow() {
if (io_->open() != 0) {
throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
}
@ -621,10 +591,9 @@ namespace Exiv2
throw Error(ErrorCode::kerFailedToReadImageData);
throw Error(ErrorCode::kerNotAnImage, "BMFF");
}
} // Bmff::openOrThrow();
} // Bmff::openOrThrow();
void BmffImage::readMetadata()
{
void BmffImage::readMetadata() {
openOrThrow();
IoCloser closer(*io_);
@ -639,33 +608,34 @@ namespace Exiv2
const auto file_end = static_cast<long>(io_->size());
while (address < file_end) {
io_->seek(address, BasicIo::beg);
address = boxHandler(std::cout,kpsNone,file_end,0);
address = boxHandler(std::cout, kpsNone, file_end, 0);
}
bReadMetadata_ = true;
} // BmffImage::readMetadata
} // BmffImage::readMetadata
void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption option,int depth)
{
if ( !bReadMetadata_ ) readMetadata();
void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption option, int depth) {
if (!bReadMetadata_)
readMetadata();
switch (option) {
default: break; // do nothing
default:
break; // do nothing
case kpsIccProfile : {
case kpsIccProfile: {
out.write(iccProfile_.c_str(), iccProfile_.size());
} break;
#ifdef EXV_HAVE_XMP_TOOLKIT
case kpsXMP : {
case kpsXMP: {
std::string xmp;
if ( Exiv2::XmpParser::encode(xmp, xmpData()) ) {
if (Exiv2::XmpParser::encode(xmp, xmpData())) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "Failed to serialize XMP data");
}
out << xmp;
} break;
#endif
case kpsBasic : // drop
case kpsRecursive : {
case kpsBasic: // drop
case kpsRecursive: {
openOrThrow();
IoCloser closer(*io_);
@ -673,31 +643,28 @@ namespace Exiv2
const auto file_end = static_cast<long>(io_->size());
while (address < file_end) {
io_->seek(address, BasicIo::beg);
address = boxHandler(out,option,file_end,depth);
address = boxHandler(out, option, file_end, depth);
}
}; break;
}
}
}
void BmffImage::writeMetadata()
{
void BmffImage::writeMetadata() {
// bmff files are read-only
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "BMFF"));
} // BmffImage::writeMetadata
} // BmffImage::writeMetadata
// *************************************************************************
// free functions
Image::UniquePtr newBmffInstance(BasicIo::UniquePtr io, bool create)
{
// *************************************************************************
// free functions
Image::UniquePtr newBmffInstance(BasicIo::UniquePtr io, bool create) {
auto image = std::make_unique<BmffImage>(std::move(io), create);
if (!image->good()) {
image.reset();
}
return image;
}
}
bool isBmffType(BasicIo& iIo, bool advance)
{
bool isBmffType(BasicIo& iIo, bool advance) {
if (!enabled) {
return false;
}
@ -722,14 +689,12 @@ namespace Exiv2
iIo.seek(static_cast<long>(0), BasicIo::beg);
}
return matched;
}
}
} // namespace Exiv2
#else // ifdef EXV_ENABLE_BMFF
namespace Exiv2
{
EXIV2API bool enableBMFF(bool)
{
return false ;
}
namespace Exiv2 {
EXIV2API bool enableBMFF(bool) {
return false;
}
} // namespace Exiv2
#endif

@ -5,48 +5,41 @@
History: 05-Mar-2007, marco: created
*/
#include "basicio.hpp"
#include "bmpimage.hpp"
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
#include "image.hpp"
// + standard includes
#include <cstring>
#include <string>
#include <iostream>
#include <string>
// *****************************************************************************
// class member definitions
namespace Exiv2
{
BmpImage::BmpImage(BasicIo::UniquePtr io) : Image(ImageType::bmp, mdNone, std::move(io))
{
}
namespace Exiv2 {
BmpImage::BmpImage(BasicIo::UniquePtr io) : Image(ImageType::bmp, mdNone, std::move(io)) {
}
std::string BmpImage::mimeType() const
{
std::string BmpImage::mimeType() const {
// "image/bmp" is a Generic Bitmap
return "image/x-ms-bmp"; // Microsoft Bitmap
}
}
void BmpImage::setExifData(const ExifData& /*exifData*/)
{
void BmpImage::setExifData(const ExifData& /*exifData*/) {
throw(Error(ErrorCode::kerInvalidSettingForImage, "Exif metadata", "BMP"));
}
}
void BmpImage::setIptcData(const IptcData& /*iptcData*/)
{
void BmpImage::setIptcData(const IptcData& /*iptcData*/) {
throw(Error(ErrorCode::kerInvalidSettingForImage, "IPTC metadata", "BMP"));
}
}
void BmpImage::setComment(std::string_view /*comment*/)
{
void BmpImage::setComment(std::string_view /*comment*/) {
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "BMP"));
}
}
void BmpImage::readMetadata()
{
void BmpImage::readMetadata() {
#ifdef EXIV2_DEBUG_MESSAGES
std::cerr << "Exiv2::BmpImage::readMetadata: Reading Windows bitmap file " << io_->path() << "\n";
#endif
@ -77,39 +70,34 @@ namespace Exiv2
22 4 bytes bitmap height
26 2 bytes plane count
28 2 bytes depth
30 4 bytes compression 0 = none; 1 = RLE, 8 bits/pixel; 2 = RLE, 4 bits/pixel; 3 = bitfield; 4 = JPEG; 5 = PNG
34 4 bytes image size size of the raw bitmap data, in bytes
38 4 bytes horizontal resolution (in pixels per meter)
42 4 bytes vertical resolution (in pixels per meter)
46 4 bytes color count
50 4 bytes important colors number of "important" colors
30 4 bytes compression 0 = none; 1 = RLE, 8 bits/pixel; 2 = RLE, 4 bits/pixel; 3 = bitfield;
4 = JPEG; 5 = PNG 34 4 bytes image size size of the raw bitmap data, in bytes 38 4
bytes horizontal resolution (in pixels per meter) 42 4 bytes vertical resolution (in pixels per
meter) 46 4 bytes color count 50 4 bytes important colors number of "important" colors
*/
byte buf[26];
if (io_->read(buf, sizeof(buf)) == sizeof(buf)) {
pixelWidth_ = getLong(buf + 18, littleEndian);
pixelHeight_ = getLong(buf + 22, littleEndian);
}
}
}
void BmpImage::writeMetadata()
{
void BmpImage::writeMetadata() {
/// \todo implement me!
throw(Error(ErrorCode::kerWritingImageFormatUnsupported, "BMP"));
}
}
// *************************************************************************
// free functions
Image::UniquePtr newBmpInstance(BasicIo::UniquePtr io, bool /*create*/)
{
// *************************************************************************
// free functions
Image::UniquePtr newBmpInstance(BasicIo::UniquePtr io, bool /*create*/) {
auto image = std::make_unique<BmpImage>(std::move(io));
if (!image->good()) {
image.reset();
}
return image;
}
}
bool isBmpType(BasicIo& iIo, bool advance)
{
bool isBmpType(BasicIo& iIo, bool advance) {
const int32_t len = 2;
const unsigned char BmpImageId[2] = {'B', 'M'};
byte buf[len];
@ -122,5 +110,5 @@ namespace Exiv2
iIo.seek(-len, BasicIo::cur);
}
return matched;
}
}
} // namespace Exiv2

File diff suppressed because it is too large Load Diff

@ -3,7 +3,8 @@
@file canonmn_int.hpp
@brief Canon makernote tags.<BR>References:<BR>
[1] <a href="http://www.burren.cx/david/canon.html">EXIF MakerNote of Canon</a> by David Burren<br>
[2] <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html">Canon makernote tags</a> by Phil Harvey
[2] <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html">Canon makernote tags</a> by
Phil Harvey
@author <a href="mailto:ahuggel@gmx.net">Andreas Huggel (ahu)</a><br>
<a href="mailto:david@edeca.net">David Cannings (dc)</a>
<a href="mailto:andi.clemens@gmx.net">Andi Clemens (ac)</a>
@ -21,11 +22,11 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2::Internal {
// *****************************************************************************
// class definitions
// *****************************************************************************
// class definitions
//! MakerNote for Canon cameras
class CanonMakerNote {
//! MakerNote for Canon cameras
class CanonMakerNote {
public:
//! Return read-only list of built-in Canon tags
static const TagInfo* tagList();
@ -94,7 +95,6 @@ namespace Exiv2::Internal {
//! Return read-only list of built-in Canon RawBurstInfo Info tags
static const TagInfo* tagListRawB();
//! @name Print functions for Canon %MakerNote tags
//@{
//! Print the FileInfo FileNumber
@ -175,15 +175,14 @@ namespace Exiv2::Internal {
static const TagInfo tagInfoVigCor_[];
static const TagInfo tagInfoVigCor2_[];
static const TagInfo tagInfoWbi_[];
static const TagInfo tagInfoRawB_ [];
static const TagInfo tagInfoRawB_[];
}; // class CanonMakerNote
}; // class CanonMakerNote
// *****************************************************************************
// template, inline and free functions
/*!
/*!
@brief Convert Canon hex-based EV (modulo 0x20) to real number
Ported from Phil Harvey's Image::ExifTool::Canon::CanonEv
by Will Stokes
@ -198,10 +197,8 @@ namespace Exiv2::Internal {
128 -> 4
143 -> 4.46875
*/
float canonEv(int64_t val);
float canonEv(int64_t val);
} // namespace Exiv2::Internal
#endif // #ifndef CANONMN_INT_HPP_

@ -5,561 +5,403 @@
Credits: See header file
*/
// included header files
#include "types.hpp"
#include "casiomn_int.hpp"
#include "i18n.h" // NLS support.
#include "tags_int.hpp"
#include "types.hpp"
#include "value.hpp"
#include "i18n.h" // NLS support.
// + standard includes
#include <sstream>
#include <iomanip>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <vector>
// *****************************************************************************
// class member definitions
namespace Exiv2::Internal {
//! RecordingMode, tag 0x0001
constexpr TagDetails casioRecordingMode[] = {
{ 1, N_("Single Shutter") },
{ 2, N_("Panorama") },
{ 3, N_("Night Scene") },
{ 4, N_("Portrait") },
{ 5, N_("Landscape") },
{ 7, N_("Panorama") },
{ 10, N_("Night Scene") },
{ 15, N_("Portrait") },
{ 16, N_("Landscape") }
};
//! Quality, tag 0x0002
constexpr TagDetails casioQuality[] = {
{ 1, N_("Economy") },
{ 2, N_("Normal") },
{ 3, N_("Fine") }
};
//! Focus Mode, tag 0x0003
constexpr TagDetails casioFocusMode[] = {
{ 2, N_("Macro") },
{ 3, N_("Auto") },
{ 4, N_("Manual") },
{ 5, N_("Infinity") },
{ 7, N_("Sport AF") }
};
//! FlashMode, tag 0x0004
constexpr TagDetails casioFlashMode[] = {
{ 1, N_("Auto") },
{ 2, N_("On") },
{ 3, N_("Off") },
{ 4, N_("Off") },
{ 5, N_("Red-eye Reduction") }
};
//! Flash intensity, tag 0x0005
constexpr TagDetails casioFlashIntensity[] = {
{ 11, N_("Weak") },
{ 12, N_("Low") },
{ 13, N_("Normal") },
{ 14, N_("High") },
{ 15, N_("Strong") }
};
//! white balance, tag 0x0007
constexpr TagDetails casioWhiteBalance[] = {
{ 1, N_("Auto") },
{ 2, N_("Tungsten") },
{ 3, N_("Daylight") },
{ 4, N_("Fluorescent") },
{ 5, N_("Shade") },
{ 129, N_("Manual") }
};
//! Flash intensity, tag 0x0005
constexpr TagDetails casioDigitalZoom[] = {
{ 0x10000, N_("Off") },
{ 0x10001, N_("2x") },
{ 0x13333, N_("1.2x") },
{ 0x13ae1, N_("1.23x") },
{ 0x19999, N_("1.6x") },
{ 0x20000, N_("2x") },
{ 0x33333, N_("3.2x") },
{ 0x40000, N_("4x") }
};
//! Sharpness, tag 0x000b
constexpr TagDetails casioSharpness[] = {
{ 0, N_("Normal") },
{ 1, N_("Soft") },
{ 2, N_("Hard") },
{ 16, N_("Normal") },
{ 17, N_("+1") },
{ 18, N_("-1") }
};
//! Contrast, tag 0x000c
constexpr TagDetails casioContrast[] = {
{ 0, N_("Normal") },
{ 1, N_("Low") },
{ 2, N_("High") },
{ 16, N_("Normal") },
{ 17, N_("+1") },
{ 18, N_("-1") }
};
//! Saturation, tag 0x000d
constexpr TagDetails casioSaturation[] = {
{ 0, N_("Normal") },
{ 1, N_("Low") },
{ 2, N_("High") },
{ 16, N_("Normal") },
{ 17, N_("+1") },
{ 18, N_("-1") }
};
//! Enhancement, tag 0x0016
constexpr TagDetails casioEnhancement[] = {
{ 1, N_("Off") },
{ 2, N_("Red") },
{ 3, N_("Green") },
{ 4, N_("Blue") },
{ 5, N_("Flesh Tones") }
};
//! Color filter, tag 0x0017
constexpr TagDetails casioColorFilter[] = {
{ 1, N_("Off") },
{ 2, N_("Black & White") },
{ 3, N_("Sepia") },
{ 4, N_("Red") },
{ 5, N_("Green") },
{ 6, N_("Blue") },
{ 7, N_("Yellow") },
{ 8, N_("Pink") },
{ 9, N_("Purple") }
};
//! flash intensity 2, tag 0x0019
constexpr TagDetails casioFlashIntensity2[] = {
{ 1, N_("Normal") },
{ 2, N_("Weak") },
{ 3, N_("Strong") }
};
//! CCD Sensitivity intensity, tag 0x0020
constexpr TagDetails casioCCDSensitivity[] = {
{ 64, N_("Normal") },
{ 125, N_("+1.0") },
{ 250, N_("+2.0") },
{ 244, N_("+3.0") },
{ 80, N_("Normal (ISO 80 equivalent)") },
{ 100, N_("High") }
};
// Casio MakerNote Tag Info
constexpr TagInfo CasioMakerNote::tagInfo_[] = {
{0x0001, "RecodingMode", N_("RecodingMode"), N_("Recording Mode"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioRecordingMode)},
{0x0002, "Quality", N_("Quality"), N_("Quality"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioQuality)},
{0x0003, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioFocusMode)},
{0x0004, "FlashMode", N_("Flash Mode"), N_("Flash Mode"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioFlashMode)},
{0x0005, "FlashIntensity", N_("Flash Intensity"), N_("Flash Intensity"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioFlashIntensity)},
{0x0006, "ObjectDistance", N_("Object Distance"), N_("Distance to object"), casioId, makerTags, unsignedLong, -1, print0x0006},
{0x0007, "WhiteBalance", N_("White Balance"), N_("White balance settings"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioWhiteBalance)},
{0x000a, "DigitalZoom", N_("Digital Zoom"), N_("Digital zoom"), casioId, makerTags, unsignedLong, -1, EXV_PRINT_TAG(casioDigitalZoom)},
{0x000b, "Sharpness", N_("Sharpness"), N_("Sharpness"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioSharpness)},
{0x000c, "Contrast", N_("Contrast"), N_("Contrast"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioContrast)},
{0x000d, "Saturation", N_("Saturation"), N_("Saturation"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioSaturation)},
//! RecordingMode, tag 0x0001
constexpr TagDetails casioRecordingMode[] = {{1, N_("Single Shutter")}, {2, N_("Panorama")}, {3, N_("Night Scene")},
{4, N_("Portrait")}, {5, N_("Landscape")}, {7, N_("Panorama")},
{10, N_("Night Scene")}, {15, N_("Portrait")}, {16, N_("Landscape")}};
//! Quality, tag 0x0002
constexpr TagDetails casioQuality[] = {{1, N_("Economy")}, {2, N_("Normal")}, {3, N_("Fine")}};
//! Focus Mode, tag 0x0003
constexpr TagDetails casioFocusMode[] = {
{2, N_("Macro")}, {3, N_("Auto")}, {4, N_("Manual")}, {5, N_("Infinity")}, {7, N_("Sport AF")}};
//! FlashMode, tag 0x0004
constexpr TagDetails casioFlashMode[] = {
{1, N_("Auto")}, {2, N_("On")}, {3, N_("Off")}, {4, N_("Off")}, {5, N_("Red-eye Reduction")}};
//! Flash intensity, tag 0x0005
constexpr TagDetails casioFlashIntensity[] = {
{11, N_("Weak")}, {12, N_("Low")}, {13, N_("Normal")}, {14, N_("High")}, {15, N_("Strong")}};
//! white balance, tag 0x0007
constexpr TagDetails casioWhiteBalance[] = {{1, N_("Auto")}, {2, N_("Tungsten")}, {3, N_("Daylight")},
{4, N_("Fluorescent")}, {5, N_("Shade")}, {129, N_("Manual")}};
//! Flash intensity, tag 0x0005
constexpr TagDetails casioDigitalZoom[] = {{0x10000, N_("Off")}, {0x10001, N_("2x")}, {0x13333, N_("1.2x")},
{0x13ae1, N_("1.23x")}, {0x19999, N_("1.6x")}, {0x20000, N_("2x")},
{0x33333, N_("3.2x")}, {0x40000, N_("4x")}};
//! Sharpness, tag 0x000b
constexpr TagDetails casioSharpness[] = {{0, N_("Normal")}, {1, N_("Soft")}, {2, N_("Hard")},
{16, N_("Normal")}, {17, N_("+1")}, {18, N_("-1")}};
//! Contrast, tag 0x000c
constexpr TagDetails casioContrast[] = {{0, N_("Normal")}, {1, N_("Low")}, {2, N_("High")},
{16, N_("Normal")}, {17, N_("+1")}, {18, N_("-1")}};
//! Saturation, tag 0x000d
constexpr TagDetails casioSaturation[] = {{0, N_("Normal")}, {1, N_("Low")}, {2, N_("High")},
{16, N_("Normal")}, {17, N_("+1")}, {18, N_("-1")}};
//! Enhancement, tag 0x0016
constexpr TagDetails casioEnhancement[] = {
{1, N_("Off")}, {2, N_("Red")}, {3, N_("Green")}, {4, N_("Blue")}, {5, N_("Flesh Tones")}};
//! Color filter, tag 0x0017
constexpr TagDetails casioColorFilter[] = {{1, N_("Off")}, {2, N_("Black & White")}, {3, N_("Sepia")},
{4, N_("Red")}, {5, N_("Green")}, {6, N_("Blue")},
{7, N_("Yellow")}, {8, N_("Pink")}, {9, N_("Purple")}};
//! flash intensity 2, tag 0x0019
constexpr TagDetails casioFlashIntensity2[] = {{1, N_("Normal")}, {2, N_("Weak")}, {3, N_("Strong")}};
//! CCD Sensitivity intensity, tag 0x0020
constexpr TagDetails casioCCDSensitivity[] = {
{64, N_("Normal")}, {125, N_("+1.0")}, {250, N_("+2.0")}, {244, N_("+3.0")}, {80, N_("Normal (ISO 80 equivalent)")},
{100, N_("High")}};
// Casio MakerNote Tag Info
constexpr TagInfo CasioMakerNote::tagInfo_[] = {
{0x0001, "RecodingMode", N_("RecodingMode"), N_("Recording Mode"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioRecordingMode)},
{0x0002, "Quality", N_("Quality"), N_("Quality"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioQuality)},
{0x0003, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFocusMode)},
{0x0004, "FlashMode", N_("Flash Mode"), N_("Flash Mode"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFlashMode)},
{0x0005, "FlashIntensity", N_("Flash Intensity"), N_("Flash Intensity"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFlashIntensity)},
{0x0006, "ObjectDistance", N_("Object Distance"), N_("Distance to object"), casioId, makerTags, unsignedLong, -1,
print0x0006},
{0x0007, "WhiteBalance", N_("White Balance"), N_("White balance settings"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioWhiteBalance)},
{0x000a, "DigitalZoom", N_("Digital Zoom"), N_("Digital zoom"), casioId, makerTags, unsignedLong, -1,
EXV_PRINT_TAG(casioDigitalZoom)},
{0x000b, "Sharpness", N_("Sharpness"), N_("Sharpness"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioSharpness)},
{0x000c, "Contrast", N_("Contrast"), N_("Contrast"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioContrast)},
{0x000d, "Saturation", N_("Saturation"), N_("Saturation"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioSaturation)},
{0x0014, "ISO", N_("ISO"), N_("ISO"), casioId, makerTags, unsignedShort, -1, printValue},
{0x0015, "FirmwareDate", N_("Firmware date"), N_("Firmware date"), casioId, makerTags, asciiString, -1, print0x0015},
{0x0016, "Enhancement", N_("Enhancement"), N_("Enhancement"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioEnhancement)},
{0x0017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioColorFilter)},
{0x0015, "FirmwareDate", N_("Firmware date"), N_("Firmware date"), casioId, makerTags, asciiString, -1,
print0x0015},
{0x0016, "Enhancement", N_("Enhancement"), N_("Enhancement"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioEnhancement)},
{0x0017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioColorFilter)},
{0x0018, "AFPoint", N_("AF Point"), N_("AF Point"), casioId, makerTags, unsignedShort, -1, printValue},
{0x0019, "FlashIntensity2", N_("Flash Intensity"), N_("Flash Intensity"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioFlashIntensity2)},
{0x0020, "CCDSensitivity", N_("CCDSensitivity"), N_("CCDSensitivity"), casioId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casioCCDSensitivity)},
{0x0019, "FlashIntensity2", N_("Flash Intensity"), N_("Flash Intensity"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFlashIntensity2)},
{0x0020, "CCDSensitivity", N_("CCDSensitivity"), N_("CCDSensitivity"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioCCDSensitivity)},
{0x0e00, "PrintIM", N_("Print IM"), N_("PrintIM information"), casioId, makerTags, undefined, -1, printValue},
{0xffff, "(UnknownCasioMakerNoteTag)", "(UnknownCasioMakerNoteTag)", N_("Unknown CasioMakerNote tag"), casioId, makerTags, asciiString, -1, printValue},
};
{0xffff, "(UnknownCasioMakerNoteTag)", "(UnknownCasioMakerNoteTag)", N_("Unknown CasioMakerNote tag"), casioId,
makerTags, asciiString, -1, printValue},
};
const TagInfo* CasioMakerNote::tagList()
{
const TagInfo* CasioMakerNote::tagList() {
return tagInfo_;
}
}
std::ostream& CasioMakerNote::print0x0006(std::ostream& os, const Value& value, const ExifData*)
{
std::ios::fmtflags f( os.flags() );
std::ostream& CasioMakerNote::print0x0006(std::ostream& os, const Value& value, const ExifData*) {
std::ios::fmtflags f(os.flags());
std::ostringstream oss;
oss.copyfmt(os);
os << std::fixed << std::setprecision(2) << value.toInt64() / 1000.0 << _(" m");
os.copyfmt(oss);
os.flags(f);
return os;
}
}
std::ostream& CasioMakerNote::print0x0015(std::ostream& os, const Value& value, const ExifData*)
{
std::ostream& CasioMakerNote::print0x0015(std::ostream& os, const Value& value, const ExifData*) {
// 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(size_t i=0; i<value.size(); i++)
{
for (size_t i = 0; i < value.size(); i++) {
const auto l = value.toInt64(i);
if(l!=0)
{
if (l != 0) {
numbers.push_back(static_cast<char>(l));
}
}
if(numbers.size()>=10)
{
//year
long l=(numbers[0]-48)*10+(numbers[1]-48);
if(l<70)
{
l+=2000;
}
else
{
l+=1900;
if (numbers.size() >= 10) {
// year
long l = (numbers[0] - 48) * 10 + (numbers[1] - 48);
if (l < 70) {
l += 2000;
} else {
l += 1900;
};
os << l << ":";
// month, day, hour, minutes
os << numbers[2] << numbers[3] << ":" << numbers[4] << numbers[5] << " " << numbers[6] << numbers[7] << ":" << numbers[8] << numbers[9];
os << numbers[2] << numbers[3] << ":" << numbers[4] << numbers[5] << " " << numbers[6] << numbers[7] << ":"
<< numbers[8] << numbers[9];
// optional seconds
if(numbers.size()==12)
{
if (numbers.size() == 12) {
os << ":" << numbers[10] << numbers[11];
};
}
else
{
} else {
os << value;
};
return os;
}
//Casio Makernotes, Type 2
//! Quality Mode, tag 0x0004
constexpr TagDetails casio2QualityMode[] = {
{ 0, N_("Economy") },
{ 1, N_("Normal") },
{ 2, N_("Fine") }
};
//! Image Size, tag 0x0009
constexpr TagDetails casio2ImageSize[] = {
{ 0, "640x480" },
{ 4, "1600x1200" },
{ 5, "2048x1536" },
{ 20, "2288x1712" },
{ 21, "2592x1944" },
{ 22, "2304x1728" },
{ 36, "3008x2008" }
};
//! Focus Mode, tag 0x000d
constexpr TagDetails casio2FocusMode[] = {
{ 0, N_("Normal") },
{ 1, N_("Macro") }
};
//! ISO Speed, tag 0x0014
constexpr TagDetails casio2IsoSpeed[] = {
{ 3, "50" },
{ 4, "64" },
{ 6, "100" },
{ 9, "200" }
};
//! White Balance, tag 0x0019
constexpr TagDetails casio2WhiteBalance[] = {
{ 0, N_("Auto") },
{ 1, N_("Daylight") },
{ 2, N_("Shade") },
{ 3, N_("Tungsten") },
{ 4, N_("Fluorescent") },
{ 5, N_("Manual") }
};
//! Saturation, tag 0x001f
constexpr TagDetails casio2Saturation[] = {
{ 0, N_("Low") },
{ 1, N_("Normal") },
{ 2, N_("High") }
};
//! Contrast, tag 0x0020
constexpr TagDetails casio2Contrast[] = {
{ 0, N_("Low") },
{ 1, N_("Normal") },
{ 2, N_("High") }
};
//! Sharpness, tag 0x0021
constexpr TagDetails casio2Sharpness[] = {
{ 0, N_("Soft") },
{ 1, N_("Normal") },
{ 2, N_("Hard") }
};
//! White Balance2, tag 0x2012
constexpr TagDetails casio2WhiteBalance2[] = {
{ 0, N_("Manual") },
{ 1, N_("Daylight") },
{ 2, N_("Cloudy") },
{ 3, N_("Shade") },
{ 4, N_("Flash") },
{ 6, N_("Fluorescent") },
{ 9, N_("Tungsten") },
{ 10, N_("Tungsten") },
{ 12, N_("Flash") }
};
//! Release Mode, tag 0x3001
constexpr TagDetails casio2ReleaseMode[] = {
{ 1, N_("Normal") },
{ 3, N_("AE Bracketing") },
{ 11, N_("WB Bracketing") },
{ 13, N_("Contrast Bracketing") },
{ 19, N_("High Speed Burst") }
};
//! Quality, tag 0x3002
constexpr TagDetails casio2Quality[] = {
{ 1, N_("Economy") },
{ 2, N_("Normal") },
{ 3, N_("Fine") }
};
//! Focus Mode 2, tag 0x3003
constexpr TagDetails casio2FocusMode2[] = {
{ 0, N_("Manual") },
{ 1, N_("Focus Lock") },
{ 2, N_("Macro") },
{ 3, N_("Single-Area Auto Focus") },
{ 5, N_("Infinity") },
{ 6, N_("Multi-Area Auto Focus") },
{ 8, N_("Super Macro") }
};
//! AutoISO, tag 0x3008
constexpr TagDetails casio2AutoISO[] = {
{ 1, N_("On") },
{ 2, N_("Off") },
{ 7, N_("On (high sensitivity)") },
{ 8, N_("On (anti-shake)") },
{ 10, N_("High Speed") }
};
//! AFMode, tag 0x3009
constexpr TagDetails casio2AFMode[] = {
{ 0, N_("Off") },
{ 1, N_("Spot") },
{ 2, N_("Multi") },
{ 3, N_("Face Detection") },
{ 4, N_("Tracking") },
{ 5, N_("Intelligent") }
};
//! ColorMode, tag 0x3015
constexpr TagDetails casio2ColorMode[] = {
{ 0, N_("Off") },
{ 2, N_("Black & White") },
{ 3, N_("Sepia") }
};
//! Enhancement, tag 0x3016
constexpr TagDetails casio2Enhancement[] = {
{ 0, N_("Off") },
{ 1, N_("Scenery") },
{ 3, N_("Green") },
{ 5, N_("Underwater") },
{ 9, N_("Flesh Tones") }
};
//! Color Filter, tag 0x3017
constexpr TagDetails casio2ColorFilter[] = {
{ 0, N_("Off") },
{ 1, N_("Blue") },
{ 3, N_("Green") },
{ 4, N_("Yellow") },
{ 5, N_("Red") },
{ 6, N_("Purple") },
{ 7, N_("Pink") }
};
//! Art Mode, tag 0x301b
constexpr TagDetails casio2ArtMode[] = {
{ 0, N_("Normal") },
{ 8, N_("Silent Movie") },
{ 39, N_("HDR") },
{ 45, N_("Premium Auto") },
{ 47, N_("Painting") },
{ 49, N_("Crayon Drawing") },
{ 51, N_("Panorama") },
{ 52, N_("Art HDR") },
{ 62, N_("High Speed Night Shot") },
{ 64, N_("Monochrome") },
{ 67, N_("Toy Camera") },
{ 68, N_("Pop Art") },
{ 69, N_("Light Tone") }
};
//! Lighting Mode, tag 0x302a
constexpr TagDetails casio2LightingMode[] = {
{ 0, N_("Off") },
{ 1, N_("High Dynamic Range") },
{ 5, N_("Shadow Enhance Low") },
{ 6, N_("Shadow Enhance High") }
};
//! Portrait Refiner, tag 0x302b
constexpr TagDetails casio2PortraitRefiner[] = {
{ 0, N_("Off") },
{ 1, N_("+1") },
{ 2, N_("+2") }
};
//! Special Effect Setting, tag 0x3031
constexpr TagDetails casio2SpecialEffectSetting[] = {
{ 0, N_("Off") },
{ 1, N_("Makeup") },
{ 2, N_("Mist Removal") },
{ 3, N_("Vivid Landscape") },
{ 16, N_("Art Shot") }
};
//! Drive Mode, tag 0x3103
constexpr TagDetails casio2DriveMode[] = {
{ 0, N_("Single Shot") },
{ 1, N_("Continuous Shooting") },
{ 2, N_("Continuous (2 fps)") },
{ 3, N_("Continuous (3 fps)") },
{ 4, N_("Continuous (4 fps)") },
{ 5, N_("Continuous (5 fps)") },
{ 6, N_("Continuous (6 fps)") },
{ 7, N_("Continuous (7 fps)") },
{ 10, N_("Continuous (10 fps)") },
{ 12, N_("Continuous (12 fps)") },
{ 15, N_("Continuous (15 fps)") },
{ 20, N_("Continuous (20 fps)") },
{ 30, N_("Continuous (30 fps)") },
{ 40, N_("Continuous (40 fps)") },
{ 60, N_("Continuous (60 fps)") },
{ 240, N_("Auto-N") }
};
//! Video Quality, tag 0x4003
constexpr TagDetails casio2VideoQuality[] = {
{ 1, N_("Standard") },
{ 3, N_("HD (720p)") },
{ 4, N_("Full HD (1080p)") },
{ 5, N_("Low") }
};
// Casio2 MakerNote Tag Info
constexpr TagInfo Casio2MakerNote::tagInfo_[] = {
{0x0002, "PreviewImageSize", N_("Preview Image Size"), N_("Preview Image Size"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x0003, "PreviewImageLength", N_("Preview Image Length"), N_("Preview Image Length"), casio2Id, makerTags, unsignedLong, -1, printValue},
{0x0004, "PreviewImageStart", N_("Preview Image Start"), N_("Preview Image Start"), casio2Id, makerTags, unsignedLong, -1, printValue},
{0x0008, "QualityMode", N_("Quality Mode"), N_("Quality Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2QualityMode)},
{0x0009, "ImageSize", N_("Image Size"), N_("Image Size"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2ImageSize)},
{0x000d, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2FocusMode)},
{0x0014, "ISOSpeed", N_("ISO Speed"), N_("ISO Speed"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2IsoSpeed)},
{0x0019, "WhiteBalance", N_("White Balance"), N_("White Balance Setting"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2WhiteBalance)},
{0x001d, "FocalLength", N_("Focal Length"), N_("Focal Length"), casio2Id, makerTags, unsignedRational, -1, printValue},
{0x001f, "Saturation", N_("Saturation"), N_("Saturation"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2Saturation)},
{0x0020, "Contrast", N_("Contrast"), N_("Contrast"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2Contrast)},
{0x0021, "Sharpness", N_("Sharpness"), N_("Sharpness"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2Sharpness)},
}
// Casio Makernotes, Type 2
//! Quality Mode, tag 0x0004
constexpr TagDetails casio2QualityMode[] = {{0, N_("Economy")}, {1, N_("Normal")}, {2, N_("Fine")}};
//! Image Size, tag 0x0009
constexpr TagDetails casio2ImageSize[] = {{0, "640x480"}, {4, "1600x1200"}, {5, "2048x1536"}, {20, "2288x1712"},
{21, "2592x1944"}, {22, "2304x1728"}, {36, "3008x2008"}};
//! Focus Mode, tag 0x000d
constexpr TagDetails casio2FocusMode[] = {{0, N_("Normal")}, {1, N_("Macro")}};
//! ISO Speed, tag 0x0014
constexpr TagDetails casio2IsoSpeed[] = {{3, "50"}, {4, "64"}, {6, "100"}, {9, "200"}};
//! White Balance, tag 0x0019
constexpr TagDetails casio2WhiteBalance[] = {{0, N_("Auto")}, {1, N_("Daylight")}, {2, N_("Shade")},
{3, N_("Tungsten")}, {4, N_("Fluorescent")}, {5, N_("Manual")}};
//! Saturation, tag 0x001f
constexpr TagDetails casio2Saturation[] = {{0, N_("Low")}, {1, N_("Normal")}, {2, N_("High")}};
//! Contrast, tag 0x0020
constexpr TagDetails casio2Contrast[] = {{0, N_("Low")}, {1, N_("Normal")}, {2, N_("High")}};
//! Sharpness, tag 0x0021
constexpr TagDetails casio2Sharpness[] = {{0, N_("Soft")}, {1, N_("Normal")}, {2, N_("Hard")}};
//! White Balance2, tag 0x2012
constexpr TagDetails casio2WhiteBalance2[] = {{0, N_("Manual")}, {1, N_("Daylight")}, {2, N_("Cloudy")},
{3, N_("Shade")}, {4, N_("Flash")}, {6, N_("Fluorescent")},
{9, N_("Tungsten")}, {10, N_("Tungsten")}, {12, N_("Flash")}};
//! Release Mode, tag 0x3001
constexpr TagDetails casio2ReleaseMode[] = {{1, N_("Normal")},
{3, N_("AE Bracketing")},
{11, N_("WB Bracketing")},
{13, N_("Contrast Bracketing")},
{19, N_("High Speed Burst")}};
//! Quality, tag 0x3002
constexpr TagDetails casio2Quality[] = {{1, N_("Economy")}, {2, N_("Normal")}, {3, N_("Fine")}};
//! Focus Mode 2, tag 0x3003
constexpr TagDetails casio2FocusMode2[] = {{0, N_("Manual")}, {1, N_("Focus Lock")},
{2, N_("Macro")}, {3, N_("Single-Area Auto Focus")},
{5, N_("Infinity")}, {6, N_("Multi-Area Auto Focus")},
{8, N_("Super Macro")}};
//! AutoISO, tag 0x3008
constexpr TagDetails casio2AutoISO[] = {{1, N_("On")},
{2, N_("Off")},
{7, N_("On (high sensitivity)")},
{8, N_("On (anti-shake)")},
{10, N_("High Speed")}};
//! AFMode, tag 0x3009
constexpr TagDetails casio2AFMode[] = {{0, N_("Off")}, {1, N_("Spot")},
{2, N_("Multi")}, {3, N_("Face Detection")},
{4, N_("Tracking")}, {5, N_("Intelligent")}};
//! ColorMode, tag 0x3015
constexpr TagDetails casio2ColorMode[] = {{0, N_("Off")}, {2, N_("Black & White")}, {3, N_("Sepia")}};
//! Enhancement, tag 0x3016
constexpr TagDetails casio2Enhancement[] = {
{0, N_("Off")}, {1, N_("Scenery")}, {3, N_("Green")}, {5, N_("Underwater")}, {9, N_("Flesh Tones")}
};
//! Color Filter, tag 0x3017
constexpr TagDetails casio2ColorFilter[] = {{0, N_("Off")}, {1, N_("Blue")}, {3, N_("Green")}, {4, N_("Yellow")},
{5, N_("Red")}, {6, N_("Purple")}, {7, N_("Pink")}};
//! Art Mode, tag 0x301b
constexpr TagDetails casio2ArtMode[] = {
{0, N_("Normal")}, {8, N_("Silent Movie")}, {39, N_("HDR")},
{45, N_("Premium Auto")}, {47, N_("Painting")}, {49, N_("Crayon Drawing")},
{51, N_("Panorama")}, {52, N_("Art HDR")}, {62, N_("High Speed Night Shot")},
{64, N_("Monochrome")}, {67, N_("Toy Camera")}, {68, N_("Pop Art")},
{69, N_("Light Tone")}};
//! Lighting Mode, tag 0x302a
constexpr TagDetails casio2LightingMode[] = {
{0, N_("Off")}, {1, N_("High Dynamic Range")}, {5, N_("Shadow Enhance Low")}, {6, N_("Shadow Enhance High")}};
//! Portrait Refiner, tag 0x302b
constexpr TagDetails casio2PortraitRefiner[] = {{0, N_("Off")}, {1, N_("+1")}, {2, N_("+2")}};
//! Special Effect Setting, tag 0x3031
constexpr TagDetails casio2SpecialEffectSetting[] = {
{0, N_("Off")}, {1, N_("Makeup")}, {2, N_("Mist Removal")}, {3, N_("Vivid Landscape")}, {16, N_("Art Shot")}};
//! Drive Mode, tag 0x3103
constexpr TagDetails casio2DriveMode[] = {{0, N_("Single Shot")}, {1, N_("Continuous Shooting")},
{2, N_("Continuous (2 fps)")}, {3, N_("Continuous (3 fps)")},
{4, N_("Continuous (4 fps)")}, {5, N_("Continuous (5 fps)")},
{6, N_("Continuous (6 fps)")}, {7, N_("Continuous (7 fps)")},
{10, N_("Continuous (10 fps)")}, {12, N_("Continuous (12 fps)")},
{15, N_("Continuous (15 fps)")}, {20, N_("Continuous (20 fps)")},
{30, N_("Continuous (30 fps)")}, {40, N_("Continuous (40 fps)")},
{60, N_("Continuous (60 fps)")}, {240, N_("Auto-N")}};
//! Video Quality, tag 0x4003
constexpr TagDetails casio2VideoQuality[] = {
{1, N_("Standard")}, {3, N_("HD (720p)")}, {4, N_("Full HD (1080p)")}, {5, N_("Low")}};
// Casio2 MakerNote Tag Info
constexpr TagInfo Casio2MakerNote::tagInfo_[] = {
{0x0002, "PreviewImageSize", N_("Preview Image Size"), N_("Preview Image Size"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x0003, "PreviewImageLength", N_("Preview Image Length"), N_("Preview Image Length"), casio2Id, makerTags,
unsignedLong, -1, printValue},
{0x0004, "PreviewImageStart", N_("Preview Image Start"), N_("Preview Image Start"), casio2Id, makerTags,
unsignedLong, -1, printValue},
{0x0008, "QualityMode", N_("Quality Mode"), N_("Quality Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2QualityMode)},
{0x0009, "ImageSize", N_("Image Size"), N_("Image Size"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ImageSize)},
{0x000d, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2FocusMode)},
{0x0014, "ISOSpeed", N_("ISO Speed"), N_("ISO Speed"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2IsoSpeed)},
{0x0019, "WhiteBalance", N_("White Balance"), N_("White Balance Setting"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2WhiteBalance)},
{0x001d, "FocalLength", N_("Focal Length"), N_("Focal Length"), casio2Id, makerTags, unsignedRational, -1,
printValue},
{0x001f, "Saturation", N_("Saturation"), N_("Saturation"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Saturation)},
{0x0020, "Contrast", N_("Contrast"), N_("Contrast"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Contrast)},
{0x0021, "Sharpness", N_("Sharpness"), N_("Sharpness"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Sharpness)},
{0x0e00, "PrintIM", N_("Print IM"), N_("PrintIM information"), casio2Id, makerTags, undefined, -1, printValue},
{0x2000, "PreviewImage", N_("Preview Image"), N_("Preview Image"), casio2Id, makerTags, undefined, -1, printValue},
{0x2001, "FirmwareDate", N_("Firmware Date"), N_("Firmware Date"), casio2Id, makerTags, asciiString, -1, print0x2001},
{0x2011, "WhiteBalanceBias", N_("White Balance Bias"), N_("White Balance Bias"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x2012, "WhiteBalance2", N_("White Balance"), N_("White Balance Setting"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2WhiteBalance2)},
{0x2021, "AFPointPosition", N_("AF Point Position"), N_("AF Point Position"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x2022, "ObjectDistance", N_("Object Distance"), N_("Object Distance"), casio2Id, makerTags, unsignedLong, -1, print0x2022},
{0x2034, "FlashDistance", N_("Flash Distance"), N_("Flash Distance"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x2076, "SpecialEffectMode", N_("Special Effect Mode"), N_("Special Effect Mode"), casio2Id, makerTags, unsignedByte, -1, printValue},
{0x2001, "FirmwareDate", N_("Firmware Date"), N_("Firmware Date"), casio2Id, makerTags, asciiString, -1,
print0x2001},
{0x2011, "WhiteBalanceBias", N_("White Balance Bias"), N_("White Balance Bias"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x2012, "WhiteBalance2", N_("White Balance"), N_("White Balance Setting"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2WhiteBalance2)},
{0x2021, "AFPointPosition", N_("AF Point Position"), N_("AF Point Position"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x2022, "ObjectDistance", N_("Object Distance"), N_("Object Distance"), casio2Id, makerTags, unsignedLong, -1,
print0x2022},
{0x2034, "FlashDistance", N_("Flash Distance"), N_("Flash Distance"), casio2Id, makerTags, unsignedShort, -1,
printValue},
{0x2076, "SpecialEffectMode", N_("Special Effect Mode"), N_("Special Effect Mode"), casio2Id, makerTags,
unsignedByte, -1, printValue},
{0x2089, "FaceInfo", N_("Face Info"), N_("Face Info"), casio2Id, makerTags, undefined, -1, printValue},
{0x211c, "FacesDetected", N_("Faces detected"), N_("Faces detected"), casio2Id, makerTags, unsignedByte, -1, printValue},
{0x211c, "FacesDetected", N_("Faces detected"), N_("Faces detected"), casio2Id, makerTags, unsignedByte, -1,
printValue},
{0x3000, "RecordMode", N_("Record Mode"), N_("Record Mode"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3001, "ReleaseMode", N_("Release Mode"), N_("Release Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2ReleaseMode)},
{0x3002, "Quality", N_("Quality"), N_("Quality"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2Quality)},
{0x3003, "FocusMode2", N_("Focus Mode2"), N_("Focus Mode2"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2FocusMode2)},
{0x3006, "HometownCity", N_("Home town city"), N_("Home town city"), casio2Id, makerTags, asciiString, -1, printValue},
{0x3007, "BestShotMode", N_("Best Shot Mode"), N_("Best Shot Mode"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3008, "AutoISO", N_("Auto ISO"), N_("Auto ISO"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2AutoISO)},
{0x3009, "AFMode", N_("AF Mode"), N_("AF Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2AFMode)},
{0x3001, "ReleaseMode", N_("Release Mode"), N_("Release Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ReleaseMode)},
{0x3002, "Quality", N_("Quality"), N_("Quality"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Quality)},
{0x3003, "FocusMode2", N_("Focus Mode2"), N_("Focus Mode2"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2FocusMode2)},
{0x3006, "HometownCity", N_("Home town city"), N_("Home town city"), casio2Id, makerTags, asciiString, -1,
printValue},
{0x3007, "BestShotMode", N_("Best Shot Mode"), N_("Best Shot Mode"), casio2Id, makerTags, unsignedShort, -1,
printValue},
{0x3008, "AutoISO", N_("Auto ISO"), N_("Auto ISO"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2AutoISO)},
{0x3009, "AFMode", N_("AF Mode"), N_("AF Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2AFMode)},
{0x3011, "Sharpness2", N_("Sharpness"), N_("Sharpness"), casio2Id, makerTags, undefined, -1, printValue},
{0x3012, "Contrast2", N_("Contrast"), N_("Contrast"), casio2Id, makerTags, undefined, -1, printValue},
{0x3013, "Saturation2", N_("Saturation"), N_("Saturation"), casio2Id, makerTags, undefined, -1, printValue},
{0x3014, "ISO", N_("ISO"), N_("ISO"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3015, "ColorMode", N_("Color Mode"), N_("Color Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2ColorMode)},
{0x3016, "Enhancement", N_("Enhancement"), N_("Enhancement"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2Enhancement)},
{0x3017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2ColorFilter)},
{0x301b, "ArtMode", N_("Art Mode"), N_("Art Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2ArtMode)},
{0x301c, "SequenceNumber", N_("Sequence Number"), N_("Sequence Number"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3020, "ImageStabilization", N_("Image Stabilization"), N_("Image Stabilization"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x302a, "LightingMode", N_("Lighting Mode"), N_("Lighting Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2LightingMode)},
{0x302b, "PortraitRefiner", N_("Portrait Refiner"), N_("Portrait Refiner settings"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2PortraitRefiner)},
{0x3030, "SpecialEffectLevel", N_("Special Effect Level"), N_("Special Effect Level"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3031, "SpecialEffectSetting", N_("Special Effect Setting"), N_("Special Effect Setting"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2SpecialEffectSetting)},
{0x3103, "DriveMode", N_("Drive Mode"), N_("Drive Mode"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2DriveMode)},
{0x310b, "ArtModeParameters", N_("Art Mode Parameters"), N_("Art Mode Parameters"), casio2Id, makerTags, undefined, -1, printValue},
{0x4001, "CaptureFrameRate", N_("Capture Frame Rate"), N_("Capture Frame Rate"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x4003, "VideoQuality", N_("Video Quality"), N_("Video Quality"), casio2Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2VideoQuality)},
{0xffff, "(UnknownCasio2MakerNoteTag)", "(UnknownCasio2MakerNoteTag)", N_("Unknown Casio2MakerNote tag"), casio2Id, makerTags, asciiString, -1, printValue},
};
const TagInfo* Casio2MakerNote::tagList()
{
{0x3015, "ColorMode", N_("Color Mode"), N_("Color Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ColorMode)},
{0x3016, "Enhancement", N_("Enhancement"), N_("Enhancement"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Enhancement)},
{0x3017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ColorFilter)},
{0x301b, "ArtMode", N_("Art Mode"), N_("Art Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ArtMode)},
{0x301c, "SequenceNumber", N_("Sequence Number"), N_("Sequence Number"), casio2Id, makerTags, unsignedShort, -1,
printValue},
{0x3020, "ImageStabilization", N_("Image Stabilization"), N_("Image Stabilization"), casio2Id, makerTags,
unsignedShort, -1, printValue},
{0x302a, "LightingMode", N_("Lighting Mode"), N_("Lighting Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2LightingMode)},
{0x302b, "PortraitRefiner", N_("Portrait Refiner"), N_("Portrait Refiner settings"), casio2Id, makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2PortraitRefiner)},
{0x3030, "SpecialEffectLevel", N_("Special Effect Level"), N_("Special Effect Level"), casio2Id, makerTags,
unsignedShort, -1, printValue},
{0x3031, "SpecialEffectSetting", N_("Special Effect Setting"), N_("Special Effect Setting"), casio2Id, makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2SpecialEffectSetting)},
{0x3103, "DriveMode", N_("Drive Mode"), N_("Drive Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2DriveMode)},
{0x310b, "ArtModeParameters", N_("Art Mode Parameters"), N_("Art Mode Parameters"), casio2Id, makerTags, undefined,
-1, printValue},
{0x4001, "CaptureFrameRate", N_("Capture Frame Rate"), N_("Capture Frame Rate"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x4003, "VideoQuality", N_("Video Quality"), N_("Video Quality"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2VideoQuality)},
{0xffff, "(UnknownCasio2MakerNoteTag)", "(UnknownCasio2MakerNoteTag)", N_("Unknown Casio2MakerNote tag"), casio2Id,
makerTags, asciiString, -1, printValue},
};
const TagInfo* Casio2MakerNote::tagList() {
return tagInfo_;
}
}
std::ostream& Casio2MakerNote::print0x2001(std::ostream& os, const Value& value, const ExifData*)
{
std::ostream& Casio2MakerNote::print0x2001(std::ostream& os, const Value& value, const ExifData*) {
// format is: "YYMM#00#00DDHH#00#00MM#00#00#00#00"
std::vector<char> numbers;
for(size_t i=0; i<value.size(); i++)
{
for (size_t i = 0; i < value.size(); i++) {
const auto l = static_cast<char>(value.toInt64(i));
if(l!=0)
{
if (l != 0) {
numbers.push_back(l);
}
}
if(numbers.size()>=10)
{
//year
long l=(numbers[0]-48)*10+(numbers[1]-48);
if(l<70)
{
l+=2000;
}
else
{
l+=1900;
if (numbers.size() >= 10) {
// year
long l = (numbers[0] - 48) * 10 + (numbers[1] - 48);
if (l < 70) {
l += 2000;
} else {
l += 1900;
};
os << l << ":";
// month, day, hour, minutes
os << numbers[2] << numbers[3] << ":" << numbers[4] << numbers[5] << " " << numbers[6] << numbers[7] << ":" << numbers[8] << numbers[9];
}
else
{
os << numbers[2] << numbers[3] << ":" << numbers[4] << numbers[5] << " " << numbers[6] << numbers[7] << ":"
<< numbers[8] << numbers[9];
} else {
os << value;
};
return os;
}
}
std::ostream& Casio2MakerNote::print0x2022(std::ostream& os, const Value& value, const ExifData*)
{
std::ios::fmtflags f( os.flags() );
if(value.toInt64()>=0x20000000)
{
std::ostream& Casio2MakerNote::print0x2022(std::ostream& os, const Value& value, const ExifData*) {
std::ios::fmtflags f(os.flags());
if (value.toInt64() >= 0x20000000) {
os << N_("Inf");
os.flags(f);
return os;
@ -570,6 +412,6 @@ namespace Exiv2::Internal {
os.copyfmt(oss);
os.flags(f);
return os;
}
}
} // namespace Exiv2::Internal

@ -3,9 +3,10 @@
/*!
@file casiomn_int.hpp
@brief Casio MakerNote implemented using the following references:
<a href="http://gvsoft.homedns.org/exif/makernote-casio-type1.html">Casio MakerNote Information</a> by GVsoft,
Casio.pm of <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> by Phil Harvey,
<a href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/casio_mn.html#Casio_Type_1_Tags">Casio Makernote Format Specification</a> by Evan Hunter.
<a href="http://gvsoft.homedns.org/exif/makernote-casio-type1.html">Casio MakerNote Information</a> by
GVsoft, Casio.pm of <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> by Phil Harvey, <a
href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/casio_mn.html#Casio_Type_1_Tags">Casio Makernote Format
Specification</a> by Evan Hunter.
@date 30-Oct-13, ahu: created
*/
#ifndef CASIOMN_INT_HPP_
@ -19,12 +20,11 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2::Internal {
// *****************************************************************************
// class definitions
// *****************************************************************************
// class definitions
//! MakerNote for Casio cameras
class CasioMakerNote {
//! MakerNote for Casio cameras
class CasioMakerNote {
public:
//! Return read-only list of built-in Casio tags
static const TagInfo* tagList();
@ -37,10 +37,10 @@ namespace Exiv2::Internal {
//! Makernote tag list
static const TagInfo tagInfo_[];
}; // class CasioMakerNote
}; // class CasioMakerNote
//! MakerNote for Casio2 cameras
class Casio2MakerNote {
//! MakerNote for Casio2 cameras
class Casio2MakerNote {
public:
//! Return read-only list of built-in Casio2 tags
static const TagInfo* tagList();
@ -53,7 +53,7 @@ namespace Exiv2::Internal {
//! Makernote tag list
static const TagInfo tagInfo_[];
}; // class Casio2MakerNote
}; // class Casio2MakerNote
} // namespace Exiv2::Internal

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save