build mac-arm
This commit is contained in:
Executable
BIN
Binary file not shown.
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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 */
|
||||
@@ -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_ */
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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 */
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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)
|
||||
@@ -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.
@@ -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}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user