2010-09-30 15:34:38 +02:00
|
|
|
// Copyright 2010 Google Inc.
|
|
|
|
//
|
|
|
|
// This code is licensed under the same terms as WebM:
|
|
|
|
// Software License Agreement: http://www.webmproject.org/license/software/
|
|
|
|
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// VP8 decoder: internal header.
|
|
|
|
//
|
|
|
|
// Author: Skal (pascal.massimino@gmail.com)
|
|
|
|
|
2011-02-01 07:00:33 +01:00
|
|
|
#ifndef WEBP_DEC_VP8I_H_
|
|
|
|
#define WEBP_DEC_VP8I_H_
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
#include <string.h> // for memcpy()
|
|
|
|
#include "bits.h"
|
|
|
|
|
|
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Various defines and enums
|
|
|
|
|
2011-03-25 00:17:10 +01:00
|
|
|
// version numbers
|
|
|
|
#define DEC_MAJ_VERSION 0
|
|
|
|
#define DEC_MIN_VERSION 1
|
|
|
|
#define DEC_REV_VERSION 2
|
|
|
|
|
2010-09-30 15:34:38 +02:00
|
|
|
#define ONLY_KEYFRAME_CODE // to remove any code related to P-Frames
|
|
|
|
|
|
|
|
// intra prediction modes
|
|
|
|
enum { B_DC_PRED = 0, // 4x4 modes
|
|
|
|
B_TM_PRED,
|
|
|
|
B_VE_PRED,
|
|
|
|
B_HE_PRED,
|
|
|
|
B_RD_PRED,
|
|
|
|
B_VR_PRED,
|
2010-11-18 05:06:01 +01:00
|
|
|
B_LD_PRED,
|
2010-09-30 15:34:38 +02:00
|
|
|
B_VL_PRED,
|
|
|
|
B_HD_PRED,
|
|
|
|
B_HU_PRED,
|
|
|
|
NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED, // = 10
|
|
|
|
|
|
|
|
// Luma16 or UV modes
|
|
|
|
DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
|
|
|
|
H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED,
|
|
|
|
B_PRED = NUM_BMODES, // refined I4x4 mode
|
|
|
|
|
|
|
|
// special modes
|
|
|
|
B_DC_PRED_NOTOP = 4,
|
|
|
|
B_DC_PRED_NOLEFT = 5,
|
2011-03-14 06:38:44 +01:00
|
|
|
B_DC_PRED_NOTOPLEFT = 6,
|
|
|
|
NUM_B_DC_MODES = 7 };
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
enum { MB_FEATURE_TREE_PROBS = 3,
|
|
|
|
NUM_MB_SEGMENTS = 4,
|
|
|
|
NUM_REF_LF_DELTAS = 4,
|
|
|
|
NUM_MODE_LF_DELTAS = 4, // I4x4, ZERO, *, SPLIT
|
|
|
|
MAX_NUM_PARTITIONS = 8,
|
|
|
|
// Probabilities
|
|
|
|
NUM_TYPES = 4,
|
|
|
|
NUM_BANDS = 8,
|
|
|
|
NUM_CTX = 3,
|
|
|
|
NUM_PROBAS = 11,
|
|
|
|
NUM_MV_PROBAS = 19 };
|
|
|
|
|
|
|
|
// YUV-cache parameters.
|
|
|
|
// Constraints are: We need to store one 16x16 block of luma samples (y),
|
|
|
|
// and two 8x8 chroma blocks (u/v). These are better be 16-bytes aligned,
|
|
|
|
// in order to be SIMD-friendly. We also need to store the top, left and
|
|
|
|
// top-left samples (from previously decoded blocks), along with four
|
|
|
|
// extra top-right samples for luma (intra4x4 prediction only).
|
|
|
|
// One possible layout is, using 32 * (17 + 9) bytes:
|
|
|
|
//
|
|
|
|
// .+------ <- only 1 pixel high
|
|
|
|
// .|yyyyt.
|
|
|
|
// .|yyyyt.
|
|
|
|
// .|yyyyt.
|
|
|
|
// .|yyyy..
|
|
|
|
// .+--.+-- <- only 1 pixel high
|
|
|
|
// .|uu.|vv
|
|
|
|
// .|uu.|vv
|
|
|
|
//
|
|
|
|
// Every character is a 4x4 block, with legend:
|
|
|
|
// '.' = unused
|
|
|
|
// 'y' = y-samples 'u' = u-samples 'v' = u-samples
|
|
|
|
// '|' = left sample, '-' = top sample, '+' = top-left sample
|
|
|
|
// 't' = extra top-right sample for 4x4 modes
|
|
|
|
// With this layout, BPS (=Bytes Per Scan-line) is one cacheline size.
|
|
|
|
#define BPS 32 // this is the common stride used by yuv[]
|
|
|
|
#define YUV_SIZE (BPS * 17 + BPS * 9)
|
|
|
|
#define Y_SIZE (BPS * 17)
|
|
|
|
#define Y_OFF (BPS * 1 + 8)
|
|
|
|
#define U_OFF (Y_OFF + BPS * 16 + BPS)
|
|
|
|
#define V_OFF (U_OFF + 16)
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Headers
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t key_frame_;
|
|
|
|
uint8_t profile_;
|
|
|
|
uint8_t show_;
|
|
|
|
uint32_t partition_length_;
|
|
|
|
} VP8FrameHeader;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint16_t width_;
|
|
|
|
uint16_t height_;
|
|
|
|
uint8_t xscale_;
|
|
|
|
uint8_t yscale_;
|
|
|
|
uint8_t colorspace_; // 0 = YCbCr
|
|
|
|
uint8_t clamp_type_;
|
|
|
|
} VP8PictureHeader;
|
|
|
|
|
|
|
|
// segment features
|
|
|
|
typedef struct {
|
|
|
|
int use_segment_;
|
|
|
|
int update_map_; // whether to update the segment map or not
|
|
|
|
int absolute_delta_; // absolute or delta values for quantizer and filter
|
|
|
|
int8_t quantizer_[NUM_MB_SEGMENTS]; // quantization changes
|
|
|
|
int8_t filter_strength_[NUM_MB_SEGMENTS]; // filter strength for segments
|
|
|
|
} VP8SegmentHeader;
|
|
|
|
|
|
|
|
// Struct collecting all frame-persistent probabilities.
|
|
|
|
typedef struct {
|
|
|
|
uint8_t segments_[MB_FEATURE_TREE_PROBS];
|
|
|
|
// Type: 0:Intra16-AC 1:Intra16-DC 2:Chroma 3:Intra4
|
|
|
|
uint8_t coeffs_[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
|
|
|
|
#ifndef ONLY_KEYFRAME_CODE
|
|
|
|
uint8_t ymode_[4], uvmode_[3];
|
|
|
|
uint8_t mv_[2][NUM_MV_PROBAS];
|
|
|
|
#endif
|
|
|
|
} VP8Proba;
|
|
|
|
|
|
|
|
// Filter parameters
|
|
|
|
typedef struct {
|
|
|
|
int simple_; // 0=complex, 1=simple
|
|
|
|
int level_; // [0..63]
|
|
|
|
int sharpness_; // [0..7]
|
|
|
|
int use_lf_delta_;
|
|
|
|
int ref_lf_delta_[NUM_REF_LF_DELTAS];
|
|
|
|
int mode_lf_delta_[NUM_MODE_LF_DELTAS];
|
|
|
|
} VP8FilterHeader;
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Informations about the macroblocks.
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
// block type
|
|
|
|
uint8_t skip_:1;
|
|
|
|
// filter specs
|
|
|
|
uint8_t f_level_:6; // filter strength: 0..63
|
|
|
|
uint8_t f_ilevel_:6; // inner limit: 1..63
|
|
|
|
uint8_t f_inner_:1; // do inner filtering?
|
|
|
|
// cbp
|
|
|
|
uint8_t nz_; // non-zero AC/DC coeffs
|
|
|
|
uint8_t dc_nz_; // non-zero DC coeffs
|
|
|
|
} VP8MB;
|
|
|
|
|
|
|
|
// Dequantization matrices
|
|
|
|
typedef struct {
|
|
|
|
uint16_t y1_mat_[2], y2_mat_[2], uv_mat_[2]; // [DC / AC]
|
|
|
|
} VP8QuantMatrix;
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// VP8Decoder: the main opaque structure handed over to user
|
|
|
|
|
|
|
|
struct VP8Decoder {
|
2011-02-16 23:33:16 +01:00
|
|
|
VP8StatusCode status_;
|
2010-09-30 15:34:38 +02:00
|
|
|
int ready_; // true if ready to decode a picture with VP8Decode()
|
|
|
|
const char* error_msg_; // set when status_ is not OK.
|
|
|
|
|
|
|
|
// Main data source
|
|
|
|
VP8BitReader br_;
|
|
|
|
|
|
|
|
// headers
|
2010-11-18 05:06:01 +01:00
|
|
|
VP8FrameHeader frm_hdr_;
|
|
|
|
VP8PictureHeader pic_hdr_;
|
|
|
|
VP8FilterHeader filter_hdr_;
|
|
|
|
VP8SegmentHeader segment_hdr_;
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
// dimension, in macroblock units.
|
|
|
|
int mb_w_, mb_h_;
|
|
|
|
|
2011-06-20 09:45:15 +02:00
|
|
|
// Macroblock to process/filter, depending on cropping and filter_type.
|
|
|
|
int tl_mb_x_, tl_mb_y_; // top-left MB that must be in-loop filtered
|
|
|
|
int br_mb_x_, br_mb_y_; // last bottom-right MB that must be decoded
|
|
|
|
|
2010-09-30 15:34:38 +02:00
|
|
|
// number of partitions.
|
|
|
|
int num_parts_;
|
|
|
|
// per-partition boolean decoders.
|
|
|
|
VP8BitReader parts_[MAX_NUM_PARTITIONS];
|
|
|
|
|
|
|
|
// buffer refresh flags
|
|
|
|
// bit 0: refresh Gold, bit 1: refresh Alt
|
|
|
|
// bit 2-3: copy to Gold, bit 4-5: copy to Alt
|
|
|
|
// bit 6: Gold sign bias, bit 7: Alt sign bias
|
|
|
|
// bit 8: refresh last frame
|
|
|
|
uint32_t buffer_flags_;
|
|
|
|
|
|
|
|
// dequantization (one set of DC/AC dequant factor per segment)
|
|
|
|
VP8QuantMatrix dqm_[NUM_MB_SEGMENTS];
|
|
|
|
|
|
|
|
// probabilities
|
2010-11-18 05:06:01 +01:00
|
|
|
VP8Proba proba_;
|
2010-09-30 15:34:38 +02:00
|
|
|
int use_skip_proba_;
|
2010-11-18 05:06:01 +01:00
|
|
|
uint8_t skip_p_;
|
|
|
|
#ifndef ONLY_KEYFRAME_CODE
|
|
|
|
uint8_t intra_p_, last_p_, golden_p_;
|
|
|
|
VP8Proba proba_saved_;
|
|
|
|
int update_proba_;
|
|
|
|
#endif
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
// Boundary data cache and persistent buffers.
|
|
|
|
uint8_t* intra_t_; // top intra modes values: 4 * mb_w_
|
|
|
|
uint8_t intra_l_[4]; // left intra modes values
|
2011-06-20 09:45:15 +02:00
|
|
|
uint8_t* y_t_; // top luma samples: 16 * mb_w_
|
|
|
|
uint8_t* u_t_, *v_t_; // top u/v samples: 8 * mb_w_ each
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
VP8MB* mb_info_; // contextual macroblock infos (mb_w_ + 1)
|
|
|
|
uint8_t* yuv_b_; // main block for Y/U/V (size = YUV_SIZE)
|
|
|
|
int16_t* coeffs_; // 384 coeffs = (16+8+8) * 4*4
|
|
|
|
|
|
|
|
uint8_t* cache_y_; // macroblock row for storing unfiltered samples
|
|
|
|
uint8_t* cache_u_;
|
|
|
|
uint8_t* cache_v_;
|
|
|
|
int cache_y_stride_;
|
|
|
|
int cache_uv_stride_;
|
|
|
|
|
|
|
|
// main memory chunk for the above data. Persistent.
|
|
|
|
void* mem_;
|
|
|
|
int mem_size_;
|
|
|
|
|
|
|
|
// Per macroblock non-persistent infos.
|
|
|
|
int mb_x_, mb_y_; // current position, in macroblock units
|
|
|
|
uint8_t is_i4x4_; // true if intra4x4
|
|
|
|
uint8_t imodes_[16]; // one 16x16 mode (#0) or sixteen 4x4 modes
|
|
|
|
uint8_t uvmode_; // chroma prediction mode
|
|
|
|
uint8_t segment_; // block's segment
|
|
|
|
|
|
|
|
// bit-wise info about the content of each sub-4x4 blocks: there are 16 bits
|
|
|
|
// for luma (bits #0->#15), then 4 bits for chroma-u (#16->#19) and 4 bits for
|
|
|
|
// chroma-v (#20->#23), each corresponding to one 4x4 block in decoding order.
|
|
|
|
// If the bit is set, the 4x4 block contains some non-zero coefficients.
|
|
|
|
uint32_t non_zero_;
|
|
|
|
uint32_t non_zero_ac_;
|
|
|
|
|
|
|
|
// Filtering side-info
|
2011-05-03 02:19:00 +02:00
|
|
|
int filter_type_; // 0=off, 1=simple, 2=complex
|
2010-09-30 15:34:38 +02:00
|
|
|
uint8_t filter_levels_[NUM_MB_SEGMENTS]; // precalculated per-segment
|
EXPERIMENTAL: add support for alpha channel
This is a (minor) bitstream change: if the 'color_space' bit is set to '1'
(which is normally an undefined/invalid behaviour), we add extra data at the
end of partition #0 (so-called 'extensions')
Namely, we add the size of the extension data as 3 bytes (little-endian),
followed by a set of bits telling which extensions we're incorporating.
The data then _preceeds_ this trailing tags.
This is all experimental, and you'll need to have
'#define WEBP_EXPERIMENTAL_FEATURES' in webp/types.h to enable this code
(at your own risk! :))
Still, this hack produces almost-valid WebP file for decoders that don't
check this color_space bit. In particular, previous 'dwebp' (and for instance
Chrome) will recognize this files and decode them, but without the alpha
of course. Other decoder will just see random extra stuff at the end of
partition #0.
To experiment with the alpha-channel, you need to compile on Unix platform
and use PNGs for input/output.
If 'alpha.png' is a source with alpha channel, then you can try (on Unix):
cwebp alpha.png -o alpha.webp
dwebp alpha.webp -o test.png
cwebp now has a '-noalpha' flag to ignore any alpha information from the
source, if present.
More hacking and experimenting welcome!
Change-Id: I3c7b1fd8411c9e7a9f77690e898479ad85c52f3e
2011-04-26 01:58:04 +02:00
|
|
|
|
|
|
|
// extensions
|
|
|
|
const uint8_t* alpha_data_; // compressed alpha data (if present)
|
|
|
|
size_t alpha_data_size_;
|
|
|
|
uint8_t* alpha_plane_; // output
|
2011-05-03 02:19:00 +02:00
|
|
|
|
|
|
|
int layer_colorspace_;
|
|
|
|
const uint8_t* layer_data_; // compressed layer data (if present)
|
|
|
|
size_t layer_data_size_;
|
2010-09-30 15:34:38 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// internal functions. Not public.
|
|
|
|
|
|
|
|
// in vp8.c
|
2011-02-16 23:33:16 +01:00
|
|
|
int VP8SetError(VP8Decoder* const dec,
|
|
|
|
VP8StatusCode error, const char * const msg);
|
2011-05-20 04:07:01 +02:00
|
|
|
// Validates the VP8 data-header and retrieve basic header information viz width
|
2011-06-20 09:45:15 +02:00
|
|
|
// and height. Returns 0 in case of formatting error. *width/*height/*has_alpha
|
|
|
|
// can be passed NULL.
|
|
|
|
int VP8GetInfo(const uint8_t* data,
|
|
|
|
uint32_t data_size, // data available so far
|
|
|
|
uint32_t chunk_size, // total data size expect in the chunk
|
|
|
|
int *width, int *height, int *has_alpha);
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
// in tree.c
|
|
|
|
void VP8ResetProba(VP8Proba* const proba);
|
|
|
|
void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec);
|
|
|
|
void VP8ParseIntraMode(VP8BitReader* const br, VP8Decoder* const dec);
|
|
|
|
|
|
|
|
// in quant.c
|
|
|
|
void VP8ParseQuant(VP8Decoder* const dec);
|
|
|
|
|
|
|
|
// in frame.c
|
|
|
|
int VP8InitFrame(VP8Decoder* const dec, VP8Io* io);
|
|
|
|
// Predict a block and add residual
|
|
|
|
void VP8ReconstructBlock(VP8Decoder* const dec);
|
2011-06-20 09:45:15 +02:00
|
|
|
// Call io->setup() and finish setting up scan parameters.
|
|
|
|
VP8StatusCode VP8FinishFrameSetup(VP8Decoder* const dec, VP8Io* const io);
|
|
|
|
// Filter the decoded macroblock row (if needed)
|
|
|
|
void VP8FilterRow(const VP8Decoder* const dec);
|
2010-11-03 22:27:51 +01:00
|
|
|
// Store a block, along with filtering params
|
2010-11-04 01:52:00 +01:00
|
|
|
void VP8StoreBlock(VP8Decoder* const dec);
|
2011-02-16 23:33:16 +01:00
|
|
|
// Finalize and transmit a complete row. Return false in case of user-abort.
|
2011-06-20 09:45:15 +02:00
|
|
|
int VP8FinishRow(VP8Decoder* const dec, VP8Io* const io);
|
2011-03-10 06:29:36 +01:00
|
|
|
// Decode one macroblock. Returns false if there is not enough data.
|
|
|
|
int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br);
|
2010-09-30 15:34:38 +02:00
|
|
|
|
EXPERIMENTAL: add support for alpha channel
This is a (minor) bitstream change: if the 'color_space' bit is set to '1'
(which is normally an undefined/invalid behaviour), we add extra data at the
end of partition #0 (so-called 'extensions')
Namely, we add the size of the extension data as 3 bytes (little-endian),
followed by a set of bits telling which extensions we're incorporating.
The data then _preceeds_ this trailing tags.
This is all experimental, and you'll need to have
'#define WEBP_EXPERIMENTAL_FEATURES' in webp/types.h to enable this code
(at your own risk! :))
Still, this hack produces almost-valid WebP file for decoders that don't
check this color_space bit. In particular, previous 'dwebp' (and for instance
Chrome) will recognize this files and decode them, but without the alpha
of course. Other decoder will just see random extra stuff at the end of
partition #0.
To experiment with the alpha-channel, you need to compile on Unix platform
and use PNGs for input/output.
If 'alpha.png' is a source with alpha channel, then you can try (on Unix):
cwebp alpha.png -o alpha.webp
dwebp alpha.webp -o test.png
cwebp now has a '-noalpha' flag to ignore any alpha information from the
source, if present.
More hacking and experimenting welcome!
Change-Id: I3c7b1fd8411c9e7a9f77690e898479ad85c52f3e
2011-04-26 01:58:04 +02:00
|
|
|
// in alpha.c
|
|
|
|
const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
|
|
|
int row, int num_rows);
|
|
|
|
|
2011-05-03 02:19:00 +02:00
|
|
|
// in layer.c
|
|
|
|
int VP8DecodeLayer(VP8Decoder* const dec);
|
|
|
|
|
2010-09-30 15:34:38 +02:00
|
|
|
// in dsp.c
|
|
|
|
typedef void (*VP8Idct)(const int16_t* coeffs, uint8_t* dst);
|
2011-06-20 09:22:37 +02:00
|
|
|
// when doing two transforms, coeffs is actually int16_t[2][16].
|
|
|
|
typedef void (*VP8Idct2)(const int16_t* coeffs, uint8_t* dst, int do_two);
|
|
|
|
extern VP8Idct2 VP8Transform;
|
2010-09-30 15:34:38 +02:00
|
|
|
extern VP8Idct VP8TransformUV;
|
|
|
|
extern VP8Idct VP8TransformDC;
|
|
|
|
extern VP8Idct VP8TransformDCUV;
|
|
|
|
extern void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
|
|
|
|
|
|
|
|
// *dst is the destination block, with stride BPS. Boundary samples are
|
|
|
|
// assumed accessible when needed.
|
2011-06-20 09:45:15 +02:00
|
|
|
typedef void (*VP8PredFunc)(uint8_t* dst);
|
2011-03-14 06:38:44 +01:00
|
|
|
extern VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
|
|
|
|
extern VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
|
|
|
|
extern VP8PredFunc VP8PredLuma4[NUM_BMODES];
|
2010-09-30 15:34:38 +02:00
|
|
|
|
2011-03-25 23:04:11 +01:00
|
|
|
void VP8DspInit(void); // must be called before anything using the above
|
|
|
|
void VP8DspInitTables(void); // needs to be called no matter what.
|
2010-09-30 15:34:38 +02:00
|
|
|
|
|
|
|
// simple filter (only for luma)
|
|
|
|
typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh);
|
|
|
|
extern VP8SimpleFilterFunc VP8SimpleVFilter16;
|
|
|
|
extern VP8SimpleFilterFunc VP8SimpleHFilter16;
|
|
|
|
extern VP8SimpleFilterFunc VP8SimpleVFilter16i; // filter 3 inner edges
|
|
|
|
extern VP8SimpleFilterFunc VP8SimpleHFilter16i;
|
|
|
|
|
|
|
|
// regular filter (on both macroblock edges and inner edges)
|
|
|
|
typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride,
|
|
|
|
int thresh, int ithresh, int hev_t);
|
|
|
|
typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride,
|
|
|
|
int thresh, int ithresh, int hev_t);
|
|
|
|
// on outter edge
|
|
|
|
extern VP8LumaFilterFunc VP8VFilter16;
|
|
|
|
extern VP8LumaFilterFunc VP8HFilter16;
|
|
|
|
extern VP8ChromaFilterFunc VP8VFilter8;
|
|
|
|
extern VP8ChromaFilterFunc VP8HFilter8;
|
|
|
|
|
|
|
|
// on inner edge
|
|
|
|
extern VP8LumaFilterFunc VP8VFilter16i; // filtering 3 inner edges altogether
|
|
|
|
extern VP8LumaFilterFunc VP8HFilter16i;
|
|
|
|
extern VP8ChromaFilterFunc VP8VFilter8i; // filtering u and v altogether
|
|
|
|
extern VP8ChromaFilterFunc VP8HFilter8i;
|
|
|
|
|
2011-06-11 00:10:18 +02:00
|
|
|
typedef enum {
|
|
|
|
kSSE2,
|
|
|
|
kSSE3
|
|
|
|
} CPUFeature;
|
|
|
|
// returns true if the CPU supports the feature.
|
|
|
|
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
|
|
|
extern VP8CPUInfo VP8DecGetCPUInfo;
|
|
|
|
|
2010-09-30 15:34:38 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
|
|
} // extern "C"
|
|
|
|
#endif
|
|
|
|
|
2011-02-01 07:00:33 +01:00
|
|
|
#endif // WEBP_DEC_VP8I_H_
|