jpayne@69: // Copyright 2010 Google Inc. All Rights Reserved. jpayne@69: // jpayne@69: // Use of this source code is governed by a BSD-style license jpayne@69: // that can be found in the COPYING file in the root of the source jpayne@69: // tree. An additional intellectual property rights grant can be found jpayne@69: // in the file PATENTS. All contributing project authors may jpayne@69: // be found in the AUTHORS file in the root of the source tree. jpayne@69: // ----------------------------------------------------------------------------- jpayne@69: // jpayne@69: // Main decoding functions for WebP images. jpayne@69: // jpayne@69: // Author: Skal (pascal.massimino@gmail.com) jpayne@69: jpayne@69: #ifndef WEBP_WEBP_DECODE_H_ jpayne@69: #define WEBP_WEBP_DECODE_H_ jpayne@69: jpayne@69: #include "./types.h" jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: extern "C" { jpayne@69: #endif jpayne@69: jpayne@69: #define WEBP_DECODER_ABI_VERSION 0x0209 // MAJOR(8b) + MINOR(8b) jpayne@69: jpayne@69: // Note: forward declaring enumerations is not allowed in (strict) C and C++, jpayne@69: // the types are left here for reference. jpayne@69: // typedef enum VP8StatusCode VP8StatusCode; jpayne@69: // typedef enum WEBP_CSP_MODE WEBP_CSP_MODE; jpayne@69: typedef struct WebPRGBABuffer WebPRGBABuffer; jpayne@69: typedef struct WebPYUVABuffer WebPYUVABuffer; jpayne@69: typedef struct WebPDecBuffer WebPDecBuffer; jpayne@69: typedef struct WebPIDecoder WebPIDecoder; jpayne@69: typedef struct WebPBitstreamFeatures WebPBitstreamFeatures; jpayne@69: typedef struct WebPDecoderOptions WebPDecoderOptions; jpayne@69: typedef struct WebPDecoderConfig WebPDecoderConfig; jpayne@69: jpayne@69: // Return the decoder's version number, packed in hexadecimal using 8bits for jpayne@69: // each of major/minor/revision. E.g: v2.5.7 is 0x020507. jpayne@69: WEBP_EXTERN int WebPGetDecoderVersion(void); jpayne@69: jpayne@69: // Retrieve basic header information: width, height. jpayne@69: // This function will also validate the header, returning true on success, jpayne@69: // false otherwise. '*width' and '*height' are only valid on successful return. jpayne@69: // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant. jpayne@69: // Note: The following chunk sequences (before the raw VP8/VP8L data) are jpayne@69: // considered valid by this function: jpayne@69: // RIFF + VP8(L) jpayne@69: // RIFF + VP8X + (optional chunks) + VP8(L) jpayne@69: // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. jpayne@69: // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. jpayne@69: WEBP_NODISCARD WEBP_EXTERN int WebPGetInfo( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height); jpayne@69: jpayne@69: // Decodes WebP images pointed to by 'data' and returns RGBA samples, along jpayne@69: // with the dimensions in *width and *height. The ordering of samples in jpayne@69: // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). jpayne@69: // The returned pointer should be deleted calling WebPFree(). jpayne@69: // Returns NULL in case of error. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGBA( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height); jpayne@69: jpayne@69: // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeARGB( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height); jpayne@69: jpayne@69: // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGRA( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height); jpayne@69: jpayne@69: // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. jpayne@69: // If the bitstream contains transparency, it is ignored. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGB( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height); jpayne@69: jpayne@69: // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGR( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height); jpayne@69: jpayne@69: // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer jpayne@69: // returned is the Y samples buffer. Upon return, *u and *v will point to jpayne@69: // the U and V chroma data. These U and V buffers need NOT be passed to jpayne@69: // WebPFree(), unlike the returned Y luma one. The dimension of the U and V jpayne@69: // planes are both (*width + 1) / 2 and (*height + 1) / 2. jpayne@69: // Upon return, the Y buffer has a stride returned as '*stride', while U and V jpayne@69: // have a common stride returned as '*uv_stride'. jpayne@69: // 'width' and 'height' may be NULL, the other pointers must not be. jpayne@69: // Returns NULL in case of error. jpayne@69: // (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeYUV( jpayne@69: const uint8_t* data, size_t data_size, int* width, int* height, jpayne@69: uint8_t** u, uint8_t** v, int* stride, int* uv_stride); jpayne@69: jpayne@69: // These five functions are variants of the above ones, that decode the image jpayne@69: // directly into a pre-allocated buffer 'output_buffer'. The maximum storage jpayne@69: // available in this buffer is indicated by 'output_buffer_size'. If this jpayne@69: // storage is not sufficient (or an error occurred), NULL is returned. jpayne@69: // Otherwise, output_buffer is returned, for convenience. jpayne@69: // The parameter 'output_stride' specifies the distance (in bytes) jpayne@69: // between scanlines. Hence, output_buffer_size is expected to be at least jpayne@69: // output_stride x picture-height. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGBAInto( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: uint8_t* output_buffer, size_t output_buffer_size, int output_stride); jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeARGBInto( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: uint8_t* output_buffer, size_t output_buffer_size, int output_stride); jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGRAInto( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: uint8_t* output_buffer, size_t output_buffer_size, int output_stride); jpayne@69: jpayne@69: // RGB and BGR variants. Here too the transparency information, if present, jpayne@69: // will be dropped and ignored. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeRGBInto( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: uint8_t* output_buffer, size_t output_buffer_size, int output_stride); jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeBGRInto( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: uint8_t* output_buffer, size_t output_buffer_size, int output_stride); jpayne@69: jpayne@69: // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly jpayne@69: // into pre-allocated luma/chroma plane buffers. This function requires the jpayne@69: // strides to be passed: one for the luma plane and one for each of the jpayne@69: // chroma ones. The size of each plane buffer is passed as 'luma_size', jpayne@69: // 'u_size' and 'v_size' respectively. jpayne@69: // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred jpayne@69: // during decoding (or because some buffers were found to be too small). jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPDecodeYUVInto( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: uint8_t* luma, size_t luma_size, int luma_stride, jpayne@69: uint8_t* u, size_t u_size, int u_stride, jpayne@69: uint8_t* v, size_t v_size, int v_stride); jpayne@69: jpayne@69: //------------------------------------------------------------------------------ jpayne@69: // Output colorspaces and buffer jpayne@69: jpayne@69: // Colorspaces jpayne@69: // Note: the naming describes the byte-ordering of packed samples in memory. jpayne@69: // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... jpayne@69: // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. jpayne@69: // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: jpayne@69: // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... jpayne@69: // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... jpayne@69: // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for jpayne@69: // these two modes: jpayne@69: // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... jpayne@69: // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... jpayne@69: jpayne@69: typedef enum WEBP_CSP_MODE { jpayne@69: MODE_RGB = 0, MODE_RGBA = 1, jpayne@69: MODE_BGR = 2, MODE_BGRA = 3, jpayne@69: MODE_ARGB = 4, MODE_RGBA_4444 = 5, jpayne@69: MODE_RGB_565 = 6, jpayne@69: // RGB-premultiplied transparent modes (alpha value is preserved) jpayne@69: MODE_rgbA = 7, jpayne@69: MODE_bgrA = 8, jpayne@69: MODE_Argb = 9, jpayne@69: MODE_rgbA_4444 = 10, jpayne@69: // YUV modes must come after RGB ones. jpayne@69: MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 jpayne@69: MODE_LAST = 13 jpayne@69: } WEBP_CSP_MODE; jpayne@69: jpayne@69: // Some useful macros: jpayne@69: static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { jpayne@69: return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || jpayne@69: mode == MODE_rgbA_4444); jpayne@69: } jpayne@69: jpayne@69: static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { jpayne@69: return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || jpayne@69: mode == MODE_RGBA_4444 || mode == MODE_YUVA || jpayne@69: WebPIsPremultipliedMode(mode)); jpayne@69: } jpayne@69: jpayne@69: static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { jpayne@69: return (mode < MODE_YUV); jpayne@69: } jpayne@69: jpayne@69: //------------------------------------------------------------------------------ jpayne@69: // WebPDecBuffer: Generic structure for describing the output sample buffer. jpayne@69: jpayne@69: struct WebPRGBABuffer { // view as RGBA jpayne@69: uint8_t* rgba; // pointer to RGBA samples jpayne@69: int stride; // stride in bytes from one scanline to the next. jpayne@69: size_t size; // total size of the *rgba buffer. jpayne@69: }; jpayne@69: jpayne@69: struct WebPYUVABuffer { // view as YUVA jpayne@69: uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples jpayne@69: int y_stride; // luma stride jpayne@69: int u_stride, v_stride; // chroma strides jpayne@69: int a_stride; // alpha stride jpayne@69: size_t y_size; // luma plane size jpayne@69: size_t u_size, v_size; // chroma planes size jpayne@69: size_t a_size; // alpha-plane size jpayne@69: }; jpayne@69: jpayne@69: // Output buffer jpayne@69: struct WebPDecBuffer { jpayne@69: WEBP_CSP_MODE colorspace; // Colorspace. jpayne@69: int width, height; // Dimensions. jpayne@69: int is_external_memory; // If non-zero, 'internal_memory' pointer is not jpayne@69: // used. If value is '2' or more, the external jpayne@69: // memory is considered 'slow' and multiple jpayne@69: // read/write will be avoided. jpayne@69: union { jpayne@69: WebPRGBABuffer RGBA; jpayne@69: WebPYUVABuffer YUVA; jpayne@69: } u; // Nameless union of buffer parameters. jpayne@69: uint32_t pad[4]; // padding for later use jpayne@69: jpayne@69: uint8_t* private_memory; // Internally allocated memory (only when jpayne@69: // is_external_memory is 0). Should not be used jpayne@69: // externally, but accessed via the buffer union. jpayne@69: }; jpayne@69: jpayne@69: // Internal, version-checked, entry point jpayne@69: WEBP_NODISCARD WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int); jpayne@69: jpayne@69: // Initialize the structure as empty. Must be called before any other use. jpayne@69: // Returns false in case of version mismatch jpayne@69: WEBP_NODISCARD static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { jpayne@69: return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); jpayne@69: } jpayne@69: jpayne@69: // Free any memory associated with the buffer. Must always be called last. jpayne@69: // Note: doesn't free the 'buffer' structure itself. jpayne@69: WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer); jpayne@69: jpayne@69: //------------------------------------------------------------------------------ jpayne@69: // Enumeration of the status codes jpayne@69: jpayne@69: typedef enum WEBP_NODISCARD VP8StatusCode { jpayne@69: VP8_STATUS_OK = 0, jpayne@69: VP8_STATUS_OUT_OF_MEMORY, jpayne@69: VP8_STATUS_INVALID_PARAM, jpayne@69: VP8_STATUS_BITSTREAM_ERROR, jpayne@69: VP8_STATUS_UNSUPPORTED_FEATURE, jpayne@69: VP8_STATUS_SUSPENDED, jpayne@69: VP8_STATUS_USER_ABORT, jpayne@69: VP8_STATUS_NOT_ENOUGH_DATA jpayne@69: } VP8StatusCode; jpayne@69: jpayne@69: //------------------------------------------------------------------------------ jpayne@69: // Incremental decoding jpayne@69: // jpayne@69: // This API allows streamlined decoding of partial data. jpayne@69: // Picture can be incrementally decoded as data become available thanks to the jpayne@69: // WebPIDecoder object. This object can be left in a SUSPENDED state if the jpayne@69: // picture is only partially decoded, pending additional input. jpayne@69: // Code example: jpayne@69: /* jpayne@69: WebPInitDecBuffer(&output_buffer); jpayne@69: output_buffer.colorspace = mode; jpayne@69: ... jpayne@69: WebPIDecoder* idec = WebPINewDecoder(&output_buffer); jpayne@69: while (additional_data_is_available) { jpayne@69: // ... (get additional data in some new_data[] buffer) jpayne@69: status = WebPIAppend(idec, new_data, new_data_size); jpayne@69: if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { jpayne@69: break; // an error occurred. jpayne@69: } jpayne@69: jpayne@69: // The above call decodes the current available buffer. jpayne@69: // Part of the image can now be refreshed by calling jpayne@69: // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. jpayne@69: } jpayne@69: WebPIDelete(idec); jpayne@69: */ jpayne@69: jpayne@69: // Creates a new incremental decoder with the supplied buffer parameter. jpayne@69: // This output_buffer can be passed NULL, in which case a default output buffer jpayne@69: // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' jpayne@69: // is kept, which means that the lifespan of 'output_buffer' must be larger than jpayne@69: // that of the returned WebPIDecoder object. jpayne@69: // The supplied 'output_buffer' content MUST NOT be changed between calls to jpayne@69: // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is jpayne@69: // not set to 0. In such a case, it is allowed to modify the pointers, size and jpayne@69: // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain jpayne@69: // within valid bounds. jpayne@69: // All other fields of WebPDecBuffer MUST remain constant between calls. jpayne@69: // Returns NULL if the allocation failed. jpayne@69: WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewDecoder( jpayne@69: WebPDecBuffer* output_buffer); jpayne@69: jpayne@69: // This function allocates and initializes an incremental-decoder object, which jpayne@69: // will output the RGB/A samples specified by 'csp' into a preallocated jpayne@69: // buffer 'output_buffer'. The size of this buffer is at least jpayne@69: // 'output_buffer_size' and the stride (distance in bytes between two scanlines) jpayne@69: // is specified by 'output_stride'. jpayne@69: // Additionally, output_buffer can be passed NULL in which case the output jpayne@69: // buffer will be allocated automatically when the decoding starts. The jpayne@69: // colorspace 'csp' is taken into account for allocating this buffer. All other jpayne@69: // parameters are ignored. jpayne@69: // Returns NULL if the allocation failed, or if some parameters are invalid. jpayne@69: WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewRGB( jpayne@69: WEBP_CSP_MODE csp, jpayne@69: uint8_t* output_buffer, size_t output_buffer_size, int output_stride); jpayne@69: jpayne@69: // This function allocates and initializes an incremental-decoder object, which jpayne@69: // will output the raw luma/chroma samples into a preallocated planes if jpayne@69: // supplied. The luma plane is specified by its pointer 'luma', its size jpayne@69: // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane jpayne@69: // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v jpayne@69: // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer jpayne@69: // can be pass NULL in case one is not interested in the transparency plane. jpayne@69: // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied. jpayne@69: // In this case, the output buffer will be automatically allocated (using jpayne@69: // MODE_YUVA) when decoding starts. All parameters are then ignored. jpayne@69: // Returns NULL if the allocation failed or if a parameter is invalid. jpayne@69: WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewYUVA( jpayne@69: uint8_t* luma, size_t luma_size, int luma_stride, jpayne@69: uint8_t* u, size_t u_size, int u_stride, jpayne@69: uint8_t* v, size_t v_size, int v_stride, jpayne@69: uint8_t* a, size_t a_size, int a_stride); jpayne@69: jpayne@69: // Deprecated version of the above, without the alpha plane. jpayne@69: // Kept for backward compatibility. jpayne@69: WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPINewYUV( jpayne@69: uint8_t* luma, size_t luma_size, int luma_stride, jpayne@69: uint8_t* u, size_t u_size, int u_stride, jpayne@69: uint8_t* v, size_t v_size, int v_stride); jpayne@69: jpayne@69: // Deletes the WebPIDecoder object and associated memory. Must always be called jpayne@69: // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. jpayne@69: WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec); jpayne@69: jpayne@69: // Copies and decodes the next available data. Returns VP8_STATUS_OK when jpayne@69: // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more jpayne@69: // data is expected. Returns error in other cases. jpayne@69: WEBP_EXTERN VP8StatusCode WebPIAppend( jpayne@69: WebPIDecoder* idec, const uint8_t* data, size_t data_size); jpayne@69: jpayne@69: // A variant of the above function to be used when data buffer contains jpayne@69: // partial data from the beginning. In this case data buffer is not copied jpayne@69: // to the internal memory. jpayne@69: // Note that the value of the 'data' pointer can change between calls to jpayne@69: // WebPIUpdate, for instance when the data buffer is resized to fit larger data. jpayne@69: WEBP_EXTERN VP8StatusCode WebPIUpdate( jpayne@69: WebPIDecoder* idec, const uint8_t* data, size_t data_size); jpayne@69: jpayne@69: // Returns the RGB/A image decoded so far. Returns NULL if output params jpayne@69: // are not initialized yet. The RGB/A output type corresponds to the colorspace jpayne@69: // specified during call to WebPINewDecoder() or WebPINewRGB(). jpayne@69: // *last_y is the index of last decoded row in raster scan order. Some pointers jpayne@69: // (*last_y, *width etc.) can be NULL if corresponding information is not jpayne@69: // needed. The values in these pointers are only valid on successful (non-NULL) jpayne@69: // return. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPIDecGetRGB( jpayne@69: const WebPIDecoder* idec, int* last_y, jpayne@69: int* width, int* height, int* stride); jpayne@69: jpayne@69: // Same as above function to get a YUVA image. Returns pointer to the luma jpayne@69: // plane or NULL in case of error. If there is no alpha information jpayne@69: // the alpha pointer '*a' will be returned NULL. jpayne@69: WEBP_NODISCARD WEBP_EXTERN uint8_t* WebPIDecGetYUVA( jpayne@69: const WebPIDecoder* idec, int* last_y, jpayne@69: uint8_t** u, uint8_t** v, uint8_t** a, jpayne@69: int* width, int* height, int* stride, int* uv_stride, int* a_stride); jpayne@69: jpayne@69: // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the jpayne@69: // alpha information (if present). Kept for backward compatibility. jpayne@69: WEBP_NODISCARD static WEBP_INLINE uint8_t* WebPIDecGetYUV( jpayne@69: const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, jpayne@69: int* width, int* height, int* stride, int* uv_stride) { jpayne@69: return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, jpayne@69: stride, uv_stride, NULL); jpayne@69: } jpayne@69: jpayne@69: // Generic call to retrieve information about the displayable area. jpayne@69: // If non NULL, the left/right/width/height pointers are filled with the visible jpayne@69: // rectangular area so far. jpayne@69: // Returns NULL in case the incremental decoder object is in an invalid state. jpayne@69: // Otherwise returns the pointer to the internal representation. This structure jpayne@69: // is read-only, tied to WebPIDecoder's lifespan and should not be modified. jpayne@69: WEBP_NODISCARD WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea( jpayne@69: const WebPIDecoder* idec, int* left, int* top, int* width, int* height); jpayne@69: jpayne@69: //------------------------------------------------------------------------------ jpayne@69: // Advanced decoding parametrization jpayne@69: // jpayne@69: // Code sample for using the advanced decoding API jpayne@69: /* jpayne@69: // A) Init a configuration object jpayne@69: WebPDecoderConfig config; jpayne@69: CHECK(WebPInitDecoderConfig(&config)); jpayne@69: jpayne@69: // B) optional: retrieve the bitstream's features. jpayne@69: CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); jpayne@69: jpayne@69: // C) Adjust 'config', if needed jpayne@69: config.options.no_fancy_upsampling = 1; jpayne@69: config.output.colorspace = MODE_BGRA; jpayne@69: // etc. jpayne@69: jpayne@69: // Note that you can also make config.output point to an externally jpayne@69: // supplied memory buffer, provided it's big enough to store the decoded jpayne@69: // picture. Otherwise, config.output will just be used to allocate memory jpayne@69: // and store the decoded picture. jpayne@69: jpayne@69: // D) Decode! jpayne@69: CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); jpayne@69: jpayne@69: // E) Decoded image is now in config.output (and config.output.u.RGBA) jpayne@69: jpayne@69: // F) Reclaim memory allocated in config's object. It's safe to call jpayne@69: // this function even if the memory is external and wasn't allocated jpayne@69: // by WebPDecode(). jpayne@69: WebPFreeDecBuffer(&config.output); jpayne@69: */ jpayne@69: jpayne@69: // Features gathered from the bitstream jpayne@69: struct WebPBitstreamFeatures { jpayne@69: int width; // Width in pixels, as read from the bitstream. jpayne@69: int height; // Height in pixels, as read from the bitstream. jpayne@69: int has_alpha; // True if the bitstream contains an alpha channel. jpayne@69: int has_animation; // True if the bitstream is an animation. jpayne@69: int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless jpayne@69: jpayne@69: uint32_t pad[5]; // padding for later use jpayne@69: }; jpayne@69: jpayne@69: // Internal, version-checked, entry point jpayne@69: WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal( jpayne@69: const uint8_t*, size_t, WebPBitstreamFeatures*, int); jpayne@69: jpayne@69: // Retrieve features from the bitstream. The *features structure is filled jpayne@69: // with information gathered from the bitstream. jpayne@69: // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns jpayne@69: // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the jpayne@69: // features from headers. Returns error in other cases. jpayne@69: // Note: The following chunk sequences (before the raw VP8/VP8L data) are jpayne@69: // considered valid by this function: jpayne@69: // RIFF + VP8(L) jpayne@69: // RIFF + VP8X + (optional chunks) + VP8(L) jpayne@69: // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. jpayne@69: // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. jpayne@69: static WEBP_INLINE VP8StatusCode WebPGetFeatures( jpayne@69: const uint8_t* data, size_t data_size, jpayne@69: WebPBitstreamFeatures* features) { jpayne@69: return WebPGetFeaturesInternal(data, data_size, features, jpayne@69: WEBP_DECODER_ABI_VERSION); jpayne@69: } jpayne@69: jpayne@69: // Decoding options jpayne@69: struct WebPDecoderOptions { jpayne@69: int bypass_filtering; // if true, skip the in-loop filtering jpayne@69: int no_fancy_upsampling; // if true, use faster pointwise upsampler jpayne@69: int use_cropping; // if true, cropping is applied _first_ jpayne@69: int crop_left, crop_top; // top-left position for cropping. jpayne@69: // Will be snapped to even values. jpayne@69: int crop_width, crop_height; // dimension of the cropping area jpayne@69: int use_scaling; // if true, scaling is applied _afterward_ jpayne@69: int scaled_width, scaled_height; // final resolution jpayne@69: int use_threads; // if true, use multi-threaded decoding jpayne@69: int dithering_strength; // dithering strength (0=Off, 100=full) jpayne@69: int flip; // if true, flip output vertically jpayne@69: int alpha_dithering_strength; // alpha dithering strength in [0..100] jpayne@69: jpayne@69: uint32_t pad[5]; // padding for later use jpayne@69: }; jpayne@69: jpayne@69: // Main object storing the configuration for advanced decoding. jpayne@69: struct WebPDecoderConfig { jpayne@69: WebPBitstreamFeatures input; // Immutable bitstream features (optional) jpayne@69: WebPDecBuffer output; // Output buffer (can point to external mem) jpayne@69: WebPDecoderOptions options; // Decoding options jpayne@69: }; jpayne@69: jpayne@69: // Internal, version-checked, entry point jpayne@69: WEBP_NODISCARD WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, jpayne@69: int); jpayne@69: jpayne@69: // Initialize the configuration as empty. This function must always be jpayne@69: // called first, unless WebPGetFeatures() is to be called. jpayne@69: // Returns false in case of mismatched version. jpayne@69: WEBP_NODISCARD static WEBP_INLINE int WebPInitDecoderConfig( jpayne@69: WebPDecoderConfig* config) { jpayne@69: return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); jpayne@69: } jpayne@69: jpayne@69: // Instantiate a new incremental decoder object with the requested jpayne@69: // configuration. The bitstream can be passed using 'data' and 'data_size' jpayne@69: // parameter, in which case the features will be parsed and stored into jpayne@69: // config->input. Otherwise, 'data' can be NULL and no parsing will occur. jpayne@69: // Note that 'config' can be NULL too, in which case a default configuration jpayne@69: // is used. If 'config' is not NULL, it must outlive the WebPIDecoder object jpayne@69: // as some references to its fields will be used. No internal copy of 'config' jpayne@69: // is made. jpayne@69: // The return WebPIDecoder object must always be deleted calling WebPIDelete(). jpayne@69: // Returns NULL in case of error (and config->status will then reflect jpayne@69: // the error condition, if available). jpayne@69: WEBP_NODISCARD WEBP_EXTERN WebPIDecoder* WebPIDecode( jpayne@69: const uint8_t* data, size_t data_size, WebPDecoderConfig* config); jpayne@69: jpayne@69: // Non-incremental version. This version decodes the full data at once, taking jpayne@69: // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK jpayne@69: // if the decoding was successful). Note that 'config' cannot be NULL. jpayne@69: WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, jpayne@69: WebPDecoderConfig* config); jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: } // extern "C" jpayne@69: #endif jpayne@69: jpayne@69: #endif // WEBP_WEBP_DECODE_H_