#ifndef WEBP_ENC_VP8I_ENC_H_
#define WEBP_ENC_VP8I_ENC_H_
#include <string.h>
#include "src/dec/common_dec.h"
#include "src/dsp/cpu.h"
#include "src/dsp/dsp.h"
#include "src/utils/bit_writer_utils.h"
#include "src/utils/thread_utils.h"
#include "src/utils/utils.h"
#include "src/webp/encode.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ENC_MAJ_VERSION 1
#define ENC_MIN_VERSION 5
#define ENC_REV_VERSION 0
enum { MAX_LF_LEVELS = 64, MAX_VARIABLE_LEVEL = 67, MAX_LEVEL = 2047 };
typedef enum { RD_OPT_NONE = 0, RD_OPT_BASIC = 1, RD_OPT_TRELLIS = 2, RD_OPT_TRELLIS_ALL = 3 } VP8RDLevel;
#define YUV_SIZE_ENC (BPS * 16)
#define PRED_SIZE_ENC (32 * BPS + 16 * BPS + 8 * BPS)
#define Y_OFF_ENC (0)
#define U_OFF_ENC (16)
#define V_OFF_ENC (16 + 8)
extern const uint16_t VP8Scan[16];
extern const uint16_t VP8UVModeOffsets[4];
extern const uint16_t VP8I16ModeOffsets[4];
#define I16DC16 (0 * 16 * BPS)
#define I16TM16 (I16DC16 + 16)
#define I16VE16 (1 * 16 * BPS)
#define I16HE16 (I16VE16 + 16)
#define C8DC8 (2 * 16 * BPS)
#define C8TM8 (C8DC8 + 1 * 16)
#define C8VE8 (2 * 16 * BPS + 8 * BPS)
#define C8HE8 (C8VE8 + 1 * 16)
#define I4DC4 (3 * 16 * BPS + 0)
#define I4TM4 (I4DC4 + 4)
#define I4VE4 (I4DC4 + 8)
#define I4HE4 (I4DC4 + 12)
#define I4RD4 (I4DC4 + 16)
#define I4VR4 (I4DC4 + 20)
#define I4LD4 (I4DC4 + 24)
#define I4VL4 (I4DC4 + 28)
#define I4HD4 (3 * 16 * BPS + 4 * BPS)
#define I4HU4 (I4HD4 + 4)
#define I4TMP (I4HD4 + 8)
typedef int64_t score_t; #define MAX_COST ((score_t)0x7fffffffffffffLL)
#define QFIX 17
#define BIAS(b) ((b) << (QFIX - 8))
static WEBP_INLINE int QUANTDIV(uint32_t n, uint32_t iQ, uint32_t B) {
return (int)((n * iQ + B) >> QFIX);
}
#define ERROR_DIFFUSION_QUALITY 98
typedef uint32_t proba_t; typedef uint8_t ProbaArray[NUM_CTX][NUM_PROBAS];
typedef proba_t StatsArray[NUM_CTX][NUM_PROBAS];
typedef uint16_t CostArray[NUM_CTX][MAX_VARIABLE_LEVEL + 1];
typedef const uint16_t* (*CostArrayPtr)[NUM_CTX]; typedef const uint16_t* CostArrayMap[16][NUM_CTX];
typedef double LFStats[NUM_MB_SEGMENTS][MAX_LF_LEVELS];
typedef struct VP8Encoder VP8Encoder;
typedef struct {
int num_segments_; int update_map_; int size_; } VP8EncSegmentHeader;
typedef struct {
uint8_t segments_[3]; uint8_t skip_proba_; ProbaArray coeffs_[NUM_TYPES][NUM_BANDS]; StatsArray stats_[NUM_TYPES][NUM_BANDS]; CostArray level_cost_[NUM_TYPES][NUM_BANDS]; CostArrayMap remapped_costs_[NUM_TYPES]; int dirty_; int use_skip_proba_; int nb_skip_; } VP8EncProba;
typedef struct {
int simple_; int level_; int sharpness_; int i4x4_lf_delta_; } VP8EncFilterHeader;
typedef struct {
unsigned int type_:2; unsigned int uv_mode_:2;
unsigned int skip_:1;
unsigned int segment_:2;
uint8_t alpha_; } VP8MBInfo;
typedef struct VP8Matrix {
uint16_t q_[16]; uint16_t iq_[16]; uint32_t bias_[16]; uint32_t zthresh_[16]; uint16_t sharpen_[16]; } VP8Matrix;
typedef struct {
VP8Matrix y1_, y2_, uv_; int alpha_; int beta_; int quant_; int fstrength_; int max_edge_; int min_disto_; int lambda_i16_, lambda_i4_, lambda_uv_;
int lambda_mode_, lambda_trellis_, tlambda_;
int lambda_trellis_i16_, lambda_trellis_i4_, lambda_trellis_uv_;
score_t i4_penalty_; } VP8SegmentInfo;
typedef int8_t DError[2 ][2 ];
typedef struct {
score_t D, SD; score_t H, R, score; int16_t y_dc_levels[16]; int16_t y_ac_levels[16][16];
int16_t uv_levels[4 + 4][16];
int mode_i16; uint8_t modes_i4[16]; int mode_uv; uint32_t nz; int8_t derr[2][3]; } VP8ModeScore;
typedef struct {
int x_, y_; uint8_t* yuv_in_; uint8_t* yuv_out_; uint8_t* yuv_out2_; uint8_t* yuv_p_; VP8Encoder* enc_; VP8MBInfo* mb_; VP8BitWriter* bw_; uint8_t* preds_; uint32_t* nz_; #if WEBP_AARCH64 && BPS == 32
uint8_t i4_boundary_[40]; #else
uint8_t i4_boundary_[37]; #endif
uint8_t* i4_top_; int i4_; int top_nz_[9]; int left_nz_[9]; uint64_t bit_count_[4][3]; uint64_t luma_bits_; uint64_t uv_bits_; LFStats* lf_stats_; int do_trellis_; int count_down_; int count_down0_; int percent0_;
DError left_derr_; DError* top_derr_;
uint8_t* y_left_; uint8_t* u_left_; uint8_t* v_left_;
uint8_t* y_top_; uint8_t* uv_top_;
uint8_t yuv_left_mem_[17 + 16 + 16 + 8 + WEBP_ALIGN_CST];
uint8_t yuv_mem_[3 * YUV_SIZE_ENC + PRED_SIZE_ENC + WEBP_ALIGN_CST];
} VP8EncIterator;
void VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it);
void VP8IteratorSetRow(VP8EncIterator* const it, int y);
void VP8IteratorSetCountDown(VP8EncIterator* const it, int count_down);
int VP8IteratorIsDone(const VP8EncIterator* const it);
void VP8IteratorImport(VP8EncIterator* const it, uint8_t* const tmp_32);
void VP8IteratorExport(const VP8EncIterator* const it);
int VP8IteratorNext(VP8EncIterator* const it);
void VP8IteratorSaveBoundary(VP8EncIterator* const it);
int VP8IteratorProgress(const VP8EncIterator* const it, int delta);
void VP8IteratorStartI4(VP8EncIterator* const it);
int VP8IteratorRotateI4(VP8EncIterator* const it,
const uint8_t* const yuv_out);
void VP8IteratorNzToBytes(VP8EncIterator* const it);
void VP8IteratorBytesToNz(VP8EncIterator* const it);
void VP8SetIntra16Mode(const VP8EncIterator* const it, int mode);
void VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes);
void VP8SetIntraUVMode(const VP8EncIterator* const it, int mode);
void VP8SetSkip(const VP8EncIterator* const it, int skip);
void VP8SetSegment(const VP8EncIterator* const it, int segment);
typedef struct VP8Tokens VP8Tokens;
typedef struct {
#if !defined(DISABLE_TOKEN_BUFFER)
VP8Tokens* pages_; VP8Tokens** last_page_; uint16_t* tokens_; int left_; int page_size_; #endif
int error_; } VP8TBuffer;
void VP8TBufferInit(VP8TBuffer* const b, int page_size);
void VP8TBufferClear(VP8TBuffer* const b);
#if !defined(DISABLE_TOKEN_BUFFER)
int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
const uint8_t* const probas, int final_pass);
int VP8RecordCoeffTokens(int ctx, const struct VP8Residual* const res,
VP8TBuffer* const tokens);
size_t VP8EstimateTokenSize(VP8TBuffer* const b, const uint8_t* const probas);
#endif
struct VP8Encoder {
const WebPConfig* config_; WebPPicture* pic_;
VP8EncFilterHeader filter_hdr_; VP8EncSegmentHeader segment_hdr_;
int profile_;
int mb_w_, mb_h_;
int preds_w_;
int num_parts_;
VP8BitWriter bw_; VP8BitWriter parts_[MAX_NUM_PARTITIONS]; VP8TBuffer tokens_;
int percent_;
int has_alpha_;
uint8_t* alpha_data_; uint32_t alpha_data_size_;
WebPWorker alpha_worker_;
VP8SegmentInfo dqm_[NUM_MB_SEGMENTS];
int base_quant_; int alpha_; int uv_alpha_; int dq_y1_dc_;
int dq_y2_dc_, dq_y2_ac_;
int dq_uv_dc_, dq_uv_ac_;
VP8EncProba proba_;
uint64_t sse_[4]; uint64_t sse_count_; int coded_size_;
int residual_bytes_[3][4];
int block_count_[3];
int method_; VP8RDLevel rd_opt_level_; int max_i4_header_bits_; int mb_header_limit_; int thread_level_; int do_search_; int use_tokens_;
VP8MBInfo* mb_info_; uint8_t* preds_; uint32_t* nz_; uint8_t* y_top_; uint8_t* uv_top_; LFStats* lf_stats_; DError* top_derr_; };
extern const uint8_t VP8CoeffsProba0[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
extern const uint8_t
VP8CoeffsUpdateProba[NUM_TYPES][NUM_BANDS][NUM_CTX][NUM_PROBAS];
void VP8DefaultProbas(VP8Encoder* const enc);
void VP8WriteProbas(VP8BitWriter* const bw, const VP8EncProba* const probas);
void VP8CodeIntraModes(VP8Encoder* const enc);
int VP8EncWrite(VP8Encoder* const enc);
void VP8EncFreeBitWriters(VP8Encoder* const enc);
extern const uint8_t VP8Cat3[];
extern const uint8_t VP8Cat4[];
extern const uint8_t VP8Cat5[];
extern const uint8_t VP8Cat6[];
void VP8MakeLuma16Preds(const VP8EncIterator* const it);
void VP8MakeChroma8Preds(const VP8EncIterator* const it);
int VP8GetCostLuma16(VP8EncIterator* const it, const VP8ModeScore* const rd);
int VP8GetCostLuma4(VP8EncIterator* const it, const int16_t levels[16]);
int VP8GetCostUV(VP8EncIterator* const it, const VP8ModeScore* const rd);
int VP8EncLoop(VP8Encoder* const enc);
int VP8EncTokenLoop(VP8Encoder* const enc);
int WebPEncodingSetError(const WebPPicture* const pic, WebPEncodingError error);
int WebPReportProgress(const WebPPicture* const pic,
int percent, int* const percent_store);
int VP8EncAnalyze(VP8Encoder* const enc);
void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
int VP8Decimate(VP8EncIterator* WEBP_RESTRICT const it,
VP8ModeScore* WEBP_RESTRICT const rd,
VP8RDLevel rd_opt);
void VP8EncInitAlpha(VP8Encoder* const enc); int VP8EncStartAlpha(VP8Encoder* const enc); int VP8EncFinishAlpha(VP8Encoder* const enc); int VP8EncDeleteAlpha(VP8Encoder* const enc);
void VP8InitFilter(VP8EncIterator* const it);
void VP8StoreFilterStats(VP8EncIterator* const it);
void VP8AdjustFilterStrength(VP8EncIterator* const it);
int VP8FilterStrengthFromDelta(int sharpness, int delta);
int WebPValidatePicture(const WebPPicture* const picture);
void WebPPictureResetBuffers(WebPPicture* const picture);
int WebPPictureAllocARGB(WebPPicture* const picture);
int WebPPictureAllocYUVA(WebPPicture* const picture);
void WebPReplaceTransparentPixels(WebPPicture* const pic, uint32_t color);
#ifdef __cplusplus
} #endif
#endif