Path: blob/master/thirdparty/libwebp/src/webp/demux.h
9913 views
// Copyright 2012 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Demux API.10// Enables extraction of image and extended format data from WebP files.1112// Code Example: Demuxing WebP data to extract all the frames, ICC profile13// and EXIF/XMP metadata.14/*15WebPDemuxer* demux = WebPDemux(&webp_data);1617uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);18uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);19// ... (Get information about the features present in the WebP file).20uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);2122// ... (Iterate over all frames).23WebPIterator iter;24if (WebPDemuxGetFrame(demux, 1, &iter)) {25do {26// ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),27// ... and get other frame properties like width, height, offsets etc.28// ... see 'struct WebPIterator' below for more info).29} while (WebPDemuxNextFrame(&iter));30WebPDemuxReleaseIterator(&iter);31}3233// ... (Extract metadata).34WebPChunkIterator chunk_iter;35if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);36// ... (Consume the ICC profile in 'chunk_iter.chunk').37WebPDemuxReleaseChunkIterator(&chunk_iter);38if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);39// ... (Consume the EXIF metadata in 'chunk_iter.chunk').40WebPDemuxReleaseChunkIterator(&chunk_iter);41if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);42// ... (Consume the XMP metadata in 'chunk_iter.chunk').43WebPDemuxReleaseChunkIterator(&chunk_iter);44WebPDemuxDelete(demux);45*/4647#ifndef WEBP_WEBP_DEMUX_H_48#define WEBP_WEBP_DEMUX_H_4950#include "./decode.h" // for WEBP_CSP_MODE51#include "./mux_types.h"52#include "./types.h"5354#ifdef __cplusplus55extern "C" {56#endif5758#define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b)5960// Note: forward declaring enumerations is not allowed in (strict) C and C++,61// the types are left here for reference.62// typedef enum WebPDemuxState WebPDemuxState;63// typedef enum WebPFormatFeature WebPFormatFeature;64typedef struct WebPDemuxer WebPDemuxer;65typedef struct WebPIterator WebPIterator;66typedef struct WebPChunkIterator WebPChunkIterator;67typedef struct WebPAnimInfo WebPAnimInfo;68typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions;6970//------------------------------------------------------------------------------7172// Returns the version number of the demux library, packed in hexadecimal using73// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.74WEBP_EXTERN int WebPGetDemuxVersion(void);7576//------------------------------------------------------------------------------77// Life of a Demux object7879typedef enum WebPDemuxState {80WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing.81WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header.82WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete,83// data may be available.84WEBP_DEMUX_DONE = 2 // Entire file has been parsed.85} WebPDemuxState;8687// Internal, version-checked, entry point88WEBP_NODISCARD WEBP_EXTERN WebPDemuxer* WebPDemuxInternal(89const WebPData*, int, WebPDemuxState*, int);9091// Parses the full WebP file given by 'data'. For single images the WebP file92// header alone or the file header and the chunk header may be absent.93// Returns a WebPDemuxer object on successful parse, NULL otherwise.94WEBP_NODISCARD static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {95return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);96}9798// Parses the possibly incomplete WebP file given by 'data'.99// If 'state' is non-NULL it will be set to indicate the status of the demuxer.100// Returns NULL in case of error or if there isn't enough data to start parsing;101// and a WebPDemuxer object on successful parse.102// Note that WebPDemuxer keeps internal pointers to 'data' memory segment.103// If this data is volatile, the demuxer object should be deleted (by calling104// WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.105// This is usually an inexpensive operation.106WEBP_NODISCARD static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(107const WebPData* data, WebPDemuxState* state) {108return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);109}110111// Frees memory associated with 'dmux'.112WEBP_EXTERN void WebPDemuxDelete(WebPDemuxer* dmux);113114//------------------------------------------------------------------------------115// Data/information extraction.116117typedef enum WebPFormatFeature {118WEBP_FF_FORMAT_FLAGS, // bit-wise combination of WebPFeatureFlags119// corresponding to the 'VP8X' chunk (if present).120WEBP_FF_CANVAS_WIDTH,121WEBP_FF_CANVAS_HEIGHT,122WEBP_FF_LOOP_COUNT, // only relevant for animated file123WEBP_FF_BACKGROUND_COLOR, // idem.124WEBP_FF_FRAME_COUNT // Number of frames present in the demux object.125// In case of a partial demux, this is the number126// of frames seen so far, with the last frame127// possibly being partial.128} WebPFormatFeature;129130// Get the 'feature' value from the 'dmux'.131// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()132// returned a state > WEBP_DEMUX_PARSING_HEADER.133// If 'feature' is WEBP_FF_FORMAT_FLAGS, the returned value is a bit-wise134// combination of WebPFeatureFlags values.135// If 'feature' is WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, the returned136// value is only meaningful if the bitstream is animated.137WEBP_EXTERN uint32_t WebPDemuxGetI(138const WebPDemuxer* dmux, WebPFormatFeature feature);139140//------------------------------------------------------------------------------141// Frame iteration.142143struct WebPIterator {144int frame_num;145int num_frames; // equivalent to WEBP_FF_FRAME_COUNT.146int x_offset, y_offset; // offset relative to the canvas.147int width, height; // dimensions of this frame.148int duration; // display duration in milliseconds.149WebPMuxAnimDispose dispose_method; // dispose method for the frame.150int complete; // true if 'fragment' contains a full frame. partial images151// may still be decoded with the WebP incremental decoder.152WebPData fragment; // The frame given by 'frame_num'. Note for historical153// reasons this is called a fragment.154int has_alpha; // True if the frame contains transparency.155WebPMuxAnimBlend blend_method; // Blend operation for the frame.156157uint32_t pad[2]; // padding for later use.158void* private_; // for internal use only.159};160161// Retrieves frame 'frame_number' from 'dmux'.162// 'iter->fragment' points to the frame on return from this function.163// Setting 'frame_number' equal to 0 will return the last frame of the image.164// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.165// Call WebPDemuxReleaseIterator() when use of the iterator is complete.166// NOTE: 'dmux' must persist for the lifetime of 'iter'.167WEBP_NODISCARD WEBP_EXTERN int WebPDemuxGetFrame(168const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);169170// Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or171// previous ('iter->frame_num' - 1) frame. These functions do not loop.172// Returns true on success, false otherwise.173WEBP_NODISCARD WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter);174WEBP_NODISCARD WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter);175176// Releases any memory associated with 'iter'.177// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same178// iter. Also, must be called before destroying the associated WebPDemuxer with179// WebPDemuxDelete().180WEBP_EXTERN void WebPDemuxReleaseIterator(WebPIterator* iter);181182//------------------------------------------------------------------------------183// Chunk iteration.184185struct WebPChunkIterator {186// The current and total number of chunks with the fourcc given to187// WebPDemuxGetChunk().188int chunk_num;189int num_chunks;190WebPData chunk; // The payload of the chunk.191192uint32_t pad[6]; // padding for later use193void* private_;194};195196// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from197// 'dmux'.198// 'fourcc' is a character array containing the fourcc of the chunk to return,199// e.g., "ICCP", "XMP ", "EXIF", etc.200// Setting 'chunk_number' equal to 0 will return the last chunk in a set.201// Returns true if the chunk is found, false otherwise. Image related chunk202// payloads are accessed through WebPDemuxGetFrame() and related functions.203// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.204// NOTE: 'dmux' must persist for the lifetime of the iterator.205WEBP_NODISCARD WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux,206const char fourcc[4],207int chunk_number,208WebPChunkIterator* iter);209210// Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous211// ('iter->chunk_num' - 1) chunk. These functions do not loop.212// Returns true on success, false otherwise.213WEBP_NODISCARD WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter);214WEBP_NODISCARD WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter);215216// Releases any memory associated with 'iter'.217// Must be called before destroying the associated WebPDemuxer with218// WebPDemuxDelete().219WEBP_EXTERN void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);220221//------------------------------------------------------------------------------222// WebPAnimDecoder API223//224// This API allows decoding (possibly) animated WebP images.225//226// Code Example:227/*228WebPAnimDecoderOptions dec_options;229WebPAnimDecoderOptionsInit(&dec_options);230// Tune 'dec_options' as needed.231WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);232WebPAnimInfo anim_info;233WebPAnimDecoderGetInfo(dec, &anim_info);234for (uint32_t i = 0; i < anim_info.loop_count; ++i) {235while (WebPAnimDecoderHasMoreFrames(dec)) {236uint8_t* buf;237int timestamp;238WebPAnimDecoderGetNext(dec, &buf, ×tamp);239// ... (Render 'buf' based on 'timestamp').240// ... (Do NOT free 'buf', as it is owned by 'dec').241}242WebPAnimDecoderReset(dec);243}244const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);245// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).246WebPAnimDecoderDelete(dec);247*/248249typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object.250251// Global options.252struct WebPAnimDecoderOptions {253// Output colorspace. Only the following modes are supported:254// MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA.255WEBP_CSP_MODE color_mode;256int use_threads; // If true, use multi-threaded decoding.257uint32_t padding[7]; // Padding for later use.258};259260// Internal, version-checked, entry point.261WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal(262WebPAnimDecoderOptions*, int);263264// Should always be called, to initialize a fresh WebPAnimDecoderOptions265// structure before modification. Returns false in case of version mismatch.266// WebPAnimDecoderOptionsInit() must have succeeded before using the267// 'dec_options' object.268WEBP_NODISCARD static WEBP_INLINE int WebPAnimDecoderOptionsInit(269WebPAnimDecoderOptions* dec_options) {270return WebPAnimDecoderOptionsInitInternal(dec_options,271WEBP_DEMUX_ABI_VERSION);272}273274// Internal, version-checked, entry point.275WEBP_NODISCARD WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal(276const WebPData*, const WebPAnimDecoderOptions*, int);277278// Creates and initializes a WebPAnimDecoder object.279// Parameters:280// webp_data - (in) WebP bitstream. This should remain unchanged during the281// lifetime of the output WebPAnimDecoder object.282// dec_options - (in) decoding options. Can be passed NULL to choose283// reasonable defaults (in particular, color mode MODE_RGBA284// will be picked).285// Returns:286// A pointer to the newly created WebPAnimDecoder object, or NULL in case of287// parsing error, invalid option or memory error.288WEBP_NODISCARD static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew(289const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) {290return WebPAnimDecoderNewInternal(webp_data, dec_options,291WEBP_DEMUX_ABI_VERSION);292}293294// Global information about the animation..295struct WebPAnimInfo {296uint32_t canvas_width;297uint32_t canvas_height;298uint32_t loop_count;299uint32_t bgcolor;300uint32_t frame_count;301uint32_t pad[4]; // padding for later use302};303304// Get global information about the animation.305// Parameters:306// dec - (in) decoder instance to get information from.307// info - (out) global information fetched from the animation.308// Returns:309// True on success.310WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderGetInfo(311const WebPAnimDecoder* dec, WebPAnimInfo* info);312313// Fetch the next frame from 'dec' based on options supplied to314// WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size315// 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The316// returned buffer 'buf' is valid only until the next call to317// WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete().318// Parameters:319// dec - (in/out) decoder instance from which the next frame is to be fetched.320// buf - (out) decoded frame.321// timestamp - (out) timestamp of the frame in milliseconds.322// Returns:323// False if any of the arguments are NULL, or if there is a parsing or324// decoding error, or if there are no more frames. Otherwise, returns true.325WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,326uint8_t** buf,327int* timestamp);328329// Check if there are more frames left to decode.330// Parameters:331// dec - (in) decoder instance to be checked.332// Returns:333// True if 'dec' is not NULL and some frames are yet to be decoded.334// Otherwise, returns false.335WEBP_NODISCARD WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(336const WebPAnimDecoder* dec);337338// Resets the WebPAnimDecoder object, so that next call to339// WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be340// helpful when all frames need to be decoded multiple times (e.g.341// info.loop_count times) without destroying and recreating the 'dec' object.342// Parameters:343// dec - (in/out) decoder instance to be reset344WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec);345346// Grab the internal demuxer object.347// Getting the demuxer object can be useful if one wants to use operations only348// available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned349// demuxer object is owned by 'dec' and is valid only until the next call to350// WebPAnimDecoderDelete().351//352// Parameters:353// dec - (in) decoder instance from which the demuxer object is to be fetched.354WEBP_NODISCARD WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer(355const WebPAnimDecoder* dec);356357// Deletes the WebPAnimDecoder object.358// Parameters:359// dec - (in/out) decoder instance to be deleted360WEBP_EXTERN void WebPAnimDecoderDelete(WebPAnimDecoder* dec);361362#ifdef __cplusplus363} // extern "C"364#endif365366#endif // WEBP_WEBP_DEMUX_H_367368369