• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 Google Inc. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
9 //
10 // Image transform methods for lossless encoder.
11 //
12 // Authors: Vikas Arora (vikaas.arora@gmail.com)
13 //          Jyrki Alakuijala (jyrki@google.com)
14 //          Urvang Joshi (urvang@google.com)
15 
16 #include "src/dsp/dsp.h"
17 
18 #include <assert.h>
19 #include <math.h>
20 #include <stdlib.h>
21 #include "src/dec/vp8li_dec.h"
22 #include "src/utils/endian_inl_utils.h"
23 #include "src/dsp/lossless.h"
24 #include "src/dsp/lossless_common.h"
25 #include "src/dsp/yuv.h"
26 
27 // lookup table for small values of log2(int) * (1 << LOG_2_PRECISION_BITS).
28 // Obtained in Python with:
29 // a = [ str(round((1<<23)*math.log2(i))) if i else "0" for i in range(256)]
30 // print(',\n'.join(['  '+','.join(v)
31 //       for v in batched([i.rjust(9) for i in a],7)]))
32 const uint32_t kLog2Table[LOG_LOOKUP_IDX_MAX] = {
33          0,        0,  8388608, 13295629, 16777216, 19477745, 21684237,
34   23549800, 25165824, 26591258, 27866353, 29019816, 30072845, 31041538,
35   31938408, 32773374, 33554432, 34288123, 34979866, 35634199, 36254961,
36   36845429, 37408424, 37946388, 38461453, 38955489, 39430146, 39886887,
37   40327016, 40751698, 41161982, 41558811, 41943040, 42315445, 42676731,
38   43027545, 43368474, 43700062, 44022807, 44337167, 44643569, 44942404,
39   45234037, 45518808, 45797032, 46069003, 46334996, 46595268, 46850061,
40   47099600, 47344097, 47583753, 47818754, 48049279, 48275495, 48497560,
41   48715624, 48929828, 49140306, 49347187, 49550590, 49750631, 49947419,
42   50141058, 50331648, 50519283, 50704053, 50886044, 51065339, 51242017,
43   51416153, 51587818, 51757082, 51924012, 52088670, 52251118, 52411415,
44   52569616, 52725775, 52879946, 53032177, 53182516, 53331012, 53477707,
45   53622645, 53765868, 53907416, 54047327, 54185640, 54322389, 54457611,
46   54591338, 54723604, 54854440, 54983876, 55111943, 55238669, 55364082,
47   55488208, 55611074, 55732705, 55853126, 55972361, 56090432, 56207362,
48   56323174, 56437887, 56551524, 56664103, 56775645, 56886168, 56995691,
49   57104232, 57211808, 57318436, 57424133, 57528914, 57632796, 57735795,
50   57837923, 57939198, 58039632, 58139239, 58238033, 58336027, 58433234,
51   58529666, 58625336, 58720256, 58814437, 58907891, 59000628, 59092661,
52   59183999, 59274652, 59364632, 59453947, 59542609, 59630625, 59718006,
53   59804761, 59890898, 59976426, 60061354, 60145690, 60229443, 60312620,
54   60395229, 60477278, 60558775, 60639726, 60720140, 60800023, 60879382,
55   60958224, 61036555, 61114383, 61191714, 61268554, 61344908, 61420785,
56   61496188, 61571124, 61645600, 61719620, 61793189, 61866315, 61939001,
57   62011253, 62083076, 62154476, 62225457, 62296024, 62366182, 62435935,
58   62505289, 62574248, 62642816, 62710997, 62778797, 62846219, 62913267,
59   62979946, 63046260, 63112212, 63177807, 63243048, 63307939, 63372484,
60   63436687, 63500551, 63564080, 63627277, 63690146, 63752690, 63814912,
61   63876816, 63938405, 63999682, 64060650, 64121313, 64181673, 64241734,
62   64301498, 64360969, 64420148, 64479040, 64537646, 64595970, 64654014,
63   64711782, 64769274, 64826495, 64883447, 64940132, 64996553, 65052711,
64   65108611, 65164253, 65219641, 65274776, 65329662, 65384299, 65438691,
65   65492840, 65546747, 65600416, 65653847, 65707044, 65760008, 65812741,
66   65865245, 65917522, 65969575, 66021404, 66073013, 66124403, 66175575,
67   66226531, 66277275, 66327806, 66378127, 66428240, 66478146, 66527847,
68   66577345, 66626641, 66675737, 66724635, 66773336, 66821842, 66870154,
69   66918274, 66966204, 67013944, 67061497
70 };
71 
72 // lookup table for small values of int*log2(int) * (1 << LOG_2_PRECISION_BITS).
73 // Obtained in Python with:
74 // a=[ "%d"%i if i<(1<<32) else "%dull"%i
75 //     for i in [ round((1<<LOG_2_PRECISION_BITS)*math.log2(i)*i) if i
76 //     else 0 for i in range(256)]]
77 // print(',\n '.join([','.join(v) for v in batched([i.rjust(15)
78 //                      for i in a],4)]))
79 const uint64_t kSLog2Table[LOG_LOOKUP_IDX_MAX] = {
80                0,              0,       16777216,       39886887,
81         67108864,       97388723,      130105423,      164848600,
82        201326592,      239321324,      278663526,      319217973,
83        360874141,      403539997,      447137711,      491600606,
84        536870912,      582898099,      629637592,      677049776,
85        725099212,      773754010,      822985323,      872766924,
86        923074875,      973887230,     1025183802,     1076945958,
87       1129156447,     1181799249,     1234859451,     1288323135,
88       1342177280,     1396409681,     1451008871,     1505964059,
89       1561265072,     1616902301,     1672866655,     1729149526,
90       1785742744,     1842638548,     1899829557,     1957308741,
91       2015069397,     2073105127,     2131409817,  2189977618ull,
92    2248802933ull,  2307880396ull,  2367204859ull,  2426771383ull,
93    2486575220ull,  2546611805ull,  2606876748ull,  2667365819ull,
94    2728074942ull,  2789000187ull,  2850137762ull,  2911484006ull,
95    2973035382ull,  3034788471ull,  3096739966ull,  3158886666ull,
96    3221225472ull,  3283753383ull,  3346467489ull,  3409364969ull,
97    3472443085ull,  3535699182ull,  3599130679ull,  3662735070ull,
98    3726509920ull,  3790452862ull,  3854561593ull,  3918833872ull,
99    3983267519ull,  4047860410ull,  4112610476ull,  4177515704ull,
100    4242574127ull,  4307783833ull,  4373142952ull,  4438649662ull,
101    4504302186ull,  4570098787ull,  4636037770ull,  4702117480ull,
102    4768336298ull,  4834692645ull,  4901184974ull,  4967811774ull,
103    5034571569ull,  5101462912ull,  5168484389ull,  5235634615ull,
104    5302912235ull,  5370315922ull,  5437844376ull,  5505496324ull,
105    5573270518ull,  5641165737ull,  5709180782ull,  5777314477ull,
106    5845565671ull,  5913933235ull,  5982416059ull,  6051013057ull,
107    6119723161ull,  6188545324ull,  6257478518ull,  6326521733ull,
108    6395673979ull,  6464934282ull,  6534301685ull,  6603775250ull,
109    6673354052ull,  6743037185ull,  6812823756ull,  6882712890ull,
110    6952703725ull,  7022795412ull,  7092987118ull,  7163278025ull,
111    7233667324ull,  7304154222ull,  7374737939ull,  7445417707ull,
112    7516192768ull,  7587062379ull,  7658025806ull,  7729082328ull,
113    7800231234ull,  7871471825ull,  7942803410ull,  8014225311ull,
114    8085736859ull,  8157337394ull,  8229026267ull,  8300802839ull,
115    8372666477ull,  8444616560ull,  8516652476ull,  8588773618ull,
116    8660979393ull,  8733269211ull,  8805642493ull,  8878098667ull,
117    8950637170ull,  9023257446ull,  9095958945ull,  9168741125ull,
118    9241603454ull,  9314545403ull,  9387566451ull,  9460666086ull,
119    9533843800ull,  9607099093ull,  9680431471ull,  9753840445ull,
120    9827325535ull,  9900886263ull,  9974522161ull, 10048232765ull,
121   10122017615ull, 10195876260ull, 10269808253ull, 10343813150ull,
122   10417890516ull, 10492039919ull, 10566260934ull, 10640553138ull,
123   10714916116ull, 10789349456ull, 10863852751ull, 10938425600ull,
124   11013067604ull, 11087778372ull, 11162557513ull, 11237404645ull,
125   11312319387ull, 11387301364ull, 11462350205ull, 11537465541ull,
126   11612647010ull, 11687894253ull, 11763206912ull, 11838584638ull,
127   11914027082ull, 11989533899ull, 12065104750ull, 12140739296ull,
128   12216437206ull, 12292198148ull, 12368021795ull, 12443907826ull,
129   12519855920ull, 12595865759ull, 12671937032ull, 12748069427ull,
130   12824262637ull, 12900516358ull, 12976830290ull, 13053204134ull,
131   13129637595ull, 13206130381ull, 13282682202ull, 13359292772ull,
132   13435961806ull, 13512689025ull, 13589474149ull, 13666316903ull,
133   13743217014ull, 13820174211ull, 13897188225ull, 13974258793ull,
134   14051385649ull, 14128568535ull, 14205807192ull, 14283101363ull,
135   14360450796ull, 14437855239ull, 14515314443ull, 14592828162ull,
136   14670396151ull, 14748018167ull, 14825693972ull, 14903423326ull,
137   14981205995ull, 15059041743ull, 15136930339ull, 15214871554ull,
138   15292865160ull, 15370910930ull, 15449008641ull, 15527158071ull,
139   15605359001ull, 15683611210ull, 15761914485ull, 15840268608ull,
140   15918673369ull, 15997128556ull, 16075633960ull, 16154189373ull,
141   16232794589ull, 16311449405ull, 16390153617ull, 16468907026ull,
142   16547709431ull, 16626560636ull, 16705460444ull, 16784408661ull,
143   16863405094ull, 16942449552ull, 17021541845ull, 17100681785ull
144 };
145 
146 const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX] = {
147   { 0, 0}, { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 1}, { 4, 1}, { 5, 1},
148   { 5, 1}, { 6, 2}, { 6, 2}, { 6, 2}, { 6, 2}, { 7, 2}, { 7, 2}, { 7, 2},
149   { 7, 2}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3},
150   { 8, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3},
151   { 9, 3}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
152   {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
153   {10, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
154   {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
155   {11, 4}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
156   {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
157   {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
158   {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
159   {12, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
160   {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
161   {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
162   {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
163   {13, 5}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
164   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
165   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
166   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
167   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
168   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
169   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
170   {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
171   {14, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
172   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
173   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
174   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
175   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
176   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
177   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
178   {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
179   {15, 6}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
180   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
181   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
182   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
183   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
184   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
185   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
186   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
187   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
188   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
189   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
190   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
191   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
192   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
193   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
194   {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
195   {16, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
196   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
197   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
198   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
199   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
200   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
201   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
202   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
203   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
204   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
205   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
206   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
207   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
208   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
209   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
210   {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
211 };
212 
213 const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {
214    0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  2,  3,  0,  1,  2,  3,
215    0,  1,  2,  3,  4,  5,  6,  7,  0,  1,  2,  3,  4,  5,  6,  7,
216    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
217    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
218    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
219   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
220    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
221   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
222    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
223   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
224   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
225   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
226    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
227   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
228   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
229   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
230    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
231   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
232   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
233   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
234   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
235   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
236   96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
237   112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
238   127,
239    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
240   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
241   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
242   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
243   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
244   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
245   96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
246   112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126
247 };
248 
FastSLog2Slow_C(uint32_t v)249 static uint64_t FastSLog2Slow_C(uint32_t v) {
250   assert(v >= LOG_LOOKUP_IDX_MAX);
251   if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
252     const uint64_t orig_v = v;
253     uint64_t correction;
254 #if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
255     // use clz if available
256     const uint64_t log_cnt = BitsLog2Floor(v) - 7;
257     const uint32_t y = 1 << log_cnt;
258     v >>= log_cnt;
259 #else
260     uint64_t log_cnt = 0;
261     uint32_t y = 1;
262     do {
263       ++log_cnt;
264       v = v >> 1;
265       y = y << 1;
266     } while (v >= LOG_LOOKUP_IDX_MAX);
267 #endif
268     // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
269     // Xf = floor(Xf) * (1 + (v % y) / v)
270     // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
271     // The correction factor: log(1 + d) ~ d; for very small d values, so
272     // log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v
273     correction = LOG_2_RECIPROCAL_FIXED * (orig_v & (y - 1));
274     return orig_v * (kLog2Table[v] + (log_cnt << LOG_2_PRECISION_BITS)) +
275            correction;
276   } else {
277     return (uint64_t)(LOG_2_RECIPROCAL_FIXED_DOUBLE * v * log((double)v) + .5);
278   }
279 }
280 
FastLog2Slow_C(uint32_t v)281 static uint32_t FastLog2Slow_C(uint32_t v) {
282   assert(v >= LOG_LOOKUP_IDX_MAX);
283   if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
284     const uint32_t orig_v = v;
285     uint32_t log_2;
286 #if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
287     // use clz if available
288     const uint32_t log_cnt = BitsLog2Floor(v) - 7;
289     const uint32_t y = 1 << log_cnt;
290     v >>= log_cnt;
291 #else
292     uint32_t log_cnt = 0;
293     uint32_t y = 1;
294     do {
295       ++log_cnt;
296       v = v >> 1;
297       y = y << 1;
298     } while (v >= LOG_LOOKUP_IDX_MAX);
299 #endif
300     log_2 = kLog2Table[v] + (log_cnt << LOG_2_PRECISION_BITS);
301     if (orig_v >= APPROX_LOG_MAX) {
302       // Since the division is still expensive, add this correction factor only
303       // for large values of 'v'.
304       const uint64_t correction = LOG_2_RECIPROCAL_FIXED * (orig_v & (y - 1));
305       log_2 += (uint32_t)DivRound(correction, orig_v);
306     }
307     return log_2;
308   } else {
309     return (uint32_t)(LOG_2_RECIPROCAL_FIXED_DOUBLE * log((double)v) + .5);
310   }
311 }
312 
313 //------------------------------------------------------------------------------
314 // Methods to calculate Entropy (Shannon).
315 
316 // Compute the combined Shanon's entropy for distribution {X} and {X+Y}
CombinedShannonEntropy_C(const uint32_t X[256],const uint32_t Y[256])317 static uint64_t CombinedShannonEntropy_C(const uint32_t X[256],
318                                          const uint32_t Y[256]) {
319   int i;
320   uint64_t retval = 0;
321   uint32_t sumX = 0, sumXY = 0;
322   for (i = 0; i < 256; ++i) {
323     const uint32_t x = X[i];
324     if (x != 0) {
325       const uint32_t xy = x + Y[i];
326       sumX += x;
327       retval += VP8LFastSLog2(x);
328       sumXY += xy;
329       retval += VP8LFastSLog2(xy);
330     } else if (Y[i] != 0) {
331       sumXY += Y[i];
332       retval += VP8LFastSLog2(Y[i]);
333     }
334   }
335   retval = VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY) - retval;
336   return retval;
337 }
338 
ShannonEntropy_C(const uint32_t * X,int n)339 static uint64_t ShannonEntropy_C(const uint32_t* X, int n) {
340   int i;
341   uint64_t retval = 0;
342   uint32_t sumX = 0;
343   for (i = 0; i < n; ++i) {
344     const int x = X[i];
345     if (x != 0) {
346       sumX += x;
347       retval += VP8LFastSLog2(x);
348     }
349   }
350   retval = VP8LFastSLog2(sumX) - retval;
351   return retval;
352 }
353 
VP8LBitEntropyInit(VP8LBitEntropy * const entropy)354 void VP8LBitEntropyInit(VP8LBitEntropy* const entropy) {
355   entropy->entropy = 0;
356   entropy->sum = 0;
357   entropy->nonzeros = 0;
358   entropy->max_val = 0;
359   entropy->nonzero_code = VP8L_NON_TRIVIAL_SYM;
360 }
361 
VP8LBitsEntropyUnrefined(const uint32_t * WEBP_RESTRICT const array,int n,VP8LBitEntropy * WEBP_RESTRICT const entropy)362 void VP8LBitsEntropyUnrefined(const uint32_t* WEBP_RESTRICT const array, int n,
363                               VP8LBitEntropy* WEBP_RESTRICT const entropy) {
364   int i;
365 
366   VP8LBitEntropyInit(entropy);
367 
368   for (i = 0; i < n; ++i) {
369     if (array[i] != 0) {
370       entropy->sum += array[i];
371       entropy->nonzero_code = i;
372       ++entropy->nonzeros;
373       entropy->entropy += VP8LFastSLog2(array[i]);
374       if (entropy->max_val < array[i]) {
375         entropy->max_val = array[i];
376       }
377     }
378   }
379   entropy->entropy = VP8LFastSLog2(entropy->sum) - entropy->entropy;
380 }
381 
GetEntropyUnrefinedHelper(uint32_t val,int i,uint32_t * WEBP_RESTRICT const val_prev,int * WEBP_RESTRICT const i_prev,VP8LBitEntropy * WEBP_RESTRICT const bit_entropy,VP8LStreaks * WEBP_RESTRICT const stats)382 static WEBP_INLINE void GetEntropyUnrefinedHelper(
383     uint32_t val, int i, uint32_t* WEBP_RESTRICT const val_prev,
384     int* WEBP_RESTRICT const i_prev,
385     VP8LBitEntropy* WEBP_RESTRICT const bit_entropy,
386     VP8LStreaks* WEBP_RESTRICT const stats) {
387   const int streak = i - *i_prev;
388 
389   // Gather info for the bit entropy.
390   if (*val_prev != 0) {
391     bit_entropy->sum += (*val_prev) * streak;
392     bit_entropy->nonzeros += streak;
393     bit_entropy->nonzero_code = *i_prev;
394     bit_entropy->entropy += VP8LFastSLog2(*val_prev) * streak;
395     if (bit_entropy->max_val < *val_prev) {
396       bit_entropy->max_val = *val_prev;
397     }
398   }
399 
400   // Gather info for the Huffman cost.
401   stats->counts[*val_prev != 0] += (streak > 3);
402   stats->streaks[*val_prev != 0][(streak > 3)] += streak;
403 
404   *val_prev = val;
405   *i_prev = i;
406 }
407 
GetEntropyUnrefined_C(const uint32_t X[],int length,VP8LBitEntropy * WEBP_RESTRICT const bit_entropy,VP8LStreaks * WEBP_RESTRICT const stats)408 static void GetEntropyUnrefined_C(
409     const uint32_t X[], int length,
410     VP8LBitEntropy* WEBP_RESTRICT const bit_entropy,
411     VP8LStreaks* WEBP_RESTRICT const stats) {
412   int i;
413   int i_prev = 0;
414   uint32_t x_prev = X[0];
415 
416   memset(stats, 0, sizeof(*stats));
417   VP8LBitEntropyInit(bit_entropy);
418 
419   for (i = 1; i < length; ++i) {
420     const uint32_t x = X[i];
421     if (x != x_prev) {
422       GetEntropyUnrefinedHelper(x, i, &x_prev, &i_prev, bit_entropy, stats);
423     }
424   }
425   GetEntropyUnrefinedHelper(0, i, &x_prev, &i_prev, bit_entropy, stats);
426 
427   bit_entropy->entropy = VP8LFastSLog2(bit_entropy->sum) - bit_entropy->entropy;
428 }
429 
GetCombinedEntropyUnrefined_C(const uint32_t X[],const uint32_t Y[],int length,VP8LBitEntropy * WEBP_RESTRICT const bit_entropy,VP8LStreaks * WEBP_RESTRICT const stats)430 static void GetCombinedEntropyUnrefined_C(
431     const uint32_t X[], const uint32_t Y[], int length,
432     VP8LBitEntropy* WEBP_RESTRICT const bit_entropy,
433     VP8LStreaks* WEBP_RESTRICT const stats) {
434   int i = 1;
435   int i_prev = 0;
436   uint32_t xy_prev = X[0] + Y[0];
437 
438   memset(stats, 0, sizeof(*stats));
439   VP8LBitEntropyInit(bit_entropy);
440 
441   for (i = 1; i < length; ++i) {
442     const uint32_t xy = X[i] + Y[i];
443     if (xy != xy_prev) {
444       GetEntropyUnrefinedHelper(xy, i, &xy_prev, &i_prev, bit_entropy, stats);
445     }
446   }
447   GetEntropyUnrefinedHelper(0, i, &xy_prev, &i_prev, bit_entropy, stats);
448 
449   bit_entropy->entropy = VP8LFastSLog2(bit_entropy->sum) - bit_entropy->entropy;
450 }
451 
452 //------------------------------------------------------------------------------
453 
VP8LSubtractGreenFromBlueAndRed_C(uint32_t * argb_data,int num_pixels)454 void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
455   int i;
456   for (i = 0; i < num_pixels; ++i) {
457     const int argb = (int)argb_data[i];
458     const int green = (argb >> 8) & 0xff;
459     const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
460     const uint32_t new_b = (((argb >>  0) & 0xff) - green) & 0xff;
461     argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b;
462   }
463 }
464 
ColorTransformDelta(int8_t color_pred,int8_t color)465 static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) {
466   return ((int)color_pred * color) >> 5;
467 }
468 
U32ToS8(uint32_t v)469 static WEBP_INLINE int8_t U32ToS8(uint32_t v) {
470   return (int8_t)(v & 0xff);
471 }
472 
VP8LTransformColor_C(const VP8LMultipliers * WEBP_RESTRICT const m,uint32_t * WEBP_RESTRICT data,int num_pixels)473 void VP8LTransformColor_C(const VP8LMultipliers* WEBP_RESTRICT const m,
474                           uint32_t* WEBP_RESTRICT data, int num_pixels) {
475   int i;
476   for (i = 0; i < num_pixels; ++i) {
477     const uint32_t argb = data[i];
478     const int8_t green = U32ToS8(argb >>  8);
479     const int8_t red   = U32ToS8(argb >> 16);
480     int new_red = red & 0xff;
481     int new_blue = argb & 0xff;
482     new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green);
483     new_red &= 0xff;
484     new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green);
485     new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red);
486     new_blue &= 0xff;
487     data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
488   }
489 }
490 
TransformColorRed(uint8_t green_to_red,uint32_t argb)491 static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
492                                              uint32_t argb) {
493   const int8_t green = U32ToS8(argb >> 8);
494   int new_red = argb >> 16;
495   new_red -= ColorTransformDelta((int8_t)green_to_red, green);
496   return (new_red & 0xff);
497 }
498 
TransformColorBlue(uint8_t green_to_blue,uint8_t red_to_blue,uint32_t argb)499 static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
500                                               uint8_t red_to_blue,
501                                               uint32_t argb) {
502   const int8_t green = U32ToS8(argb >>  8);
503   const int8_t red   = U32ToS8(argb >> 16);
504   int new_blue = argb & 0xff;
505   new_blue -= ColorTransformDelta((int8_t)green_to_blue, green);
506   new_blue -= ColorTransformDelta((int8_t)red_to_blue, red);
507   return (new_blue & 0xff);
508 }
509 
VP8LCollectColorRedTransforms_C(const uint32_t * WEBP_RESTRICT argb,int stride,int tile_width,int tile_height,int green_to_red,uint32_t histo[])510 void VP8LCollectColorRedTransforms_C(const uint32_t* WEBP_RESTRICT argb,
511                                      int stride,
512                                      int tile_width, int tile_height,
513                                      int green_to_red, uint32_t histo[]) {
514   while (tile_height-- > 0) {
515     int x;
516     for (x = 0; x < tile_width; ++x) {
517       ++histo[TransformColorRed((uint8_t)green_to_red, argb[x])];
518     }
519     argb += stride;
520   }
521 }
522 
VP8LCollectColorBlueTransforms_C(const uint32_t * WEBP_RESTRICT argb,int stride,int tile_width,int tile_height,int green_to_blue,int red_to_blue,uint32_t histo[])523 void VP8LCollectColorBlueTransforms_C(const uint32_t* WEBP_RESTRICT argb,
524                                       int stride,
525                                       int tile_width, int tile_height,
526                                       int green_to_blue, int red_to_blue,
527                                       uint32_t histo[]) {
528   while (tile_height-- > 0) {
529     int x;
530     for (x = 0; x < tile_width; ++x) {
531       ++histo[TransformColorBlue((uint8_t)green_to_blue, (uint8_t)red_to_blue,
532                                  argb[x])];
533     }
534     argb += stride;
535   }
536 }
537 
538 //------------------------------------------------------------------------------
539 
VectorMismatch_C(const uint32_t * const array1,const uint32_t * const array2,int length)540 static int VectorMismatch_C(const uint32_t* const array1,
541                             const uint32_t* const array2, int length) {
542   int match_len = 0;
543 
544   while (match_len < length && array1[match_len] == array2[match_len]) {
545     ++match_len;
546   }
547   return match_len;
548 }
549 
550 // Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
VP8LBundleColorMap_C(const uint8_t * WEBP_RESTRICT const row,int width,int xbits,uint32_t * WEBP_RESTRICT dst)551 void VP8LBundleColorMap_C(const uint8_t* WEBP_RESTRICT const row,
552                           int width, int xbits, uint32_t* WEBP_RESTRICT dst) {
553   int x;
554   if (xbits > 0) {
555     const int bit_depth = 1 << (3 - xbits);
556     const int mask = (1 << xbits) - 1;
557     uint32_t code = 0xff000000;
558     for (x = 0; x < width; ++x) {
559       const int xsub = x & mask;
560       if (xsub == 0) {
561         code = 0xff000000;
562       }
563       code |= row[x] << (8 + bit_depth * xsub);
564       dst[x >> xbits] = code;
565     }
566   } else {
567     for (x = 0; x < width; ++x) dst[x] = 0xff000000 | (row[x] << 8);
568   }
569 }
570 
571 //------------------------------------------------------------------------------
572 
ExtraCost_C(const uint32_t * population,int length)573 static uint32_t ExtraCost_C(const uint32_t* population, int length) {
574   int i;
575   uint32_t cost = population[4] + population[5];
576   assert(length % 2 == 0);
577   for (i = 2; i < length / 2 - 1; ++i) {
578     cost += i * (population[2 * i + 2] + population[2 * i + 3]);
579   }
580   return cost;
581 }
582 
ExtraCostCombined_C(const uint32_t * WEBP_RESTRICT X,const uint32_t * WEBP_RESTRICT Y,int length)583 static uint32_t ExtraCostCombined_C(const uint32_t* WEBP_RESTRICT X,
584                                     const uint32_t* WEBP_RESTRICT Y,
585                                     int length) {
586   int i;
587   uint32_t cost = X[4] + Y[4] + X[5] + Y[5];
588   assert(length % 2 == 0);
589   for (i = 2; i < length / 2 - 1; ++i) {
590     const int xy0 = X[2 * i + 2] + Y[2 * i + 2];
591     const int xy1 = X[2 * i + 3] + Y[2 * i + 3];
592     cost += i * (xy0 + xy1);
593   }
594   return cost;
595 }
596 
597 //------------------------------------------------------------------------------
598 
AddVector_C(const uint32_t * WEBP_RESTRICT a,const uint32_t * WEBP_RESTRICT b,uint32_t * WEBP_RESTRICT out,int size)599 static void AddVector_C(const uint32_t* WEBP_RESTRICT a,
600                         const uint32_t* WEBP_RESTRICT b,
601                         uint32_t* WEBP_RESTRICT out, int size) {
602   int i;
603   for (i = 0; i < size; ++i) out[i] = a[i] + b[i];
604 }
605 
AddVectorEq_C(const uint32_t * WEBP_RESTRICT a,uint32_t * WEBP_RESTRICT out,int size)606 static void AddVectorEq_C(const uint32_t* WEBP_RESTRICT a,
607                           uint32_t* WEBP_RESTRICT out, int size) {
608   int i;
609   for (i = 0; i < size; ++i) out[i] += a[i];
610 }
611 
612 #define ADD(X, ARG, LEN) do {                                                  \
613   if (a->is_used_[X]) {                                                        \
614     if (b->is_used_[X]) {                                                      \
615       VP8LAddVector(a->ARG, b->ARG, out->ARG, (LEN));                          \
616     } else {                                                                   \
617       memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0]));           \
618     }                                                                          \
619   } else if (b->is_used_[X]) {                                                 \
620     memcpy(&out->ARG[0], &b->ARG[0], (LEN) * sizeof(out->ARG[0]));             \
621   } else {                                                                     \
622     memset(&out->ARG[0], 0, (LEN) * sizeof(out->ARG[0]));                      \
623   }                                                                            \
624 } while (0)
625 
626 #define ADD_EQ(X, ARG, LEN) do {                                               \
627   if (a->is_used_[X]) {                                                        \
628     if (out->is_used_[X]) {                                                    \
629       VP8LAddVectorEq(a->ARG, out->ARG, (LEN));                                \
630     } else {                                                                   \
631       memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0]));           \
632     }                                                                          \
633   }                                                                            \
634 } while (0)
635 
VP8LHistogramAdd(const VP8LHistogram * WEBP_RESTRICT const a,const VP8LHistogram * WEBP_RESTRICT const b,VP8LHistogram * WEBP_RESTRICT const out)636 void VP8LHistogramAdd(const VP8LHistogram* WEBP_RESTRICT const a,
637                       const VP8LHistogram* WEBP_RESTRICT const b,
638                       VP8LHistogram* WEBP_RESTRICT const out) {
639   int i;
640   const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
641   assert(a->palette_code_bits_ == b->palette_code_bits_);
642 
643   if (b != out) {
644     ADD(0, literal_, literal_size);
645     ADD(1, red_, NUM_LITERAL_CODES);
646     ADD(2, blue_, NUM_LITERAL_CODES);
647     ADD(3, alpha_, NUM_LITERAL_CODES);
648     ADD(4, distance_, NUM_DISTANCE_CODES);
649     for (i = 0; i < 5; ++i) {
650       out->is_used_[i] = (a->is_used_[i] | b->is_used_[i]);
651     }
652   } else {
653     ADD_EQ(0, literal_, literal_size);
654     ADD_EQ(1, red_, NUM_LITERAL_CODES);
655     ADD_EQ(2, blue_, NUM_LITERAL_CODES);
656     ADD_EQ(3, alpha_, NUM_LITERAL_CODES);
657     ADD_EQ(4, distance_, NUM_DISTANCE_CODES);
658     for (i = 0; i < 5; ++i) out->is_used_[i] |= a->is_used_[i];
659   }
660 }
661 #undef ADD
662 #undef ADD_EQ
663 
664 //------------------------------------------------------------------------------
665 // Image transforms.
666 
PredictorSub0_C(const uint32_t * in,const uint32_t * upper,int num_pixels,uint32_t * WEBP_RESTRICT out)667 static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,
668                             int num_pixels, uint32_t* WEBP_RESTRICT out) {
669   int i;
670   for (i = 0; i < num_pixels; ++i) out[i] = VP8LSubPixels(in[i], ARGB_BLACK);
671   (void)upper;
672 }
673 
PredictorSub1_C(const uint32_t * in,const uint32_t * upper,int num_pixels,uint32_t * WEBP_RESTRICT out)674 static void PredictorSub1_C(const uint32_t* in, const uint32_t* upper,
675                             int num_pixels, uint32_t* WEBP_RESTRICT out) {
676   int i;
677   for (i = 0; i < num_pixels; ++i) out[i] = VP8LSubPixels(in[i], in[i - 1]);
678   (void)upper;
679 }
680 
681 // It subtracts the prediction from the input pixel and stores the residual
682 // in the output pixel.
683 #define GENERATE_PREDICTOR_SUB(PREDICTOR_I)                                \
684 static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in,              \
685                                           const uint32_t* upper,           \
686                                           int num_pixels,                  \
687                                           uint32_t* WEBP_RESTRICT out) {   \
688   int x;                                                                   \
689   assert(upper != NULL);                                                   \
690   for (x = 0; x < num_pixels; ++x) {                                       \
691     const uint32_t pred =                                                  \
692         VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x);             \
693     out[x] = VP8LSubPixels(in[x], pred);                                   \
694   }                                                                        \
695 }
696 
697 GENERATE_PREDICTOR_SUB(2)
698 GENERATE_PREDICTOR_SUB(3)
699 GENERATE_PREDICTOR_SUB(4)
700 GENERATE_PREDICTOR_SUB(5)
701 GENERATE_PREDICTOR_SUB(6)
702 GENERATE_PREDICTOR_SUB(7)
703 GENERATE_PREDICTOR_SUB(8)
704 GENERATE_PREDICTOR_SUB(9)
705 GENERATE_PREDICTOR_SUB(10)
706 GENERATE_PREDICTOR_SUB(11)
707 GENERATE_PREDICTOR_SUB(12)
708 GENERATE_PREDICTOR_SUB(13)
709 
710 //------------------------------------------------------------------------------
711 
712 VP8LProcessEncBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
713 
714 VP8LTransformColorFunc VP8LTransformColor;
715 
716 VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
717 VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
718 
719 VP8LFastLog2SlowFunc VP8LFastLog2Slow;
720 VP8LFastSLog2SlowFunc VP8LFastSLog2Slow;
721 
722 VP8LCostFunc VP8LExtraCost;
723 VP8LCostCombinedFunc VP8LExtraCostCombined;
724 VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;
725 VP8LShannonEntropyFunc VP8LShannonEntropy;
726 
727 VP8LGetEntropyUnrefinedFunc VP8LGetEntropyUnrefined;
728 VP8LGetCombinedEntropyUnrefinedFunc VP8LGetCombinedEntropyUnrefined;
729 
730 VP8LAddVectorFunc VP8LAddVector;
731 VP8LAddVectorEqFunc VP8LAddVectorEq;
732 
733 VP8LVectorMismatchFunc VP8LVectorMismatch;
734 VP8LBundleColorMapFunc VP8LBundleColorMap;
735 
736 VP8LPredictorAddSubFunc VP8LPredictorsSub[16];
737 VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];
738 
739 extern VP8CPUInfo VP8GetCPUInfo;
740 extern void VP8LEncDspInitSSE2(void);
741 extern void VP8LEncDspInitSSE41(void);
742 extern void VP8LEncDspInitNEON(void);
743 extern void VP8LEncDspInitMIPS32(void);
744 extern void VP8LEncDspInitMIPSdspR2(void);
745 extern void VP8LEncDspInitMSA(void);
746 
WEBP_DSP_INIT_FUNC(VP8LEncDspInit)747 WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
748   VP8LDspInit();
749 
750 #if !WEBP_NEON_OMIT_C_CODE
751   VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;
752 
753   VP8LTransformColor = VP8LTransformColor_C;
754 #endif
755 
756   VP8LCollectColorBlueTransforms = VP8LCollectColorBlueTransforms_C;
757   VP8LCollectColorRedTransforms = VP8LCollectColorRedTransforms_C;
758 
759   VP8LFastLog2Slow = FastLog2Slow_C;
760   VP8LFastSLog2Slow = FastSLog2Slow_C;
761 
762   VP8LExtraCost = ExtraCost_C;
763   VP8LExtraCostCombined = ExtraCostCombined_C;
764   VP8LCombinedShannonEntropy = CombinedShannonEntropy_C;
765   VP8LShannonEntropy = ShannonEntropy_C;
766 
767   VP8LGetEntropyUnrefined = GetEntropyUnrefined_C;
768   VP8LGetCombinedEntropyUnrefined = GetCombinedEntropyUnrefined_C;
769 
770   VP8LAddVector = AddVector_C;
771   VP8LAddVectorEq = AddVectorEq_C;
772 
773   VP8LVectorMismatch = VectorMismatch_C;
774   VP8LBundleColorMap = VP8LBundleColorMap_C;
775 
776   VP8LPredictorsSub[0] = PredictorSub0_C;
777   VP8LPredictorsSub[1] = PredictorSub1_C;
778   VP8LPredictorsSub[2] = PredictorSub2_C;
779   VP8LPredictorsSub[3] = PredictorSub3_C;
780   VP8LPredictorsSub[4] = PredictorSub4_C;
781   VP8LPredictorsSub[5] = PredictorSub5_C;
782   VP8LPredictorsSub[6] = PredictorSub6_C;
783   VP8LPredictorsSub[7] = PredictorSub7_C;
784   VP8LPredictorsSub[8] = PredictorSub8_C;
785   VP8LPredictorsSub[9] = PredictorSub9_C;
786   VP8LPredictorsSub[10] = PredictorSub10_C;
787   VP8LPredictorsSub[11] = PredictorSub11_C;
788   VP8LPredictorsSub[12] = PredictorSub12_C;
789   VP8LPredictorsSub[13] = PredictorSub13_C;
790   VP8LPredictorsSub[14] = PredictorSub0_C;  // <- padding security sentinels
791   VP8LPredictorsSub[15] = PredictorSub0_C;
792 
793   VP8LPredictorsSub_C[0] = PredictorSub0_C;
794   VP8LPredictorsSub_C[1] = PredictorSub1_C;
795   VP8LPredictorsSub_C[2] = PredictorSub2_C;
796   VP8LPredictorsSub_C[3] = PredictorSub3_C;
797   VP8LPredictorsSub_C[4] = PredictorSub4_C;
798   VP8LPredictorsSub_C[5] = PredictorSub5_C;
799   VP8LPredictorsSub_C[6] = PredictorSub6_C;
800   VP8LPredictorsSub_C[7] = PredictorSub7_C;
801   VP8LPredictorsSub_C[8] = PredictorSub8_C;
802   VP8LPredictorsSub_C[9] = PredictorSub9_C;
803   VP8LPredictorsSub_C[10] = PredictorSub10_C;
804   VP8LPredictorsSub_C[11] = PredictorSub11_C;
805   VP8LPredictorsSub_C[12] = PredictorSub12_C;
806   VP8LPredictorsSub_C[13] = PredictorSub13_C;
807   VP8LPredictorsSub_C[14] = PredictorSub0_C;  // <- padding security sentinels
808   VP8LPredictorsSub_C[15] = PredictorSub0_C;
809 
810   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
811   if (VP8GetCPUInfo != NULL) {
812 #if defined(WEBP_HAVE_SSE2)
813     if (VP8GetCPUInfo(kSSE2)) {
814       VP8LEncDspInitSSE2();
815 #if defined(WEBP_HAVE_SSE41)
816       if (VP8GetCPUInfo(kSSE4_1)) {
817         VP8LEncDspInitSSE41();
818       }
819 #endif
820     }
821 #endif
822 #if defined(WEBP_USE_MIPS32)
823     if (VP8GetCPUInfo(kMIPS32)) {
824       VP8LEncDspInitMIPS32();
825     }
826 #endif
827 #if defined(WEBP_USE_MIPS_DSP_R2)
828     if (VP8GetCPUInfo(kMIPSdspR2)) {
829       VP8LEncDspInitMIPSdspR2();
830     }
831 #endif
832 #if defined(WEBP_USE_MSA)
833     if (VP8GetCPUInfo(kMSA)) {
834       VP8LEncDspInitMSA();
835     }
836 #endif
837   }
838 
839 #if defined(WEBP_HAVE_NEON)
840   if (WEBP_NEON_OMIT_C_CODE ||
841       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
842     VP8LEncDspInitNEON();
843   }
844 #endif
845 
846   assert(VP8LSubtractGreenFromBlueAndRed != NULL);
847   assert(VP8LTransformColor != NULL);
848   assert(VP8LCollectColorBlueTransforms != NULL);
849   assert(VP8LCollectColorRedTransforms != NULL);
850   assert(VP8LFastLog2Slow != NULL);
851   assert(VP8LFastSLog2Slow != NULL);
852   assert(VP8LExtraCost != NULL);
853   assert(VP8LExtraCostCombined != NULL);
854   assert(VP8LCombinedShannonEntropy != NULL);
855   assert(VP8LShannonEntropy != NULL);
856   assert(VP8LGetEntropyUnrefined != NULL);
857   assert(VP8LGetCombinedEntropyUnrefined != NULL);
858   assert(VP8LAddVector != NULL);
859   assert(VP8LAddVectorEq != NULL);
860   assert(VP8LVectorMismatch != NULL);
861   assert(VP8LBundleColorMap != NULL);
862   assert(VP8LPredictorsSub[0] != NULL);
863   assert(VP8LPredictorsSub[1] != NULL);
864   assert(VP8LPredictorsSub[2] != NULL);
865   assert(VP8LPredictorsSub[3] != NULL);
866   assert(VP8LPredictorsSub[4] != NULL);
867   assert(VP8LPredictorsSub[5] != NULL);
868   assert(VP8LPredictorsSub[6] != NULL);
869   assert(VP8LPredictorsSub[7] != NULL);
870   assert(VP8LPredictorsSub[8] != NULL);
871   assert(VP8LPredictorsSub[9] != NULL);
872   assert(VP8LPredictorsSub[10] != NULL);
873   assert(VP8LPredictorsSub[11] != NULL);
874   assert(VP8LPredictorsSub[12] != NULL);
875   assert(VP8LPredictorsSub[13] != NULL);
876   assert(VP8LPredictorsSub[14] != NULL);
877   assert(VP8LPredictorsSub[15] != NULL);
878   assert(VP8LPredictorsSub_C[0] != NULL);
879   assert(VP8LPredictorsSub_C[1] != NULL);
880   assert(VP8LPredictorsSub_C[2] != NULL);
881   assert(VP8LPredictorsSub_C[3] != NULL);
882   assert(VP8LPredictorsSub_C[4] != NULL);
883   assert(VP8LPredictorsSub_C[5] != NULL);
884   assert(VP8LPredictorsSub_C[6] != NULL);
885   assert(VP8LPredictorsSub_C[7] != NULL);
886   assert(VP8LPredictorsSub_C[8] != NULL);
887   assert(VP8LPredictorsSub_C[9] != NULL);
888   assert(VP8LPredictorsSub_C[10] != NULL);
889   assert(VP8LPredictorsSub_C[11] != NULL);
890   assert(VP8LPredictorsSub_C[12] != NULL);
891   assert(VP8LPredictorsSub_C[13] != NULL);
892   assert(VP8LPredictorsSub_C[14] != NULL);
893   assert(VP8LPredictorsSub_C[15] != NULL);
894 }
895 
896 //------------------------------------------------------------------------------
897