add Advanced Decoding Interface

You can now use WebPDecBuffer, WebPBitstreamFeatures and WebPDecoderOptions
to have better control over the decoding process (and the speed/quality tradeoff).

WebPDecoderOptions allow to:
 - turn fancy upsampler on/off
 - turn in-loop filter on/off
 - perform on-the-fly cropping
 - perform on the-fly rescale
(and more to come. Not all features are implemented yet).

On-the-fly cropping and scaling allow to save quite some memory
(as the decoding operation will now scale with the output's size, not
the input's one). It saves some CPU too (since for instance,
in-loop filtering is partially turned off where it doesn't matter,
and some YUV->RGB conversion operations are ommitted too).

The scaler uses summed area, so is mainly meant to be used for
downscaling (like: for generating thumbnails or previews).

Incremental decoding works with these new options.
More doc to come soon.

dwebp is now using the new decoding interface, with the new flags:
  -nofancy
  -nofilter
  -crop top left width height
  -scale width height

Change-Id: I08baf2fa291941686f4ef70a9cc2e4137874e85e
This commit is contained in:
Pascal Massimino
2011-06-20 00:45:15 -07:00
parent bd2f65f67c
commit d260310511
19 changed files with 2052 additions and 788 deletions

View File

@ -18,46 +18,81 @@ extern "C" {
#include "../webp/decode_vp8.h"
// Decoding output parameters.
//------------------------------------------------------------------------------
// WebPDecParams: Decoding output parameters. Transcient internal object.
typedef struct WebPDecParams WebPDecParams;
typedef int (*OutputFunc)(const VP8Io* const io, WebPDecParams* const p);
// Structure use for on-the-fly rescaling
typedef struct {
uint8_t* output; // rgb(a) or luma
uint8_t *u, *v; // chroma u/v
uint8_t *top_y, *top_u, *top_v; // cache for the fancy upscaler
int stride; // rgb(a) stride or luma stride
int u_stride; // chroma-u stride
int v_stride; // chroma-v stride
WEBP_CSP_MODE mode; // rgb(a) or yuv
int last_y; // coordinate of the line that was last output
int output_size; // size of 'output' buffer
int output_u_size; // size of 'u' buffer
int output_v_size; // size of 'v' buffer
int external_buffer; // If true, the output buffers are externally owned
} WebPDecParams;
int x_expand; // true if we're expanding in the x direction
int fy_scale, fx_scale; // fixed-point scaling factor
int64_t fxy_scale; // ''
// we need hpel-precise add/sub increments, for the downsampled U/V planes.
int y_accum; // vertical accumulator
int y_add, y_sub; // vertical increments (add ~= src, sub ~= dst)
int x_add, x_sub; // horizontal increments (add ~= src, sub ~= dst)
int src_width, src_height; // source dimensions
int dst_width, dst_height; // destination dimensions
uint8_t* dst;
int dst_stride;
int32_t* irow, *frow; // work buffer
} WebPRescaler;
struct WebPDecParams {
WebPDecBuffer* output; // output buffer.
uint8_t* tmp_y, *tmp_u, *tmp_v; // cache for the fancy upsampler
// or used for tmp rescaling
int last_y; // coordinate of the line that was last output
const WebPDecoderOptions* options; // if not NULL, use alt decoding features
// rescalers
WebPRescaler scaler_y, scaler_u, scaler_v, scaler_a;
void* memory; // overall scratch memory for the output work.
OutputFunc emit; // output RGB or YUV samples
OutputFunc emit_alpha; // output alpha channel
};
// Should be called first, before any use of the WebPDecParams object.
void WebPResetDecParams(WebPDecParams* const params);
//------------------------------------------------------------------------------
// Misc utils
// If a RIFF container is detected, validate it and skip over it. Returns
// VP8 bit-stream size if RIFF header is valid else returns 0
uint32_t WebPCheckRIFFHeader(const uint8_t** data_ptr,
uint32_t *data_size_ptr);
uint32_t* data_size_ptr);
// Initializes VP8Io with custom setup, io and teardown functions
void WebPInitCustomIo(VP8Io* const io);
// Initializes VP8Io with custom setup, io and teardown functions. The default
// hooks will use the supplied 'params' as io->opaque handle.
void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
// Initializes params_out by allocating output buffer and setting the
// stride information. It also outputs width and height information of
// the WebP image. Returns 1 if succeeds.
int WebPInitDecParams(const uint8_t* data, uint32_t data_size, int* width,
int* height, WebPDecParams* const params_out);
//------------------------------------------------------------------------------
// Internal functions regarding WebPDecBuffer memory (in buffer.c).
// Don't really need to be externally visible for now.
// Verifies various size configurations (e.g stride >= width, specified
// output size <= stride * height etc.). Returns 0 if checks fail.
int WebPCheckDecParams(const VP8Io* io, const WebPDecParams* params);
// Prepare 'buffer' with the requested initial dimensions width/height.
// If no external storage is supplied, initializes buffer by allocating output
// memory and setting up the stride information. Validate the parameters. Return
// an error code in case of problem (no memory, or invalid stride / size /
// dimension / etc.). If *options is not NULL, also verify that the options'
// parameters are valid and apply them to the width/height dimensions of the
// output buffer. This takes cropping / scaling / rotation into account.
VP8StatusCode WebPAllocateDecBuffer(int width, int height,
const WebPDecoderOptions* const options,
WebPDecBuffer* const buffer);
// Deallocate memory allocated by WebPInitDecParams() and reset the
// WebPDecParams object.
void WebPClearDecParams(WebPDecParams* params);
// Copy 'src' into 'dst' buffer, making sure 'dst' is not marked as owner of the
// memory (still held by 'src').
void WebPCopyDecBuffer(const WebPDecBuffer* const src,
WebPDecBuffer* const dst);
// Copy and transfer ownership from src to dst (beware of parameter order!)
void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst);
//------------------------------------------------------------------------------
#if defined(__cplusplus) || defined(c_plusplus)
} // extern "C"