annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/webp/demux.h @ 69:33d812a61356

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