build mac-arm

This commit is contained in:
2023-06-02 15:46:21 +08:00
parent 22b65ccfea
commit c3e0a79359
55 changed files with 11414 additions and 0 deletions
BIN
View File
Binary file not shown.
+180
View File
@@ -0,0 +1,180 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Spec : Advanced Systems Format (ASF) Specification : Revision 01.20.05 :
// https://exse.eyewated.com/fls/54b3ed95bbfb1a92.pdf
#pragma once
// *****************************************************************************
#include <array>
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access ASF video files.
*/
class EXIV2API AsfVideo : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a ASF video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit AsfVideo(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
/* @class GUID_struct
*
* @brief A class to represent a globally unique identifier (GUID) structure
*
* This class represents a globally unique identifier (GUID) structure which is used to identify objects in a
* distributed environment. A GUID is a unique identifier that is generated on a computer and can be used to
* identify an object across different systems. The GUID structure is comprised of four 32-bit values and an
* array of 8 bytes.
*
* @note The byte order of the GUID structure is in little endian.
*
* @see https://en.wikipedia.org/wiki/Globally_unique_identifier
*
*/
class GUIDTag {
uint32_t data1_;
uint16_t data2_;
uint16_t data3_;
std::array<byte, 8> data4_;
public:
bool operator==(const GUIDTag& other) const;
// Constructor to create a GUID object by passing individual values for each attribute
GUIDTag(unsigned int data1, unsigned short data2, unsigned short data3, std::array<byte, 8> data4);
// Constructor to create a GUID object from a byte array
explicit GUIDTag(const uint8_t* bytes);
std::string to_string();
bool operator<(const GUIDTag& other) const;
};
private:
static constexpr size_t CODEC_TYPE_VIDEO = 1;
static constexpr size_t CODEC_TYPE_AUDIO = 2;
class HeaderReader {
DataBuf IdBuf_;
uint64_t size_{};
uint64_t remaining_size_{};
public:
explicit HeaderReader(const BasicIo::UniquePtr& io);
[[nodiscard]] uint64_t getSize() const {
return size_;
}
[[nodiscard]] uint64_t getRemainingSize() const {
return remaining_size_;
}
[[nodiscard]] DataBuf& getId() {
return IdBuf_;
}
};
protected:
/*!
@brief Check for a valid tag and decode the block at the current IO
position. Calls tagDecoder() or skips to next tag, if required.
*/
void decodeBlock();
void decodeHeader();
/*!
@brief Interpret File_Properties tag information, and save it in
the respective XMP container.
*/
void fileProperties();
/*!
@brief Interpret Stream_Properties tag information, and save it
in the respective XMP container.
*/
void streamProperties();
/*!
@brief Interpret Codec_List tag information, and save it in
the respective XMP container.
*/
void codecList();
/*!
@brief Interpret Content_Description tag information, and save it
in the respective XMP container.
*/
void contentDescription();
/*!
@brief Interpret Extended_Stream_Properties tag information, and
save it in the respective XMP container.
*/
void extendedStreamProperties();
/*!
@brief Interpret Header_Extension tag information, and save it in
the respective XMP container.
*/
void headerExtension() const;
/*!
@brief Interpret Metadata, Extended_Content_Description,
Metadata_Library tag information, and save it in the respective
XMP container.
*/
void extendedContentDescription();
void DegradableJPEGMedia();
private:
//! Variable to store height and width of a video frame.
uint64_t height_{};
uint64_t width_{};
}; // Class AsfVideo
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new AsfVideo 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 newAsfInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Windows Asf Video.
EXIV2API bool isAsfType(BasicIo& iIo, bool advance);
} // namespace Exiv2
+993
View File
@@ -0,0 +1,993 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef BASICIO_HPP_
#define BASICIO_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "error.hpp"
#include "types.hpp"
// + standard includes
#include <memory>
// The way to handle data from stdin or data uri path. If EXV_XPATH_MEMIO = 1,
// it uses MemIo. Otherwises, it uses FileIo.
#ifndef EXV_XPATH_MEMIO
#define EXV_XPATH_MEMIO 0
#endif
// *****************************************************************************
// 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 {
public:
//! BasicIo auto_ptr type
using UniquePtr = std::unique_ptr<BasicIo>;
//! Seek starting positions
enum Position { beg, cur, end };
//! @name Creators
//@{
//! Destructor
virtual ~BasicIo() = default;
//@}
//! @name Manipulators
//@{
/*!
@brief Open the IO source using the default access mode. The
default mode should allow for reading and writing.
This method can also be used to "reopen" an IO source which will
flush any unwritten data and reset the IO position to the start.
Subclasses may provide custom methods to allow for
opening IO sources differently.
@return 0 if successful;<BR>
Nonzero if failure.
*/
virtual int open() = 0;
/*!
@brief Close the IO source. After closing a BasicIo instance can not
be read or written. Closing flushes any unwritten data. It is
safe to call close on a closed instance.
@return 0 if successful;<BR>
Nonzero if failure.
*/
virtual int close() = 0;
/*!
@brief Write data to the IO source. Current IO position is advanced
by the number of bytes written.
@param data Pointer to data. Data must be at least \em wcount
bytes long
@param wcount Number of bytes to be written.
@return Number of bytes written to IO source successfully;<BR>
0 if failure;
*/
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
of bytes written.
@param src Reference to another BasicIo instance. Reading start
at the source's current IO position
@return Number of bytes written to IO source successfully;<BR>
0 if failure;
*/
virtual size_t write(BasicIo& src) = 0;
/*!
@brief Write one byte to the IO source. Current IO position is
advanced by one byte.
@param data The single byte to be written.
@return The value of the byte written if successful;<BR>
EOF if failure;
*/
virtual int putb(byte data) = 0;
/*!
@brief Read data from the IO source. Reading starts at the current
IO position and the position is advanced by the number of bytes
read.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return DataBuf instance containing the bytes read. Use the
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
virtual DataBuf read(size_t rcount) = 0;
/*!
@brief Read data from the IO source. Reading starts at the current
IO position and the position is advanced by the number of bytes
read.
@param buf Pointer to a block of memory into which the read data
is stored. The memory block must be at least \em rcount bytes
long.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return Number of bytes read from IO source successfully;<BR>
0 if failure;
*/
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.
@param buf Pointer to a block of memory into which the read data
is stored. The memory block must be at least \em rcount bytes
long.
@param rcount Maximum number of bytes to read. Fewer bytes may be
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 = ErrorCode::kerCorruptedMetadata);
/*!
@brief Read one byte from the IO source. Current IO position is
advanced by one byte.
@return The byte read from the IO source if successful;<BR>
EOF if failure;
*/
virtual int getb() = 0;
/*!
@brief Remove all data from this object's IO source and then transfer
data from the \em src BasicIo object into this object.
The source object is invalidated by this operation and should not be
used after this method returns. This method exists primarily to
be used with the BasicIo::temporary() method.
@param src Reference to another BasicIo instance. The entire contents
of src are transferred to this object. The \em src object is
invalidated by the method.
@throw Error In case of failure
*/
virtual void transfer(BasicIo& src) = 0;
/*!
@brief Move the current IO position.
@param offset Number of bytes to move the position relative
to the starting position specified by \em pos
@param pos Position from which the seek should start
@return 0 if successful;<BR>
Nonzero if failure;
*/
virtual int seek(int64_t offset, Position pos) = 0;
/*!
@brief Safe version of `seek()` that checks for errors and throws
an exception if the seek was unsuccessful.
@param offset Number of bytes to move the position relative
to the starting position specified by \em pos
@param pos Position from which the seek should start
@param err Error code to use if an exception is thrown.
*/
void seekOrThrow(int64_t offset, Position pos, ErrorCode err);
/*!
@brief Direct access to the IO data. For files, this is done by
mapping the file into the process's address space; for memory
blocks, this allows direct access to the memory block.
@param isWriteable Set to true if the mapped area should be writeable
(default is false).
@return A pointer to the mapped area.
@throw Error In case of failure.
*/
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;
//@}
//! @name Accessors
//@{
/*!
@brief Get the current IO position.
@return Offset from the start of IO
*/
[[nodiscard]] virtual size_t tell() const = 0;
/*!
@brief Get the current size of the IO source in bytes.
@return Size of the IO source in bytes;<BR>
-1 if failure;
*/
[[nodiscard]] virtual size_t size() const = 0;
//! Returns true if the IO source is open, otherwise false.
[[nodiscard]] virtual bool isopen() const = 0;
//! Returns 0 if the IO source is in a valid state, otherwise nonzero.
[[nodiscard]] virtual int error() const = 0;
//! Returns true if the IO position has reached the end, otherwise false.
[[nodiscard]] 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.
*/
[[nodiscard]] virtual const std::string& path() const noexcept = 0;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
for parts of the file that contain image-date (non-metadata/pixel data)
@note This method should be only called after the concerned data (metadata)
are all downloaded from the remote file to memory.
*/
virtual void populateFakeData() = 0;
/*!
@brief this is allocated and populated by mmap()
*/
byte* bigBlock_{};
//@}
}; // 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 {
public:
//! @name Creators
//@{
//! Constructor, takes a BasicIo reference
explicit IoCloser(BasicIo& bio) : bio_(bio) {
}
//! Destructor, closes the BasicIo reference
virtual ~IoCloser() {
close();
}
//@}
//! @name Manipulators
//@{
//! Close the BasicIo if it is open
void close() {
if (bio_.isopen())
bio_.close();
}
//@}
// DATA
//! The BasicIo reference
BasicIo& bio_;
// Not implemented
//! Copy constructor
IoCloser(const IoCloser&) = delete;
//! Assignment operator
IoCloser& operator=(const IoCloser&) = delete;
}; // class IoCloser
/*!
@brief Provides binary file IO by implementing the BasicIo
interface.
*/
class EXIV2API FileIo : public BasicIo {
public:
//! @name Creators
//@{
/*!
@brief Constructor that accepts the file path on which IO will be
performed. The constructor does not open the file, and
therefore never fails.
@param path The full path of a file
*/
explicit FileIo(const std::string& path);
//! Destructor. Flushes and closes an open file.
~FileIo() override;
//@}
//! @name Manipulators
//@{
/*!
@brief Open the file using the specified mode.
This method can also be used to "reopen" a file which will flush any
unwritten data and reset the IO position to the start. Although
files can be opened in binary or text mode, this class has
only been tested carefully in binary mode.
@param mode Specified that type of access allowed on the file.
Valid values match those of the C fopen command exactly.
@return 0 if successful;<BR>
Nonzero if failure.
*/
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
any unwritten data and reset the IO position to the start.
@return 0 if successful;<BR>
Nonzero if failure.
*/
int open() override;
/*!
@brief Flush and unwritten data and close the file . It is
safe to call close on an already closed instance.
@return 0 if successful;<BR>
Nonzero if failure;
*/
int close() override;
/*!
@brief Write data to the file. The file position is advanced
by the number of bytes written.
@param data Pointer to data. Data must be at least \em wcount
bytes long
@param wcount Number of bytes to be written.
@return Number of bytes written to the file successfully;<BR>
0 if failure;
*/
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
of bytes written.
@param src Reference to another BasicIo instance. Reading start
at the source's current IO position
@return Number of bytes written to the file successfully;<BR>
0 if failure;
*/
size_t write(BasicIo& src) override;
/*!
@brief Write one byte to the file. The file position is
advanced by one byte.
@param data The single byte to be written.
@return The value of the byte written if successful;<BR>
EOF if failure;
*/
int putb(byte data) override;
/*!
@brief Read data from the file. Reading starts at the current
file position and the position is advanced by the number of
bytes read.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return DataBuf instance containing the bytes read. Use the
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
DataBuf read(size_t rcount) override;
/*!
@brief Read data from the file. Reading starts at the current
file position and the position is advanced by the number of
bytes read.
@param buf Pointer to a block of memory into which the read data
is stored. The memory block must be at least \em rcount bytes
long.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return Number of bytes read from the file successfully;<BR>
0 if failure;
*/
size_t read(byte* buf, size_t rcount) override;
/*!
@brief Read one byte from the file. The file position is
advanced by one byte.
@return The byte read from the file if successful;<BR>
EOF if failure;
*/
int getb() override;
/*!
@brief Remove the contents of the file and then transfer data from
the \em src BasicIo object into the empty file.
This method is optimized to simply rename the source file if the
source object is another FileIo instance. The source BasicIo object
is invalidated by this operation and should not be used after this
method returns. This method exists primarily to be used with
the BasicIo::temporary() method.
@note If the caller doesn't have permissions to write to the file,
an exception is raised and \em src is deleted.
@param src Reference to another BasicIo instance. The entire contents
of src are transferred to this object. The \em src object is
invalidated by the method.
@throw Error In case of failure
*/
void transfer(BasicIo& src) override;
int seek(int64_t offset, Position pos) override;
/*!
@brief Map the file into the process's address space. The file must be
open before mmap() is called. If the mapped area is writeable,
changes may not be written back to the underlying file until
munmap() is called. The pointer is valid only as long as the
FileIo object exists.
@param isWriteable Set to true if the mapped area should be writeable
(default is false).
@return A pointer to the mapped area.
@throw Error In case of failure.
*/
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
underlying file.
@return 0 if successful;<BR>
Nonzero if failure;
*/
int munmap() override;
/*!
@brief close the file source and set a new path.
*/
virtual void setPath(const std::string& path);
//@}
//! @name Accessors
//@{
/*!
@brief Get the current file position.
@return Offset from the start of the file
*/
[[nodiscard]] size_t tell() const override;
/*!
@brief Flush any buffered writes and get the current file size
in bytes.
@return Size of the file in bytes;<BR>
-1 if failure;
*/
[[nodiscard]] size_t size() const override;
//! Returns true if the file is open, otherwise false.
[[nodiscard]] bool isopen() const override;
//! Returns 0 if the file is in a valid state, otherwise nonzero.
[[nodiscard]] int error() const override;
//! Returns true if the file position has reached the end, otherwise false.
[[nodiscard]] bool eof() const override;
//! Returns the path of the file
[[nodiscard]] const std::string& path() const noexcept override;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
for parts of the file that contain image-date (non-metadata/pixel data)
@note This method should be only called after the concerned data (metadata)
are all downloaded from the remote file to memory.
*/
void populateFakeData() override;
//@}
// NOT IMPLEMENTED
//! Copy constructor
FileIo(const FileIo&) = delete;
//! Assignment operator
FileIo& operator=(const FileIo&) = delete;
private:
// Pimpl idiom
class Impl;
std::unique_ptr<Impl> p_;
}; // 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
the MemIo. The original data is only used for reading. If writes are
performed, the changed data can be retrieved using the read methods
(since the data used in construction is never modified).
@note If read only usage of this class is common, it might be worth
creating a specialized readonly class or changing this one to
have a readonly mode.
*/
class EXIV2API MemIo : public BasicIo {
public:
//! @name Creators
//@{
//! Default constructor that results in an empty object
MemIo();
/*!
@brief Constructor that accepts a block of memory. A copy-on-write
algorithm allows read operations directly from the original data
and will create a copy of the buffer on the first write operation.
@param data Pointer to data. Data must be at least \em size bytes long
@param size Number of bytes to copy.
*/
MemIo(const byte* data, size_t size);
//! Destructor. Releases all managed memory
~MemIo() override;
//@}
//! @name Manipulators
//@{
/*!
@brief Memory IO is always open for reading and writing. This method
therefore only resets the IO position to the start.
@return 0
*/
int open() override;
/*!
@brief Does nothing on MemIo objects.
@return 0
*/
int close() override;
/*!
@brief Write data to the memory block. If needed, the size of the
internal memory block is expanded. The IO position is advanced
by the number of bytes written.
@param data Pointer to data. Data must be at least \em wcount
bytes long
@param wcount Number of bytes to be written.
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
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
block is expanded. The IO position is advanced by the number
of bytes written.
@param src Reference to another BasicIo instance. Reading start
at the source's current IO position
@return Number of bytes written to the memory block successfully;<BR>
0 if failure;
*/
size_t write(BasicIo& src) override;
/*!
@brief Write one byte to the memory block. The IO position is
advanced by one byte.
@param data The single byte to be written.
@return The value of the byte written if successful;<BR>
EOF if failure;
*/
int putb(byte data) override;
/*!
@brief Read data from the memory block. Reading starts at the current
IO position and the position is advanced by the number of
bytes read.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return DataBuf instance containing the bytes read. Use the
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
DataBuf read(size_t rcount) override;
/*!
@brief Read data from the memory block. Reading starts at the current
IO position and the position is advanced by the number of
bytes read.
@param buf Pointer to a block of memory into which the read data
is stored. The memory block must be at least \em rcount bytes
long.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return Number of bytes read from the memory block successfully;<BR>
0 if failure;
*/
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.
@return The byte read from the memory block if successful;<BR>
EOF if failure;
*/
int getb() override;
/*!
@brief Clear the memory block and then transfer data from
the \em src BasicIo object into a new block of memory.
This method is optimized to simply swap memory block if the source
object is another MemIo instance. The source BasicIo instance
is invalidated by this operation and should not be used after this
method returns. This method exists primarily to be used with
the BasicIo::temporary() method.
@param src Reference to another BasicIo instance. The entire contents
of src are transferred to this object. The \em src object is
invalidated by the method.
@throw Error In case of failure
*/
void transfer(BasicIo& src) override;
int seek(int64_t offset, Position pos) override;
/*!
@brief Allow direct access to the underlying data buffer. The buffer
is not protected against write access in any way, the argument
is ignored.
@note The application must ensure that the memory pointed to by the
returned pointer remains valid and allocated as long as the
MemIo object exists.
*/
byte* mmap(bool /*isWriteable*/ = false) override;
int munmap() override;
//@}
//! @name Accessors
//@{
/*!
@brief Get the current IO position.
@return Offset from the start of the memory block
*/
[[nodiscard]] size_t tell() const override;
/*!
@brief Get the current memory buffer size in bytes.
@return Size of the in memory data in bytes;<BR>
-1 if failure;
*/
[[nodiscard]] size_t size() const override;
//! Always returns true
[[nodiscard]] bool isopen() const override;
//! Always returns 0
[[nodiscard]] int error() const override;
//! Returns true if the IO position has reached the end, otherwise false.
[[nodiscard]] bool eof() const override;
//! Returns a dummy path, indicating that memory access is used
[[nodiscard]] const std::string& path() const noexcept override;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
for parts of the file that contain image-date (non-metadata/pixel data)
@note This method should be only called after the concerned data (metadata)
are all downloaded from the remote file to memory.
*/
void populateFakeData() override;
//@}
// NOT IMPLEMENTED
//! Copy constructor
MemIo(const MemIo&) = delete;
//! Assignment operator
MemIo& operator=(const MemIo&) = delete;
private:
// Pimpl idiom
class Impl;
std::unique_ptr<Impl> p_;
}; // class MemIo
/*!
@brief Provides binary IO for the data from stdin and data uri path.
*/
#if EXV_XPATH_MEMIO
class EXIV2API XPathIo : public MemIo {
public:
//! @name Creators
//@{
//! Default constructor
XPathIo(const std::string& path);
//@}
private:
/*!
@brief Read data from stdin and write the data to memory.
@throw Error if it can't convert stdin to binary.
*/
void ReadStdin();
/*!
@brief Read the data from data uri path and write the data to memory.
@param path The data uri.
@throw Error if no base64 data in path.
*/
void ReadDataUri(const std::string& path);
}; // class XPathIo
#else
class EXIV2API XPathIo : public FileIo {
public:
/*!
@brief The extension of the temporary file which is created when getting input data
to read metadata. This file will be deleted in destructor.
*/
static constexpr auto TEMP_FILE_EXT = ".exiv2_temp";
/*!
@brief The extension of the generated file which is created when getting input data
to add or modify the metadata.
*/
static constexpr auto GEN_FILE_EXT = ".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);
//! Destructor. Releases all managed memory and removes the temp file.
~XPathIo() override;
//@}
XPathIo(const XPathIo&) = delete;
XPathIo& operator=(const XPathIo&) = delete;
//! @name Manipulators
//@{
/*!
@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;
//@}
//! @name Static methods
//@{
/*!
@brief Read the data from stdin/data uri path and write them to the file.
@param orgPath It equals "-" if the input data's from stdin. Otherwise, it's data uri path.
@return the name of the new file.
@throw Error if it fails.
*/
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_{true};
std::string tempFilePath_;
}; // 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 {
public:
//! Destructor. Releases all managed memory.
RemoteIo();
~RemoteIo() override;
//@}
RemoteIo(const RemoteIo&) = delete;
RemoteIo& operator=(const RemoteIo&) = delete;
//! @name Manipulators
//@{
/*!
@brief Connect to the remote server, get the size of the remote file and
allocate the array of blocksMap.
If the blocksMap is already allocated (this method has been called before),
it just reset IO position to the start and does not flush the old data.
@return 0 if successful;<BR>
Nonzero if failure.
*/
int open() override;
/*!
@brief Reset the IO position to the start. It does not release the data.
@return 0 if successful;<BR>
Nonzero if failure.
*/
int close() override;
/*!
@brief Not support this method.
@return 0 means failure
*/
size_t write(const byte* data, size_t wcount) override;
/*!
@brief Write data that is read from another BasicIo instance to the remote file.
The write access is done in an efficient way. It only sends the range of different
bytes between the current data and BasicIo instance to the remote machine.
@param src Reference to another BasicIo instance. Reading start
at the source's current IO position
@return The size of BasicIo instance;<BR>
0 if failure;
@throw Error In case of failure
@note The write access is only supported by http, https, ssh.
*/
size_t write(BasicIo& src) override;
/*!
@brief Not support
@return 0 means failure
*/
int putb(byte data) override;
/*!
@brief Read data from the memory blocks. Reading starts at the current
IO position and the position is advanced by the number of
bytes read.
If the memory blocks are not populated (False), it will connect to server
and populate the data to memory blocks.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return DataBuf instance containing the bytes read. Use the
DataBuf::size_ member to find the number of bytes read.
DataBuf::size_ will be 0 on failure.
*/
DataBuf read(size_t rcount) override;
/*!
@brief Read data from the memory blocks. Reading starts at the current
IO position and the position is advanced by the number of
bytes read.
If the memory blocks are not populated (!= bMemory), it will connect to server
and populate the data to memory blocks.
@param buf Pointer to a block of memory into which the read data
is stored. The memory block must be at least \em rcount bytes
long.
@param rcount Maximum number of bytes to read. Fewer bytes may be
read if \em rcount bytes are not available.
@return Number of bytes read from the memory block successfully;<BR>
0 if failure;
*/
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.
If the memory block is not populated (!= bMemory), it will connect to server
and populate the data to the memory block.
@return The byte read from the memory block if successful;<BR>
EOF if failure;
*/
int getb() override;
/*!
@brief Remove the contents of the file and then transfer data from
the \em src BasicIo object into the empty file.
The write access is done in an efficient way. It only sends the range of different
bytes between the current data and BasicIo instance to the remote machine.
@param src Reference to another BasicIo instance. The entire contents
of src are transferred to this object. The \em src object is
invalidated by the method.
@throw Error In case of failure
@note The write access is only supported by http, https, ssh.
*/
void transfer(BasicIo& src) override;
int seek(int64_t offset, Position pos) override;
/*!
@brief Not support
@return NULL
*/
byte* mmap(bool /*isWriteable*/ = false) override;
/*!
@brief Not support
@return 0
*/
int munmap() override;
//@}
//! @name Accessors
//@{
/*!
@brief Get the current IO position.
@return Offset from the start of the memory block
*/
[[nodiscard]] size_t tell() const override;
/*!
@brief Get the current memory buffer size in bytes.
@return Size of the in memory data in bytes;<BR>
-1 if failure;
*/
[[nodiscard]] size_t size() const override;
//! Returns true if the memory area is allocated.
[[nodiscard]] bool isopen() const override;
//! Always returns 0
[[nodiscard]] int error() const override;
//! Returns true if the IO position has reached the end, otherwise false.
[[nodiscard]] bool eof() const override;
//! Returns the URL of the file.
[[nodiscard]] const std::string& path() const noexcept override;
/*!
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
for parts of the file that contain image-date (non-metadata/pixel data)
@note This method should be only called after the concerned data (metadata)
are all downloaded from the remote file to memory.
*/
void populateFakeData() override;
//@}
protected:
// Pimpl idiom
class Impl;
//! Pointer to implementation
std::unique_ptr<Impl> p_;
}; // class RemoteIo
/*!
@brief Provides the http read/write access for the RemoteIo.
*/
class EXIV2API HttpIo : public RemoteIo {
public:
//! @name Creators
//@{
/*!
@brief Constructor that accepts the http URL on which IO will be
performed. The constructor does not open the file, and
therefore never fails.
@param url The full path of url
@param blockSize the size of the memory block. The file content is
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);
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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that accepts the URL on which IO will be
performed.
@param url The full path of url
@param blockSize the size of the memory block. The file content is
divided into the memory blocks. These blocks are populated
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);
/*!
@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;
/*!
@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;
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);
/*!
@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);
#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);
#endif
} // namespace Exiv2
#endif // #ifndef BASICIO_HPP_
+176
View File
@@ -0,0 +1,176 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
#include <set>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
EXIV2API bool enableBMFF(bool enable = true);
} // namespace Exiv2
#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) {
}
virtual ~Iloc() = default;
Iloc(const Iloc&) = default;
Iloc& operator=(const Iloc&) = default;
uint32_t ID_;
uint32_t start_;
uint32_t length_;
[[nodiscard]] std::string toString() const;
}; // class Iloc
// *****************************************************************************
// class definitions
/*!
@brief Class to access BMFF images.
*/
class EXIV2API BmffImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a BMFF image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
BmffImage(BasicIo::UniquePtr io, bool create);
//@}
//@{
void parseTiff(uint32_t root_tag, uint64_t length);
/*!
@brief parse embedded tiff file (Exif metadata)
@param root_tag root of parse tree Tag::root, Tag::cmt2 etc.
@param length tiff block length
@param start offset in file (default, io_->tell())
@
*/
void parseTiff(uint32_t root_tag, uint64_t length, uint64_t start);
//@}
//@{
/*!
@brief parse embedded xmp/xml
@param length xmp block length
@param start offset in file
@
*/
void parseXmp(uint64_t length, uint64_t start);
//@}
//@{
/*!
@brief Parse a Canon PRVW or THMB box and add an entry to the set
of native previews.
@param data Buffer containing the box
@param out Logging stream
@param bTrace Controls logging
@param width_offset Index of image width field in data
@param height_offset Index of image height field in data
@param size_offset Index of image size field in data
@param relative_position Location of the start of image data in the file,
relative to the current file position indicator.
*/
void parseCr3Preview(const 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
//@{
void readMetadata() override;
void writeMetadata() override;
void setExifData(const ExifData&) override;
void setIptcData(const IptcData&) override;
void setXmpData(const XmpData&) override;
void setComment(const std::string& comment) override;
void printStructure(std::ostream& out, Exiv2::PrintStructureOption option, size_t depth) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
static constexpr Exiv2::ByteOrder endian_{Exiv2::bigEndian};
private:
void openOrThrow() const;
/*!
@brief recursiveBoxHandler
@throw Error if we visit a box more than once
@param pbox_end The end location of the parent box. Boxes are
nested, so we must not read beyond this.
@return address of next box
@warning This function should only be called by readMetadata()
*/
uint64_t boxHandler(std::ostream& out, Exiv2::PrintStructureOption option, uint64_t pbox_end, size_t depth);
uint32_t fileType_{0};
std::set<size_t> visits_;
uint64_t visits_max_{0};
uint16_t unknownID_{0xffff};
uint16_t exifID_{0xffff};
uint16_t xmpID_{0};
std::map<uint32_t, Iloc> ilocs_;
bool bReadMetadata_{false};
//@}
/*!
@brief box utilities
*/
static std::string toAscii(uint32_t n);
std::string boxName(uint32_t box);
static bool superBox(uint32_t box);
static bool fullBox(uint32_t box);
static std::string uuidName(const Exiv2::DataBuf& uuid);
/*!
@brief Wrapper around brotli to uncompress JXL brob content.
*/
#ifdef EXV_HAVE_BROTLI
static void brotliUncompress(const byte* compressedBuf, size_t compressedBufSize, DataBuf& arr);
#endif
}; // class BmffImage
// *****************************************************************************
// template, inline and free functions
// 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);
//! Check if the file iIo is a BMFF image.
EXIV2API bool isBmffType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // EXV_ENABLE_BMFF
+86
View File
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@author Marco Piovanelli, Ovolab (marco)
<a href="mailto:marco.piovanelli@pobox.com">marco.piovanelli@pobox.com</a>
@date 05-Mar-2007, marco: created
*/
#ifndef BMPIMAGE_HPP_
#define BMPIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a Windows bitmap image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit BmpImage(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
/// @throws Error(ErrorCode::kerWritingImageFormatUnsupported).
void writeMetadata() override;
/// @throws Error(ErrorCode::kerInvalidSettingForImage)
void setExifData(const ExifData& exifData) override;
/// @throws Error(ErrorCode::kerInvalidSettingForImage)
void setIptcData(const IptcData& iptcData) override;
/// @throws Error(ErrorCode::kerInvalidSettingForImage)
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a Windows Bitmap image.
EXIV2API bool isBmpType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef BMPIMAGE_HPP_
+75
View File
@@ -0,0 +1,75 @@
// config.h
#ifndef _CONFIG_H_
#define _CONFIG_H_
///// Start of Visual Studio Support /////
#ifdef _MSC_VER
#pragma warning(disable : 4996) // Disable warnings about 'deprecated' standard functions
#pragma warning(disable : 4251) // Disable warnings from std templates about exporting interfaces
#endif // _MSC_VER
///// End of Visual Studio Support /////
#include "exv_conf.h"
////////////////////////////////////////
///// Start of platform macros /////////
#if defined(__MINGW32__) || defined(__MINGW64__)
#ifndef __MING__
#define __MING__ 1
#endif
#ifndef __MINGW__
#define __MINGW__ 1
#endif
#endif
#ifndef __CYGWIN__
#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
#endif
#ifndef __LITTLE_ENDIAN__
#if defined(_WIN32) || defined(__CYGWIN__)
#define __LITTLE_ENDIAN__ 1
#endif
#endif
/*
If you're using Solaris and the Solaris Studio compiler
you must -library=stdcxx4 along with these inclusions below
*/
#if defined(OS_SOLARIS)
#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)
#define EXV_SEPARATOR_STR "\\"
#define EXV_SEPARATOR_CHR '\\'
#else
#define EXV_SEPARATOR_STR "/"
#define EXV_SEPARATOR_CHR '/'
#endif
#endif
//////////////////////////////////////
#endif // _CONFIG_H_
+97
View File
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@file convert.hpp
@brief Exif and IPTC conversions to and from XMP
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a><BR>
Vladimir Nadvornik (vn)
<a href="mailto:nadvornik@suse.cz">nadvornik@suse.cz</a>
@date 17-Mar-08, ahu: created basic converter framework<BR>
20-May-08, vn: added actual conversion logic
*/
#ifndef CONVERT_HPP_
#define CONVERT_HPP_
#include "exiv2lib_export.h"
// included header files
#include "config.h"
// + standard includes
#include <string>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
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) 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);
//! 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);
/*!
@brief Convert character encoding of \em str from \em from to \em to.
If the function succeeds, \em str contains the result string.
This function uses the iconv library, if the %Exiv2 library was compiled
with iconv support. Otherwise, on Windows, it uses Windows functions to
support a limited number of conversions and fails with a warning if an
unsupported conversion is attempted. If the function is called but %Exiv2
was not compiled with iconv support and can't use Windows functions, it
fails with a warning.
The conversions supported on Windows without iconv are:
<TABLE>
<TR><TD><B>from</B></TD><TD><B>to</B></TD></TR>
<TR><TD>UTF-8</TD> <TD>UCS-2BE</TD></TR>
<TR><TD>UTF-8</TD> <TD>UCS-2LE</TD></TR>
<TR><TD>UCS-2BE</TD> <TD>UTF-8</TD></TR>
<TR><TD>UCS-2BE</TD> <TD>UCS-2LE</TD></TR>
<TR><TD>UCS-2LE</TD> <TD>UTF-8</TD></TR>
<TR><TD>UCS-2LE</TD> <TD>UCS-2BE</TD></TR>
<TR><TD>ISO-8859-1</TD><TD>UTF-8</TD></TR>
<TR><TD>ASCII</TD> <TD>UTF-8</TD></TR>
</TABLE>
@param str The string to convert. It is updated to the converted string,
which may have a different size. If the function call fails,
the string is not modified.
@param from Charset in which the input string is encoded as a name
understood by \c iconv_open(3).
@param to Charset to convert the string to as a name
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);
} // namespace Exiv2
#endif // #ifndef CONVERT_HPP_
+114
View File
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 22-Apr-06, ahu: created
*/
#ifndef CR2IMAGE_HPP_
#define CR2IMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing CR2 image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
Cr2Image(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
@warning This function is not thread safe and intended for exiv2 -pS for debugging.
*/
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
/*!
@brief Not supported. CR2 format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
}; // 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 {
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);
/*!
@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, ExifData& exifData,
IptcData& iptcData, XmpData& xmpData);
}; // 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.
/*!
@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);
//! Check if the file iIo is a CR2 image.
EXIV2API bool isCr2Type(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef CR2IMAGE_HPP_
+133
View File
@@ -0,0 +1,133 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@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
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 28-Aug-05, ahu: created
*/
#ifndef CRWIMAGE_HPP_
#define CRWIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing CRW image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
CrwImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Not supported. CRW format does not contain IPTC metadata.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setIptcData(const IptcData& iptcData) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
}; // class CrwImage
/*!
Stateless parser class for Canon CRW images (Ciff format).
*/
class EXIV2API CrwParser {
public:
/*!
@brief Decode metadata from a Canon CRW image in data buffer \em pData
of length \em size into \em crwImage.
This is the entry point to access image data in Ciff format. The
parser uses classes CiffHeader, CiffEntry, CiffDirectory.
@param pCrwImage Pointer to the %Exiv2 CRW image to hold the metadata
read from the buffer.
@param pData Pointer to the data buffer. Must point to the data of
a CRW image; no checks are performed.
@param size Length of the data buffer.
@throw Error If the data buffer cannot be parsed.
*/
static void decode(CrwImage* pCrwImage, const byte* pData, size_t size);
/*!
@brief Encode metadata from the CRW image into a data buffer (the
binary CRW image).
@param blob Data buffer for the binary image (target).
@param pData Pointer to the binary image data buffer. Must
point to data in CRW format; no checks are
performed.
@param size Length of the data buffer.
@param pCrwImage Pointer to the %Exiv2 CRW image with the metadata to
encode.
@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);
}; // 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.
/*!
@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);
//! Check if the file iIo is a CRW image.
EXIV2API bool isCrwType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef CRWIMAGE_HPP_
+322
View File
@@ -0,0 +1,322 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@brief IPTC dataset and type information
@author Brad Schick (brad) <brad@robotbattle.com>
@date 24-Jul-04, brad: created
*/
#ifndef DATASETS_HPP_
#define DATASETS_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "metadatum.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
//! 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 {
uint16_t number_; //!< Dataset number
const char* name_; //!< Dataset name
const char* title_; //!< Dataset title or label
const char* desc_; //!< Dataset description
bool mandatory_; //!< True if dataset is mandatory
bool repeatable_; //!< True if dataset is repeatable
uint32_t minbytes_; //!< Minimum number of bytes
uint32_t maxbytes_; //!< Maximum number of bytes
TypeId type_; //!< Exiv2 default type
uint16_t recordId_; //!< Record id
const char* photoshop_; //!< Photoshop string
}; // struct DataSet
//! IPTC dataset reference, implemented as a static class.
class EXIV2API IptcDataSets {
public:
/*!
@name Record identifiers
@brief Record identifiers to logically group dataSets. There are other
possible record types, but they are not standardized by the IPTC
IIM4 standard (and not commonly used in images).
*/
//@{
static constexpr uint16_t invalidRecord = 0;
static constexpr uint16_t envelope = 1;
static constexpr uint16_t application2 = 2;
//@}
//! @name Dataset identifiers
//@{
static constexpr uint16_t ModelVersion = 0;
static constexpr uint16_t Destination = 5;
static constexpr uint16_t FileFormat = 20;
static constexpr uint16_t FileVersion = 22;
static constexpr uint16_t ServiceId = 30;
static constexpr uint16_t EnvelopeNumber = 40;
static constexpr uint16_t ProductId = 50;
static constexpr uint16_t EnvelopePriority = 60;
static constexpr uint16_t DateSent = 70;
static constexpr uint16_t TimeSent = 80;
static constexpr uint16_t CharacterSet = 90;
static constexpr uint16_t UNO = 100;
static constexpr uint16_t ARMId = 120;
static constexpr uint16_t ARMVersion = 122;
static constexpr uint16_t RecordVersion = 0;
static constexpr uint16_t ObjectType = 3;
static constexpr uint16_t ObjectAttribute = 4;
static constexpr uint16_t ObjectName = 5;
static constexpr uint16_t EditStatus = 7;
static constexpr uint16_t EditorialUpdate = 8;
static constexpr uint16_t Urgency = 10;
static constexpr uint16_t Subject = 12;
static constexpr uint16_t Category = 15;
static constexpr uint16_t SuppCategory = 20;
static constexpr uint16_t FixtureId = 22;
static constexpr uint16_t Keywords = 25;
static constexpr uint16_t LocationCode = 26;
static constexpr uint16_t LocationName = 27;
static constexpr uint16_t ReleaseDate = 30;
static constexpr uint16_t ReleaseTime = 35;
static constexpr uint16_t ExpirationDate = 37;
static constexpr uint16_t ExpirationTime = 38;
static constexpr uint16_t SpecialInstructions = 40;
static constexpr uint16_t ActionAdvised = 42;
static constexpr uint16_t ReferenceService = 45;
static constexpr uint16_t ReferenceDate = 47;
static constexpr uint16_t ReferenceNumber = 50;
static constexpr uint16_t DateCreated = 55;
static constexpr uint16_t TimeCreated = 60;
static constexpr uint16_t DigitizationDate = 62;
static constexpr uint16_t DigitizationTime = 63;
static constexpr uint16_t Program = 65;
static constexpr uint16_t ProgramVersion = 70;
static constexpr uint16_t ObjectCycle = 75;
static constexpr uint16_t Byline = 80;
static constexpr uint16_t BylineTitle = 85;
static constexpr uint16_t City = 90;
static constexpr uint16_t SubLocation = 92;
static constexpr uint16_t ProvinceState = 95;
static constexpr uint16_t CountryCode = 100;
static constexpr uint16_t CountryName = 101;
static constexpr uint16_t TransmissionReference = 103;
static constexpr uint16_t Headline = 105;
static constexpr uint16_t Credit = 110;
static constexpr uint16_t Source = 115;
static constexpr uint16_t Copyright = 116;
static constexpr uint16_t Contact = 118;
static constexpr uint16_t Caption = 120;
static constexpr uint16_t Writer = 122;
static constexpr uint16_t RasterizedCaption = 125;
static constexpr uint16_t ImageType = 130;
static constexpr uint16_t ImageOrientation = 131;
static constexpr uint16_t Language = 135;
static constexpr uint16_t AudioType = 150;
static constexpr uint16_t AudioRate = 151;
static constexpr uint16_t AudioResolution = 152;
static constexpr uint16_t AudioDuration = 153;
static constexpr uint16_t AudioOutcue = 154;
static constexpr uint16_t PreviewFormat = 200;
static constexpr uint16_t PreviewVersion = 201;
static constexpr uint16_t Preview = 202;
//@}
/*!
@brief Return the name of the dataset.
@param number The dataset number
@param recordId The IPTC record Id
@return The name of the dataset or a string containing the hexadecimal
value of the dataset in the form "0x01ff", if this is an unknown
dataset.
*/
static std::string dataSetName(uint16_t number, uint16_t recordId);
/*!
@brief Return the title (label) of the dataset.
@param number The dataset number
@param recordId The IPTC record Id
@return The title (label) of the dataset
*/
static const char* dataSetTitle(uint16_t number, uint16_t recordId);
/*!
@brief Return the description of the dataset.
@param number The dataset number
@param recordId The IPTC record Id
@return The description of the dataset
*/
static const char* dataSetDesc(uint16_t number, uint16_t recordId);
/*!
@brief Return the Photoshop name of a given dataset.
@param number The dataset number
@param recordId The IPTC record Id
@return The name used by Photoshop for a dataset or an empty
string if Photoshop does not use the dataset.
*/
static const char* dataSetPsName(uint16_t number, uint16_t recordId);
/*!
@brief Check if a given dataset is repeatable
@param number The dataset number
@param recordId The IPTC record Id
@return true if the given dataset is repeatable otherwise false
*/
static bool dataSetRepeatable(uint16_t number, uint16_t recordId);
/*!
@brief Return the dataSet number for dataset name and record id
@param dataSetName dataSet name
@param recordId recordId
@return dataSet number
@throw Error if the \em dataSetName or \em recordId are invalid
*/
static uint16_t dataSet(const std::string& dataSetName, uint16_t recordId);
//! Return the type for dataSet number and Record id
static TypeId dataSetType(uint16_t number, uint16_t recordId);
/*!
@brief Return the name of the Record
@param recordId The record id
@return The name of the record or a string containing the hexadecimal
value of the record in the form "0x01ff", if this is an
unknown record.
*/
static std::string recordName(uint16_t recordId);
/*!
@brief Return the description of a record
@param recordId Record Id number
@return the description of the Record
*/
static const char* recordDesc(uint16_t recordId);
/*!
@brief Return the Id number of a record
@param recordName Name of a record type
@return the Id number of a Record
@throw Error if the record is not known;
*/
static uint16_t recordId(const std::string& recordName);
//! Return read-only list of built-in Envelope Record datasets
static const DataSet* envelopeRecordList();
//! Return read-only list of built-in Application2 Record datasets
static const DataSet* application2RecordList();
//! Print a list of all dataSets to output stream
static void dataSetList(std::ostream& os);
private:
static int dataSetIdx(uint16_t number, uint16_t recordId);
static int dataSetIdx(const std::string& dataSetName, uint16_t recordId);
static const DataSet* const records_[];
}; // class IptcDataSets
/*!
@brief Concrete keys for IPTC metadata.
*/
class EXIV2API IptcKey : public Key {
public:
//! Shortcut for an %IptcKey auto pointer.
using UniquePtr = std::unique_ptr<IptcKey>;
//! @name Creators
//@{
/*!
@brief Constructor to create an IPTC key from a key string.
@param key The key string.
@throw Error if the first part of the key is not '<b>Iptc</b>' or
the remaining parts of the key cannot be parsed and
converted to a record name and a dataset name.
*/
explicit IptcKey(std::string key);
/*!
@brief Constructor to create an IPTC key from dataset and record ids.
@param tag Dataset id
@param record Record id
*/
IptcKey(uint16_t tag, uint16_t record);
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string key() const override;
[[nodiscard]] const char* familyName() const override;
/*!
@brief Return the name of the group (the second part of the key).
For IPTC keys, the group name is the record name.
*/
[[nodiscard]] std::string groupName() const override;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] UniquePtr clone() const;
//! Return the name of the record
[[nodiscard]] std::string recordName() const;
//! Return the record id
[[nodiscard]] uint16_t record() const;
//@}
protected:
//! @name Manipulators
//@{
/*!
@brief Set the key corresponding to the dataset and record id.
The key is of the form '<b>Iptc</b>.recordName.dataSetName'.
*/
void makeKey();
/*!
@brief Parse and convert the key string into dataset and record id.
Updates data members if the string can be decomposed, or throws
\em Error.
@throw Error if the key cannot be decomposed.
*/
void decomposeKey();
//@}
private:
//! Internal virtual copy constructor.
[[nodiscard]] IptcKey* clone_() const override;
uint16_t tag_; //!< Tag value
uint16_t record_; //!< Record value
std::string key_; //!< Key
}; // class IptcKey
/*!
@brief typedef for string:string map
*/
using Dictionary = std::map<std::string, std::string>;
// *****************************************************************************
// free functions
//! Output operator for dataSet
EXIV2API std::ostream& operator<<(std::ostream& os, const DataSet& dataSet);
} // namespace Exiv2
#endif // #ifndef DATASETS_HPP_
+93
View File
@@ -0,0 +1,93 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@brief Provides easy (high-level) access to some Exif meta data.
@author Carsten Pfeiffer <pfeiffer@kde.org>
@date 28-Feb-09, gis: created
*/
#ifndef EASYACCESS_HPP_
#define EASYACCESS_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "exif.hpp"
namespace Exiv2 {
// *****************************************************************************
// class declarations
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);
} // namespace Exiv2
#endif // EASYACCESS_HPP_
+94
View File
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@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
@author Michael Ulbrich (mul)
<a href="mailto:mul@rentapacs.de">mul@rentapacs.de</a>
@author Volker Grabsch (vog)
<a href="mailto:vog@notjusthosting.com">vog@notjusthosting.com</a>
@date 7-Mar-2011, vog: created
*/
#ifndef EPSIMAGE_HPP_
#define EPSIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access EPS images.
*/
class EXIV2API EpsImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a EPS image. Since the
constructor can't return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
EpsImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Not supported.
Calling this function will throw an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a EPS image.
EXIV2API bool isEpsType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef EPSIMAGE_HPP_
+304
View File
@@ -0,0 +1,304 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@file error.hpp
@brief Error class for exceptions, log message class
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 15-Jan-04, ahu: created<BR>
11-Feb-04, ahu: isolated as a component
*/
#ifndef ERROR_HPP_
#define ERROR_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
#include "config.h"
#include <exception> // for exception
#include <sstream> // for operator<<, ostream, ostringstream, bas...
#include <string> // for basic_string, string
// *****************************************************************************
// namespace extensions
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).
This class is meant to be used as a temporary object with the
related macro-magic like this:
<code>
EXV_WARNING << "Warning! Something looks fishy.\n";
</code>
which translates to
<code>
if (LogMsg::warn >= LogMsg::level() && LogMsg::handler())
LogMsg(LogMsg::warn).os() << "Warning! Something looks fishy.\n";
</code>
The macros EXV_DEBUG, EXV_INFO, EXV_WARNING and EXV_ERROR are
shorthands and ensure efficient use of the logging facility: If a
log message doesn't need to be generated because of the log level
setting, the temp object is not even created.
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 {
public:
//! Prevent copy-construction: not implemented.
LogMsg(const LogMsg&) = delete;
//! Prevent assignment: not implemented.
LogMsg& operator=(const LogMsg&) = delete;
/*!
@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,
};
/*!
@brief Type for a log message handler function. The function receives
the log level and message and can process it in an application
specific way. The default handler sends the log message to
standard error.
*/
using Handler = void (*)(int, const char*);
//! @name Creators
//@{
//! Constructor, takes the log message type as an argument
explicit LogMsg(Level msgType);
//! Destructor, passes the log message to the message handler depending on the log level
~LogMsg();
//@}
//! @name Manipulators
//@{
//! Return a reference to the ostringstream which holds the log message
std::ostringstream& os();
//@}
/*!
@brief Set the log level. Only log messages with a level greater or
equal \em level are sent to the log message handler. Default
log level is \c warn. To suppress all log messages, set the log
level to \c mute (or set the log message handler to 0).
*/
static void setLevel(Level level);
/*!
@brief Set the log message handler. The default handler writes log
messages to standard error. To suppress all log messages, set
the log message handler to 0 (or set the log level to \c mute).
*/
static void setHandler(Handler handler);
//! Return the current log level
static Level level();
//! Return the current log message handler
static Handler handler();
//! The default log handler. Sends the log message to standard error.
static void defaultHandler(int level, const char* s);
private:
// DATA
// The output level. Only messages with type >= level_ will be written
static Level level_;
// The log handler in use
static Handler handler_;
// The type of this log message
Level msgType_;
// Holds the log message until it is passed to the message handler
std::ostringstream os_;
}; // class LogMsg
// Macros for simple access
//! Shorthand to create a temp debug log message object and return its ostringstream
#define EXV_DEBUG \
if (LogMsg::debug >= LogMsg::level() && LogMsg::handler()) \
LogMsg(LogMsg::debug).os()
//! Shorthand for a temp info log message object and return its ostringstream
#define EXV_INFO \
if (LogMsg::info >= LogMsg::level() && LogMsg::handler()) \
LogMsg(LogMsg::info).os()
//! Shorthand for a temp warning log message object and return its ostringstream
#define EXV_WARNING \
if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
LogMsg(LogMsg::warn).os()
//! Shorthand for a temp error log message object and return its ostringstream
#define EXV_ERROR \
if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
LogMsg(LogMsg::error).os()
#ifdef _MSC_VER
// Disable MSVC warnings "non - DLL-interface classkey 'identifier' used as base
// for DLL-interface classkey 'identifier'"
#pragma warning(disable : 4275)
#endif
//! 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 {
kerSuccess = 0,
kerGeneralError,
kerErrorMessage,
kerCallFailed,
kerNotAnImage,
kerInvalidDataset,
kerInvalidRecord,
kerInvalidKey,
kerInvalidTag,
kerValueNotSet,
kerDataSourceOpenFailed,
kerFileOpenFailed,
kerFileContainsUnknownImageType,
kerMemoryContainsUnknownImageType,
kerUnsupportedImageType,
kerFailedToReadImageData,
kerNotAJpeg,
kerFailedToMapFileForReadWrite,
kerFileRenameFailed,
kerTransferFailed,
kerMemoryTransferFailed,
kerInputDataReadFailed,
kerImageWriteFailed,
kerNoImageInInputData,
kerInvalidIfdId,
kerValueTooLarge,
kerDataAreaValueTooLarge,
kerOffsetOutOfRange,
kerUnsupportedDataAreaOffsetType,
kerInvalidCharset,
kerUnsupportedDateFormat,
kerUnsupportedTimeFormat,
kerWritingImageFormatUnsupported,
kerInvalidSettingForImage,
kerNotACrwImage,
kerFunctionNotSupported,
kerNoNamespaceInfoForXmpPrefix,
kerNoPrefixForNamespace,
kerTooLargeJpegSegment,
kerUnhandledXmpdatum,
kerUnhandledXmpNode,
kerXMPToolkitError,
kerDecodeLangAltPropertyFailed,
kerDecodeLangAltQualifierFailed,
kerEncodeLangAltPropertyFailed,
kerPropertyNameIdentificationFailed,
kerSchemaNamespaceNotRegistered,
kerNoNamespaceForPrefix,
kerAliasesNotSupported,
kerInvalidXmpText,
kerTooManyTiffDirectoryEntries,
kerMultipleTiffArrayElementTagsInDirectory,
kerWrongTiffArrayElementTagType,
kerInvalidKeyXmpValue,
kerInvalidIccProfile,
kerInvalidXMP,
kerTiffDirectoryTooLarge,
kerInvalidTypeValue,
kerInvalidLangAltValue,
kerInvalidMalloc,
kerCorruptedMetadata,
kerArithmeticOverflow,
kerMallocFailed,
kerInvalidIconvEncoding,
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 {
public:
//! @name Creators
//@{
//! Constructor taking only an error code
explicit Error(ErrorCode code);
//! Constructor taking an error code and one argument
template <typename A>
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)) {
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),
arg1_(toBasicString<char>(arg1)),
arg2_(toBasicString<char>(arg2)),
arg3_(toBasicString<char>(arg3)) {
setMsg(3);
}
//! Virtual destructor. (Needed because of throw())
~Error() noexcept override = default;
//@}
//! @name Accessors
//@{
[[nodiscard]] ErrorCode code() const noexcept;
/*!
@brief Return the error message as a C-string. The pointer returned by what()
is valid only as long as the BasicError object exists.
*/
[[nodiscard]] const char* what() const noexcept override;
//@}
private:
//! @name Manipulators
//@{
//! Assemble the error message from the arguments
void setMsg(int count);
//@}
// DATA
ErrorCode code_; //!< Error code
std::string arg1_; //!< First argument
std::string arg2_; //!< Second argument
std::string arg3_; //!< Third argument
std::string msg_; //!< Complete error message
};
//! %Error output operator
inline std::ostream& operator<<(std::ostream& os, const Error& error) {
return os << error.what();
}
#ifdef _MSC_VER
#pragma warning(default : 4275)
#endif
} // namespace Exiv2
#endif // #ifndef ERROR_HPP_
+562
View File
@@ -0,0 +1,562 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@file exif.hpp
@brief Encoding and decoding of Exif data
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created
*/
#ifndef EXIF_HPP_
#define EXIF_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "metadatum.hpp"
#include "tags.hpp"
// + standard includes
#include <list>
// *****************************************************************************
// namespace extensions
/*!
@brief Provides classes and functions to encode and decode Exif and Iptc data.
The <b>libexiv2</b> API consists of the objects of this namespace.
*/
namespace Exiv2 {
// *****************************************************************************
// class declarations
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&);
public:
//! @name Creators
//@{
/*!
@brief Constructor for new tags created by an application. The
%Exifdatum is created from a \em key / value pair. %Exifdatum copies
(clones) the \em key and value if one is provided. Alternatively,
a program can create an 'empty' %Exifdatum with only a key
and set the value using setValue().
@param key %ExifKey.
@param pValue Pointer to an %Exifdatum value.
@throw Error if the key cannot be parsed and converted.
*/
explicit Exifdatum(const ExifKey& key, const Value* pValue = nullptr);
//! Copy constructor
Exifdatum(const Exifdatum& rhs);
//! Destructor
~Exifdatum() override = default;
//@}
//! @name Manipulators
//@{
//! Assignment operator
Exifdatum& operator=(const Exifdatum& rhs);
/*!
@brief Assign \em value to the %Exifdatum. The type of the new Value
is set to UShortValue.
*/
Exifdatum& operator=(const uint16_t& value);
/*!
@brief Assign \em value to the %Exifdatum. The type of the new Value
is set to ULongValue.
*/
Exifdatum& operator=(const uint32_t& value);
/*!
@brief Assign \em value to the %Exifdatum. The type of the new Value
is set to URationalValue.
*/
Exifdatum& operator=(const URational& value);
/*!
@brief Assign \em value to the %Exifdatum. The type of the new Value
is set to ShortValue.
*/
Exifdatum& operator=(const int16_t& value);
/*!
@brief Assign \em value to the %Exifdatum. The type of the new Value
is set to LongValue.
*/
Exifdatum& operator=(const int32_t& value);
/*!
@brief Assign \em value to the %Exifdatum. The type of the new Value
is set to RationalValue.
*/
Exifdatum& operator=(const Rational& value);
/*!
@brief Assign \em value to the %Exifdatum.
Calls setValue(const std::string&).
*/
Exifdatum& operator=(const std::string& value);
/*!
@brief Assign \em value to the %Exifdatum.
Calls setValue(const Value*).
*/
Exifdatum& operator=(const Value& value);
void setValue(const Value* pValue) override;
/*!
@brief Set the value to the string \em value. Uses Value::read(const
std::string&). If the %Exifdatum does not have a Value yet,
then a %Value of the correct type for this %Exifdatum is
created. An AsciiValue is created for unknown tags. Return
0 if the value was read successfully.
*/
int setValue(const std::string& value) override;
/*!
@brief Set the data area by copying (cloning) the buffer pointed to
by \em buf.
Values may have a data area, which can contain additional
information besides the actual value. This method is used to set such
a data area.
@param buf Pointer to the source data area
@param len Size of the data area
@return Return -1 if the %Exifdatum does not have a value yet or the
value has no data area, else 0.
*/
int setDataArea(const byte* buf, size_t len) const;
//@}
//! @name Accessors
//@{
//! Return the key of the %Exifdatum.
[[nodiscard]] std::string key() const override;
[[nodiscard]] const char* familyName() const override;
[[nodiscard]] std::string groupName() const override;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
[[nodiscard]] uint16_t tag() const override;
//! Return the IFD id as an integer. (Do not use, this is meant for library internal use.)
[[nodiscard]] IfdId ifdId() const;
//! Return the name of the IFD
[[nodiscard]] const char* ifdName() const;
//! Return the index (unique id of this key within the original IFD)
[[nodiscard]] int idx() const;
/*!
@brief Write value to a data buffer and return the number
of bytes written.
The user must ensure that the buffer has enough memory. Otherwise
the call results in undefined behaviour.
@param buf Data buffer to write to.
@param byteOrder Applicable byte order (little or big endian).
@return Number of characters written.
*/
size_t copy(byte* buf, ByteOrder byteOrder) const override;
std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const override;
//! Return the type id of the value
[[nodiscard]] TypeId typeId() const override;
//! Return the name of the type
[[nodiscard]] const char* typeName() const override;
//! Return the size in bytes of one component of this type
[[nodiscard]] size_t typeSize() const override;
//! Return the number of components in the value
[[nodiscard]] size_t count() const override;
//! Return the size of the value in bytes
[[nodiscard]] size_t size() const override;
//! Return the value as a string.
[[nodiscard]] std::string toString() const override;
[[nodiscard]] std::string toString(size_t n) const override;
[[nodiscard]] int64_t toInt64(size_t n = 0) const override;
[[nodiscard]] float toFloat(size_t n = 0) const override;
[[nodiscard]] Rational toRational(size_t n = 0) const override;
[[nodiscard]] Value::UniquePtr getValue() const override;
[[nodiscard]] const Value& value() const override;
//! Return the size of the data area.
[[nodiscard]] size_t sizeDataArea() const;
/*!
@brief Return a copy of the data area of the value. The caller owns
this copy and %DataBuf ensures that it will be deleted.
Values may have a data area, which can contain additional
information besides the actual value. This method is used to access
such a data area.
@return A %DataBuf containing a copy of the data area or an empty
%DataBuf if the value does not have a data area assigned or the
value is not set.
*/
[[nodiscard]] DataBuf dataArea() const;
//@}
private:
// DATA
ExifKey::UniquePtr key_; //!< Key
Value::UniquePtr value_; //!< Value
}; // 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.
Manipulators are provided in subclass ExifThumb.
@note Various other preview and thumbnail images may be contained in an
image, depending on its format and the camera make and model. This
class only provides access to the Exif thumbnail as specified in the
Exif standard.
*/
class EXIV2API ExifThumbC {
public:
//! @name Creators
//@{
//! Constructor.
explicit ExifThumbC(const ExifData& exifData);
//@}
//! @name Accessors
//@{
/*!
@brief Return the thumbnail image in a %DataBuf. The caller owns the
data buffer and %DataBuf ensures that it will be deleted.
*/
[[nodiscard]] DataBuf copy() const;
/*!
@brief Write the thumbnail image to a file.
A filename extension is appended to \em path according to the image
type of the thumbnail, so \em path should not include an extension.
The function will overwrite an existing file of the same name.
@param path File name of the thumbnail without extension.
@return The number of bytes written.
*/
[[nodiscard]] size_t writeFile(const std::string& path) const;
/*!
@brief Return the MIME type of the thumbnail, either \c "image/tiff"
or \c "image/jpeg".
*/
[[nodiscard]] const char* mimeType() const;
/*!
@brief Return the file extension for the format of the thumbnail
(".tif" or ".jpg").
*/
[[nodiscard]] const char* extension() const;
//@}
private:
// DATA
const ExifData& exifData_; //!< Const reference to the Exif metadata.
}; // 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
base class, ExifThumbC.
@note Various other preview and thumbnail images may be contained in an
image, depending on its format and the camera make and model. This
class only provides access to the Exif thumbnail as specified in the
Exif standard.
*/
class EXIV2API ExifThumb : public ExifThumbC {
public:
//! @name Creators
//@{
//! Constructor.
explicit ExifThumb(ExifData& exifData);
//@}
//! @name Manipulators
//@{
/*!
@brief Set the Exif thumbnail to the JPEG image \em path. Set
XResolution, YResolution and ResolutionUnit to \em xres,
\em yres and \em unit, respectively.
This results in the minimal thumbnail tags being set for a JPEG
thumbnail, as mandated by the Exif standard.
@throw Error if reading the file fails.
@note No checks on the file format or size are performed.
@note Additional existing Exif thumbnail tags are not modified.
@note The JPEG image inserted as thumbnail image should not
itself contain Exif data (or other metadata), as existing
applications may have problems with that. (The preview
application that comes with OS X for one.) - David Harvey.
*/
void setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit);
/*!
@brief Set the Exif thumbnail to the JPEG image pointed to by \em buf,
and size \em size. Set XResolution, YResolution and
ResolutionUnit to \em xres, \em yres and \em unit, respectively.
This results in the minimal thumbnail tags being set for a JPEG
thumbnail, as mandated by the Exif standard.
@throw Error if reading the file fails.
@note No checks on the image format or size are performed.
@note Additional existing Exif thumbnail tags are not modified.
@note The JPEG image inserted as thumbnail image should not
itself contain Exif data (or other metadata), as existing
applications may have problems with that. (The preview
application that comes with OS X for one.) - David Harvey.
*/
void setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit);
/*!
@brief Set the Exif thumbnail to the JPEG image \em path.
This sets only the Compression, JPEGInterchangeFormat and
JPEGInterchangeFormatLength tags, which is not all the thumbnail
Exif information mandatory according to the Exif standard. (But it's
enough to work with the thumbnail.)
@throw Error if reading the file fails.
@note No checks on the file format or size are performed.
@note Additional existing Exif thumbnail tags are not modified.
*/
void setJpegThumbnail(const std::string& path);
/*!
@brief Set the Exif thumbnail to the JPEG image pointed to by \em buf,
and size \em size.
This sets only the Compression, JPEGInterchangeFormat and
JPEGInterchangeFormatLength tags, which is not all the thumbnail
Exif information mandatory according to the Exif standard. (But it's
enough to work with the thumbnail.)
@note No checks on the image format or size are performed.
@note Additional existing Exif thumbnail tags are not modified.
*/
void setJpegThumbnail(const byte* buf, size_t size);
/*!
@brief Delete the thumbnail from the Exif data. Removes all
Exif.%Thumbnail.*, i.e., Exif IFD1 tags.
*/
void erase();
//@}
private:
// DATA
ExifData& exifData_; //!< Reference to the related Exif metadata.
}; // class ExifThumb
//! 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.
Provide high-level access to the Exif data of an image:
- read Exif information from JPEG files
- access metadata through keys and standard C++ iterators
- add, modify and delete metadata
- 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 {
public:
//! ExifMetadata iterator type
using iterator = ExifMetadata::iterator;
//! ExifMetadata const iterator type
using const_iterator = ExifMetadata::const_iterator;
//! @name Manipulators
//@{
/*!
@brief Returns a reference to the %Exifdatum that is associated with a
particular \em key. If %ExifData does not already contain such
an %Exifdatum, operator[] adds object \em Exifdatum(key).
@note Since operator[] might insert a new element, it can't be a const
member function.
*/
Exifdatum& operator[](const std::string& key);
/*!
@brief Add an Exifdatum from the supplied key and value pair. This
method copies (clones) key and value. No duplicate checks are
performed, i.e., it is possible to add multiple metadata with
the same key.
*/
void add(const ExifKey& key, const Value* pValue);
/*!
@brief Add a copy of the \em exifdatum to the Exif metadata. No
duplicate checks are performed, i.e., it is possible to add
multiple metadata with the same key.
@throw Error if the makernote cannot be created
*/
void add(const Exifdatum& exifdatum);
/*!
@brief Delete the Exifdatum at iterator position \em pos, return the
position of the next exifdatum. Note that iterators into
the metadata, including \em pos, are potentially invalidated
by this call.
*/
iterator erase(iterator pos);
/*!
@brief Remove all elements of the range \em beg, \em end, return the
position of the next element. Note that iterators into
the metadata are potentially invalidated by this call.
*/
iterator erase(iterator beg, iterator end);
/*!
@brief Delete all Exifdatum instances resulting in an empty container.
Note that this also removes thumbnails.
*/
void clear();
//! Sort metadata by key
void sortByKey();
//! Sort metadata by tag
void sortByTag();
//! Begin of the metadata
iterator begin() {
return exifMetadata_.begin();
}
//! End of the metadata
iterator end() {
return exifMetadata_.end();
}
/*!
@brief Find the first Exifdatum with the given \em key, return an
iterator to it.
*/
iterator findKey(const ExifKey& key);
//@}
//! @name Accessors
//@{
//! Begin of the metadata
[[nodiscard]] const_iterator begin() const {
return exifMetadata_.begin();
}
//! End of the metadata
[[nodiscard]] const_iterator end() const {
return exifMetadata_.end();
}
/*!
@brief Find the first Exifdatum with the given \em key, return a const
iterator to it.
*/
[[nodiscard]] const_iterator findKey(const ExifKey& key) const;
//! Return true if there is no Exif metadata
[[nodiscard]] bool empty() const {
return exifMetadata_.empty();
}
//! Get the number of metadata entries
[[nodiscard]] size_t count() const {
return exifMetadata_.size();
}
//@}
private:
// DATA
ExifMetadata exifMetadata_;
}; // 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 {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
with binary Exif data to the provided metadata container.
The buffer must start with a TIFF header. Return byte order
in which the data is encoded.
@param exifData Exif metadata container.
@param pData Pointer to the data buffer. Must point to data in
binary Exif format; no checks are performed.
@param size Length of the data buffer
@return Byte order in which the data is encoded.
*/
static ByteOrder decode(ExifData& exifData, const byte* pData, size_t size);
/*!
@brief Encode Exif metadata from the provided metadata to binary Exif
format.
The original binary Exif data in the memory block \em pData, \em size
is parsed and updated in-place if possible ("non-intrusive"
writing). If that is not possible (e.g., if new tags were added), the
entire Exif structure is re-written to the \em blob ("intrusive"
writing). The return value indicates which write method was used. If
it is \c wmNonIntrusive, the original memory \em pData, \em size
contains the result and \em blob is empty. If the return value is
\c wmIntrusive, a new Exif structure was created and returned in
\em blob. The memory block \em pData, \em size may be partly updated in
this case and should not be used anymore.
Encode is a lossy operation. It attempts to fit the Exif data into a
binary block suitable as the payload of a JPEG APP1 Exif segment,
which can be at most 65527 bytes large. Encode omits IFD0 tags that
are "not recorded" in compressed images according to the Exif 2.2
specification. It also doesn't write tags in groups which do not occur
in JPEG images. If the resulting binary block is larger than allowed,
it further deletes specific large preview tags, unknown tags larger
than 4kB and known tags larger than 40kB. The operation succeeds even
if the end result is still larger than the allowed size. Application
should therefore always check the size of the \em blob.
@param blob Container for the binary Exif data if "intrusive"
writing is necessary. Empty otherwise.
@param pData Pointer to the binary Exif data buffer. Must
point to data in Exif format; no checks are
performed. Will be modified if "non-intrusive"
writing is possible.
@param size Length of the data buffer.
@param byteOrder Byte order to use.
@param exifData Exif metadata container.
@return Write method used.
*/
static WriteMethod encode(Blob& blob, const byte* pData, size_t size, ByteOrder byteOrder, ExifData& exifData);
/*!
@brief Encode metadata from the provided metadata to Exif format.
Encode Exif metadata from the \em ExifData container to binary Exif
format in the \em blob, encoded in \em byteOrder.
This simpler encode method uses "intrusive" writing, i.e., it builds
the binary representation of the metadata from scratch. It does not
attempt "non-intrusive", i.e., in-place updating. It's better to use
the other encode() method, if the metadata is already available in
binary format, in order to allow for "non-intrusive" updating of the
existing binary representation.
This is just an inline wrapper for
ExifParser::encode(blob, 0, 0, byteOrder, exifData).
@param blob Container for the binary Exif data.
@param byteOrder Byte order to use.
@param exifData Exif metadata container.
*/
static void encode(Blob& blob, ByteOrder byteOrder, ExifData& exifData) {
encode(blob, nullptr, 0, byteOrder, exifData);
}
}; // class ExifParser
} // namespace Exiv2
#endif // #ifndef EXIF_HPP_
+52
View File
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef EXIV2_HPP_
#define EXIV2_HPP_
// *****************************************************************************
// included header files
#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"
#include "exiv2/exif.hpp"
#include "exiv2/futils.hpp"
#include "exiv2/gifimage.hpp"
#include "exiv2/http.hpp"
#include "exiv2/image.hpp"
#include "exiv2/iptc.hpp"
#include "exiv2/jp2image.hpp"
#include "exiv2/jpgimage.hpp"
#include "exiv2/metadatum.hpp"
#include "exiv2/mrwimage.hpp"
#include "exiv2/orfimage.hpp"
#include "exiv2/pgfimage.hpp"
#include "exiv2/photoshop.hpp"
#ifdef EXV_HAVE_LIBZ
#include "exiv2/pngimage.hpp"
#endif
#include "exiv2/preview.hpp"
#include "exiv2/properties.hpp"
#include "exiv2/psdimage.hpp"
#include "exiv2/rafimage.hpp"
#include "exiv2/rw2image.hpp"
#include "exiv2/tags.hpp"
#include "exiv2/tgaimage.hpp"
#include "exiv2/tiffimage.hpp"
#include "exiv2/types.hpp"
#include "exiv2/value.hpp"
#include "exiv2/version.hpp"
#include "exiv2/xmp_exiv2.hpp"
#include "exiv2/xmpsidecar.hpp"
#endif // ifndef EXIV2_HPP_
+42
View File
@@ -0,0 +1,42 @@
#ifndef EXIV2API_H
#define EXIV2API_H
#ifdef exiv2lib_STATIC
# define EXIV2API
# define EXIV2LIB_NO_EXPORT
#else
# ifndef EXIV2API
# ifdef exiv2lib_EXPORTS
/* We are building this library */
# define EXIV2API
# else
/* We are using this library */
# define EXIV2API
# endif
# endif
# ifndef EXIV2LIB_NO_EXPORT
# define EXIV2LIB_NO_EXPORT
# endif
#endif
#ifndef EXIV2LIB_DEPRECATED
# define EXIV2LIB_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef EXIV2LIB_DEPRECATED_EXPORT
# define EXIV2LIB_DEPRECATED_EXPORT EXIV2API EXIV2LIB_DEPRECATED
#endif
#ifndef EXIV2LIB_DEPRECATED_NO_EXPORT
# define EXIV2LIB_DEPRECATED_NO_EXPORT EXIV2LIB_NO_EXPORT EXIV2LIB_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef EXIV2LIB_NO_DEPRECATED
# define EXIV2LIB_NO_DEPRECATED
# endif
#endif
#endif /* EXIV2API_H */
+77
View File
@@ -0,0 +1,77 @@
// File generated by cmake from cmake/config.h.cmake.
#ifndef _EXV_CONF_H_
#define _EXV_CONF_H_
// Define to 1 if you want to use libcurl in httpIO.
/* #undef EXV_USE_CURL */
// Define if you require webready support.
/* #undef EXV_ENABLE_WEBREADY */
// Define if you want translation of program messages to the user's native language
/* #undef EXV_ENABLE_NLS */
// Define if you want to enable the decoding of video metadata
#define EXV_ENABLE_VIDEO
// Define if you want BMFF support.
/* #undef EXV_ENABLE_BMFF */
// Define if you want to use the inih library.
/* #undef EXV_ENABLE_INIH */
// Define if you have the strerror_r function.
#define EXV_HAVE_STRERROR_R
// Define if the strerror_r function returns char*.
/* #undef EXV_STRERROR_R_CHAR_P */
/* Define to `const' or to empty, depending on the second argument of `iconv'. */
/* #undef ICONV_ACCEPTS_CONST_INPUT */
#if defined(__NetBSD__)
#include <sys/param.h>
#if __NetBSD_Prereq__(9,99,17)
#define NETBSD_POSIX_ICONV 1
#else
#define NETBSD_POSIX_ICONV 0
#endif
#endif
#if defined(ICONV_ACCEPTS_CONST_INPUT) || (defined(__NetBSD__) && !NETBSD_POSIX_ICONV)
#define EXV_ICONV_CONST const
#else
#define EXV_ICONV_CONST
#endif
// Define if you have the zlib library.
#define EXV_HAVE_LIBZ
// Define if you have the brotli library.
/* #undef EXV_HAVE_BROTLI */
/* Define if you have (Exiv2/xmpsdk) Adobe XMP Toolkit. */
/* #undef EXV_HAVE_XMP_TOOLKIT */
/* Define to the full name of this package. */
#define EXV_PACKAGE_NAME "exiv2"
/* Define to the full name and version of this package. */
#define EXV_PACKAGE_STRING "exiv2 1.00.0.9"
/* Define to the version of this package. */
#define EXV_PACKAGE_VERSION "1.00.0.9"
#define EXIV2_MAJOR_VERSION (1U)
#define EXIV2_MINOR_VERSION (00U)
#define EXIV2_PATCH_VERSION (0U)
#define EXIV2_TWEAK_VERSION (9U)
// Definition to enable translation of Nikon lens names.
#define EXV_HAVE_LENSDATA
// Define if you have the iconv function.
#define EXV_HAVE_ICONV
#endif /* !_EXV_CONF_H_ */
+123
View File
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef FUTILS_HPP_
#define FUTILS_HPP_
#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
/*!
@brief Return the value of environmental variable.
@param[in] env_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);
/*!
@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(const std::string& 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);
/*!
@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
@param result The container for the result, NULL if it fails
@param resultSize Size in bytes of the out string, it should be at least
((dataLength + 2) / 3) * 4 + 1
@return 1 indicate success
@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);
/*!
@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.
@param out_size The size of out in bytes.
@return the size of the resulting string. If it fails, return -1.
@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);
/*!
@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);
/*!
@brief Test if a file exists.
@param path Name of file to verify.
@return true if <i>path</i> exists and, if <i>ct</i> is set,
is a regular file, else false.
@note The function calls <b>stat()</b> test for <i>path</i>
and its type, see stat(2). <b>errno</b> is left unchanged
in case of an error.
*/
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();
//! @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.
Source: http://stackoverflow.com/questions/2616011/easy-way-to-parse-a-url-in-c-cross-platform
@todo This class can probably be hidden from the API
*/
class Uri {
public:
// DATA
std::string QueryString; //!< URL query string
std::string Path; //!< URL file path
std::string Protocol; //!< URL protocol
std::string Host; //!< URL host
std::string Port; //!< URL port
std::string Username; //!< URL username
std::string Password; //!< URL password
/// @brief Parse the input URL to the protocol, host, path, username, password
static Uri EXIV2API Parse(const std::string& uri);
/// @brief Decode the url components.
static void EXIV2API Decode(Uri& uri);
};
} // namespace Exiv2
#endif // #ifndef FUTILS_HPP_
+90
View File
@@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef GIFIMAGE_HPP_
#define GIFIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access raw GIF images. Exif/IPTC metadata are supported
directly.
*/
class EXIV2API GifImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a GIF image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit GifImage(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
/*!
@brief Todo: Write metadata back to the image. This method is not
yet(?) implemented. Calling it will throw an Error(ErrorCode::kerWritingImageFormatUnsupported).
*/
void writeMetadata() override;
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setExifData(const ExifData& exifData) override;
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setIptcData(const IptcData& iptcData) override;
/*!
@brief Not supported. Calling this function will throw an instance
of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a GIF image.
EXIV2API bool isGifType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef GIFIMAGE_HPP_
+21
View File
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef HTTP_HPP_
#define HTTP_HPP_
#include "exiv2lib_export.h"
#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);
} // namespace Exiv2
#endif
+670
View File
@@ -0,0 +1,670 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef IMAGE_HPP_
#define IMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "basicio.hpp"
#include "exif.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 {
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>;
/*!
@brief Options for printStructure
*/
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.
Image has containers to store image metadata and subclasses implement
read and save metadata from and to specific image formats.<BR>
Most client apps will obtain an Image instance by calling a static
ImageFactory method. The Image class can then be used to to read, write,
and save metadata.
*/
class EXIV2API Image {
public:
//! Image auto_ptr type
using UniquePtr = std::unique_ptr<Image>;
//! @name Creators
//@{
/*!
@brief Constructor taking the image type, a bitmap of the supported
metadata types and an auto-pointer that owns an IO instance.
See subclass constructor doc.
*/
Image(ImageType type, uint16_t supportedMetadata, BasicIo::UniquePtr io);
//! Virtual Destructor
virtual ~Image() = default;
//@}
//! @name Manipulators
//@{
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
@warning This function is not thread safe and intended for exiv2 -pS for debugging.
@warning You may need to put the stream into binary mode (see src/actions.cpp)
*/
virtual void printStructure(std::ostream& out, PrintStructureOption option = kpsNone, size_t 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
cleared.
This method returns success even if no metadata is found in the
image. Callers must therefore check the size of individual metadata
types before accessing the data.
@throw Error if opening or reading of the file fails or the image
data is not valid (does not look like data of the specific image
type).
*/
virtual void readMetadata() = 0;
/*!
@brief Write metadata back to the image.
All existing metadata sections in the image are either created,
replaced, or erased. If values for a given metadata type have been
assigned, a section for that metadata type will either be created or
replaced. If no values have been assigned to a given metadata type,
any exists section for that metadata type will be removed from the
image.
@throw Error if the operation fails
*/
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.
@param exifData An ExifData instance holding Exif data to be copied
*/
virtual void setExifData(const ExifData& exifData);
/*!
@brief Erase any buffered Exif data. Exif data is not removed from
the actual image until the writeMetadata() method is called.
*/
virtual void clearExifData();
/*!
@brief Assign new IPTC data. The new IPTC data is not written
to the image until the writeMetadata() method is called.
@param iptcData An IptcData instance holding IPTC data to be copied
*/
virtual void setIptcData(const IptcData& iptcData);
/*!
@brief Erase any buffered IPTC data. IPTC data is not removed from
the actual image until the writeMetadata() method is called.
*/
virtual void clearIptcData();
/*!
@brief Assign a raw XMP packet. The new XMP packet is not written
to the image until the writeMetadata() method is called.
Subsequent calls to writeMetadata() write the XMP packet from
the buffered raw XMP packet rather than from buffered parsed XMP
data. In order to write from parsed XMP data again, use
either writeXmpFromPacket(false) or setXmpData().
@param xmpPacket A string containing the raw XMP packet.
*/
virtual void setXmpPacket(const std::string& xmpPacket);
/*!
@brief Erase the buffered XMP packet. XMP data is not removed from
the actual image until the writeMetadata() method is called.
This has the same effect as clearXmpData() but operates on the
buffered raw XMP packet only, not the parsed XMP data.
Subsequent calls to writeMetadata() write the XMP packet from
the buffered raw XMP packet rather than from buffered parsed XMP
data. In order to write from parsed XMP data again, use
either writeXmpFromPacket(false) or setXmpData().
*/
virtual void clearXmpPacket();
/*!
@brief Assign new XMP data. The new XMP data is not written
to the image until the writeMetadata() method is called.
Subsequent calls to writeMetadata() encode the XMP data to
a raw XMP packet and write the newly encoded packet to the image.
In the process, the buffered raw XMP packet is updated.
In order to write directly from the raw XMP packet, use
writeXmpFromPacket(true) or setXmpPacket().
@param xmpData An XmpData instance holding XMP data to be copied
*/
virtual void setXmpData(const XmpData& xmpData);
/*!
@brief Erase any buffered XMP data. XMP data is not removed from
the actual image until the writeMetadata() method is called.
This has the same effect as clearXmpPacket() but operates on the
buffered parsed XMP data.
Subsequent calls to writeMetadata() encode the XMP data to
a raw XMP packet and write the newly encoded packet to the image.
In the process, the buffered raw XMP packet is updated.
In order to write directly from the raw XMP packet, use
writeXmpFromPacket(true) or setXmpPacket().
*/
virtual void clearXmpData();
/// @brief Set the image comment. The comment is written to the image when writeMetadata() is called.
virtual void setComment(const std::string& comment);
/*!
@brief Erase any buffered comment. Comment is not removed
from the actual image until the writeMetadata() method is called.
*/
virtual void clearComment();
/*!
@brief Set the image iccProfile. The new profile is not written
to the image until the writeMetadata() method is called.
@param iccProfile DataBuf containing profile (binary)
@param bTestValid - tests that iccProfile contains credible data
*/
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.
*/
virtual void clearIccProfile();
/*!
@brief Returns the status of the ICC profile in the image instance
*/
virtual bool iccProfileDefined() {
return !iccProfile_.empty();
}
/*!
@brief return iccProfile
*/
[[nodiscard]] virtual const DataBuf& iccProfile() const {
return iccProfile_;
}
/*!
@brief Copy all existing metadata from source Image. The data is
copied into internal buffers and is not written to the image
until the writeMetadata() method is called.
@param image Metadata source. All metadata types are copied.
*/
virtual void setMetadata(const Image& image);
/*!
@brief Erase all buffered metadata. Metadata is not removed
from the actual image until the writeMetadata() method is called.
*/
virtual void clearMetadata();
/*!
@brief Returns an ExifData instance containing currently buffered
Exif data.
The contained Exif data may have been read from the image by
a previous call to readMetadata() or added directly. The Exif
data in the returned instance will be written to the image when
writeMetadata() is called.
@return modifiable ExifData instance containing Exif values
*/
virtual ExifData& exifData();
/*!
@brief Returns an IptcData instance containing currently buffered
IPTC data.
The contained IPTC data may have been read from the image by
a previous call to readMetadata() or added directly. The IPTC
data in the returned instance will be written to the image when
writeMetadata() is called.
@return modifiable IptcData instance containing IPTC values
*/
virtual IptcData& iptcData();
/*!
@brief Returns an XmpData instance containing currently buffered
XMP data.
The contained XMP data may have been read from the image by
a previous call to readMetadata() or added directly. The XMP
data in the returned instance will be written to the image when
writeMetadata() is called.
@return modifiable XmpData instance containing XMP values
*/
virtual XmpData& xmpData();
/*!
@brief Return a modifiable reference to the raw XMP packet.
*/
virtual std::string& xmpPacket();
/*!
@brief Determine the source when writing XMP.
Depending on the setting of this flag, writeMetadata() writes
XMP from the buffered raw XMP packet or from parsed XMP data.
The default is to write from parsed XMP data. The switch is also
set by all functions to set and clear the buffered raw XMP packet
and parsed XMP data, so using this function should usually not be
necessary.
If %Exiv2 was compiled without XMP support, the default for this
flag is true and it will never be changed in order to preserve
access to the raw XMP packet.
*/
void writeXmpFromPacket(bool flag);
/*!
@brief Set the byte order to encode the Exif metadata in.
The setting is only used when new Exif metadata is created and may
not be applicable at all for some image formats. If the target image
already contains Exif metadata, the byte order of the existing data
is used. If byte order is not set when writeMetadata() is called,
little-endian byte order (II) is used by default.
*/
void setByteOrder(ByteOrder byteOrder);
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
*/
void printTiffStructure(BasicIo& io, std::ostream& out, PrintStructureOption option, size_t 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, size_t depth);
/*!
@brief is the host platform bigEndian
*/
static bool isBigEndianPlatform();
/*!
@brief is the host platform littleEndian
*/
static bool isLittleEndianPlatform();
static bool isStringType(uint16_t type);
static bool isShortType(uint16_t type);
static bool isLongType(uint16_t type);
static bool isLongLongType(uint16_t type);
static bool isRationalType(uint16_t type);
static bool is2ByteType(uint16_t type);
static bool is4ByteType(uint16_t type);
static bool is8ByteType(uint16_t type);
static bool isPrintXMP(uint16_t type, Exiv2::PrintStructureOption option);
static bool isPrintICC(uint16_t type, Exiv2::PrintStructureOption option);
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);
//@}
//! @name Accessors
//@{
/*!
@brief Return the byte order in which the Exif metadata of the image is
encoded. Initially, it is not set (\em invalidByteOrder).
*/
[[nodiscard]] ByteOrder byteOrder() const;
/*! @brief Check if the Image instance is valid. Use after object construction.
@return true if the Image is in a valid state.
*/
[[nodiscard]] bool good() const;
/*!
@brief Return the MIME type of the image.
@note For each supported image format, the library knows only one MIME
type. This may not be the most specific MIME type for that format. In
particular, several RAW formats are variants of the TIFF format with
the same magic as TIFF itself. Class TiffImage handles most of them
and thus they all have MIME type "image/tiff", although a more
specific MIME type may exist (e.g., "image/x-nikon-nef").
*/
[[nodiscard]] virtual std::string mimeType() const = 0;
/*!
@brief Return the pixel width of the image.
*/
[[nodiscard]] virtual uint32_t pixelWidth() const;
/*!
@brief Return the pixel height of the image.
*/
[[nodiscard]] virtual uint32_t pixelHeight() const;
/*!
@brief Returns an ExifData instance containing currently buffered
Exif data.
The Exif data may have been read from the image by
a previous call to readMetadata() or added directly. The Exif
data in the returned instance will be written to the image when
writeMetadata() is called.
@return read only ExifData instance containing Exif values
*/
[[nodiscard]] virtual const ExifData& exifData() const;
/*!
@brief Returns an IptcData instance containing currently buffered
IPTC data.
The contained IPTC data may have been read from the image by
a previous call to readMetadata() or added directly. The IPTC
data in the returned instance will be written to the image when
writeMetadata() is called.
@return modifiable IptcData instance containing IPTC values
*/
[[nodiscard]] virtual const IptcData& iptcData() const;
/*!
@brief Returns an XmpData instance containing currently buffered
XMP data.
The contained XMP data may have been read from the image by
a previous call to readMetadata() or added directly. The XMP
data in the returned instance will be written to the image when
writeMetadata() is called.
@return modifiable XmpData instance containing XMP values
*/
[[nodiscard]] virtual const XmpData& xmpData() const;
/*!
@brief Return a copy of the image comment. May be an empty string.
*/
[[nodiscard]] virtual std::string comment() const;
/*!
@brief Return the raw XMP packet as a string.
*/
[[nodiscard]] virtual const std::string& xmpPacket() const;
/*!
@brief Return a reference to the BasicIo instance being used for Io.
This refence is particularly useful to reading the results of
operations on a MemIo instance. For example after metadata has
been modified and the writeMetadata() method has been called,
this method can be used to get access to the modified image.
@return BasicIo instance that can be used to read or write image
data directly.
@note If the returned BasicIo is used to write to the image, the
Image class will not see those changes until the readMetadata()
method is called.
*/
[[nodiscard]] virtual BasicIo& io() const;
/*!
@brief Returns the access mode, i.e., the metadata functions, which
this image supports for the metadata type \em metadataId.
@param metadataId The metadata identifier.
@return Access mode for the requested image type and metadata identifier.
*/
[[nodiscard]] AccessMode checkMode(MetadataId metadataId) const;
/*!
@brief Check if image supports a particular type of metadata.
This method is deprecated. Use checkMode() instead.
*/
[[nodiscard]] bool supportsMetadata(MetadataId metadataId) const;
//! Return the flag indicating the source when writing XMP metadata.
[[nodiscard]] bool writeXmpFromPacket() const;
//! Return list of native previews. This is meant to be used only by the PreviewManager.
[[nodiscard]] const NativePreviewList& nativePreviews() const;
//@}
//! set type support for this image format
void setTypeSupported(ImageType imageType, uint16_t supportedMetadata) {
imageType_ = imageType;
supportedMetadata_ = supportedMetadata;
}
//! set type support for this image format
[[nodiscard]] ImageType imageType() const {
return imageType_;
}
//! @name NOT implemented
//@{
//! Copy constructor
Image(const Image&) = delete;
//! Assignment operator
Image& operator=(const Image&) = delete;
//@}
protected:
// DATA
BasicIo::UniquePtr io_; //!< Image data IO pointer
ExifData exifData_; //!< Exif data container
IptcData iptcData_; //!< IPTC data container
XmpData xmpData_; //!< XMP data container
DataBuf iccProfile_; //!< ICC buffer (binary data)
std::string comment_; //!< User comment
std::string xmpPacket_; //!< XMP packet
uint32_t pixelWidth_{0}; //!< image pixel width
uint32_t pixelHeight_{0}; //!< image pixel height
NativePreviewList nativePreviews_; //!< list of native previews
//! Return tag name for given tag id.
const std::string& tagName(uint16_t tag);
//! Return tag type for given tag id.
static const char* typeName(uint16_t tag);
private:
// DATA
ImageType imageType_; //!< Image type
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
#ifdef EXV_HAVE_XMP_TOOLKIT
bool writeXmpFromPacket_{false}; //!< Determines the source when writing XMP
#else
bool writeXmpFromPacket_{true}; //!< Determines the source when writing XMP
#endif
ByteOrder byteOrder_{invalidByteOrder}; //!< Byte order
std::map<int, std::string> tags_; //!< Map of tags
bool init_{true}; //!< Flag marking if map of tags needs to be initialized
}; // 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);
/*!
@brief Returns an Image instance of the specified type.
The factory is implemented as a static class.
*/
class EXIV2API ImageFactory {
friend bool Image::good() const;
public:
/*!
@brief Create the appropriate class type implemented BasicIo based on the protocol of the input.
"-" path implies the data from stdin and it is handled by StdinIo.
Http path can be handled by either HttpIo or CurlIo. Https, ftp paths
are handled by CurlIo. Ssh, sftp paths are handled by SshIo. Others are handled by FileIo.
@param path %Image file.
@param useCurl Indicate whether the libcurl is used or not.
If it's true, http is handled by CurlIo. Otherwise it is handled by HttpIo.
@return An auto-pointer that owns an BasicIo instance.
@throw Error If the file is not found or it is unable to connect to the server to
read the remote file.
*/
static BasicIo::UniquePtr createIo(const std::string& path, bool useCurl = true);
/*!
@brief Create an Image subclass of the appropriate type by reading
the specified file. %Image type is derived from the file
contents.
@param path %Image file. The contents of the file are tested to
determine the image type. File extension is ignored.
@param useCurl Indicate whether the libcurl is used or not.
If it's true, http is handled by CurlIo. Otherwise it is handled by HttpIo.
@return An auto-pointer that owns an Image instance whose type
matches that of the file.
@throw Error If opening the file fails or it contains data of an
unknown image type.
*/
static Image::UniquePtr open(const std::string& path, bool useCurl = true);
/*!
@brief Create an Image subclass of the appropriate type by reading
the provided memory. %Image type is derived from the memory
contents.
@param data Pointer to a data buffer containing an image. The contents
of the memory are tested to determine the image type.
@param size Number of bytes pointed to by \em data.
@return An auto-pointer that owns an Image instance whose type
matches that of the data buffer.
@throw Error If the memory contains data of an unknown image type.
*/
static Image::UniquePtr open(const byte* data, size_t size);
/*!
@brief Create an Image subclass of the appropriate type by reading
the provided BasicIo instance. %Image type is derived from the
data provided by \em io. The passed in \em io instance is
(re)opened by this method.
@param io An auto-pointer that owns a BasicIo instance that provides
image data. The contents of the image data are tested to determine
the type.
@note This method takes ownership of the passed
in BasicIo instance through the auto-pointer. Callers should not
continue to use the BasicIo instance after it is passed to this method.
Use the Image::io() method to get a temporary reference.
@return An auto-pointer that owns an Image instance whose type
matches that of the \em io data. If no image type could be
determined, the pointer is 0.
@throw Error If opening the BasicIo fails
*/
static Image::UniquePtr open(BasicIo::UniquePtr io);
/*!
@brief Create an Image subclass of the requested type by creating a
new image file. If the file already exists, it will be overwritten.
@param type Type of the image to be created.
@param path %Image file to create. File extension is ignored.
@return An auto-pointer that owns an Image instance of the requested
type.
@throw Error If the image type is not supported.
*/
static Image::UniquePtr create(ImageType type, const std::string& path);
/*!
@brief Create an Image subclass of the requested type by creating a
new image in memory.
@param type Type of the image to be created.
@return An auto-pointer that owns an Image instance of the requested
type.
@throw Error If the image type is not supported
*/
static Image::UniquePtr create(ImageType type);
/*!
@brief Create an Image subclass of the requested type by writing a
new image to a BasicIo instance. If the BasicIo instance already
contains data, it will be overwritten.
@param type Type of the image to be created.
@param io An auto-pointer that owns a BasicIo instance that will
be written to when creating a new image.
@note This method takes ownership of the passed in BasicIo instance
through the auto-pointer. Callers should not continue to use the
BasicIo instance after it is passed to this method. Use the
Image::io() method to get a temporary reference.
@return An auto-pointer that owns an Image instance of the requested
type. If the image type is not supported, the pointer is 0.
*/
static Image::UniquePtr create(ImageType type, BasicIo::UniquePtr io);
/*!
@brief Returns the image type of the provided file.
@param path %Image file. The contents of the file are tested to
determine the image type. File extension is ignored.
@return %Image type or Image::none if the type is not recognized.
*/
static ImageType getType(const std::string& path);
/*!
@brief Returns the image type of the provided data buffer.
@param data Pointer to a data buffer containing an image. The contents
of the memory are tested to determine the image type.
@param size Number of bytes pointed to by \em data.
@return %Image type or Image::none if the type is not recognized.
*/
static ImageType getType(const byte* data, size_t size);
/*!
@brief Returns the image type of data provided by a BasicIo instance.
The passed in \em io instance is (re)opened by this method.
@param io A BasicIo instance that provides image data. The contents
of the image data are tested to determine the type.
@return %Image type or Image::none if the type is not recognized.
*/
static ImageType getType(BasicIo& io);
/*!
@brief Returns the access mode or supported metadata functions for an
image type and a metadata type.
@param type The image type.
@param metadataId The metadata identifier.
@return Access mode for the requested image type and metadata identifier.
@throw Error(kerUnsupportedImageType) if the image type is not supported.
*/
static AccessMode checkMode(ImageType type, MetadataId metadataId);
/*!
@brief Determine if the content of \em io is an image of \em type.
The \em advance flag determines if the read position in the
stream is moved (see below). This applies only if the type
matches and the function returns true. If the type does not
match, the stream position is not changed. However, if
reading from the stream fails, the stream position is
undefined. Consult the stream state to obtain more
information in this case.
@param type Type of the image.
@param io BasicIo instance to read from.
@param advance Flag indicating whether the position of the io
should be advanced by the number of characters read to
analyse the data (true) or left at its original
position (false). This applies only if the type matches.
@return true if the data matches the type of this class;<BR>
false if the data does not match
*/
static bool checkType(ImageType type, BasicIo& io, bool advance);
}; // 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);
} // namespace Exiv2
#endif // #ifndef IMAGE_HPP_
+44
View File
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef IMAGE_TYPES_H
#define IMAGE_TYPES_H
namespace Exiv2 {
/// Supported Image Formats
enum class ImageType {
none,
arw,
asf,
bigtiff,
bmff,
bmp, ///< Windows bitmap
cr2,
crw,
dng,
eps,
exv,
gif, ///< GIF
jp2, ///< JPEG-2000
jpeg,
mrw,
nef,
orf,
pef,
png,
pgf,
psd, ///< Photoshop (PSD)
raf,
rw2,
sr2,
srw,
tga,
tiff,
webp,
xmp, ///< XMP sidecar files
qtime,
riff,
mkv,
};
} // namespace Exiv2
#endif // IMAGE_TYPES_H
+307
View File
@@ -0,0 +1,307 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*!
@file iptc.hpp
@brief Encoding and decoding of IPTC data
*/
#ifndef IPTC_HPP_
#define IPTC_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "datasets.hpp"
#include "metadatum.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor for new tags created by an application. The
%Iptcdatum is created from a key / value pair. %Iptcdatum
copies (clones) the value if one is provided. Alternatively, a
program can create an 'empty' %Iptcdatum with only a key and
set the value using setValue().
@param key The key of the %Iptcdatum.
@param pValue Pointer to a %Iptcdatum value.
@throw Error if the key cannot be parsed and converted
to a tag number and record id.
*/
explicit Iptcdatum(const IptcKey& key, const Value* pValue = nullptr);
//! Copy constructor
Iptcdatum(const Iptcdatum& rhs);
//! Destructor
~Iptcdatum() override = default;
//@}
//! @name Manipulators
//@{
//! Assignment operator
Iptcdatum& operator=(const Iptcdatum& rhs);
/*!
@brief Assign \em value to the %Iptcdatum. The type of the new Value
is set to UShortValue.
*/
Iptcdatum& operator=(const uint16_t& value);
/*!
@brief Assign \em value to the %Iptcdatum.
Calls setValue(const std::string&).
*/
Iptcdatum& operator=(const std::string& value);
/*!
@brief Assign \em value to the %Iptcdatum.
Calls setValue(const Value*).
*/
Iptcdatum& operator=(const Value& value);
void setValue(const Value* pValue) override;
/*!
@brief Set the value to the string \em value, using
Value::read(const std::string&).
If the %Iptcdatum does not have a Value yet, then a %Value of
the correct type for this %Iptcdatum is created. If that
fails (because of an unknown dataset), a StringValue is
created. Return 0 if the value was read successfully.
*/
int setValue(const std::string& value) override;
//@}
//! @name Accessors
//@{
size_t copy(byte* buf, ByteOrder byteOrder) const override;
std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const override;
/*!
@brief Return the key of the Iptcdatum. The key is of the form
'<b>Iptc</b>.recordName.datasetName'. Note however that the key
is not necessarily unique, i.e., an IptcData object may contain
multiple metadata with the same key.
*/
[[nodiscard]] std::string key() const override;
/*!
@brief Return the name of the record (deprecated)
@return record name
*/
[[nodiscard]] std::string recordName() const;
/*!
@brief Return the record id
@return record id
*/
[[nodiscard]] uint16_t record() const;
[[nodiscard]] const char* familyName() const override;
[[nodiscard]] std::string groupName() const override;
/*!
@brief Return the name of the tag (aka dataset)
@return tag name
*/
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Return the tag (aka dataset) number
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] TypeId typeId() const override;
[[nodiscard]] const char* typeName() const override;
[[nodiscard]] size_t typeSize() const override;
[[nodiscard]] size_t count() const override;
[[nodiscard]] size_t size() const override;
[[nodiscard]] std::string toString() const override;
[[nodiscard]] std::string toString(size_t n) const override;
[[nodiscard]] int64_t toInt64(size_t n = 0) const override;
[[nodiscard]] float toFloat(size_t n = 0) const override;
[[nodiscard]] Rational toRational(size_t n = 0) const override;
[[nodiscard]] Value::UniquePtr getValue() const override;
[[nodiscard]] const Value& value() const override;
//@}
private:
// DATA
IptcKey::UniquePtr key_; //!< Key
Value::UniquePtr value_; //!< Value
}; // class 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:
- read IPTC information from JPEG files
- access metadata through keys and standard C++ iterators
- add, modify and delete metadata
- write IPTC data to JPEG files
- extract IPTC metadata to files, insert from these files
*/
class EXIV2API IptcData {
public:
//! IptcMetadata iterator type
using iterator = IptcMetadata::iterator;
//! IptcMetadata const iterator type
using const_iterator = IptcMetadata::const_iterator;
// Use the compiler generated constructors and assignment operator
//! @name Manipulators
//@{
/*!
@brief Returns a reference to the %Iptcdatum that is associated with a
particular \em key. If %IptcData does not already contain such
an %Iptcdatum, operator[] adds object \em Iptcdatum(key).
@note Since operator[] might insert a new element, it can't be a const
member function.
*/
Iptcdatum& operator[](const std::string& key);
/*!
@brief Add an %Iptcdatum from the supplied key and value pair. This
method copies (clones) the value. A check for non-repeatable
datasets is performed.
@return 0 if successful;<BR>
6 if the dataset already exists and is not repeatable
*/
int add(const IptcKey& key, const Value* value);
/*!
@brief Add a copy of the Iptcdatum to the IPTC metadata. A check
for non-repeatable datasets is performed.
@return 0 if successful;<BR>
6 if the dataset already exists and is not repeatable;<BR>
*/
int add(const Iptcdatum& iptcdatum);
/*!
@brief Delete the Iptcdatum at iterator position pos, return the
position of the next Iptcdatum. Note that iterators into
the metadata, including pos, are potentially invalidated
by this call.
*/
iterator erase(iterator pos);
/*!
@brief Delete all Iptcdatum instances resulting in an empty container.
*/
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();
}
//! End of the metadata
iterator end() {
return iptcMetadata_.end();
}
/*!
@brief Find the first Iptcdatum with the given key, return an iterator
to it.
*/
iterator findKey(const IptcKey& key);
/*!
@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);
//@}
//! @name Accessors
//@{
//! Begin of the metadata
[[nodiscard]] const_iterator begin() const {
return iptcMetadata_.begin();
}
//! End of the metadata
[[nodiscard]] const_iterator end() const {
return iptcMetadata_.end();
}
/*!
@brief Find the first Iptcdatum with the given key, return a const
iterator to it.
*/
[[nodiscard]] const_iterator findKey(const IptcKey& key) const;
/*!
@brief Find the first Iptcdatum with the given record and dataset
number, return a const iterator to it.
*/
[[nodiscard]] const_iterator findId(uint16_t dataset, uint16_t record = IptcDataSets::application2) const;
//! Return true if there is no IPTC metadata
[[nodiscard]] bool empty() const {
return iptcMetadata_.empty();
}
//! Get the number of metadata entries
[[nodiscard]] size_t count() const {
return iptcMetadata_.size();
}
//! @brief Return the exact size of all contained IPTC metadata
[[nodiscard]] size_t size() const;
//! @brief Return the metadata charset name or 0
[[nodiscard]] const char* detectCharset() const;
//! @brief dump iptc formatted binary data (used by printStructure kpsRecursive)
static void printStructure(std::ostream& out, const Slice<byte*>& bytes, size_t depth);
//@}
private:
// DATA
IptcMetadata iptcMetadata_;
}; // class IptcData
/*!
@brief Stateless parser class for IPTC data. Images use this class to
decode and encode binary IPTC data.
*/
class EXIV2API IptcParser {
public:
/*!
@brief Decode binary IPTC data in IPTC IIM4 format from a buffer \em pData
of length \em size to the provided metadata container.
@param iptcData Metadata container to add the decoded IPTC datasets to.
@param pData Pointer to the data buffer to read from.
@param size Number of bytes in the data buffer.
@return 0 if successful;<BR>
5 if the binary IPTC data is invalid or corrupt
*/
static int decode(IptcData& iptcData, const byte* pData, size_t size);
/*!
@brief Encode the IPTC datasets from \em iptcData to a binary representation in IPTC IIM4 format.
Convert the IPTC datasets to binary format and return it. Caller owns
the returned buffer. The copied data follows the IPTC IIM4 standard.
@return Data buffer containing the binary IPTC data in IPTC IIM4 format.
*/
static DataBuf encode(const IptcData& iptcData);
private:
// Constant data
static constexpr byte marker_ = 0x1C; // Dataset marker
}; // class IptcParser
} // namespace Exiv2
#endif // #ifndef IPTC_HPP_
+105
View File
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef JP2IMAGE_HPP_
#define JP2IMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access JPEG-2000 images.
*/
class EXIV2API Jp2Image : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a JPEG-2000 image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
Jp2Image(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
@warning This function is not thread safe and intended for exiv2 -pS for debugging.
*/
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
private:
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@throw Error on input-output errors or when the image data is not valid.
@param outIo BasicIo instance to write to (a temporary location).
*/
void doWriteMetadata(BasicIo& outIo);
/*!
@brief reformats the Jp2Header to store iccProfile
@param boxBuf DataBufRef to data in the file.
@param outBuf DataBufRef with updated data
*/
void encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf);
//@}
static std::string toAscii(uint32_t n);
}; // 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.
/*!
@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);
//! Check if the file iIo is a JPEG-2000 image.
EXIV2API bool isJp2Type(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef JP2IMAGE_HPP_
+251
View File
@@ -0,0 +1,251 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef JPGIMAGE_HPP_
#define JPGIMAGE_HPP_
#include "exiv2lib_export.h"
// included header files
#include "error.hpp"
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Abstract helper base class to access JPEG images.
*/
class EXIV2API JpegBase : public Image {
public:
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
//@}
protected:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten.
@param type Image type.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new image should be created (true).
@param initData Data to initialize newly created images. Only used
when \em create is true. Should contain data for the smallest
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);
//@}
//! @name Accessors
//@{
/*!
@brief Determine if the content of the BasicIo instance is of the
type supported by this class.
The advance flag determines if the read position in the stream is
moved (see below). This applies only if the type matches and the
function returns true. If the type does not match, the stream
position is not changed. However, if reading from the stream fails,
the stream position is undefined. Consult the stream state to obtain
more information in this case.
@param iIo BasicIo instance to read from.
@param advance Flag indicating whether the position of the io
should be advanced by the number of characters read to
analyse the data (true) or left at its original
position (false). This applies only if the type matches.
@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;
//@}
//! @name Manipulators
//@{
/*!
@brief Writes the image header (aka signature) to the BasicIo instance.
@param oIo BasicIo instance that the header is written to.
@return 0 if successful;<BR>
4 if the output file can not be written to
*/
virtual int writeHeader(BasicIo& oIo) const = 0;
//@}
private:
//! @name Manipulators
//@{
/*!
@brief Initialize the image with the provided data.
@param initData Data to be written to the associated BasicIo
@param dataSize Size in bytes of data to be written
@return 0 if successful;<BR>
4 if the image can not be written to.
*/
int initImage(const byte initData[], size_t dataSize);
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@throw Error on input-output errors or when the image data is not valid.
@param outIo BasicIo instance to write to (a temporary location).
*/
void doWriteMetadata(BasicIo& outIo);
//@}
//! @name Accessors
//@{
/*!
@brief Advances associated io instance to one byte past the next
Jpeg marker and returns the marker. This method should be called
when the BasicIo instance is positioned one byte past the end of a
Jpeg segment.
@param err the error code to throw if no marker is found
@return the next Jpeg segment marker if successful;<BR>
throws an Error if not successful
*/
[[nodiscard]] byte advanceToMarker(ErrorCode err) const;
//@}
DataBuf readNextSegment(byte marker);
};
/*!
@brief Class to access JPEG images
*/
class EXIV2API JpegImage : public JpegBase {
friend EXIV2API bool isJpegType(BasicIo& iIo, bool advance);
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing Jpeg image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
JpegImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
protected:
//! @name Accessors
//@{
bool isThisType(BasicIo& iIo, bool advance) const override;
//@}
//! @name Manipulators
//@{
/*!
@brief Writes a Jpeg header (aka signature) to the BasicIo instance.
@param outIo BasicIo instance that the header is written to.
@return 0 if successful;<BR>
2 if the input image is invalid or can not be read;<BR>
4 if the temporary image can not be written to;<BR>
-3 other temporary errors
*/
int writeHeader(BasicIo& outIo) const override;
//@}
private:
// Constant data
static const byte blank_[]; ///< Minimal Jpeg image
};
//! Helper class to access %Exiv2 files
class EXIV2API ExvImage : public JpegBase {
friend EXIV2API bool isExvType(BasicIo& iIo, bool advance);
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing EXV image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
ExvImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
protected:
//! @name Accessors
//@{
bool isThisType(BasicIo& iIo, bool advance) const override;
//@}
//! @name Manipulators
//@{
int writeHeader(BasicIo& outIo) const override;
//@}
private:
// Constant data
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
// *****************************************************************************
// template, inline and free functions
// 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);
/*!
@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);
} // namespace Exiv2
#endif // #ifndef JPGIMAGE_HPP_
+190
View File
@@ -0,0 +1,190 @@
// ***************************************************************** -*- 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.
*/
#ifndef MATROSKAVIDEO_HPP_
#define MATROSKAVIDEO_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
/*!
@brief Helper structure for the Matroska tags lookup table.
*/
// *****************************************************************************
// class definitions
namespace Internal {
enum matroskaTypeEnum : char {
String = 's',
Integer = 'i',
UInteger = 'u',
Date = 'd',
InternalField = 'n',
Boolean = 'o',
Binary = 'b',
Master = 'm',
Float = 'f',
Utf8 = '8',
UndefinedType = 'z',
};
enum matroskaProcessEnum : char {
Process = 'p',
Skip = 's',
Composite = 'c',
Undefined = 'u',
};
struct MatroskaTag {
uint64_t _id;
std::string _label;
matroskaTypeEnum _type;
matroskaProcessEnum _process;
MatroskaTag(uint64_t id, std::string label, matroskaTypeEnum type, matroskaProcessEnum process) :
_id(id), _label(std::move(label)), _type(type), _process(process) {
}
MatroskaTag(uint64_t id, std::string label) :
_id(id),
_label(std::move(label)),
_type(matroskaTypeEnum::UndefinedType),
_process(matroskaProcessEnum::Undefined) {
}
bool operator==(uint64_t id) const {
return id == _id;
}
[[nodiscard]] bool isSkipped() const {
return _process == Skip;
}
[[nodiscard]] bool isComposite() const {
return _process == Composite;
}
void dump(std::ostream& os) const {
os << " MatroskaTag "
<< " id: [0x" << std::hex << _id << "] label:[" << _label << "] type:[" << _type << "] process :[" << _process
<< "]\n";
}
};
} // namespace Internal
/*!
@brief Class to access Matroska video files.
*/
class EXIV2API MatroskaVideo : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a Matroska video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit MatroskaVideo(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
protected:
/*!
@brief Function used to calulate the size of a block.
This information is only stored in one byte.
The size of the block is calculated by counting
the number of leading zeros in the binary code of the byte.
Size = (No. of leading zeros + 1) bytes
@param b The byte, which stores the information to calculate the size
@return Return the size of the block.
*/
[[nodiscard]] static uint32_t findBlockSize(byte b);
/*!
@brief Check for a valid tag and decode the block at the current IO position.
Calls contentManagement() or skips to next tag, if required.
*/
void decodeBlock();
/*!
@brief Interpret tag information, and save it in the respective XMP container.
@param tag Pointer to current tag,
@param buf Pointer to the memory area with the tag information.
@param size Size of \em buf.
*/
void decodeInternalTags(const Internal::MatroskaTag* tag, const byte* buf);
void decodeStringTags(const Internal::MatroskaTag* tag, const byte* buf);
void decodeIntegerTags(const Internal::MatroskaTag* tag, const byte* buf);
void decodeBooleanTags(const Internal::MatroskaTag* tag, const byte* buf);
void decodeDateTags(const Internal::MatroskaTag* tag, const byte* buf, size_t size);
void decodeFloatTags(const Internal::MatroskaTag* tag, const byte* buf);
private:
//! Variable to check the end of metadata traversing.
bool continueTraversing_{};
//! Variable to store height and width of a video frame.
uint64_t height_{};
uint64_t width_{};
uint32_t track_count_{};
double time_code_scale_ = 1.0;
uint64_t stream_{};
static constexpr double bytesMB = 1048576;
}; // class MatroskaVideo
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new MatroskaVideo 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 newMkvInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Matroska Video.
EXIV2API bool isMkvType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef MATROSKAVIDEO_HPP_
+293
View File
@@ -0,0 +1,293 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef METADATUM_HPP_
#define METADATUM_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "value.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
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 {
public:
//! Shortcut for a %Key auto pointer.
using UniquePtr = std::unique_ptr<Key>;
//! @name Creators
//@{
//! Destructor
virtual ~Key() = default;
//@}
Key(Key&&) = delete;
Key& operator=(Key&&) = delete;
//! @name Accessors
//@{
/*!
@brief Return the key of the metadatum as a string. The key is of the
form 'familyName.groupName.tagName'. Note however that the
key is not necessarily unique, e.g., an ExifData may contain
multiple metadata with the same key.
*/
[[nodiscard]] virtual std::string key() const = 0;
//! Return an identifier for the type of metadata (the first part of the key)
[[nodiscard]] virtual const char* familyName() const = 0;
//! Return the name of the group (the second part of the key)
[[nodiscard]] virtual std::string groupName() const = 0;
//! Return the name of the tag (which is also the third part of the key)
[[nodiscard]] virtual std::string tagName() const = 0;
//! Return a label for the tag
[[nodiscard]] virtual std::string tagLabel() const = 0;
//! Return a description for the tag
[[nodiscard]] virtual std::string tagDesc() const = 0;
//! Return the tag number
[[nodiscard]] 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
will be deleted.
*/
[[nodiscard]] UniquePtr clone() const;
/*!
@brief Write the key to an output stream. You do not usually have
to use this function; it is used for the implementation of
the output operator for %Key,
operator<<(std::ostream &os, const Key &key).
*/
std::ostream& write(std::ostream& os) const {
return os << key();
}
//@}
protected:
Key() = default;
Key(const Key&) = default;
//! @name Manipulators
//@{
/*!
@brief Assignment operator. Protected so that it can only be used
by subclasses but not directly.
*/
Key& operator=(const Key&) = default;
//@}
private:
//! Internal virtual copy constructor.
[[nodiscard]] virtual Key* clone_() const = 0;
}; // class 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 {
public:
//! @name Creators
//@{
//! Destructor
virtual ~Metadatum() = default;
//@}
//! @name Manipulators
//@{
/*!
@brief Set the value. This method copies (clones) the value pointed
to by pValue.
*/
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;
//@}
//! @name Accessors
//@{
/*!
@brief Write the interpreted value to a string.
Implemented in terms of write(), see there.
*/
std::string print(const ExifData* pMetadata = nullptr) const;
/*!
@brief Write value to a data buffer and return the number
of bytes written.
The user must ensure that the buffer has enough memory. Otherwise
the call results in undefined behaviour.
@param buf Data buffer to write to.
@param byteOrder Applicable byte order (little or big endian).
@return Number of characters written.
*/
virtual size_t copy(byte* buf, ByteOrder byteOrder) const = 0;
/*!
@brief Write the interpreted value to an output stream, return
the stream.
The method takes an optional pointer to a metadata container.
Pretty-print functions may use that to refer to other metadata as it
is sometimes not sufficient to know only the value of the metadatum
that should be interpreted. Thus, it is advisable to always call this
method with a pointer to the metadata container if possible.
This functionality is currently only implemented for Exif tags.
The pointer is ignored when used to write IPTC datasets or XMP
properties.
Without the optional metadata pointer, you do not usually have to use
this function; it is used for the implementation of the output
operator for %Metadatum,
operator<<(std::ostream &os, const Metadatum &md).
See also print(), which prints the interpreted value to a string.
*/
virtual std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const = 0;
/*!
@brief Return the key of the metadatum. The key is of the form
'familyName.groupName.tagName'. Note however that the key
is not necessarily unique, e.g., an ExifData object may
contain multiple metadata with the same key.
*/
[[nodiscard]] virtual std::string key() const = 0;
//! Return the name of the metadata family (which is also the first part of the key)
[[nodiscard]] virtual const char* familyName() const = 0;
//! Return the name of the metadata group (which is also the second part of the key)
[[nodiscard]] virtual std::string groupName() const = 0;
//! Return the name of the tag (which is also the third part of the key)
[[nodiscard]] virtual std::string tagName() const = 0;
//! Return a label for the tag
[[nodiscard]] virtual std::string tagLabel() const = 0;
//! Return a description for the tag
[[nodiscard]] virtual std::string tagDesc() const = 0;
//! Return the tag
[[nodiscard]] virtual uint16_t tag() const = 0;
//! Return the type id of the value
[[nodiscard]] virtual TypeId typeId() const = 0;
//! Return the name of the type
[[nodiscard]] virtual const char* typeName() const = 0;
//! Return the size in bytes of one component of this type
[[nodiscard]] virtual size_t typeSize() const = 0;
//! Return the number of components in the value
[[nodiscard]] virtual size_t count() const = 0;
//! Return the size of the value in bytes
[[nodiscard]] virtual size_t size() const = 0;
//! Return the value as a string.
[[nodiscard]] 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.
*/
[[nodiscard]] 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.
*/
[[nodiscard]] 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.
*/
[[nodiscard]] 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.
*/
[[nodiscard]] 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.
*/
[[nodiscard]] 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
be deleted.
This method is provided for users who need full control over the
value. A caller may, e.g., downcast the pointer to the appropriate
subclass of Value to make use of the interface of the subclass to set
or modify its contents.
@return An auto-pointer containing a pointer to a copy (clone) of the
value, 0 if the value is not set.
*/
[[nodiscard]] virtual Value::UniquePtr getValue() const = 0;
/*!
@brief Return a constant reference to the value.
This method is provided mostly for convenient and versatile output of
the value which can (to some extent) be formatted through standard
stream manipulators. Do not attempt to write to the value through
this reference. An Error is thrown if the value is not set; as an
alternative to catching it, one can use count() to check if there
is any data before calling this method.
@return A constant reference to the value.
@throw Error if the value is not set.
*/
[[nodiscard]] virtual const Value& value() const = 0;
//@}
protected:
Metadatum() = default;
Metadatum(const Metadatum&) = default;
//! @name Manipulators
//@{
/*!
@brief Assignment operator. Protected so that it can only be used
by subclasses but not directly.
*/
Metadatum& operator=(const Metadatum&) = default;
//@}
}; // class Metadatum
/*!
@brief Output operator for Metadatum types, writing the interpreted
tag value.
*/
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);
/*!
@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);
} // namespace Exiv2
#endif // #ifndef METADATUM_HPP_
+94
View File
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef MRWIMAGE_HPP_
#define MRWIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing MRW image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
MrwImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
/*!
@brief Todo: Write metadata back to the image. This method is not
yet implemented. Calling it will throw an Error(ErrorCode::kerWritingImageFormatUnsupported).
*/
void writeMetadata() override;
/*!
@brief Todo: Not supported yet, requires writeMetadata(). Calling
this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setExifData(const ExifData& exifData) override;
/*!
@brief Todo: Not supported yet, requires writeMetadata(). Calling
this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setIptcData(const IptcData& iptcData) override;
/*!
@brief Not supported. MRW format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a MRW image.
EXIV2API bool isMrwType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef MRWIMAGE_HPP_
+102
View File
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef ORFIMAGE_HPP_
#define ORFIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "tiffimage.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing ORF image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
OrfImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Not supported. ORF format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
std::string mimeType() const override;
uint32_t pixelWidth() const override;
uint32_t pixelHeight() const override;
//@}
}; // 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 {
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);
/*!
@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, ExifData& exifData,
IptcData& iptcData, 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.
/*!
@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);
//! Check if the file iIo is an ORF image.
EXIV2API bool isOrfType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef ORFIMAGE_HPP_
+94
View File
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PGFIMAGE_HPP_
#define PGFIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access PGF images. Exif and IPTC metadata are supported
directly.
*/
class EXIV2API PgfImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing PGF image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
PgfImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override {
return "image/pgf";
}
//@}
private:
bool bSwap_; // true for bigEndian hardware, else false
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@throw Error on input-output errors or when the image data is not valid.
@param outIo BasicIo instance to write to (a temporary location).
*/
void doWriteMetadata(BasicIo& outIo);
//! Read Magick number. Only version >= 6 is supported.
static byte readPgfMagicNumber(BasicIo& iIo);
//! Read PGF Header size encoded in 32 bits integer.
size_t readPgfHeaderSize(BasicIo& iIo) const;
//! Read header structure.
DataBuf readPgfHeaderStructure(BasicIo& iIo, uint32_t& width, uint32_t& height) const;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a PGF image.
EXIV2API bool isPgfType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef PGFIMAGE_HPP_
+70
View File
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PHOTOSHOP_INT_HPP
#define PHOTOSHOP_INT_HPP
#include "exiv2lib_export.h"
#include "types.hpp"
#include <array>
namespace Exiv2 {
// Forward declarations
class IptcData;
/// @brief Helper class, has methods to deal with %Photoshop "Information Resource Blocks" (IRBs).
struct EXIV2API Photoshop {
// Todo: Public for now
static constexpr std::array<const char*, 4> irbId_{"8BIM", "AgHg", "DCSR", "PHUT"}; //!< %Photoshop IRB markers
static constexpr auto ps3Id_ = "Photoshop 3.0\0"; //!< %Photoshop marker
static constexpr uint16_t iptc_ = 0x0404; //!< %Photoshop IPTC marker
static constexpr uint16_t preview_ = 0x040c; //!< %Photoshop preview marker
/// @brief Checks an IRB
/// @param pPsData Existing IRB buffer. It is expected to be of size 4.
/// @return true if the IRB marker is known
/// @todo This should be an implementation detail and not exposed in the API. An attacker could try to pass
/// a smaller buffer or null pointer.
static bool isIrb(const byte* pPsData);
/// @brief Validates all IRBs
/// @param pPsData Existing IRB buffer
/// @param sizePsData Size of the IRB buffer, may be 0
/// @return true if all IRBs are valid;<BR> false otherwise
static bool valid(const byte* pPsData, size_t sizePsData);
/// @brief Locates the data for a %Photoshop tag in a %Photoshop formated memory buffer.
/// Operates on raw data to simplify reuse.
/// @param pPsData Pointer to buffer containing entire payload of %Photoshop formated data (from APP13 Jpeg segment)
/// @param sizePsData Size in bytes of pPsData.
/// @param psTag %Tag number of the block to look for.
/// @param record Output value that is set to the start of the data block within pPsData (may not be null).
/// @param sizeHdr Output value that is set to the size of the header within the data block pointed to by record
/// (may not be null).
/// @param sizeData Output value that is set to the size of the actual data within the data block pointed to by record
/// (may not be null).
/// @return 0 if successful;<BR>
/// 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& sizeHdr,
uint32_t& sizeData);
/// @brief Forwards to locateIrb() with \em psTag = \em iptc_
static int locateIptcIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t& sizeHdr,
uint32_t& sizeData);
/// @brief Forwards to locatePreviewIrb() with \em psTag = \em preview_
static int locatePreviewIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t& sizeHdr,
uint32_t& sizeData);
/// @brief Set the new IPTC IRB, keeps existing IRBs but removes the IPTC block if there is no new IPTC data to write.
/// @param pPsData Existing IRB buffer
/// @param sizePsData Size of the IRB buffer, may be 0
/// @param iptcData Iptc data to embed, may be empty
/// @return A data buffer containing the new IRB buffer, may have 0 size
static DataBuf setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData);
};
} // namespace Exiv2
#endif // PHOTOSHOP_INT_HPP
+95
View File
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PNGIMAGE_HPP_
#define PNGIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access PNG images. Exif and IPTC metadata are supported
directly.
*/
class EXIV2API PngImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing PNG image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
PngImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
@warning This function is not thread safe and intended for exiv2 -pS for debugging.
*/
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
private:
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@throw Error on input-output errors or when the image data is not valid.
@param outIo BasicIo instance to write to (a temporary location).
*/
void doWriteMetadata(BasicIo& outIo);
//@}
std::string profileName_;
}; // 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.
/*!
@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);
//! Check if the file iIo is a PNG image.
EXIV2API bool isPngType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef PNGIMAGE_HPP_
+146
View File
@@ -0,0 +1,146 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PREVIEW_HPP_
#define PREVIEW_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
//! Type of preview image.
using PreviewId = int;
/*!
@brief Preview image properties.
*/
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>;
/*!
@brief Class that holds preview image properties and data buffer.
*/
class EXIV2API PreviewImage {
friend class PreviewManager;
public:
//! @name Constructors
//@{
//! Copy constructor
PreviewImage(const PreviewImage& rhs);
//@}
~PreviewImage() = default;
//! @name Manipulators
//@{
//! Assignment operator
PreviewImage& operator=(const PreviewImage& rhs);
//@}
//! @name Accessors
//@{
/*!
@brief Return a copy of the preview image data. The caller owns
this copy and %DataBuf ensures that it will be deleted.
*/
[[nodiscard]] DataBuf copy() const;
/*!
@brief Return a pointer to the image data for read-only access.
*/
[[nodiscard]] const byte* pData() const;
/*!
@brief Return the size of the preview image in bytes.
*/
[[nodiscard]] uint32_t size() const;
/*!
@brief Write the thumbnail image to a file.
A filename extension is appended to \em path according to the image
type of the preview image, so \em path should not include an extension.
The function will overwrite an existing file of the same name.
@param path File name of the preview image without extension.
@return The number of bytes written.
*/
[[nodiscard]] size_t writeFile(const std::string& path) const;
/*!
@brief Return the MIME type of the preview image, usually either
\c "image/tiff" or \c "image/jpeg".
*/
[[nodiscard]] std::string mimeType() const;
/*!
@brief Return the file extension for the format of the preview image
(".tif" or ".jpg").
*/
[[nodiscard]] std::string extension() const;
/*!
@brief Return the width of the preview image in pixels.
*/
[[nodiscard]] size_t width() const;
/*!
@brief Return the height of the preview image in pixels.
*/
[[nodiscard]] size_t height() const;
/*!
@brief Return the preview image type identifier.
*/
[[nodiscard]] PreviewId id() const;
//@}
private:
//! Private constructor
PreviewImage(PreviewProperties properties, DataBuf&& data);
PreviewProperties properties_; //!< Preview image properties
DataBuf preview_; //!< Preview image data
}; // class PreviewImage
/*!
@brief Class for extracting preview images from image metadata.
*/
class EXIV2API PreviewManager {
public:
//! @name Constructors
//@{
//! Constructor.
explicit PreviewManager(const Image& image);
//@}
//! @name Accessors
//@{
/*!
@brief Return the properties of all preview images in a list
sorted by preview width * height, starting with the smallest
preview image.
*/
[[nodiscard]] PreviewPropertiesList getPreviewProperties() const;
/*!
@brief Return the preview image for the given preview properties.
*/
[[nodiscard]] PreviewImage getPreviewImage(const PreviewProperties& properties) const;
//@}
private:
const Image& image_;
}; // class PreviewManager
} // namespace Exiv2
#endif // #ifndef PREVIEW_HPP_
+285
View File
@@ -0,0 +1,285 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PROPERTIES_HPP_
#define PROPERTIES_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include <mutex>
#include "datasets.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
class XmpKey;
// *****************************************************************************
// class definitions
//! Category of an XMP property
enum XmpCategory { xmpInternal, xmpExternal };
//! Information about one XMP property.
struct EXIV2API XmpPropertyInfo {
//! Comparison operator for name
bool operator==(const std::string& name) const;
const char* name_; //!< Property name
const char* title_; //!< Property title or label
const char* xmpValueType_; //!< XMP value type (for info only)
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 {
//! For comparison with prefix
struct Prefix {
//! The prefix string.
std::string prefix_;
};
//! For comparison with namespace
struct Ns {
//! The namespace string
std::string ns_;
};
//! Comparison operator for namespace
bool operator==(const Ns& ns) const;
//! Comparison operator for prefix
bool operator==(const Prefix& prefix) const;
const char* ns_; //!< Namespace
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 {
private:
static const XmpNsInfo* nsInfoUnsafe(const std::string& prefix);
static void unregisterNsUnsafe(const std::string& ns);
static const XmpNsInfo* lookupNsRegistryUnsafe(const XmpNsInfo::Prefix& prefix);
public:
/*!
@brief Return the title (label) of the property.
@param key The property key
@return The title (label) of the property, 0 if the
key is of an unknown property.
*/
static const char* propertyTitle(const XmpKey& key);
/*!
@brief Return the description of the property.
@param key The property key
@return The description of the property, 0 if the
key is of an unknown property.
*/
static const char* propertyDesc(const XmpKey& key);
/*!
@brief Return the type for property \em key. The default
for unknown keys is xmpText.
@param key The property key
@return The type of the property
*/
static TypeId propertyType(const XmpKey& key);
/*!
@brief Return information for the property for key.
If the key is a path to a nested property (one which contains a slash,
like \c Xmp.MP.RegionInfo/MPRI:Regions), determines the innermost element
(\c Xmp.MPRI.Regions) and returns its property information.
@param key The property key
@return A pointer to the property information, 0 if the
key is of an unknown property.
*/
static const XmpPropertyInfo* propertyInfo(const XmpKey& key);
/*!
@brief Return the namespace name for the schema associated
with \em prefix.
@param prefix Prefix
@return The namespace name
@throw Error if no namespace is registered with \em prefix.
*/
static std::string ns(const std::string& prefix);
/*!
@brief Return the namespace description for the schema associated
with \em prefix.
@param prefix Prefix
@return The namespace description
@throw Error if no namespace is registered with \em prefix.
*/
static const char* nsDesc(const std::string& prefix);
/*!
@brief Return read-only list of built-in properties for \em prefix.
@param prefix Prefix
@return Pointer to the built-in properties for prefix, may be 0 if
none is configured in the namespace info.
@throw Error if no namespace is registered with \em prefix.
*/
static const XmpPropertyInfo* propertyList(const std::string& prefix);
/*!
@brief Return information about a schema namespace for \em prefix.
Always returns a valid pointer.
@param prefix The prefix
@return A pointer to the related information
@throw Error if no namespace is registered with \em prefix.
*/
static const XmpNsInfo* nsInfo(const std::string& prefix);
/*!
@brief Return the (preferred) prefix for schema namespace \em ns.
@param ns Schema namespace
@return The prefix or an empty string if namespace \em ns is not
registered.
*/
static std::string prefix(const std::string& ns);
//! Print a list of properties of a schema namespace to output stream \em os.
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);
/*!
@brief Register namespace \em ns with preferred prefix \em prefix.
If the prefix is a known or previously registered prefix, the
corresponding namespace URI is overwritten.
@note This invalidates XMP keys generated with the previous prefix.
*/
static void registerNs(const std::string& ns, const std::string& prefix);
/*!
@brief Unregister a custom namespace \em ns.
The function only has an effect if there is a namespace \em ns
registered earlier, it does not unregister built-in namespaces.
@note This invalidates XMP keys generated in this namespace.
*/
static void unregisterNs(const std::string& ns);
/*!
@brief Lock to be used while modifying properties.
@todo For a proper read-write lock, this shall be improved by a
\em std::shared_timed_mutex (once C++14 is allowed) or
\em std::shared_mutex (once C++17 is allowed). The
read-access locks shall be updated to \em std::shared_lock then.
*/
static std::mutex mutex_;
/*!
@brief Unregister all custom namespaces.
The function only unregisters namespaces registered earlier, it does not
unregister built-in namespaces.
@note This invalidates XMP keys generated in any custom namespace.
*/
static void unregisterNs();
//! Type for the namespace registry
using NsRegistry = std::map<std::string, XmpNsInfo>;
/*!
@brief Get the registered namespace for a specific \em prefix from the registry.
*/
static const XmpNsInfo* lookupNsRegistry(const XmpNsInfo::Prefix& prefix);
// DATA
static NsRegistry nsRegistry_; //!< Namespace registry
/*!
@brief Get all registered namespaces (for both Exiv2 and XMPsdk)
*/
static void registeredNamespaces(Exiv2::Dictionary& nsDict);
}; // class XmpProperties
/*!
@brief Concrete keys for XMP metadata.
*/
class EXIV2API XmpKey : public Key {
public:
//! Shortcut for an %XmpKey auto pointer.
using UniquePtr = std::unique_ptr<XmpKey>;
//! @name Creators
//@{
/*!
@brief Constructor to create an XMP key from a key string.
@param key The key string.
@throw Error if the first part of the key is not '<b>Xmp</b>' or
the second part of the key cannot be parsed and converted
to a known (i.e., built-in or registered) schema prefix.
*/
explicit XmpKey(const std::string& key);
/*!
@brief Constructor to create an XMP key from a schema prefix
and a property name.
@param prefix Schema prefix name
@param property Property name
@throw Error if the schema prefix is not known.
*/
XmpKey(const std::string& prefix, const std::string& property);
//! Copy constructor.
XmpKey(const XmpKey& rhs);
//! Virtual destructor.
~XmpKey() override;
//@}
//! @name Manipulators
//@{
//! Assignment operator.
XmpKey& operator=(const XmpKey& rhs);
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string key() const override;
[[nodiscard]] const char* familyName() const override;
/*!
@brief Return the name of the group (the second part of the key).
For XMP keys, the group name is the schema prefix name.
*/
[[nodiscard]] std::string groupName() const override;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Properties don't have a tag number. Return 0.
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] UniquePtr clone() const;
// Todo: Should this be removed? What about tagLabel then?
//! Return the schema namespace for the prefix of the key
[[nodiscard]] std::string ns() const;
//@}
private:
//! Internal virtual copy constructor.
[[nodiscard]] XmpKey* clone_() const override;
// Pimpl idiom
struct Impl;
std::unique_ptr<Impl> p_;
}; // class XmpKey
// *****************************************************************************
// free functions
//! Output operator for property info
EXIV2API std::ostream& operator<<(std::ostream& os, const XmpPropertyInfo& propertyInfo);
} // namespace Exiv2
#endif // #ifndef PROPERTIES_HPP_
+106
View File
@@ -0,0 +1,106 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PSDIMAGE_HPP_
#define PSDIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access raw Photoshop images.
*/
class EXIV2API PsdImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a Photoshop image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit PsdImage(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Not supported. Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
/*!
@brief Return the MIME type of the image.
The MIME type returned for Photoshop images is "image/x-photoshop".
@note This should really be "image/vnd.adobe.photoshop"
(officially registered with IANA in December 2005 -- see
http://www.iana.org/assignments/media-types/image/vnd.adobe.photoshop)
but Apple, as of Tiger (10.4.8), maps this official MIME type to a
dynamic UTI, rather than "com.adobe.photoshop-image" as it should.
*/
[[nodiscard]] std::string mimeType() const override;
//@}
private:
//! @name Manipulators
//@{
void readResourceBlock(uint16_t resourceId, uint32_t resourceSize);
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@throw Error on input-output errors or when the image data is not valid.
@param outIo BasicIo instance to write to (a temporary location).
*/
void doWriteMetadata(BasicIo& outIo);
uint32_t writeExifData(ExifData& exifData, BasicIo& out);
//@}
//! @name Accessors
//@{
static uint32_t writeIptcData(const IptcData& iptcData, BasicIo& out);
uint32_t writeXmpData(const XmpData& xmpData, BasicIo& out) const;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a Photoshop image.
EXIV2API bool isPsdType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef PSDIMAGE_HPP_
+225
View File
@@ -0,0 +1,225 @@
// ***************************************************************** -*- 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.
*/
#ifndef QUICKTIMEVIDEO_HPP_
#define QUICKTIMEVIDEO_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "exif.hpp"
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access QuickTime video files.
*/
class EXIV2API QuickTimeVideo : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a QuickTime video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit QuickTimeVideo(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
protected:
/*!
@brief Check for a valid tag and decode the block at the current IO
position. Calls tagDecoder() or skips to next tag, if required.
*/
void decodeBlock(std::string const& entered_from = "");
/*!
@brief Interpret tag information, and call the respective function
to save it in the respective XMP container. Decodes a Tag
Information and saves it in the respective XMP container, if
the block size is small.
@param buf Data buffer which cotains tag ID.
@param size Size of the data block used to store Tag Information.
*/
void tagDecoder(Exiv2::DataBuf& buf, size_t size);
private:
/*!
@brief Interpret file type of the video, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void fileTypeDecoder(size_t size);
/*!
@brief Interpret Media Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void mediaHeaderDecoder(size_t size);
/*!
@brief Interpret Video Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void videoHeaderDecoder(size_t size);
/*!
@brief Interpret Movie Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void movieHeaderDecoder(size_t size);
/*!
@brief Interpret Track Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void trackHeaderDecoder(size_t size);
/*!
@brief Interpret Handler Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void handlerDecoder(size_t size);
/*!
@brief Interpret Tag which contain other sub-tags,
and save it in the respective XMP container.
*/
void multipleEntriesDecoder();
/*!
@brief Interpret Sample Description Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void sampleDesc(size_t size);
/*!
@brief Interpret Image Description Tag, and save it
in the respective XMP container.
*/
void imageDescDecoder();
/*!
@brief Interpret User Data Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void userDataDecoder(size_t size);
/*!
@brief Interpret Preview Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void previewTagDecoder(size_t size);
/*!
@brief Interpret Meta Keys Tags, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void keysTagDecoder(size_t size);
/*!
@brief Interpret Track Aperture Tags, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void trackApertureTagDecoder(size_t size);
/*!
@brief Interpret Nikon Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void NikonTagsDecoder(size_t size);
/*!
@brief Interpret Tags from Different Camera make, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void CameraTagsDecoder(size_t size);
/*!
@brief Interpret Audio Description Tag, and save it
in the respective XMP container.
*/
void audioDescDecoder();
/*!
@brief Helps to calculate Frame Rate from timeToSample chunk,
and save it in the respective XMP container.
*/
void timeToSampleDecoder();
/*!
@brief Recognizes which stream is currently under processing,
and save its information in currentStream_ .
*/
void setMediaStream();
/*!
@brief Used to discard a tag along with its data. The Tag will
be skipped and not decoded.
@param size Size of the data block that is to skipped.
*/
void discard(size_t size);
//! Variable which stores Time Scale unit, used to calculate time.
uint64_t timeScale_ = 0;
//! Variable which stores current stream being processsed.
int currentStream_ = 0;
//! Variable to check the end of metadata traversing.
bool continueTraversing_ = false;
//! Variable to store height and width of a video frame.
uint64_t height_ = 0;
uint64_t width_ = 0;
}; // QuickTimeVideo End
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new QuicktimeVideo 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 newQTimeInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Quick Time Video.
EXIV2API bool isQTimeType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // QUICKTIMEVIDEO_HPP_
+95
View File
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef RAFIMAGE_HPP_
#define RAFIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing RAF image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
RafImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
void readMetadata() override;
/*!
@brief Todo: Write metadata back to the image. This method is not
yet implemented. Calling it will throw an Error(ErrorCode::kerWritingImageFormatUnsupported).
*/
void writeMetadata() override;
/*!
@brief Todo: Not supported yet, requires writeMetadata(). Calling
this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setExifData(const ExifData& exifData) override;
/*!
@brief Todo: Not supported yet, requires writeMetadata(). Calling
this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setIptcData(const IptcData& iptcData) override;
/*!
@brief Not supported. RAF format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a RAF image.
EXIV2API bool isRafType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef RAFIMAGE_HPP_
+185
View File
@@ -0,0 +1,185 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "exif.hpp"
#include "exiv2lib_export.h"
#include "image.hpp"
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access RIFF video files.
*/
class EXIV2API RiffVideo : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a Riff video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit RiffVideo(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
protected:
class HeaderReader {
std::string id_;
uint64_t size_ = 0;
public:
explicit HeaderReader(const BasicIo::UniquePtr& io);
[[nodiscard]] uint64_t getSize() const {
return size_;
}
[[nodiscard]] const std::string& getId() const {
return id_;
}
};
void readList(const HeaderReader& header_);
void readChunk(const HeaderReader& header_);
void decodeBlocks();
private:
static bool equal(const std::string& str1, const std::string& str2);
/*!
@brief Interpret MainAVIHeader (avih) structure, and save it in the respective XMP container.
*/
void readAviHeader();
/*!
@brief Interpret stream header list element (strh), and save it in the respective XMP container.
*/
void readStreamHeader();
/*!
@brief Interpret stream header list element (strf), and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void readStreamFormat(uint64_t size_);
/*!
@brief Interpret Additional header data (strd), and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void readStreamData(uint64_t size_) const;
/*!
@brief Interpret stream header list element (strn) , and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void StreamName(uint64_t size_) const;
/*!
@brief Interpret INFO List Chunk, and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void readInfoListChunk(uint64_t size_);
/*!
@brief Interpret Riff Stream Data tag information, and save it in the respective XMP container.
The Movi - Lists contain Video, Audio, Subtitle and (secondary) index data. Those can be grouped into rec - Lists.
@param size_ Size of the data block used to store Tag Information.
*/
void readMoviList(uint64_t size_) const;
/*!
@brief Interpret Video Properties Header chunk, and save it in the respective XMP container.
The video properties header identifies video signal properties associated with a digital video stream in an AVI file
@param size_ Size of the data block used to store Tag Information.
*/
void readVPRPChunk(uint64_t size_) const;
/*!
@brief Interpret Riff INdex Chunk, and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void readIndexChunk(uint64_t size_) const;
/*!
@brief Interpret Riff Stream Chunk, and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void readDataChunk(uint64_t size_) const;
/*!
@brief Interpret Junk Chunk and save it in the respective XMP container.
@param size_ Size of the data block used to store Tag Information.
*/
void readJunk(uint64_t size_) const;
static std::string getStreamType(uint32_t stream);
/*!
@brief Calculates Duration of a video, and stores it in the respective XMP container.
@param frame_rate Frame rate of the video.
@param frame_count Total number of frames present in the video.
*/
void fillDuration(double frame_rate, size_t frame_count);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the respective XMP container.
@param width Width of the video.
@param height Height of the video.
*/
void fillAspectRatio(size_t width, size_t height);
static constexpr auto CHUNK_HEADER_ICCP = "ICCP";
static constexpr auto CHUNK_HEADER_EXIF = "EXIF";
static constexpr auto CHUNK_HEADER_XMP = "XMP ";
/* Chunk header names */
static constexpr auto CHUNK_ID_MOVI = "MOVI";
static constexpr auto CHUNK_ID_DATA = "DATA";
static constexpr auto CHUNK_ID_HDRL = "HDRL";
static constexpr auto CHUNK_ID_STRL = "STRL";
static constexpr auto CHUNK_ID_LIST = "LIST";
static constexpr auto CHUNK_ID_JUNK = "JUNK";
static constexpr auto CHUNK_ID_AVIH = "AVIH";
static constexpr auto CHUNK_ID_STRH = "STRH";
static constexpr auto CHUNK_ID_STRF = "STRF";
static constexpr auto CHUNK_ID_FMT = "FMT ";
static constexpr auto CHUNK_ID_STRN = "STRN";
static constexpr auto CHUNK_ID_STRD = "STRD";
static constexpr auto CHUNK_ID_IDIT = "IDIT";
static constexpr auto CHUNK_ID_INFO = "INFO";
static constexpr auto CHUNK_ID_NCDT = "NCDT";
static constexpr auto CHUNK_ID_ODML = "ODML";
static constexpr auto CHUNK_ID_VPRP = "VPRP";
static constexpr auto CHUNK_ID_IDX1 = "IDX1";
int streamType_{};
}; // Class RiffVideo
/*
@brief Create a new RiffVideo 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 newRiffInstance(BasicIo::UniquePtr io, bool create);
//! Check if the file iIo is a Riff Video.
EXIV2API bool isRiffType(BasicIo& iIo, bool advance);
} // namespace Exiv2
+109
View File
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef RW2IMAGE_HPP_
#define RW2IMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open an existing RW2 image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success or
failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit Rw2Image(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
void readMetadata() override;
/*!
@brief Todo: Write metadata back to the image. This method is not
yet implemented. Calling it will throw an Error(ErrorCode::kerWritingImageFormatUnsupported).
*/
void writeMetadata() override;
/*!
@brief Todo: Not supported yet, requires writeMetadata(). Calling
this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setExifData(const ExifData& exifData) override;
/*!
@brief Todo: Not supported yet, requires writeMetadata(). Calling
this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setIptcData(const IptcData& iptcData) override;
/*!
@brief Not supported. RW2 format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
}; // 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 {
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);
}; // 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.
/*!
@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);
//! Check if the file iIo is a RW2 image.
EXIV2API bool isRw2Type(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef RW2IMAGE_HPP_
+580
View File
@@ -0,0 +1,580 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef EXIV2_INCLUDE_SLICE_HPP
#define EXIV2_INCLUDE_SLICE_HPP
#include <cassert>
#include <cstddef>
#include <iterator>
#include <stdexcept>
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) {
if (begin >= end) {
throw std::out_of_range("Begin must be smaller than end");
}
}
/*!
* Return the number of elements in the slice.
*/
[[nodiscard]] inline size_t size() const noexcept {
// cannot underflow, as we know that begin < end
return end_ - begin_;
}
protected:
/*!
* Throw an exception when index is too large.
*
* @throw std::out_of_range when `index` will access an element
* outside of the slice
*/
inline void rangeCheck(size_t index) const {
if (index >= size()) {
throw std::out_of_range("Index outside of the slice");
}
}
/*!
* lower and upper bounds of the slice with respect to the
* container/array stored in storage_
*/
size_t begin_;
size_t end_;
};
/*!
* @brief This class provides the public-facing const-qualified methods
* of a slice.
*
* The public methods are implemented in a generic fashion using a
* storage_type. This type contains the actual reference to the data to
* which the slice points and provides the following methods:
*
* - (const) value_type& unsafeAt(size_t index) (const)
* Return the value at the given index of the underlying container,
* without promising to perform a range check and without any
* knowledge of the slices' size
*
* - const_iterator/iterator unsafeGetIteratorAt(size_t index) (const)
* Return a (constant) iterator at the given index of the underlying
* container. Again, no range checks are promised.
*
* - Constructor(data_type& data, size_t begin, size_t end)
* Can use `begin` & `end` to perform range checks on `data`, but
* should not store both values. Must not take ownership of `data`!
*
* - Must save data as a public member named `data_`.
*
* - 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 {
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;
/*!
* Default constructor, requires begin to be smaller than end,
* 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) {
}
/*!
* Obtain a constant reference to the element with the specified
* index in the slice.
*
* @throw std::out_of_range when index is out of bounds of the slice
*/
const value_type& at(size_t index) const {
rangeCheck(index);
// we know: begin_ < end <= size() <= SIZE_T_MAX
// and: index < end - begin
// thus: index + begin < end <= SIZE_T_MAX
// => no overflow is possible
return storage_.unsafeAt(begin_ + index);
}
/*!
* Obtain a constant iterator to the first element in the slice.
*/
[[nodiscard]] const_iterator cbegin() const noexcept {
return storage_.unsafeGetIteratorAt(begin_);
}
/*!
* Obtain a constant iterator to the first beyond the slice.
*/
[[nodiscard]] const_iterator cend() const noexcept {
return storage_.unsafeGetIteratorAt(end_);
}
/*!
* Create a constant sub-slice with the given bounds (with respect
* to the current slice).
*
* @tparam slice_type Type of the slice that this function shall
* return. Provide it with the type of the class that derives from
* mutable_slice_base.
*/
template <typename slice_type>
[[nodiscard]] 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
// end == 0 is not a legal value (subtraction will underflow and
// throw an exception)
this->rangeCheck(end - 1);
// additions are safe, begin and end are smaller than size()
const size_t new_begin = begin + this->begin_;
const size_t new_end = this->begin_ + end;
if (new_end > this->end_) {
throw std::out_of_range("Invalid input parameters to slice");
}
return slice_type(storage_.data_, new_begin, new_end);
}
protected:
/*!
* 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> {
using ConstSliceBase<storage_type, data_type>::ConstSliceBase;
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;
/*!
* Obtain a reference to the element with the specified index in the
* slice.
*
* @throw std::out_of_range when index is out of bounds of the slice
*/
value_type& at(size_t index) {
this->rangeCheck(index);
return this->storage_.unsafeAt(this->begin_ + index);
}
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 {
return this->storage_.unsafeGetIteratorAt(this->begin_);
}
/*!
* Obtain an iterator to the first element beyond the slice.
*/
iterator end() noexcept {
return this->storage_.unsafeGetIteratorAt(this->end_);
}
protected:
/*!
* Explicitly convert this instance into a base-class of the
* appropriate constant version of this slice.
*
* This function is required to properly implement the `subSlice()
* const` function for mutable slices. The problem here is, that a
* slice<T> and a slice<const T> actually don't share the same base
* class `ConstSliceBase<storage_type, T>`. Instead `slice<T>`
* inherits from `ConstSliceBase<storage_type, T>` and `slice<const
* T>` inherits from `ConstSliceBase<storage_type, const T>`.
*
* Now, `slice<T>` can call the `subSlice() const` method from its
* base class, but that will return a mutable `slice<T>`! Instead we
* use this function to convert the ``slice<T>` into the parent of
* the appropriate `slice<const T>` and call its `subSlice() const`,
* which returns the correct type.
*/
[[nodiscard]] ConstSliceBase<storage_type, const data_type> to_const_base() const noexcept {
return {this->storage_.data_, this->begin_, this->end_};
}
using base_type = ConstSliceBase<storage_type, data_type>;
/*!
* Create a mutable sub-slice with the given bounds (with respect to
* the current slice).
*
* @tparam slice_type Type of the slice that this function shall
* return. Provide it with the type of the class that derives from
* mutable_slice_base.
*/
template <typename slice_type>
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
// end == 0 is not a legal value (subtraction will underflow and
// throw an exception)
this->rangeCheck(end - 1);
// additions are safe, begin & end are smaller than size()
const size_t new_begin = begin + this->begin_;
const size_t new_end = this->begin_ + end;
if (new_end > this->end_) {
throw std::out_of_range("Invalid input parameters to slice");
}
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 {
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
#if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
using value_type = std::remove_cv_t<typename container::value_type>;
#else
using value_type = typename std::remove_cv<typename container::value_type>::type;
#endif
/*!
* @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) {
if (end > data.size()) {
throw std::out_of_range("Invalid input parameters to slice");
}
}
/*!
* Obtain a constant reference to the element with the given `index`
* in the container.
*
* @throw whatever container::at() throws
*/
[[nodiscard]] const value_type& unsafeAt(size_t index) const {
return data_.at(index);
}
[[nodiscard]] value_type& unsafeAt(size_t index) {
return data_.at(index);
}
/*!
* Obtain an iterator at the position of the element with the given
* index in the container.
*
* @throw whatever container::begin() and std::advance() throw
*/
[[nodiscard]] iterator unsafeGetIteratorAt(size_t index) {
// we are screwed if the container got changed => try to catch it
assert(index <= data_.size());
auto it = data_.begin();
std::advance(it, index);
return it;
}
[[nodiscard]] const_iterator unsafeGetIteratorAt(size_t index) const {
assert(index <= data_.size());
auto it = data_.begin();
std::advance(it, index);
return it;
}
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 {
#if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
using value_type = std::remove_cv_t<std::remove_pointer_t<storage_type>>;
#else
using value_type = typename std::remove_cv<typename std::remove_pointer<storage_type>::type>::type;
#endif
using iterator = value_type*;
using const_iterator = const value_type*;
/*!
* Stores ptr and checks that it is not `NULL`. The slice's bounds
* are ignored, as we do not know the array's length.
*
* @throw std::invalid_argument when ptr is `NULL`
*/
PtrSliceStorage(storage_type ptr, size_t /*begin*/, size_t /*end*/) : data_(ptr) {
if (!ptr) {
throw std::invalid_argument("Null pointer passed to slice constructor");
}
}
/*!
* Obtain a reference to the element with the given `index` in the
* array.
*
* @throw nothing
*/
[[nodiscard]] value_type& unsafeAt(size_t index) noexcept {
return data_[index];
}
[[nodiscard]] const value_type& unsafeAt(size_t index) const noexcept {
return data_[index];
}
/*!
* Obtain an iterator (=pointer) at the position of the element with
* the given index in the container.
*
* @throw nothing
*/
[[nodiscard]] iterator unsafeGetIteratorAt(size_t index) noexcept {
return data_ + index;
}
[[nodiscard]] const_iterator unsafeGetIteratorAt(size_t index) const noexcept {
return data_ + index;
}
storage_type data_;
};
} // namespace Internal
/*!
* @brief Slice (= view) for STL containers.
*
* This is a very simple implementation of slices (i.e. views of sub-arrays)
* for STL containers that support O(1) element access and random access
* iterators (like std::vector, std::array and std::string).
*
* A slice represents the semi-open interval [begin, end) and provides a
* (mutable) view, it does however not own the data! It can be used to
* conveniently pass parts of containers into functions without having to use
* iterators or offsets.
*
* In contrast to C++20's std::span<T> it is impossible to read beyond the
* container's bounds and unchecked access is not-possible (by design).
*
* Example usage:
* ~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
* std::vector<int> vec = {0, 1, 2, 3, 4};
* slice<std::vector<int> > one_two(vec, 1, 3);
* assert(one_two.size() == 2);
* assert(one_two.at(0) == 1 && one_two.at(1) == 2);
* // mutate the contents:
* one_two.at(0) *= 2;
* one_two.at(1) *= 3;
* assert(one_two.at(0) == 2 && one_two.at(1) == 6);
* ~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Slices also offer access via iterators of the same type as the underlying
* container, so that they can be used in a comparable fashion:
* ~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
* std::vector<int> vec = {0, 1, 2, 3, 4};
* slice<std::vector<int>> three_four(vec, 3, 5);
* assert(*three_four.begin() == 3 && *three_four.end() == 4);
* // this prints:
* // 3
* // 4
* for (const auto & elem : three_four) {
* std::cout << elem << std::endl;
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @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> {
using Internal::MutableSliceBase<Internal::ContainerStorage, container>::MutableSliceBase;
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
#if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
using value_type = std::remove_cv_t<typename container::value_type>;
#else
using value_type = typename std::remove_cv<typename container::value_type>::type;
#endif
/*!
* Construct a sub-slice of this slice with the given bounds. The bounds
* are evaluated with respect to the current slice.
*
* @param[in] begin First element in the new slice.
* @param[in] end First element beyond the new slice.
*
* @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);
}
/*!
* Constructs a new constant subSlice. Behaves otherwise exactly like
* the non-const version.
*/
[[nodiscard]] 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> {
using Internal::ConstSliceBase<Internal::ContainerStorage, const container>::ConstSliceBase;
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
#if __cplusplus >= 201402L || _MSVC_LANG >= 201402L
using value_type = std::remove_cv_t<typename container::value_type>;
#else
using value_type = typename std::remove_cv<typename container::value_type>::type;
#endif
Slice subSlice(size_t begin, size_t end) const {
return Internal::ConstSliceBase<Internal::ContainerStorage,
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,
* with the *crucial* exception, that the slice's constructor *cannot* make
* 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*> {
/*!
* Constructor.
*
* @param[in] ptr C-array of which a slice should be constructed. Must
* not be a null pointer.
* @param[in] begin Index of the first element in the slice.
* @param[in] end Index of the first element that is no longer in the
* slice.
*
* 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) {
// 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);
}
};
/*!
* 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) {
// 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);
}
[[nodiscard]] 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) {
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) {
return Slice<T*>(ptr, begin, end);
}
/*!
* @brief Return a new slice spanning the whole container.
*/
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) {
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) {
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) {
return Slice<T*>(ptr, 0, end);
}
} // namespace Exiv2
#endif /* EXIV2_INCLUDE_SLICE_HPP */
+358
View File
@@ -0,0 +1,358 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef TAGS_HPP_
#define TAGS_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "metadatum.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
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* (*)();
// *****************************************************************************
// class definitions
//! Type to specify the IFD to which a metadata belongs
enum class IfdId : uint32_t {
ifdIdNotSet,
ifd0Id,
ifd1Id,
ifd2Id,
ifd3Id,
exifId,
gpsId,
iopId,
mpfId,
subImage1Id,
subImage2Id,
subImage3Id,
subImage4Id,
subImage5Id,
subImage6Id,
subImage7Id,
subImage8Id,
subImage9Id,
subThumb1Id,
panaRawId,
mnId,
canonId,
canonAfCId,
canonAfMiAdjId,
canonAmId,
canonAsId,
canonCbId,
canonCiId,
canonCsId,
canonFilId,
canonFlId,
canonHdrId,
canonLeId,
canonMeId,
canonMoID,
canonMvId,
canonRawBId,
canonSiId,
canonCfId,
canonContrastId,
canonFcd1Id,
canonFcd2Id,
canonFcd3Id,
canonLiOpId,
canonMyColorID,
canonPiId,
canonPaId,
canonTiId,
canonFiId,
canonPrId,
canonPreID,
canonVigCorId,
canonVigCor2Id,
canonWbId,
casioId,
casio2Id,
fujiId,
minoltaId,
minoltaCs5DId,
minoltaCs7DId,
minoltaCsOldId,
minoltaCsNewId,
nikon1Id,
nikon2Id,
nikon3Id,
nikonPvId,
nikonVrId,
nikonPcId,
nikonWtId,
nikonIiId,
nikonAfId,
nikonAf21Id,
nikonAf22Id,
nikonAFTId,
nikonFiId,
nikonMeId,
nikonFl1Id,
nikonFl2Id,
nikonFl3Id,
nikonFl6Id,
nikonFl7Id,
nikonSi1Id,
nikonSi2Id,
nikonSi3Id,
nikonSi4Id,
nikonSi5Id,
nikonSi6Id,
nikonLd1Id,
nikonLd2Id,
nikonLd3Id,
nikonLd4Id,
nikonCb1Id,
nikonCb2Id,
nikonCb2aId,
nikonCb2bId,
nikonCb3Id,
nikonCb4Id,
olympusId,
olympus2Id,
olympusCsId,
olympusEqId,
olympusRdId,
olympusRd2Id,
olympusIpId,
olympusFiId,
olympusFe1Id,
olympusFe2Id,
olympusFe3Id,
olympusFe4Id,
olympusFe5Id,
olympusFe6Id,
olympusFe7Id,
olympusFe8Id,
olympusFe9Id,
olympusRiId,
panasonicId,
pentaxId,
pentaxDngId,
samsung2Id,
samsungPvId,
samsungPwId,
sigmaId,
sony1Id,
sony2Id,
sonyMltId,
sony1CsId,
sony1Cs2Id,
sony2CsId,
sony2Cs2Id,
sony2FpId,
sonyMisc1Id,
sonyMisc2bId,
sonyMisc3cId,
sonySInfo1Id,
sony2010eId,
sony1MltCs7DId,
sony1MltCsOldId,
sony1MltCsNewId,
sony1MltCsA100Id,
tagInfoMvId,
lastId,
ignoreId = lastId
};
inline std::ostream& operator<<(std::ostream& os, IfdId id) {
return os << static_cast<int>(id);
}
//! The details of an Exif group. Groups include IFDs and binary arrays.
struct EXIV2API GroupInfo {
using GroupName = std::string;
bool operator==(IfdId ifdId) const; //!< Comparison operator for IFD id
bool operator==(const GroupName& groupName) const; //!< Comparison operator for group name
IfdId ifdId_; //!< IFD id
const char* ifdName_; //!< IFD name
const char* groupName_; //!< Group name, unique for each group.
TagListFct tagList_; //!< Tag list
};
/*!
@brief Section identifiers to logically group tags. A section consists
of nothing more than a name, based on the Exif standard.
*/
enum class SectionId {
sectionIdNotSet,
imgStruct, // 4.6.4 A
recOffset, // 4.6.4 B
imgCharacter, // 4.6.4 C
otherTags, // 4.6.4 D
exifFormat, // 4.6.3
exifVersion, // 4.6.5 A
imgConfig, // 4.6.5 C
userInfo, // 4.6.5 D
relatedFile, // 4.6.5 E
dateTime, // 4.6.5 F
captureCond, // 4.6.5 G
gpsTags, // 4.6.6
iopTags, // 4.6.7
mpfTags,
makerTags, // MakerNote
dngTags, // DNG Spec
panaRaw,
tiffEp, // TIFF-EP Spec
tiffPm6,
adobeOpi,
lastSectionId
};
//! Tag information
struct EXIV2API TagInfo {
uint16_t tag_; //!< Tag
const char* name_; //!< One word tag label
const char* title_; //!< Tag title
const char* desc_; //!< Short tag description
IfdId ifdId_; //!< Link to the (preferred) IFD
SectionId sectionId_; //!< Section id
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
//! Access to Exif group and tag lists and misc. tag reference methods, implemented as a static class.
class EXIV2API ExifTags {
public:
//! Return read-only list of built-in groups
static const GroupInfo* groupList();
//! Return read-only list of built-in \em groupName tags.
static const TagInfo* tagList(const std::string& groupName);
//! Print a list of all standard Exif tags to output stream
static void taglist(std::ostream& os);
//! Print the list of tags for \em groupName
static void taglist(std::ostream& os, const std::string& groupName);
//! Return the name of the section for an Exif \em key.
static const char* sectionName(const ExifKey& key);
//! Return the default number of components (not bytes!) \em key has. (0=any, -1=count not known)
static uint16_t defaultCount(const ExifKey& key);
//! Return the name of the IFD for the group.
static const char* ifdName(const std::string& groupName);
/*!
@brief Return true if \em groupName is a makernote group.
*/
static bool isMakerGroup(const std::string& groupName);
/*!
@brief Return true if \em groupName is a TIFF or Exif IFD, else false.
This is used to differentiate between standard Exif IFDs
and IFDs associated with the makernote.
*/
static bool isExifGroup(const std::string& groupName);
}; // class ExifTags
/*!
@brief Concrete keys for Exif metadata and access to Exif tag reference data.
*/
class EXIV2API ExifKey : public Key {
public:
//! Shortcut for an %ExifKey auto pointer.
using UniquePtr = std::unique_ptr<ExifKey>;
//! @name Creators
//@{
/*!
@brief Constructor to create an Exif key from a key string.
@param key The key string.
@throw Error if the first part of the key is not '<b>Exif</b>' or
the remaining parts of the key cannot be parsed and
converted to a group name and tag name.
*/
explicit ExifKey(const std::string& key);
/*!
@brief Constructor to create an Exif key from the tag number and
group name.
@param tag The tag value
@param groupName The name of the group, i.e., the second part of
the Exif key.
@throw Error if the key cannot be constructed from the tag number
and group name.
*/
ExifKey(uint16_t tag, const std::string& groupName);
/*!
@brief Constructor to create an Exif key from a TagInfo instance.
@param ti The TagInfo instance
@throw Error if the key cannot be constructed from the tag number
and group name.
*/
explicit ExifKey(const TagInfo& ti);
//! Copy constructor
ExifKey(const ExifKey& rhs);
//! Destructor
~ExifKey() override;
//@}
//! @name Manipulators
//@{
/*!
@brief Assignment operator.
*/
ExifKey& operator=(const ExifKey& rhs);
//! Set the index.
void setIdx(int idx) const;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string key() const override;
[[nodiscard]] const char* familyName() const override;
[[nodiscard]] std::string groupName() const override;
//! Return the IFD id. (Do not use, this is meant for library internal use.)
[[nodiscard]] IfdId ifdId() const;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Return the default type id for this tag.
[[nodiscard]] TypeId defaultTypeId() const; // Todo: should be in the base class
[[nodiscard]] UniquePtr clone() const;
//! Return the index (unique id of this key within the original Exif data, 0 if not set)
[[nodiscard]] int idx() const;
//@}
private:
//! Internal virtual copy constructor.
[[nodiscard]] ExifKey* clone_() const override;
// Pimpl idiom
struct Impl;
std::unique_ptr<Impl> p_;
}; // class ExifKey
// *****************************************************************************
// free functions
//! Output operator for TagInfo
EXIV2API std::ostream& operator<<(std::ostream& os, const TagInfo& ti);
} // namespace Exiv2
#endif // #ifndef TAGS_HPP_
+89
View File
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef TGAIMAGE_HPP_
#define TGAIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a Targa image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit TgaImage(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
/*!
@brief Todo: Write metadata back to the image. This method is not
yet(?) implemented. Calling it will throw an Error(ErrorCode::kerWritingImageFormatUnsupported).
*/
void writeMetadata() override;
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setExifData(const ExifData& exifData) override;
/*!
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setIptcData(const IptcData& iptcData) override;
/*!
@brief Not supported. Calling this function will throw an instance
of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
}; // 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.
/*!
@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);
//! Check if the file iIo is a Targa v2 image.
EXIV2API bool isTgaType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef TGAIMAGE_HPP_
+162
View File
@@ -0,0 +1,162 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef TIFFIMAGE_HPP_
#define TIFFIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// 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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor that can either open an existing TIFF image or create
a new image from scratch. If a new image is to be created, any
existing data is overwritten. Since the constructor can not return
a result, callers should check the good() method after object
construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
TiffImage(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Print out the structure of image file.
@throw Error if reading of the file fails or the image data is
not valid (does not look like data of the specific image type).
@warning This function is not thread safe and intended for exiv2 -p{S|R} as a file debugging aid
*/
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
/*!
@brief Not supported. TIFF format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
std::string mimeType() const override;
uint32_t pixelWidth() const override;
uint32_t pixelHeight() const override;
//@}
private:
//! @name Accessors
//@{
//! Return the group name of the group with the primary image.
std::string primaryGroup() const;
//@}
// DATA
mutable std::string primaryGroup_; //!< The primary group
mutable std::string mimeType_; //!< The MIME type
mutable uint32_t pixelWidthPrimary_{0}; //!< Width of the primary image in pixels
mutable uint32_t pixelHeightPrimary_{0}; //!< Height of the primary image in pixels
}; // 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 {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
with data in TIFF format to the provided metadata containers.
@param exifData Exif metadata container.
@param iptcData IPTC metadata container.
@param xmpData XMP metadata container.
@param pData Pointer to the data buffer. Must point to data in TIFF
format; no checks are performed.
@param size Length of the data buffer.
@return Byte order in which the data is encoded.
*/
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.
The original binary image in the memory block \em pData, \em size is
parsed and updated in-place if possible ("non-intrusive" writing).
If that is not possible (e.g., if new tags were added), the entire
TIFF structure is re-written to the \em io instance ("intrusive" writing).<br>
The return value indicates which write method was used. If it is
\c wmNonIntrusive, the original memory \em pData, \em size contains
the result and nothing is written to \em io. If the return value is
\c wmIntrusive, a new TIFF structure was created and written to
\em io. The memory block \em pData, \em size may be partly updated
in this case and should not be used anymore.
@note If there is no metadata to encode, i.e., all metadata
containers are empty, then the return value is \c wmIntrusive
and nothing is written to \em io, i.e., no TIFF header is written.
@param io IO instance to write the binary image to in case of
"intrusive" writing. Nothing is written to \em io in
the case of "non-intrusive" writing.
@param pData Pointer to the binary image data buffer. Must
point to data in TIFF format; no checks are
performed. Will be modified if "non-intrusive"
writing is possible.
@param size Length of the data buffer.
@param byteOrder Byte order to use.
@param exifData Exif metadata container.
@param iptcData IPTC metadata container.
@param xmpData XMP metadata container.
@return Write method used.
*/
static WriteMethod encode(BasicIo& io, const byte* pData, size_t size, ByteOrder byteOrder, ExifData& exifData,
IptcData& iptcData, XmpData& xmpData);
}; // 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.
/*!
@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);
//! Check if the file iIo is a TIFF image.
EXIV2API bool isTiffType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef TIFFIMAGE_HPP_
+497
View File
@@ -0,0 +1,497 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef TYPES_HPP_
#define TYPES_HPP_
#include "exiv2lib_export.h"
// included header files
#include "config.h"
#include "slice.hpp"
// standard includes
#include <algorithm>
#include <cstdint>
#include <limits>
#include <sstream>
#include <vector>
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// type definitions
//! 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>;
//! 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 {
wmIntrusive,
wmNonIntrusive,
};
//! 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 {
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 {
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.
unsignedLong = 4, //!< Exif LONG type, 32-bit (4-byte) unsigned integer.
unsignedRational = 5, //!< Exif RATIONAL type, two LONGs: numerator and denominator of a fraction.
signedByte = 6, //!< Exif SBYTE type, an 8-bit signed (twos-complement) integer.
undefined = 7, //!< Exif UNDEFINED type, an 8-bit byte that may contain anything.
signedShort = 8, //!< Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
signedLong = 9, //!< Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
signedRational = 10, //!< Exif SRATIONAL type, two SLONGs: numerator and denominator of a fraction.
tiffFloat = 11, //!< TIFF FLOAT type, single precision (4-byte) IEEE format.
tiffDouble = 12, //!< TIFF DOUBLE type, double precision (8-byte) IEEE format.
tiffIfd = 13, //!< TIFF IFD type, 32-bit (4-byte) unsigned integer.
unsignedLongLong = 16, //!< Exif LONG LONG type, 64-bit (8-byte) unsigned integer.
signedLongLong = 17, //!< Exif LONG LONG type, 64-bit (8-byte) signed integer.
tiffIfd8 = 18, //!< TIFF IFD type, 64-bit (8-byte) unsigned integer.
string = 0x10000, //!< IPTC string type.
date = 0x10001, //!< IPTC date type.
time = 0x10002, //!< IPTC time type.
comment = 0x10003, //!< %Exiv2 type for the Exif user comment.
directory = 0x10004, //!< %Exiv2 type for a CIFF directory.
xmpText = 0x10005, //!< XMP text type.
xmpAlt = 0x10006, //!< XMP alternative type.
xmpBag = 0x10007, //!< XMP bag type.
xmpSeq = 0x10008, //!< XMP sequence type.
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>;
// *****************************************************************************
// class definitions
//! Type information lookup functions. Implemented as a static class.
class EXIV2API TypeInfo {
public:
//! Return the name of the type, 0 if unknown.
static const char* typeName(TypeId typeId);
//! Return the type id for a type name
static TypeId typeId(const std::string& typeName);
//! Return the size in bytes of one element of this type
static 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 {
//! @name Creators
//@{
//! Default constructor
DataBuf() = default;
//! Constructor with an initial buffer size
explicit DataBuf(size_t size);
//! Constructor, copies an existing buffer
DataBuf(const byte* pData, size_t size);
//@}
//! @name Manipulators
//@{
/*!
@brief Allocate a data buffer of at least the given size. Note that if
the requested \em size is less than the current buffer size, no
new memory is allocated and the buffer size doesn't change.
*/
void alloc(size_t size);
/*!
@brief Resize the buffer. Existing data is preserved (like std::realloc()).
*/
void resize(size_t size);
//! Reset value
void reset();
//@}
using iterator = std::vector<byte>::iterator;
using const_iterator = std::vector<byte>::const_iterator;
iterator begin() noexcept {
return pData_.begin();
}
[[nodiscard]] const_iterator cbegin() const noexcept {
return pData_.cbegin();
}
iterator end() noexcept {
return pData_.end();
}
[[nodiscard]] const_iterator cend() const noexcept {
return pData_.end();
}
[[nodiscard]] size_t size() const {
return pData_.size();
}
[[nodiscard]] uint8_t read_uint8(size_t offset) const;
void write_uint8(size_t offset, uint8_t x);
[[nodiscard]] uint16_t read_uint16(size_t offset, ByteOrder byteOrder) const;
void write_uint16(size_t offset, uint16_t x, ByteOrder byteOrder);
[[nodiscard]] uint32_t read_uint32(size_t offset, ByteOrder byteOrder) const;
void write_uint32(size_t offset, uint32_t x, ByteOrder byteOrder);
[[nodiscard]] uint64_t read_uint64(size_t offset, ByteOrder byteOrder) const;
void write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder);
//! Equivalent to: memcmp(&pData_[offset], buf, bufsize)
int cmpBytes(size_t offset, const void* buf, size_t bufsize) const;
//! Returns a data pointer.
[[nodiscard]] byte* data(size_t offset = 0);
//! Returns a (read-only) data pointer.
[[nodiscard]] const byte* c_data(size_t offset = 0) const;
//! Returns a (read-only) C-style string pointer.
[[nodiscard]] const char* c_str(size_t offset = 0) const;
[[nodiscard]] bool empty() const {
return pData_.empty();
}
private:
std::vector<byte> pData_;
};
/*!
* @brief Create a new Slice from a DataBuf given the bounds.
*
* @param[in] buf The DataBuf from which' data the Slice will be
* constructed
* @param[in] begin Beginning bound of the new Slice. Must be smaller
* than `end` and both must not be larger than LONG_MAX.
* @param[in] end End bound of the new Slice. Must be smaller
* than `end` and both must not be larger than LONG_MAX.
*
* @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);
//! 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
//! 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);
/*!
@brief Convert an unsigned short to data, write the data to the buffer,
return number of bytes written.
*/
EXIV2API size_t 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 size_t 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 size_t 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 size_t 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 size_t 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 size_t 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 size_t 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 size_t 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 size_t 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);
/*!
@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 = "");
/*!
@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, 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);
/*!
@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
handles \em float, \em Rational and boolean
(see also: stringTo(const std::string& s, bool& ok)).
@param s String to parse
@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);
/*!
@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
handles \em float, \em Rational and boolean
(see also: stringTo(const std::string& s, bool& ok)).
@param s String to parse
@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);
/*!
@brief Return a \em float set to the value represented by \em s.
Besides strings that represent \em float values, the function also
handles \em long, \em Rational and boolean
(see also: stringTo(const std::string& s, bool& ok)).
@param s String to parse
@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);
/*!
@brief Return a \em Rational set to the value represented by \em s.
Besides strings that represent \em Rational values, the function also
handles \em long, \em float and boolean
(see also: stringTo(const std::string& s, bool& ok)).
Uses floatToRationalCast(float f) if the string can be parsed into a
\em float.
@param s String to parse
@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);
/*!
@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);
// *****************************************************************************
// 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.
Requires a %Key structure (ideally in the array) and a comparison operator
to compare a key with an array element. The size of the array is
determined automagically. Thanks to Stephan Broennimann for this nifty
implementation.
@code
struct Bar {
int i;
int k;
const char* data;
struct Key;
bool operator==(const Bar::Key& rhs) const;
};
struct Bar::Key {
Key(int a, int b) : i(a), k(b) {}
int i;
int k;
};
bool Bar::operator==(const Bar::Key& key) const // definition
{
return i == key.i && k == key.k;
}
const Bar bars[] = {
{ 1, 1, "bar data 1" },
{ 1, 2, "bar data 2" },
{ 1, 3, "bar data 3" }
};
int main ( void ) {
const Bar* bar = find(bars, Bar::Key(1, 3));
if (bar) std::cout << bar->data << "\n";
else std::cout << "Key not found.\n";
return 0;
}
@endcode
*/
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) {
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
the input operator for \c T for this function to succeed.
@param s String to convert
@param ok Output variable indicating the success of the operation.
@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) {
std::istringstream is(s);
T tmp = T();
ok = static_cast<bool>(is >> tmp);
std::string rest;
is >> std::skipws >> rest;
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);
} // namespace Exiv2
#endif // #ifndef TYPES_HPP_
File diff suppressed because it is too large Load Diff
+107
View File
@@ -0,0 +1,107 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef VERSION_HPP_
#define VERSION_HPP_
#include "exiv2lib_export.h"
#include "exv_conf.h"
// *****************************************************************************
// included header files
// + standard includes
#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))
/*!
@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)
/*!
@brief Macro to test the version the %Exiv2 library at compile-time.
Return true if it is the same as or newer than the passed-in version.
Versions prior to v0.27 are denoted using a triplet of integers: \em MAJOR.MINOR.PATCH .
From v0.27 forward, the fourth digit is a "tweak" and designates the pre-release number of the version.
@code
// Application code is expected to include <exiv2/exiv2.hpp>
// Don't include the <exiv2/version.hpp> file directly
// Early Exiv2 versions didn't have version.hpp and the macros.
#include <exiv2/exiv2.hpp>
// Make sure an EXIV2_TEST_VERSION macro exists:
#ifdef EXIV2_VERSION
# ifndef EXIV2_TEST_VERSION
# define EXIV2_TEST_VERSION(major,minor,patch) \
( EXIV2_VERSION >= EXIV2_MAKE_VERSION(major,minor,patch) )
# endif
#else
# define EXIV2_TEST_VERSION(major,minor,patch) (false)
#endif
std::cout << "Compiled with Exiv2 version " << EXV_PACKAGE_VERSION << "\n"
<< "Runtime Exiv2 version is " << Exiv2::version() << "\n";
// 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
std::cout << "Compile-time Exiv2 version doesn't have Exiv2::testVersion()\n";
#endif
@endcode
*/
#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 a uint32_t.
*/
EXIV2API uint32_t versionNumber();
/*!
@brief Return the version string Example: "0.25.0" (major.minor.patch)
*/
EXIV2API std::string versionString();
/*!
@brief Return the version of %Exiv2 as hex string of fixed length 6.
*/
EXIV2API std::string versionNumberHexString();
/*!
@brief Return the version of %Exiv2 as "C" string eg "0.27.0.2".
*/
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(uint32_t major, uint32_t minor, uint32_t 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);
} // namespace Exiv2
#endif // VERSION_HPP_
+104
View File
@@ -0,0 +1,104 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef WEBPIMAGE_HPP
#define WEBPIMAGE_HPP
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access WEBP video files.
*/
class EXIV2API WebPImage : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a WebP video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit WebPImage(BasicIo::UniquePtr io);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
//@}
/*!
@brief Not supported. Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
void setIptcData(const IptcData& /*iptcData*/) override;
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
private:
void doWriteMetadata(BasicIo& outIo);
//! Finds the offset of header in data. Returns std::string::npos if the header isn't found.
static size_t getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size);
static bool equalsWebPTag(const Exiv2::DataBuf& buf, const char* str);
void debugPrintHex(byte* data, size_t size);
void decodeChunks(uint32_t filesize);
void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_alpha, bool has_icc, uint32_t width,
uint32_t height) const;
/* Misc. */
static constexpr byte WEBP_PAD_ODD = 0;
static constexpr int WEBP_TAG_SIZE = 0x4;
/* VP8X feature flags */
static constexpr int WEBP_VP8X_ICC_BIT = 0x20;
static constexpr int WEBP_VP8X_ALPHA_BIT = 0x10;
static constexpr int WEBP_VP8X_EXIF_BIT = 0x8;
static constexpr int WEBP_VP8X_XMP_BIT = 0x4;
/* Chunk header names */
static constexpr auto WEBP_CHUNK_HEADER_VP8X = "VP8X";
static constexpr auto WEBP_CHUNK_HEADER_VP8L = "VP8L";
static constexpr auto WEBP_CHUNK_HEADER_VP8 = "VP8 ";
static constexpr auto WEBP_CHUNK_HEADER_ANMF = "ANMF";
static constexpr auto WEBP_CHUNK_HEADER_ANIM = "ANIM";
static constexpr auto WEBP_CHUNK_HEADER_ICCP = "ICCP";
static constexpr auto WEBP_CHUNK_HEADER_EXIF = "EXIF";
static constexpr auto WEBP_CHUNK_HEADER_XMP = "XMP ";
}; // 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.
/*!
@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);
//! Check if the file iIo is a WebP Video.
EXIV2API bool isWebPType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // WEBPIMAGE_HPP
+413
View File
@@ -0,0 +1,413 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef XMP_HPP_
#define XMP_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "metadatum.hpp"
#include "properties.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class declarations
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 {
public:
//! @name Creators
//@{
/*!
@brief Constructor for new tags created by an application. The
%Xmpdatum is created from a key / value pair. %Xmpdatum
copies (clones) the value if one is provided. Alternatively, a
program can create an 'empty' %Xmpdatum with only a key and
set the value using setValue().
@param key The key of the %Xmpdatum.
@param pValue Pointer to a %Xmpdatum value.
@throw Error if the key cannot be parsed and converted
to a known schema namespace prefix and property name.
*/
explicit Xmpdatum(const XmpKey& key, const Value* pValue = nullptr);
//! Copy constructor
Xmpdatum(const Xmpdatum& rhs);
//! Destructor
~Xmpdatum() override;
//@}
//! @name Manipulators
//@{
//! Assignment operator
Xmpdatum& operator=(const Xmpdatum& rhs);
/*!
@brief Assign std::string \em value to the %Xmpdatum.
Calls setValue(const std::string&).
*/
Xmpdatum& operator=(const std::string& value);
/*!
@brief Assign a \em value of any type with an output operator
to the %Xmpdatum. Calls operator=(const std::string&).
*/
template <typename T>
Xmpdatum& operator=(const T& value);
/*!
@brief Assign Value \em value to the %Xmpdatum.
Calls setValue(const Value*).
*/
Xmpdatum& operator=(const Value& value);
void setValue(const Value* pValue) override;
/*!
@brief Set the value to the string \em value. Uses Value::read(const
std::string&). If the %Xmpdatum does not have a Value yet,
then a %Value of the correct type for this %Xmpdatum is
created. If the key is unknown, a XmpTextValue is used as
default. Return 0 if the value was read successfully.
*/
int setValue(const std::string& value) override;
//@}
//! @name Accessors
//@{
//! Not implemented. Calling this method will raise an exception.
size_t copy(byte* buf, ByteOrder byteOrder) const override;
std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const override;
/*!
@brief Return the key of the Xmpdatum. The key is of the form
'<b>Xmp</b>.prefix.property'. Note however that the
key is not necessarily unique, i.e., an XmpData object may
contain multiple metadata with the same key.
*/
[[nodiscard]] std::string key() const override;
[[nodiscard]] const char* familyName() const override;
//! Return the (preferred) schema namespace prefix.
[[nodiscard]] std::string groupName() const override;
//! Return the property name.
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Properties don't have a tag number. Return 0.
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] TypeId typeId() const override;
[[nodiscard]] const char* typeName() const override;
// Todo: Remove this method from the baseclass
//! The Exif typeSize doesn't make sense here. Return 0.
[[nodiscard]] size_t typeSize() const override;
[[nodiscard]] size_t count() const override;
[[nodiscard]] size_t size() const override;
[[nodiscard]] std::string toString() const override;
[[nodiscard]] std::string toString(size_t n) const override;
[[nodiscard]] int64_t toInt64(size_t n = 0) const override;
[[nodiscard]] float toFloat(size_t n = 0) const override;
[[nodiscard]] Rational toRational(size_t n = 0) const override;
[[nodiscard]] Value::UniquePtr getValue() const override;
[[nodiscard]] const Value& value() const override;
//@}
private:
// Pimpl idiom
struct Impl;
std::unique_ptr<Impl> p_;
}; // class 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.
Provide high-level access to the XMP data of an image:
- read XMP information from an XML block
- access metadata through keys and standard C++ iterators
- add, modify and delete metadata
- serialize XMP data to an XML block
*/
class EXIV2API XmpData {
public:
//! Default constructor
XmpData() = default;
//! XmpMetadata iterator type
using iterator = XmpMetadata::iterator;
//! XmpMetadata const iterator type
using const_iterator = XmpMetadata::const_iterator;
//! @name Manipulators
//@{
/*!
@brief Returns a reference to the %Xmpdatum that is associated with a
particular \em key. If %XmpData does not already contain such
an %Xmpdatum, operator[] adds object \em Xmpdatum(key).
@note Since operator[] might insert a new element, it can't be a const
member function.
*/
Xmpdatum& operator[](const std::string& key);
/*!
@brief Add an %Xmpdatum from the supplied key and value pair. This
method copies (clones) the value.
@return 0 if successful.
*/
int add(const XmpKey& key, const Value* value);
/*!
@brief Add a copy of the Xmpdatum to the XMP metadata.
@return 0 if successful.
*/
int add(const Xmpdatum& xmpdatum);
/*
@brief Delete the Xmpdatum at iterator position pos, return the
position of the next Xmpdatum.
@note Iterators into the metadata, including pos, are potentially
invalidated by this call.
@brief Delete the Xmpdatum at iterator position pos and update pos
*/
iterator erase(XmpData::iterator pos);
/*!
@brief Delete the Xmpdatum at iterator position pos and update pos
erases all following keys from the same family
See: https://github.com/Exiv2/exiv2/issues/521
*/
void eraseFamily(XmpData::iterator& pos);
//! Delete all Xmpdatum instances resulting in an empty container.
void clear();
//! Sort metadata by key
void sortByKey();
//! Begin of the metadata
iterator begin();
//! End of the metadata
iterator end();
/*!
@brief Find the first Xmpdatum with the given key, return an iterator
to it.
*/
iterator findKey(const XmpKey& key);
//@}
//! @name Accessors
//@{
//! Begin of the metadata
[[nodiscard]] const_iterator begin() const;
//! End of the metadata
[[nodiscard]] const_iterator end() const;
/*!
@brief Find the first Xmpdatum with the given key, return a const
iterator to it.
*/
[[nodiscard]] const_iterator findKey(const XmpKey& key) const;
//! Return true if there is no XMP metadata
[[nodiscard]] bool empty() const;
//! Get the number of metadata entries
[[nodiscard]] long count() const;
//! are we to use the packet?
[[nodiscard]] bool usePacket() const {
return usePacket_;
}
//! set usePacket_
bool usePacket(bool b) {
bool r = usePacket_;
usePacket_ = b;
return r;
}
//! setPacket
void setPacket(std::string xmpPacket) {
xmpPacket_ = std::move(xmpPacket);
usePacket(false);
}
// ! getPacket
[[nodiscard]] const std::string& xmpPacket() const {
return xmpPacket_;
}
//@}
private:
// DATA
XmpMetadata xmpMetadata_;
std::string xmpPacket_;
bool usePacket_{};
}; // 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 {
public:
//! Options to control the format of the serialized XMP packet.
enum XmpFormatFlags {
omitPacketWrapper = 0x0010UL, //!< Omit the XML packet wrapper.
readOnlyPacket = 0x0020UL, //!< Default is a writeable packet.
useCompactFormat = 0x0040UL, //!< Use a compact form of RDF.
includeThumbnailPad = 0x0100UL, //!< Include a padding allowance for a thumbnail image.
exactPacketLength = 0x0200UL, //!< The padding parameter is the overall packet length.
writeAliasComments = 0x0400UL, //!< Show aliases as XML comments.
omitAllFormatting = 0x0800UL //!< Omit all formatting whitespace.
};
/*!
@brief Decode XMP metadata from an XMP packet \em xmpPacket into
\em xmpData. The format of the XMP packet must follow the
XMP specification. This method clears any previous contents
of \em xmpData.
@param xmpData Container for the decoded XMP properties
@param xmpPacket The raw XMP packet to decode
@return 0 if successful;<BR>
1 if XMP support has not been compiled-in;<BR>
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);
/*!
@brief Encode (serialize) XMP metadata from \em xmpData into a
string xmpPacket. The XMP packet returned in the string
follows the XMP specification. This method only modifies
\em xmpPacket if the operations succeeds (return code 0).
@param xmpPacket Reference to a string to hold the encoded XMP
packet.
@param xmpData XMP properties to encode.
@param formatFlags Flags that control the format of the XMP packet,
see enum XmpFormatFlags.
@param padding Padding length.
@return 0 if successful;<BR>
1 if XMP support has not been compiled-in;<BR>
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);
/*!
@brief Lock/unlock function type
A function of this type can be passed to initialize() to
make subsequent registration of XMP namespaces thread-safe.
See the initialize() function for more information.
@param pLockData Pointer to the pLockData passed to initialize()
@param lockUnlock Indicates whether to lock (true) or unlock (false)
*/
using XmpLockFct = void (*)(void* pLockData, bool lockUnlock);
/*!
@brief Initialize the XMP Toolkit.
Calling this method is usually not needed, as encode() and
decode() will initialize the XMP Toolkit if necessary.
The function takes optional pointers to a callback function
\em xmpLockFct and related data \em pLockData that the parser
uses when XMP namespaces are subsequently registered.
The initialize() function itself still is not thread-safe and
needs to be called in a thread-safe manner (e.g., on program
startup), but if used with suitable additional locking
parameters, any subsequent registration of namespaces will be
thread-safe.
Example usage on Windows using a critical section:
@code
void main()
{
struct XmpLock
{
CRITICAL_SECTION cs;
XmpLock() { InitializeCriticalSection(&cs); }
~XmpLock() { DeleteCriticalSection(&cs); }
static void LockUnlock(void* pData, bool fLock)
{
XmpLock* pThis = reinterpret_cast<XmpLock*>(pData);
if (pThis)
{
(fLock) ? EnterCriticalSection(&pThis->cs)
: LeaveCriticalSection(&pThis->cs);
}
}
} xmpLock;
// Pass the locking mechanism to the XMP parser on initialization.
// Note however that this call itself is still not thread-safe.
Exiv2::XmpParser::initialize(XmpLock::LockUnlock, &xmpLock);
// Program continues here, subsequent registrations of XMP
// namespaces are serialized using xmpLock.
}
@endcode
@return True if the initialization was successful, else false.
*/
static bool initialize(XmpParser::XmpLockFct xmpLockFct = nullptr, void* pLockData = nullptr);
/*!
@brief Terminate the XMP Toolkit and unregister custom namespaces.
Call this method when the XmpParser is no longer needed to
allow the XMP Toolkit to cleanly shutdown.
*/
static void terminate();
private:
/*!
@brief Register a namespace with the XMP Toolkit.
*/
static void registerNs(const std::string& ns, const std::string& prefix);
/*!
@brief Delete a namespace from the XMP Toolkit.
XmpProperties::unregisterNs calls this to synchronize namespaces.
*/
static void unregisterNs(const std::string& ns);
/*!
@brief Get namespaces registered with XMPsdk
*/
static void registeredNamespaces(Exiv2::Dictionary&);
// DATA
static bool initialized_; //! Indicates if the XMP Toolkit has been initialized
static XmpLockFct xmpLockFct_;
static void* pLockData_;
friend class XmpProperties; // permit XmpProperties -> registerNs() and registeredNamespaces()
}; // class XmpParser
// *****************************************************************************
// free functions, template and inline definitions
template <typename T>
Xmpdatum& Xmpdatum::operator=(const T& value) {
#ifdef __cpp_if_constexpr
if constexpr (std::is_same_v<T, bool>) {
#else
if (std::is_same<T, bool>::value) {
#endif
setValue(Exiv2::toString(value ? "True" : "False"));
return *this;
} else {
setValue(Exiv2::toString(value));
return *this;
}
}
} // namespace Exiv2
#endif // #ifndef XMP_HPP_
+77
View File
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef XMPSIDECAR_HPP_
#define XMPSIDECAR_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
/*!
@brief Class to access XMP sidecar files. They contain only XMP metadata.
*/
class EXIV2API XmpSidecar : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for an XMP sidecar file. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new image should be created (true).
*/
XmpSidecar(BasicIo::UniquePtr io, bool create);
//@}
//! @name Manipulators
//@{
void readMetadata() override;
void writeMetadata() override;
/*!
@brief Not supported. XMP sidecar files do not contain a comment.
Calling this function will throw an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(const std::string&) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
//@}
Exiv2::Dictionary dates_;
}; // 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.
/*!
@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);
//! Check if the file iIo is an XMP sidecar file.
EXIV2API bool isXmpType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef XMPSIDECAR_HPP_
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "exiv2lib" for configuration "Release"
set_property(TARGET exiv2lib APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(exiv2lib PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libexiv2.a"
)
list(APPEND _cmake_import_check_targets exiv2lib )
list(APPEND _cmake_import_check_files_for_exiv2lib "${_IMPORT_PREFIX}/lib/libexiv2.a" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
+107
View File
@@ -0,0 +1,107 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.0 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...3.24)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS exiv2lib)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target exiv2lib
add_library(exiv2lib STATIC IMPORTED)
set_target_properties(exiv2lib PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:ZLIB::ZLIB>;\$<LINK_ONLY:Iconv::Iconv>"
)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.")
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/exiv2Config-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,83 @@
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is equal to the requested version.
# The tweak version component is ignored.
# The variable CVF_VERSION must be set before calling configure_file().
if (PACKAGE_FIND_VERSION_RANGE)
message(AUTHOR_WARNING
"`find_package()` specify a version range but the version strategy "
"(ExactVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible "
"with this request. Only the lower endpoint of the range will be used.")
endif()
set(PACKAGE_VERSION "1.00.0.9")
if("1.00.0.9" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")
set(CVF_VERSION_PATCH "${CMAKE_MATCH_3}")
if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
endif()
if(NOT CVF_VERSION_MINOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MINOR "${CVF_VERSION_MINOR}")
endif()
if(NOT CVF_VERSION_PATCH VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_PATCH "${CVF_VERSION_PATCH}")
endif()
set(CVF_VERSION_NO_TWEAK "${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR}.${CVF_VERSION_PATCH}")
else()
set(CVF_VERSION_NO_TWEAK "1.00.0.9")
endif()
if(PACKAGE_FIND_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
set(REQUESTED_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(REQUESTED_VERSION_MINOR "${CMAKE_MATCH_2}")
set(REQUESTED_VERSION_PATCH "${CMAKE_MATCH_3}")
if(NOT REQUESTED_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MAJOR "${REQUESTED_VERSION_MAJOR}")
endif()
if(NOT REQUESTED_VERSION_MINOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MINOR "${REQUESTED_VERSION_MINOR}")
endif()
if(NOT REQUESTED_VERSION_PATCH VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_PATCH "${REQUESTED_VERSION_PATCH}")
endif()
set(REQUESTED_VERSION_NO_TWEAK
"${REQUESTED_VERSION_MAJOR}.${REQUESTED_VERSION_MINOR}.${REQUESTED_VERSION_PATCH}")
else()
set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
endif()
if(REQUESTED_VERSION_NO_TWEAK STREQUAL CVF_VERSION_NO_TWEAK)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if(CMAKE_SIZEOF_VOID_P STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
prefix=/Users/yangzuhao/Data/code/flyaha/third_party/exiv2/output
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: exiv2
Description: Exif/IPTC/Xmp C++ metadata library and tools plus ICC Profiles, Previews and more.
Version: 1.00.0.9
URL: https://exiv2.org
Requires.private: zlib
Libs: -L${libdir} -lexiv2
Libs.private: -liconv
Cflags: -I${includedir}
+6
View File
@@ -0,0 +1,6 @@
The Exiv2 manpage is available online.
.sp 1
.nf
Latest release: https://www.exiv2.org/manpage.html
Github 'main': https://github.com/Exiv2/exiv2/blob/main/exiv2.md
.fi