/src/exiv2/include/exiv2/jpgimage.hpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | |
3 | | #ifndef EXIV2_JPGIMAGE_HPP |
4 | | #define EXIV2_JPGIMAGE_HPP |
5 | | |
6 | | #include "exiv2lib_export.h" |
7 | | |
8 | | // included header files |
9 | | #include "image.hpp" |
10 | | |
11 | | // ***************************************************************************** |
12 | | // namespace extensions |
13 | | namespace Exiv2 { |
14 | | enum class ErrorCode; |
15 | | // ***************************************************************************** |
16 | | // class definitions |
17 | | |
18 | | /*! |
19 | | @brief Abstract helper base class to access JPEG images. |
20 | | */ |
21 | | class EXIV2API JpegBase : public Image { |
22 | | public: |
23 | | //! @name Manipulators |
24 | | //@{ |
25 | | void readMetadata() override; |
26 | | void writeMetadata() override; |
27 | | void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override; |
28 | | //@} |
29 | | |
30 | | protected: |
31 | | //! @name Creators |
32 | | //@{ |
33 | | /*! |
34 | | @brief Constructor that can either open an existing image or create |
35 | | a new image from scratch. If a new image is to be created, any |
36 | | existing data is overwritten. |
37 | | @param type Image type. |
38 | | @param io An auto-pointer that owns a BasicIo instance used for |
39 | | reading and writing image metadata. \b Important: The constructor |
40 | | takes ownership of the passed in BasicIo instance through the |
41 | | auto-pointer. Callers should not continue to use the BasicIo |
42 | | instance after it is passed to this method. Use the Image::io() |
43 | | method to get a temporary reference. |
44 | | @param create Specifies if an existing image should be read (false) |
45 | | or if a new image should be created (true). |
46 | | @param initData Data to initialize newly created images. Only used |
47 | | when \em create is true. Should contain data for the smallest |
48 | | valid image of the calling subclass. |
49 | | @param dataSize Size of initData in bytes. |
50 | | */ |
51 | | JpegBase(ImageType type, std::unique_ptr<BasicIo> io, bool create, const byte initData[], size_t dataSize); |
52 | | //@} |
53 | | |
54 | | //! @name Accessors |
55 | | //@{ |
56 | | /*! |
57 | | @brief Determine if the content of the BasicIo instance is of the |
58 | | type supported by this class. |
59 | | |
60 | | The advance flag determines if the read position in the stream is |
61 | | moved (see below). This applies only if the type matches and the |
62 | | function returns true. If the type does not match, the stream |
63 | | position is not changed. However, if reading from the stream fails, |
64 | | the stream position is undefined. Consult the stream state to obtain |
65 | | more information in this case. |
66 | | |
67 | | @param iIo BasicIo instance to read from. |
68 | | @param advance Flag indicating whether the position of the io |
69 | | should be advanced by the number of characters read to |
70 | | analyse the data (true) or left at its original |
71 | | position (false). This applies only if the type matches. |
72 | | @return true if the data matches the type of this class;<BR> |
73 | | false if the data does not match |
74 | | */ |
75 | | virtual bool isThisType(BasicIo& iIo, bool advance) const = 0; |
76 | | //@} |
77 | | |
78 | | //! @name Manipulators |
79 | | //@{ |
80 | | /*! |
81 | | @brief Writes the image header (aka signature) to the BasicIo instance. |
82 | | @param oIo BasicIo instance that the header is written to. |
83 | | @return 0 if successful;<BR> |
84 | | 4 if the output file can not be written to |
85 | | */ |
86 | | virtual int writeHeader(BasicIo& oIo) const = 0; |
87 | | //@} |
88 | | |
89 | | int num_color_components_{-1}; //!< image number of color components |
90 | | std::string sof_encoding_process_; //!< image encoding process |
91 | | |
92 | | private: |
93 | | //! @name Manipulators |
94 | | //@{ |
95 | | /*! |
96 | | @brief Initialize the image with the provided data. |
97 | | @param initData Data to be written to the associated BasicIo |
98 | | @param dataSize Size in bytes of data to be written |
99 | | @return 0 if successful;<BR> |
100 | | 4 if the image can not be written to. |
101 | | */ |
102 | | int initImage(const byte initData[], size_t dataSize); |
103 | | /*! |
104 | | @brief Provides the main implementation of writeMetadata() by |
105 | | writing all buffered metadata to the provided BasicIo. |
106 | | @throw Error on input-output errors or when the image data is not valid. |
107 | | @param outIo BasicIo instance to write to (a temporary location). |
108 | | |
109 | | */ |
110 | | void doWriteMetadata(BasicIo& outIo); |
111 | | //@} |
112 | | |
113 | | //! @name Accessors |
114 | | //@{ |
115 | | /*! |
116 | | @brief Advances associated io instance to one byte past the next |
117 | | Jpeg marker and returns the marker. This method should be called |
118 | | when the BasicIo instance is positioned one byte past the end of a |
119 | | Jpeg segment. |
120 | | @param err the error code to throw if no marker is found |
121 | | @return the next Jpeg segment marker if successful;<BR> |
122 | | throws an Error if not successful |
123 | | */ |
124 | | [[nodiscard]] byte advanceToMarker(ErrorCode err) const; |
125 | | //@} |
126 | | |
127 | | DataBuf readNextSegment(byte marker); |
128 | | }; |
129 | | |
130 | | /*! |
131 | | @brief Class to access JPEG images |
132 | | */ |
133 | | class EXIV2API JpegImage : public JpegBase { |
134 | | friend EXIV2API bool isJpegType(BasicIo& iIo, bool advance); |
135 | | |
136 | | public: |
137 | | //! @name Creators |
138 | | //@{ |
139 | | /*! |
140 | | @brief Constructor that can either open an existing Jpeg image or create |
141 | | a new image from scratch. If a new image is to be created, any |
142 | | existing data is overwritten. Since the constructor can not return |
143 | | a result, callers should check the good() method after object |
144 | | construction to determine success or failure. |
145 | | @param io An auto-pointer that owns a BasicIo instance used for |
146 | | reading and writing image metadata. \b Important: The constructor |
147 | | takes ownership of the passed in BasicIo instance through the |
148 | | auto-pointer. Callers should not continue to use the BasicIo |
149 | | instance after it is passed to this method. Use the Image::io() |
150 | | method to get a temporary reference. |
151 | | @param create Specifies if an existing image should be read (false) |
152 | | or if a new file should be created (true). |
153 | | */ |
154 | | JpegImage(std::unique_ptr<BasicIo> io, bool create); |
155 | | //@} |
156 | | //! @name Accessors |
157 | | //@{ |
158 | | [[nodiscard]] std::string mimeType() const override; |
159 | | /*! |
160 | | @brief Get the number of color components of the JPEG Image |
161 | | */ |
162 | 0 | [[nodiscard]] int numColorComponents() const { |
163 | 0 | return num_color_components_; |
164 | 0 | } |
165 | | /*! |
166 | | @brief Get the encoding process of the JPEG Image derived from the Start of Frame (SOF) markers |
167 | | */ |
168 | 0 | [[nodiscard]] const std::string& encodingProcess() const { |
169 | 0 | return sof_encoding_process_; |
170 | 0 | } |
171 | | //@} |
172 | | |
173 | | protected: |
174 | | //! @name Accessors |
175 | | //@{ |
176 | | bool isThisType(BasicIo& iIo, bool advance) const override; |
177 | | //@} |
178 | | //! @name Manipulators |
179 | | //@{ |
180 | | /*! |
181 | | @brief Writes a Jpeg header (aka signature) to the BasicIo instance. |
182 | | @param outIo BasicIo instance that the header is written to. |
183 | | @return 0 if successful;<BR> |
184 | | 2 if the input image is invalid or can not be read;<BR> |
185 | | 4 if the temporary image can not be written to;<BR> |
186 | | -3 other temporary errors |
187 | | */ |
188 | | int writeHeader(BasicIo& outIo) const override; |
189 | | //@} |
190 | | |
191 | | private: |
192 | | // Constant data |
193 | | static const byte blank_[]; //!< Minimal Jpeg image |
194 | | }; |
195 | | |
196 | | //! Helper class to access %Exiv2 files |
197 | | class EXIV2API ExvImage : public JpegBase { |
198 | | friend EXIV2API bool isExvType(BasicIo& iIo, bool advance); |
199 | | |
200 | | public: |
201 | | //! @name Creators |
202 | | //@{ |
203 | | /*! |
204 | | @brief Constructor that can either open an existing EXV image or create |
205 | | a new image from scratch. If a new image is to be created, any |
206 | | existing data is overwritten. Since the constructor can not return |
207 | | a result, callers should check the good() method after object |
208 | | construction to determine success or failure. |
209 | | @param io An auto-pointer that owns a BasicIo instance used for |
210 | | reading and writing image metadata. \b Important: The constructor |
211 | | takes ownership of the passed in BasicIo instance through the |
212 | | auto-pointer. Callers should not continue to use the BasicIo |
213 | | instance after it is passed to this method. Use the Image::io() |
214 | | method to get a temporary reference. |
215 | | @param create Specifies if an existing image should be read (false) |
216 | | or if a new file should be created (true). |
217 | | */ |
218 | | ExvImage(std::unique_ptr<BasicIo> io, bool create); |
219 | | //@} |
220 | | //! @name Accessors |
221 | | //@{ |
222 | | [[nodiscard]] std::string mimeType() const override; |
223 | | //@} |
224 | | |
225 | | protected: |
226 | | //! @name Accessors |
227 | | //@{ |
228 | | bool isThisType(BasicIo& iIo, bool advance) const override; |
229 | | //@} |
230 | | //! @name Manipulators |
231 | | //@{ |
232 | | int writeHeader(BasicIo& outIo) const override; |
233 | | //@} |
234 | | |
235 | | private: |
236 | | // Constant data |
237 | | static constexpr char exiv2Id_[] = "Exiv2"; // EXV identifier |
238 | | static constexpr byte blank_[] = {0xff, 0x01, 'E', 'x', 'i', 'v', '2', 0xff, 0xd9}; // Minimal exiv2 file |
239 | | |
240 | | }; // class ExvImage |
241 | | |
242 | | // ***************************************************************************** |
243 | | // template, inline and free functions |
244 | | |
245 | | // These could be static private functions on Image subclasses but then |
246 | | // ImageFactory needs to be made a friend. |
247 | | /*! |
248 | | @brief Create a new JpegImage instance and return an auto-pointer to it. |
249 | | Caller owns the returned object and the auto-pointer ensures that |
250 | | it will be deleted. |
251 | | */ |
252 | | EXIV2API Image::UniquePtr newJpegInstance(std::unique_ptr<BasicIo> io, bool create); |
253 | | //! Check if the file iIo is a JPEG image. |
254 | | EXIV2API bool isJpegType(BasicIo& iIo, bool advance); |
255 | | /*! |
256 | | @brief Create a new ExvImage instance and return an auto-pointer to it. |
257 | | Caller owns the returned object and the auto-pointer ensures that |
258 | | it will be deleted. |
259 | | */ |
260 | | EXIV2API Image::UniquePtr newExvInstance(std::unique_ptr<BasicIo> io, bool create); |
261 | | //! Check if the file iIo is an EXV file |
262 | | EXIV2API bool isExvType(BasicIo& iIo, bool advance); |
263 | | |
264 | | } // namespace Exiv2 |
265 | | |
266 | | #endif // EXIV2_JPGIMAGE_HPP |