/work/include/webp/demux.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2012 Google Inc. All Rights Reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style license |
4 | | // that can be found in the COPYING file in the root of the source |
5 | | // tree. An additional intellectual property rights grant can be found |
6 | | // in the file PATENTS. All contributing project authors may |
7 | | // be found in the AUTHORS file in the root of the source tree. |
8 | | // ----------------------------------------------------------------------------- |
9 | | // |
10 | | // Demux API. |
11 | | // Enables extraction of image and extended format data from WebP files. |
12 | | |
13 | | // Code Example: Demuxing WebP data to extract all the frames, ICC profile |
14 | | // and EXIF/XMP metadata. |
15 | | /* |
16 | | WebPDemuxer* demux = WebPDemux(&webp_data); |
17 | | |
18 | | uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); |
19 | | uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); |
20 | | // ... (Get information about the features present in the WebP file). |
21 | | uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); |
22 | | |
23 | | // ... (Iterate over all frames). |
24 | | WebPIterator iter; |
25 | | if (WebPDemuxGetFrame(demux, 1, &iter)) { |
26 | | do { |
27 | | // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), |
28 | | // ... and get other frame properties like width, height, offsets etc. |
29 | | // ... see 'struct WebPIterator' below for more info). |
30 | | } while (WebPDemuxNextFrame(&iter)); |
31 | | WebPDemuxReleaseIterator(&iter); |
32 | | } |
33 | | |
34 | | // ... (Extract metadata). |
35 | | WebPChunkIterator chunk_iter; |
36 | | if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); |
37 | | // ... (Consume the ICC profile in 'chunk_iter.chunk'). |
38 | | WebPDemuxReleaseChunkIterator(&chunk_iter); |
39 | | if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); |
40 | | // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). |
41 | | WebPDemuxReleaseChunkIterator(&chunk_iter); |
42 | | if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); |
43 | | // ... (Consume the XMP metadata in 'chunk_iter.chunk'). |
44 | | WebPDemuxReleaseChunkIterator(&chunk_iter); |
45 | | WebPDemuxDelete(demux); |
46 | | */ |
47 | | |
48 | | #ifndef WEBP_WEBP_DEMUX_H_ |
49 | | #define WEBP_WEBP_DEMUX_H_ |
50 | | |
51 | | #include <stddef.h> |
52 | | |
53 | | #include "./decode.h" // for WEBP_CSP_MODE |
54 | | #include "./mux_types.h" |
55 | | #include "./types.h" |
56 | | |
57 | | #ifdef __cplusplus |
58 | | extern "C" { |
59 | | #endif |
60 | | |
61 | 1.05k | #define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b) |
62 | | |
63 | | // Note: forward declaring enumerations is not allowed in (strict) C and C++, |
64 | | // the types are left here for reference. |
65 | | // typedef enum WebPDemuxState WebPDemuxState; |
66 | | // typedef enum WebPFormatFeature WebPFormatFeature; |
67 | | typedef struct WebPDemuxer WebPDemuxer; |
68 | | typedef struct WebPIterator WebPIterator; |
69 | | typedef struct WebPChunkIterator WebPChunkIterator; |
70 | | typedef struct WebPAnimInfo WebPAnimInfo; |
71 | | typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions; |
72 | | |
73 | | //------------------------------------------------------------------------------ |
74 | | |
75 | | // Returns the version number of the demux library, packed in hexadecimal using |
76 | | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. |
77 | | WEBP_EXTERN int WebPGetDemuxVersion(void); |
78 | | |
79 | | //------------------------------------------------------------------------------ |
80 | | // Life of a Demux object |
81 | | |
82 | | typedef enum WebPDemuxState { |
83 | | WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing. |
84 | | WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header. |
85 | | WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete, |
86 | | // data may be available. |
87 | | WEBP_DEMUX_DONE = 2 // Entire file has been parsed. |
88 | | } WebPDemuxState; |
89 | | |
90 | | // Internal, version-checked, entry point |
91 | | WEBP_NODISCARD WEBP_EXTERN WebPDemuxer* WebPDemuxInternal( |
92 | | const WebPData*, int, WebPDemuxState*, int); |
93 | | |
94 | | // Parses the full WebP file given by 'data'. For single images the WebP file |
95 | | // header alone or the file header and the chunk header may be absent. |
96 | | // Returns a WebPDemuxer object on successful parse, NULL otherwise. |
97 | 1.05k | WEBP_NODISCARD static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { |
98 | 1.05k | return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); |
99 | 1.05k | } |
100 | | |
101 | | // Parses the possibly incomplete WebP file given by 'data'. |
102 | | // If 'state' is non-NULL it will be set to indicate the status of the demuxer. |
103 | | // Returns NULL in case of error or if there isn't enough data to start parsing; |
104 | | // and a WebPDemuxer object on successful parse. |
105 | | // Note that WebPDemuxer keeps internal pointers to 'data' memory segment. |
106 | | // If this data is volatile, the demuxer object should be deleted (by calling |
107 | | // WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data. |
108 | | // This is usually an inexpensive operation. |
109 | | WEBP_NODISCARD static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( |
110 | 0 | const WebPData* data, WebPDemuxState* state) { |
111 | 0 | return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); |
112 | 0 | } |
113 | | |
114 | | // Frees memory associated with 'dmux'. |
115 | | WEBP_EXTERN void WebPDemuxDelete(WebPDemuxer* dmux); |
116 | | |
117 | | //------------------------------------------------------------------------------ |
118 | | // Data/information extraction. |
119 | | |
120 | | typedef enum WebPFormatFeature { |
121 | | WEBP_FF_FORMAT_FLAGS, // bit-wise combination of WebPFeatureFlags |
122 | | // corresponding to the 'VP8X' chunk (if present). |
123 | | WEBP_FF_CANVAS_WIDTH, |
124 | | WEBP_FF_CANVAS_HEIGHT, |
125 | | WEBP_FF_LOOP_COUNT, // only relevant for animated file |
126 | | WEBP_FF_BACKGROUND_COLOR, // idem. |
127 | | WEBP_FF_FRAME_COUNT // Number of frames present in the demux object. |
128 | | // In case of a partial demux, this is the number |
129 | | // of frames seen so far, with the last frame |
130 | | // possibly being partial. |
131 | | } WebPFormatFeature; |
132 | | |
133 | | // Get the 'feature' value from the 'dmux'. |
134 | | // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() |
135 | | // returned a state > WEBP_DEMUX_PARSING_HEADER. |
136 | | // If 'feature' is WEBP_FF_FORMAT_FLAGS, the returned value is a bit-wise |
137 | | // combination of WebPFeatureFlags values. |
138 | | // If 'feature' is WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, the returned |
139 | | // value is only meaningful if the bitstream is animated. |
140 | | WEBP_EXTERN uint32_t WebPDemuxGetI( |
141 | | const WebPDemuxer* dmux, WebPFormatFeature feature); |
142 | | |
143 | | //------------------------------------------------------------------------------ |
144 | | // Frame iteration. |
145 | | |
146 | | struct WebPIterator { |
147 | | int frame_num; |
148 | | int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. |
149 | | int x_offset, y_offset; // offset relative to the canvas. |
150 | | int width, height; // dimensions of this frame. |
151 | | int duration; // display duration in milliseconds. |
152 | | WebPMuxAnimDispose dispose_method; // dispose method for the frame. |
153 | | int complete; // true if 'fragment' contains a full frame. partial images |
154 | | // may still be decoded with the WebP incremental decoder. |
155 | | WebPData fragment; // The frame given by 'frame_num'. Note for historical |
156 | | // reasons this is called a fragment. |
157 | | int has_alpha; // True if the frame contains transparency. |
158 | | WebPMuxAnimBlend blend_method; // Blend operation for the frame. |
159 | | |
160 | | uint32_t pad[2]; // padding for later use. |
161 | | void* private_; // for internal use only. |
162 | | }; |
163 | | |
164 | | // Retrieves frame 'frame_number' from 'dmux'. |
165 | | // 'iter->fragment' points to the frame on return from this function. |
166 | | // Setting 'frame_number' equal to 0 will return the last frame of the image. |
167 | | // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. |
168 | | // Call WebPDemuxReleaseIterator() when use of the iterator is complete. |
169 | | // NOTE: 'dmux' must persist for the lifetime of 'iter'. |
170 | | WEBP_NODISCARD WEBP_EXTERN int WebPDemuxGetFrame( |
171 | | const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); |
172 | | |
173 | | // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or |
174 | | // previous ('iter->frame_num' - 1) frame. These functions do not loop. |
175 | | // Returns true on success, false otherwise. |
176 | | WEBP_NODISCARD WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter); |
177 | | WEBP_NODISCARD WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter); |
178 | | |
179 | | // Releases any memory associated with 'iter'. |
180 | | // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same |
181 | | // iter. Also, must be called before destroying the associated WebPDemuxer with |
182 | | // WebPDemuxDelete(). |
183 | | WEBP_EXTERN void WebPDemuxReleaseIterator(WebPIterator* iter); |
184 | | |
185 | | //------------------------------------------------------------------------------ |
186 | | // Chunk iteration. |
187 | | |
188 | | struct WebPChunkIterator { |
189 | | // The current and total number of chunks with the fourcc given to |
190 | | // WebPDemuxGetChunk(). |
191 | | int chunk_num; |
192 | | int num_chunks; |
193 | | WebPData chunk; // The payload of the chunk. |
194 | | |
195 | | uint32_t pad[6]; // padding for later use |
196 | | void* private_; |
197 | | }; |
198 | | |
199 | | // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from |
200 | | // 'dmux'. |
201 | | // 'fourcc' is a character array containing the fourcc of the chunk to return, |
202 | | // e.g., "ICCP", "XMP ", "EXIF", etc. |
203 | | // Setting 'chunk_number' equal to 0 will return the last chunk in a set. |
204 | | // Returns true if the chunk is found, false otherwise. Image related chunk |
205 | | // payloads are accessed through WebPDemuxGetFrame() and related functions. |
206 | | // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. |
207 | | // NOTE: 'dmux' must persist for the lifetime of the iterator. |
208 | | WEBP_NODISCARD WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux, |
209 | | const char fourcc[4], |
210 | | int chunk_number, |
211 | | WebPChunkIterator* iter); |
212 | | |
213 | | // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous |
214 | | // ('iter->chunk_num' - 1) chunk. These functions do not loop. |
215 | | // Returns true on success, false otherwise. |
216 | | WEBP_NODISCARD WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter); |
217 | | WEBP_NODISCARD WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter); |
218 | | |
219 | | // Releases any memory associated with 'iter'. |
220 | | // Must be called before destroying the associated WebPDemuxer with |
221 | | // WebPDemuxDelete(). |
222 | | WEBP_EXTERN void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); |
223 | | |
224 | | //------------------------------------------------------------------------------ |
225 | | // WebPAnimDecoder API |
226 | | // |
227 | | // This API allows decoding (possibly) animated WebP images. |
228 | | // |
229 | | // Code Example: |
230 | | /* |
231 | | WebPAnimDecoderOptions dec_options; |
232 | | WebPAnimDecoderOptionsInit(&dec_options); |
233 | | // Tune 'dec_options' as needed. |
234 | | WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options); |
235 | | WebPAnimInfo anim_info; |
236 | | WebPAnimDecoderGetInfo(dec, &anim_info); |
237 | | for (uint32_t i = 0; i < anim_info.loop_count; ++i) { |
238 | | while (WebPAnimDecoderHasMoreFrames(dec)) { |
239 | | uint8_t* buf; |
240 | | int timestamp; |
241 | | WebPAnimDecoderGetNext(dec, &buf, ×tamp); |
242 | | // ... (Render 'buf' based on 'timestamp'). |
243 | | // ... (Do NOT free 'buf', as it is owned by 'dec'). |
244 | | } |
245 | | WebPAnimDecoderReset(dec); |
246 | | } |
247 | | const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec); |
248 | | // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data). |
249 | | WebPAnimDecoderDelete(dec); |
250 | | */ |
251 | | |
252 | | typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object. |
253 | | |
254 | | // Global options. |
255 | | struct WebPAnimDecoderOptions { |
256 | | // Output colorspace. Only the following modes are supported: |
257 | | // MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA. |
258 | | WEBP_CSP_MODE color_mode; |
259 | | int use_threads; // If true, use multi-threaded decoding. |
260 | | uint32_t padding[7]; // Padding for later use. |
261 | | }; |
262 | | |
263 | | // Internal, version-checked, entry point. |
264 | | WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal( |
265 | | WebPAnimDecoderOptions*, int); |
266 | | |
267 | | // Should always be called, to initialize a fresh WebPAnimDecoderOptions |
268 | | // structure before modification. Returns false in case of version mismatch. |
269 | | // WebPAnimDecoderOptionsInit() must have succeeded before using the |
270 | | // 'dec_options' object. |
271 | | WEBP_NODISCARD static WEBP_INLINE int WebPAnimDecoderOptionsInit( |
272 | 0 | WebPAnimDecoderOptions* dec_options) { |
273 | 0 | return WebPAnimDecoderOptionsInitInternal(dec_options, |
274 | 0 | WEBP_DEMUX_ABI_VERSION); |
275 | 0 | } |
276 | | |
277 | | // Internal, version-checked, entry point. |
278 | | WEBP_NODISCARD WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal( |
279 | | const WebPData*, const WebPAnimDecoderOptions*, int); |
280 | | |
281 | | // Creates and initializes a WebPAnimDecoder object. |
282 | | // Parameters: |
283 | | // webp_data - (in) WebP bitstream. This should remain unchanged during the |
284 | | // lifetime of the output WebPAnimDecoder object. |
285 | | // dec_options - (in) decoding options. Can be passed NULL to choose |
286 | | // reasonable defaults (in particular, color mode MODE_RGBA |
287 | | // will be picked). |
288 | | // Returns: |
289 | | // A pointer to the newly created WebPAnimDecoder object, or NULL in case of |
290 | | // parsing error, invalid option or memory error. |
291 | | WEBP_NODISCARD static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew( |
292 | 0 | const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) { |
293 | 0 | return WebPAnimDecoderNewInternal(webp_data, dec_options, |
294 | 0 | WEBP_DEMUX_ABI_VERSION); |
295 | 0 | } |
296 | | |
297 | | // Global information about the animation.. |
298 | | struct WebPAnimInfo { |
299 | | uint32_t canvas_width; |
300 | | uint32_t canvas_height; |
301 | | uint32_t loop_count; |
302 | | uint32_t bgcolor; |
303 | | uint32_t frame_count; |
304 | | uint32_t pad[4]; // padding for later use |
305 | | }; |
306 | | |
307 | | // Get global information about the animation. |
308 | | // Parameters: |
309 | | // dec - (in) decoder instance to get information from. |
310 | | // info - (out) global information fetched from the animation. |
311 | | // Returns: |
312 | | // True on success. |
313 | | WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderGetInfo( |
314 | | const WebPAnimDecoder* dec, WebPAnimInfo* info); |
315 | | |
316 | | // Fetch the next frame from 'dec' based on options supplied to |
317 | | // WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size |
318 | | // 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The |
319 | | // returned buffer 'buf' is valid only until the next call to |
320 | | // WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete(). |
321 | | // Parameters: |
322 | | // dec - (in/out) decoder instance from which the next frame is to be fetched. |
323 | | // buf - (out) decoded frame. |
324 | | // timestamp - (out) timestamp of the frame in milliseconds. |
325 | | // Returns: |
326 | | // False if any of the arguments are NULL, or if there is a parsing or |
327 | | // decoding error, or if there are no more frames. Otherwise, returns true. |
328 | | WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, |
329 | | uint8_t** buf, |
330 | | int* timestamp); |
331 | | |
332 | | // Check if there are more frames left to decode. |
333 | | // Parameters: |
334 | | // dec - (in) decoder instance to be checked. |
335 | | // Returns: |
336 | | // True if 'dec' is not NULL and some frames are yet to be decoded. |
337 | | // Otherwise, returns false. |
338 | | WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderHasMoreFrames( |
339 | | const WebPAnimDecoder* dec); |
340 | | |
341 | | // Resets the WebPAnimDecoder object, so that next call to |
342 | | // WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be |
343 | | // helpful when all frames need to be decoded multiple times (e.g. |
344 | | // info.loop_count times) without destroying and recreating the 'dec' object. |
345 | | // Parameters: |
346 | | // dec - (in/out) decoder instance to be reset |
347 | | WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec); |
348 | | |
349 | | // Grab the internal demuxer object. |
350 | | // Getting the demuxer object can be useful if one wants to use operations only |
351 | | // available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned |
352 | | // demuxer object is owned by 'dec' and is valid only until the next call to |
353 | | // WebPAnimDecoderDelete(). |
354 | | // |
355 | | // Parameters: |
356 | | // dec - (in) decoder instance from which the demuxer object is to be fetched. |
357 | | WEBP_NODISCARD WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer( |
358 | | const WebPAnimDecoder* dec); |
359 | | |
360 | | // Deletes the WebPAnimDecoder object. |
361 | | // Parameters: |
362 | | // dec - (in/out) decoder instance to be deleted |
363 | | WEBP_EXTERN void WebPAnimDecoderDelete(WebPAnimDecoder* dec); |
364 | | |
365 | | #ifdef __cplusplus |
366 | | } // extern "C" |
367 | | #endif |
368 | | |
369 | | #endif // WEBP_WEBP_DEMUX_H_ |