1a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Copyright 2012 Google Inc. All Rights Reserved.
2a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
30406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Use of this source code is governed by a BSD-style license
40406ce1417f76f2034833414dcecc9f56253640cVikas Arora// that can be found in the COPYING file in the root of the source
50406ce1417f76f2034833414dcecc9f56253640cVikas Arora// tree. An additional intellectual property rights grant can be found
60406ce1417f76f2034833414dcecc9f56253640cVikas Arora// in the file PATENTS. All contributing project authors may
70406ce1417f76f2034833414dcecc9f56253640cVikas Arora// be found in the AUTHORS file in the root of the source tree.
8a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// -----------------------------------------------------------------------------
9a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
10a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Image transforms and color space conversion methods for lossless decoder.
11a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
12a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Authors: Vikas Arora (vikaas.arora@gmail.com)
13a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//          Jyrki Alakuijala (jyrki@google.com)
14a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
15a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#ifndef WEBP_DSP_LOSSLESS_H_
16a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define WEBP_DSP_LOSSLESS_H_
17a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
189e80ee991168a0a6c2a906dd2c17c5e17df4566eJames Zern#include "../webp/types.h"
199e80ee991168a0a6c2a906dd2c17c5e17df4566eJames Zern#include "../webp/decode.h"
20a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
2133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora#include "../enc/histogram.h"
2233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora#include "../utils/utils.h"
2333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
248b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#ifdef __cplusplus
25a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraextern "C" {
26a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
27a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
28a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
2933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// Signatures and generic function-pointers
3033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
3133f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
3233f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LPredictorFunc VP8LPredictors[16];
3333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
3433f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef void (*VP8LProcessBlueAndRedFunc)(uint32_t* argb_data, int num_pixels);
3533f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LProcessBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
3633f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LProcessBlueAndRedFunc VP8LAddGreenToBlueAndRed;
3733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
3833f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef struct {
3933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  // Note: the members are uint8_t, so that any negative values are
4033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  // automatically converted to "mod 256" values.
4133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  uint8_t green_to_red_;
4233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  uint8_t green_to_blue_;
4333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  uint8_t red_to_blue_;
4433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora} VP8LMultipliers;
4533f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef void (*VP8LTransformColorFunc)(const VP8LMultipliers* const m,
4633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                       uint32_t* argb_data, int num_pixels);
4733f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LTransformColorFunc VP8LTransformColor;
4833f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LTransformColorFunc VP8LTransformColorInverse;
4933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
5033f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef void (*VP8LConvertFunc)(const uint32_t* src, int num_pixels,
5133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                uint8_t* dst);
5233f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LConvertFunc VP8LConvertBGRAToRGB;
5333f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LConvertFunc VP8LConvertBGRAToRGBA;
5433f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LConvertFunc VP8LConvertBGRAToRGBA4444;
5533f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LConvertFunc VP8LConvertBGRAToRGB565;
5633f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LConvertFunc VP8LConvertBGRAToBGR;
5733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
5833f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// Expose some C-only fallback functions
598c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LTransformColor_C(const VP8LMultipliers* const m,
608c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Arora                          uint32_t* data, int num_pixels);
618c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
6233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                 uint32_t* data, int num_pixels);
6333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
648c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LConvertBGRAToRGB_C(const uint32_t* src, int num_pixels, uint8_t* dst);
658c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LConvertBGRAToRGBA_C(const uint32_t* src, int num_pixels, uint8_t* dst);
668c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LConvertBGRAToRGBA4444_C(const uint32_t* src,
678c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Arora                                 int num_pixels, uint8_t* dst);
688c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LConvertBGRAToRGB565_C(const uint32_t* src,
698c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Arora                               int num_pixels, uint8_t* dst);
708c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LConvertBGRAToBGR_C(const uint32_t* src, int num_pixels, uint8_t* dst);
718c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels);
728c098653157979e397d3954fc2ea0ee43bae6ab2Vikas Aroravoid VP8LAddGreenToBlueAndRed_C(uint32_t* data, int num_pixels);
738b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
748b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// Must be called before calling any of the above methods.
758b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroravoid VP8LDspInit(void);
768b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
778b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora//------------------------------------------------------------------------------
78a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Image transforms.
79a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
80a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastruct VP8LTransform;  // Defined in dec/vp8li.h.
81a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
82a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Performs inverse transform of data given transform information, start and end
83a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// rows. Transform will be applied to rows [row_start, row_end[.
84a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// The *in and *out pointers refer to source and destination data respectively
85a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// corresponding to the intermediate row (row_start).
86a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LInverseTransform(const struct VP8LTransform* const transform,
87a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                          int row_start, int row_end,
88a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                          const uint32_t* const in, uint32_t* const out);
89a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
900406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Similar to the static method ColorIndexInverseTransform() that is part of
910406ce1417f76f2034833414dcecc9f56253640cVikas Arora// lossless.c, but used only for alpha decoding. It takes uint8_t (rather than
920406ce1417f76f2034833414dcecc9f56253640cVikas Arora// uint32_t) arguments for 'src' and 'dst'.
930406ce1417f76f2034833414dcecc9f56253640cVikas Aroravoid VP8LColorIndexInverseTransformAlpha(
940406ce1417f76f2034833414dcecc9f56253640cVikas Arora    const struct VP8LTransform* const transform, int y_start, int y_end,
950406ce1417f76f2034833414dcecc9f56253640cVikas Arora    const uint8_t* src, uint8_t* dst);
960406ce1417f76f2034833414dcecc9f56253640cVikas Arora
97a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LResidualImage(int width, int height, int bits,
98a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                       uint32_t* const argb, uint32_t* const argb_scratch,
99a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                       uint32_t* const image);
100a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
10133f74dabbc7920a65ed435d7417987589febdc16Vikas Aroravoid VP8LColorSpaceTransform(int width, int height, int bits, int quality,
102a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                             uint32_t* const argb, uint32_t* image);
103a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
104a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
105a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Color space conversion.
106a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
107a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Converts from BGRA to other color spaces.
108a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
109a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                         WEBP_CSP_MODE out_colorspace, uint8_t* const rgba);
110a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
111a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
112a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Misc methods.
113a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
114a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Computes sampled size of 'size' when sampling using 'sampling bits'.
115a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size,
116a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                                              uint32_t sampling_bits) {
117a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return (size + (1 << sampling_bits) - 1) >> sampling_bits;
118a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
119a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
12033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// -----------------------------------------------------------------------------
1211e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Faster logarithm for integers. Small values use a look-up table.
1221e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#define LOG_LOOKUP_IDX_MAX 256
1231e7bf8805bd030c19924a5306837ecd72c295751Vikas Aroraextern const float kLog2Table[LOG_LOOKUP_IDX_MAX];
1241e7bf8805bd030c19924a5306837ecd72c295751Vikas Aroraextern const float kSLog2Table[LOG_LOOKUP_IDX_MAX];
12533f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef float (*VP8LFastLog2SlowFunc)(uint32_t v);
12633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
12733f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LFastLog2SlowFunc VP8LFastLog2Slow;
12833f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
12933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
13033f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic WEBP_INLINE float VP8LFastLog2(uint32_t v) {
1311e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v);
1321e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
133a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Fast calculation of v * log2(v) for integer input.
13433f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic WEBP_INLINE float VP8LFastSLog2(uint32_t v) {
1351e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v);
1361e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
1371e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
1388b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// -----------------------------------------------------------------------------
13933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// Huffman-cost related functions.
1408b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
14133f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef double (*VP8LCostFunc)(const uint32_t* population, int length);
14233f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef double (*VP8LCostCombinedFunc)(const uint32_t* X, const uint32_t* Y,
14333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                       int length);
14433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
14533f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LCostFunc VP8LExtraCost;
14633f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LCostCombinedFunc VP8LExtraCostCombined;
14733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
14833f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef struct {        // small struct to hold counters
14933f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  int counts[2];        // index: 0=zero steak, 1=non-zero streak
15033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora  int streaks[2][2];    // [zero/non-zero][streak<3 / streak>=3]
15133f74dabbc7920a65ed435d7417987589febdc16Vikas Arora} VP8LStreaks;
15233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
15333f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef VP8LStreaks (*VP8LCostCountFunc)(const uint32_t* population,
15433f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                         int length);
15533f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef VP8LStreaks (*VP8LCostCombinedCountFunc)(const uint32_t* X,
15633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                                 const uint32_t* Y, int length);
15733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
15833f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LCostCountFunc VP8LHuffmanCostCount;
15933f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LCostCombinedCountFunc VP8LHuffmanCostCombinedCount;
16033f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
16133f74dabbc7920a65ed435d7417987589febdc16Vikas Aroratypedef void (*VP8LHistogramAddFunc)(const VP8LHistogram* const a,
16233f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                     const VP8LHistogram* const b,
16333f74dabbc7920a65ed435d7417987589febdc16Vikas Arora                                     VP8LHistogram* const out);
16433f74dabbc7920a65ed435d7417987589febdc16Vikas Aroraextern VP8LHistogramAddFunc VP8LHistogramAdd;
16533f74dabbc7920a65ed435d7417987589febdc16Vikas Arora
16633f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// -----------------------------------------------------------------------------
16733f74dabbc7920a65ed435d7417987589febdc16Vikas Arora// PrefixEncode()
1688b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1698b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) {
1708b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int log_floor = BitsLog2Floor(n);
1718b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  if (n == (n & ~(n - 1)))  // zero or a power of two.
1728b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    return log_floor;
1738b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  else
1748b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    return log_floor + 1;
1758b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
1768b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1778b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// Splitting of distance and length codes into prefixes and
1788b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// extra bits. The prefixes are encoded with an entropy code
1798b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// while the extra bits are stored just as normal bits.
1808b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8LPrefixEncodeBitsNoLUT(int distance, int* const code,
1818b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                                                  int* const extra_bits) {
1828b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int highest_bit = BitsLog2Floor(--distance);
1838b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
1848b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  *extra_bits = highest_bit - 1;
1858b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  *code = 2 * highest_bit + second_highest_bit;
1868b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
1878b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1888b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code,
1898b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                                              int* const extra_bits,
1908b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                                              int* const extra_bits_value) {
1918b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int highest_bit = BitsLog2Floor(--distance);
1928b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int second_highest_bit = (distance >> (highest_bit - 1)) & 1;
1938b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  *extra_bits = highest_bit - 1;
1948b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  *extra_bits_value = distance & ((1 << *extra_bits) - 1);
1958b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  *code = 2 * highest_bit + second_highest_bit;
1968b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
1978b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1988b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#define PREFIX_LOOKUP_IDX_MAX   512
1998b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroratypedef struct {
2008b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  int8_t code_;
2018b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  int8_t extra_bits_;
2028b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora} VP8LPrefixCode;
2038b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
2048b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// These tables are derived using VP8LPrefixEncodeNoLUT.
2058b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroraextern const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX];
2068b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroraextern const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX];
2078b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8LPrefixEncodeBits(int distance, int* const code,
2088b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                                             int* const extra_bits) {
2098b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  if (distance < PREFIX_LOOKUP_IDX_MAX) {
2108b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance];
2118b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    *code = prefix_code.code_;
2128b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    *extra_bits = prefix_code.extra_bits_;
2138b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  } else {
2148b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    VP8LPrefixEncodeBitsNoLUT(distance, code, extra_bits);
2158b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  }
2168b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
2178b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
2188b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code,
2198b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                                         int* const extra_bits,
2208b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                                         int* const extra_bits_value) {
2218b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  if (distance < PREFIX_LOOKUP_IDX_MAX) {
2228b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance];
2238b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    *code = prefix_code.code_;
2248b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    *extra_bits = prefix_code.extra_bits_;
2258b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    *extra_bits_value = kPrefixEncodeExtraBitsValue[distance];
2268b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  } else {
2278b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value);
2288b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  }
2298b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
230a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
231a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// In-place difference of each component with mod 256.
232a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {
233a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const uint32_t alpha_and_green =
234a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u);
235a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const uint32_t red_and_blue =
236a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      0xff00ff00u + (a & 0x00ff00ffu) - (b & 0x00ff00ffu);
237a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu);
238a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
239a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
2400406ce1417f76f2034833414dcecc9f56253640cVikas Aroravoid VP8LBundleColorMap(const uint8_t* const row, int width,
2410406ce1417f76f2034833414dcecc9f56253640cVikas Arora                        int xbits, uint32_t* const dst);
2420406ce1417f76f2034833414dcecc9f56253640cVikas Arora
243a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
244a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
2458b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#ifdef __cplusplus
246a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}    // extern "C"
247a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
248a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
249a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif  // WEBP_DSP_LOSSLESS_H_
250