Merge pull request #2197 from Exiv2/mainRefactoringFormats

Refactoring in JpegImage and Photoshop classes
This commit is contained in:
Luis Díaz Más
2022-04-10 13:23:33 +02:00
committed by GitHub
17 changed files with 342 additions and 325 deletions
+1
View File
@@ -29,6 +29,7 @@
#include "exiv2/mrwimage.hpp"
#include "exiv2/orfimage.hpp"
#include "exiv2/pgfimage.hpp"
#include "exiv2/photoshop.hpp"
#ifdef EXV_HAVE_LIBZ
#include "exiv2/pngimage.hpp"
+3 -105
View File
@@ -3,11 +3,8 @@
#ifndef JPGIMAGE_HPP_
#define JPGIMAGE_HPP_
// *****************************************************************************
#include "exiv2lib_export.h"
#include <array>
// included header files
#include "error.hpp"
#include "image.hpp"
@@ -18,59 +15,6 @@ namespace Exiv2 {
// *****************************************************************************
// class definitions
/// @brief Helper class, has methods to deal with %Photoshop "Information Resource Blocks" (IRBs).
struct EXIV2API Photoshop {
// Todo: Public for now
static constexpr std::array 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* const sizeHdr, uint32_t* const sizeData);
/// @brief Forwards to locateIrb() with \em psTag = \em iptc_
static int locateIptcIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t* const sizeHdr,
uint32_t* const sizeData);
/// @brief Forwards to locatePreviewIrb() with \em psTag = \em preview_
static int locatePreviewIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t* const sizeHdr,
uint32_t* const sizeData);
/// @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);
};
/*!
@brief Abstract helper base class to access JPEG images.
*/
@@ -151,44 +95,6 @@ class EXIV2API JpegBase : public Image {
virtual int writeHeader(BasicIo& oIo) const = 0;
//@}
// Constant Data
static constexpr byte dht_ = 0xc4; //!< JPEG DHT marker
static constexpr byte dqt_ = 0xdb; //!< JPEG DQT marker
static constexpr byte dri_ = 0xdd; //!< JPEG DRI marker
static constexpr byte sos_ = 0xda; //!< JPEG SOS marker
static constexpr byte eoi_ = 0xd9; //!< JPEG EOI marker
static constexpr byte app0_ = 0xe0; //!< JPEG APP0 marker
static constexpr byte app1_ = 0xe1; //!< JPEG APP1 marker
static constexpr byte app2_ = 0xe2; //!< JPEG APP2 marker
static constexpr byte app13_ = 0xed; //!< JPEG APP13 marker
static constexpr byte com_ = 0xfe; //!< JPEG Comment marker
// Start of Frame markers, nondifferential Huffman-coding frames
static constexpr byte sof0_ = 0xc0; //!< JPEG Start-Of-Frame marker
static constexpr byte sof1_ = 0xc1; //!< JPEG Start-Of-Frame marker
static constexpr byte sof2_ = 0xc2; //!< JPEG Start-Of-Frame marker
static constexpr byte sof3_ = 0xc3; //!< JPEG Start-Of-Frame marker
// Start of Frame markers, differential Huffman-coding frames
static constexpr byte sof5_ = 0xc5; //!< JPEG Start-Of-Frame marker
static constexpr byte sof6_ = 0xc6; //!< JPEG Start-Of-Frame marker
static constexpr byte sof7_ = 0xc7; //!< JPEG Start-Of-Frame marker
// Start of Frame markers, nondifferential arithmetic-coding frames
static constexpr byte sof9_ = 0xc9; //!< JPEG Start-Of-Frame marker
static constexpr byte sof10_ = 0xca; //!< JPEG Start-Of-Frame marker
static constexpr byte sof11_ = 0xcb; //!< JPEG Start-Of-Frame marker
// Start of Frame markers, differential arithmetic-coding frames
static constexpr byte sof13_ = 0xcd; //!< JPEG Start-Of-Frame marker
static constexpr byte sof14_ = 0xce; //!< JPEG Start-Of-Frame marker
static constexpr byte sof15_ = 0xcf; //!< JPEG Start-Of-Frame marker
static constexpr auto exifId_ = "Exif\0\0"; //!< Exif identifier
static constexpr auto jfifId_ = "JFIF\0"; //!< JFIF identifier
static constexpr auto xmpId_ = "http://ns.adobe.com/xap/1.0/\0"; //!< XMP packet identifier
static constexpr auto iccId_ = "ICC_PROFILE\0"; //!< ICC profile identifier
private:
//! @name Manipulators
//@{
@@ -225,14 +131,7 @@ class EXIV2API JpegBase : public Image {
//@}
DataBuf readNextSegment(byte marker);
/*!
@brief Is the marker followed by a non-zero payload?
@param marker The marker at the start of a segment
@return true if the marker is followed by a non-zero payload
*/
static bool markerHasLength(byte marker);
}; // class JpegBase
};
/*!
@brief Class to access JPEG images
@@ -292,9 +191,8 @@ class EXIV2API JpegImage : public JpegBase {
private:
// Constant data
static constexpr byte soi_ = 0xd8; // SOI marker
static const byte blank_[]; // Minimal Jpeg image
}; // class JpegImage
static const byte blank_[]; ///< Minimal Jpeg image
};
//! Helper class to access %Exiv2 files
class EXIV2API ExvImage : public JpegBase {
+70
View File
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef PHOTOSHOP_INT_HPP
#define PHOTOSHOP_INT_HPP
#include "exiv2lib_export.h"
#include "types.hpp"
#include <array>
namespace Exiv2 {
// Forward declarations
class IptcData;
/// @brief Helper class, has methods to deal with %Photoshop "Information Resource Blocks" (IRBs).
struct EXIV2API Photoshop {
// Todo: Public for now
static constexpr std::array 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* const sizeHdr, uint32_t* const sizeData);
/// @brief Forwards to locateIrb() with \em psTag = \em iptc_
static int locateIptcIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t* const sizeHdr,
uint32_t* const sizeData);
/// @brief Forwards to locatePreviewIrb() with \em psTag = \em preview_
static int locatePreviewIrb(const byte* pPsData, size_t sizePsData, const byte** record, uint32_t* const sizeHdr,
uint32_t* const sizeData);
/// @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