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)
28const float kLog2Table[LOG_LOOKUP_IDX_MAX] = {
29 0.0000000000000000f, 0.0000000000000000f,
30 1.0000000000000000f, 1.5849625007211560f,
31 2.0000000000000000f, 2.3219280948873621f,
32 2.5849625007211560f, 2.8073549220576041f,
33 3.0000000000000000f, 3.1699250014423121f,
34 3.3219280948873621f, 3.4594316186372973f,
35 3.5849625007211560f, 3.7004397181410921f,
36 3.8073549220576041f, 3.9068905956085187f,
37 4.0000000000000000f, 4.0874628412503390f,
38 4.1699250014423121f, 4.2479275134435852f,
39 4.3219280948873626f, 4.3923174227787606f,
40 4.4594316186372973f, 4.5235619560570130f,
41 4.5849625007211560f, 4.6438561897747243f,
42 4.7004397181410917f, 4.7548875021634682f,
43 4.8073549220576037f, 4.8579809951275718f,
44 4.9068905956085187f, 4.9541963103868749f,
45 5.0000000000000000f, 5.0443941193584533f,
46 5.0874628412503390f, 5.1292830169449663f,
47 5.1699250014423121f, 5.2094533656289501f,
48 5.2479275134435852f, 5.2854022188622487f,
49 5.3219280948873626f, 5.3575520046180837f,
50 5.3923174227787606f, 5.4262647547020979f,
51 5.4594316186372973f, 5.4918530963296747f,
52 5.5235619560570130f, 5.5545888516776376f,
53 5.5849625007211560f, 5.6147098441152083f,
54 5.6438561897747243f, 5.6724253419714951f,
55 5.7004397181410917f, 5.7279204545631987f,
56 5.7548875021634682f, 5.7813597135246599f,
57 5.8073549220576037f, 5.8328900141647412f,
58 5.8579809951275718f, 5.8826430493618415f,
59 5.9068905956085187f, 5.9307373375628866f,
60 5.9541963103868749f, 5.9772799234999167f,
61 6.0000000000000000f, 6.0223678130284543f,
62 6.0443941193584533f, 6.0660891904577720f,
63 6.0874628412503390f, 6.1085244567781691f,
64 6.1292830169449663f, 6.1497471195046822f,
65 6.1699250014423121f, 6.1898245588800175f,
66 6.2094533656289501f, 6.2288186904958804f,
67 6.2479275134435852f, 6.2667865406949010f,
68 6.2854022188622487f, 6.3037807481771030f,
69 6.3219280948873626f, 6.3398500028846243f,
70 6.3575520046180837f, 6.3750394313469245f,
71 6.3923174227787606f, 6.4093909361377017f,
72 6.4262647547020979f, 6.4429434958487279f,
73 6.4594316186372973f, 6.4757334309663976f,
74 6.4918530963296747f, 6.5077946401986963f,
75 6.5235619560570130f, 6.5391588111080309f,
76 6.5545888516776376f, 6.5698556083309478f,
77 6.5849625007211560f, 6.5999128421871278f,
78 6.6147098441152083f, 6.6293566200796094f,
79 6.6438561897747243f, 6.6582114827517946f,
80 6.6724253419714951f, 6.6865005271832185f,
81 6.7004397181410917f, 6.7142455176661224f,
82 6.7279204545631987f, 6.7414669864011464f,
83 6.7548875021634682f, 6.7681843247769259f,
84 6.7813597135246599f, 6.7944158663501061f,
85 6.8073549220576037f, 6.8201789624151878f,
86 6.8328900141647412f, 6.8454900509443747f,
87 6.8579809951275718f, 6.8703647195834047f,
88 6.8826430493618415f, 6.8948177633079437f,
89 6.9068905956085187f, 6.9188632372745946f,
90 6.9307373375628866f, 6.9425145053392398f,
91 6.9541963103868749f, 6.9657842846620869f,
92 6.9772799234999167f, 6.9886846867721654f,
93 7.0000000000000000f, 7.0112272554232539f,
94 7.0223678130284543f, 7.0334230015374501f,
95 7.0443941193584533f, 7.0552824355011898f,
96 7.0660891904577720f, 7.0768155970508308f,
97 7.0874628412503390f, 7.0980320829605263f,
98 7.1085244567781691f, 7.1189410727235076f,
99 7.1292830169449663f, 7.1395513523987936f,
100 7.1497471195046822f, 7.1598713367783890f,
101 7.1699250014423121f, 7.1799090900149344f,
102 7.1898245588800175f, 7.1996723448363644f,
103 7.2094533656289501f, 7.2191685204621611f,
104 7.2288186904958804f, 7.2384047393250785f,
105 7.2479275134435852f, 7.2573878426926521f,
106 7.2667865406949010f, 7.2761244052742375f,
107 7.2854022188622487f, 7.2946207488916270f,
108 7.3037807481771030f, 7.3128829552843557f,
109 7.3219280948873626f, 7.3309168781146167f,
110 7.3398500028846243f, 7.3487281542310771f,
111 7.3575520046180837f, 7.3663222142458160f,
112 7.3750394313469245f, 7.3837042924740519f,
113 7.3923174227787606f, 7.4008794362821843f,
114 7.4093909361377017f, 7.4178525148858982f,
115 7.4262647547020979f, 7.4346282276367245f,
116 7.4429434958487279f, 7.4512111118323289f,
117 7.4594316186372973f, 7.4676055500829976f,
118 7.4757334309663976f, 7.4838157772642563f,
119 7.4918530963296747f, 7.4998458870832056f,
120 7.5077946401986963f, 7.5156998382840427f,
121 7.5235619560570130f, 7.5313814605163118f,
122 7.5391588111080309f, 7.5468944598876364f,
123 7.5545888516776376f, 7.5622424242210728f,
124 7.5698556083309478f, 7.5774288280357486f,
125 7.5849625007211560f, 7.5924570372680806f,
126 7.5999128421871278f, 7.6073303137496104f,
127 7.6147098441152083f, 7.6220518194563764f,
128 7.6293566200796094f, 7.6366246205436487f,
129 7.6438561897747243f, 7.6510516911789281f,
130 7.6582114827517946f, 7.6653359171851764f,
131 7.6724253419714951f, 7.6794800995054464f,
132 7.6865005271832185f, 7.6934869574993252f,
133 7.7004397181410917f, 7.7073591320808825f,
134 7.7142455176661224f, 7.7210991887071855f,
135 7.7279204545631987f, 7.7347096202258383f,
136 7.7414669864011464f, 7.7481928495894605f,
137 7.7548875021634682f, 7.7615512324444795f,
138 7.7681843247769259f, 7.7747870596011736f,
139 7.7813597135246599f, 7.7879025593914317f,
140 7.7944158663501061f, 7.8008998999203047f,
141 7.8073549220576037f, 7.8137811912170374f,
142 7.8201789624151878f, 7.8265484872909150f,
143 7.8328900141647412f, 7.8392037880969436f,
144 7.8454900509443747f, 7.8517490414160571f,
145 7.8579809951275718f, 7.8641861446542797f,
146 7.8703647195834047f, 7.8765169465649993f,
147 7.8826430493618415f, 7.8887432488982591f,
148 7.8948177633079437f, 7.9008668079807486f,
149 7.9068905956085187f, 7.9128893362299619f,
150 7.9188632372745946f, 7.9248125036057812f,
151 7.9307373375628866f, 7.9366379390025709f,
152 7.9425145053392398f, 7.9483672315846778f,
153 7.9541963103868749f, 7.9600019320680805f,
154 7.9657842846620869f, 7.9715435539507719f,
155 7.9772799234999167f, 7.9829935746943103f,
156 7.9886846867721654f, 7.9943534368588577f
157};
158
159const float kSLog2Table[LOG_LOOKUP_IDX_MAX] = {
160 0.00000000f, 0.00000000f, 2.00000000f, 4.75488750f,
161 8.00000000f, 11.60964047f, 15.50977500f, 19.65148445f,
162 24.00000000f, 28.52932501f, 33.21928095f, 38.05374781f,
163 43.01955001f, 48.10571634f, 53.30296891f, 58.60335893f,
164 64.00000000f, 69.48686830f, 75.05865003f, 80.71062276f,
165 86.43856190f, 92.23866588f, 98.10749561f, 104.04192499f,
166 110.03910002f, 116.09640474f, 122.21143267f, 128.38196256f,
167 134.60593782f, 140.88144886f, 147.20671787f, 153.58008562f,
168 160.00000000f, 166.46500594f, 172.97373660f, 179.52490559f,
169 186.11730005f, 192.74977453f, 199.42124551f, 206.13068654f,
170 212.87712380f, 219.65963219f, 226.47733176f, 233.32938445f,
171 240.21499122f, 247.13338933f, 254.08384998f, 261.06567603f,
172 268.07820003f, 275.12078236f, 282.19280949f, 289.29369244f,
173 296.42286534f, 303.57978409f, 310.76392512f, 317.97478424f,
174 325.21187564f, 332.47473081f, 339.76289772f, 347.07593991f,
175 354.41343574f, 361.77497759f, 369.16017124f, 376.56863518f,
176 384.00000000f, 391.45390785f, 398.93001188f, 406.42797576f,
177 413.94747321f, 421.48818752f, 429.04981119f, 436.63204548f,
178 444.23460010f, 451.85719280f, 459.49954906f, 467.16140179f,
179 474.84249102f, 482.54256363f, 490.26137307f, 497.99867911f,
180 505.75424759f, 513.52785023f, 521.31926438f, 529.12827280f,
181 536.95466351f, 544.79822957f, 552.65876890f, 560.53608414f,
182 568.42998244f, 576.34027536f, 584.26677867f, 592.20931226f,
183 600.16769996f, 608.14176943f, 616.13135206f, 624.13628279f,
184 632.15640007f, 640.19154569f, 648.24156472f, 656.30630539f,
185 664.38561898f, 672.47935976f, 680.58738488f, 688.70955430f,
186 696.84573069f, 704.99577935f, 713.15956818f, 721.33696754f,
187 729.52785023f, 737.73209140f, 745.94956849f, 754.18016116f,
188 762.42375127f, 770.68022275f, 778.94946161f, 787.23135586f,
189 795.52579543f, 803.83267219f, 812.15187982f, 820.48331383f,
190 828.82687147f, 837.18245171f, 845.54995518f, 853.92928416f,
191 862.32034249f, 870.72303558f, 879.13727036f, 887.56295522f,
192 896.00000000f, 904.44831595f, 912.90781569f, 921.37841320f,
193 929.86002376f, 938.35256392f, 946.85595152f, 955.37010560f,
194 963.89494641f, 972.43039537f, 980.97637504f, 989.53280911f,
195 998.09962237f, 1006.67674069f, 1015.26409097f, 1023.86160116f,
196 1032.46920021f, 1041.08681805f, 1049.71438560f, 1058.35183469f,
197 1066.99909811f, 1075.65610955f, 1084.32280357f, 1092.99911564f,
198 1101.68498204f, 1110.38033993f, 1119.08512727f, 1127.79928282f,
199 1136.52274614f, 1145.25545758f, 1153.99735821f, 1162.74838989f,
200 1171.50849518f, 1180.27761738f, 1189.05570047f, 1197.84268914f,
201 1206.63852876f, 1215.44316535f, 1224.25654560f, 1233.07861684f,
202 1241.90932703f, 1250.74862473f, 1259.59645914f, 1268.45278005f,
203 1277.31753781f, 1286.19068338f, 1295.07216828f, 1303.96194457f,
204 1312.85996488f, 1321.76618236f, 1330.68055071f, 1339.60302413f,
205 1348.53355734f, 1357.47210556f, 1366.41862452f, 1375.37307041f,
206 1384.33539991f, 1393.30557020f, 1402.28353887f, 1411.26926400f,
207 1420.26270412f, 1429.26381818f, 1438.27256558f, 1447.28890615f,
208 1456.31280014f, 1465.34420819f, 1474.38309138f, 1483.42941118f,
209 1492.48312945f, 1501.54420843f, 1510.61261078f, 1519.68829949f,
210 1528.77123795f, 1537.86138993f, 1546.95871952f, 1556.06319119f,
211 1565.17476976f, 1574.29342040f, 1583.41910860f, 1592.55180020f,
212 1601.69146137f, 1610.83805860f, 1619.99155871f, 1629.15192882f,
213 1638.31913637f, 1647.49314911f, 1656.67393509f, 1665.86146266f,
214 1675.05570047f, 1684.25661744f, 1693.46418280f, 1702.67836605f,
215 1711.89913698f, 1721.12646563f, 1730.36032233f, 1739.60067768f,
216 1748.84750254f, 1758.10076802f, 1767.36044551f, 1776.62650662f,
217 1785.89892323f, 1795.17766747f, 1804.46271172f, 1813.75402857f,
218 1823.05159087f, 1832.35537170f, 1841.66534438f, 1850.98148244f,
219 1860.30375965f, 1869.63214999f, 1878.96662767f, 1888.30716711f,
220 1897.65374295f, 1907.00633003f, 1916.36490342f, 1925.72943838f,
221 1935.09991037f, 1944.47629506f, 1953.85856831f, 1963.24670620f,
222 1972.64068498f, 1982.04048108f, 1991.44607117f, 2000.85743204f,
223 2010.27454072f, 2019.69737440f, 2029.12591044f, 2038.56012640f
224};
225
226const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX] = {
227 { 0, 0}, { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 1}, { 4, 1}, { 5, 1},
228 { 5, 1}, { 6, 2}, { 6, 2}, { 6, 2}, { 6, 2}, { 7, 2}, { 7, 2}, { 7, 2},
229 { 7, 2}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3},
230 { 8, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3},
231 { 9, 3}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
232 {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
233 {10, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
234 {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
235 {11, 4}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
236 {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
237 {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
238 {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
239 {12, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
240 {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
241 {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
242 {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
243 {13, 5}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
244 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
245 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
246 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
247 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
248 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
249 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
250 {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
251 {14, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
252 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
253 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
254 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
255 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
256 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
257 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
258 {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
259 {15, 6}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
260 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
261 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
262 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
263 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
264 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
265 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
266 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
267 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
268 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
269 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
270 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
271 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
272 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
273 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
274 {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
275 {16, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
276 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
277 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
278 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
279 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
280 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
281 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
282 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
283 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
284 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
285 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
286 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
287 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
288 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
289 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
290 {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
291};
292
293const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {
294 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3,
295 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
296 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
297 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
298 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
299 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
300 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
301 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
302 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
303 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
304 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
305 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
306 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
307 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
308 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
309 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
310 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
311 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
312 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
313 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
314 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
315 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
316 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
317 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
318 127,
319 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
320 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
321 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
322 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
323 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
324 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
325 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
326 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126
327};
328
329static float FastSLog2Slow_C(uint32_t v) {
330 assert(v >= LOG_LOOKUP_IDX_MAX);
331 if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
332#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
333 // use clz if available
334 const int log_cnt = BitsLog2Floor(v) - 7;
335 const uint32_t y = 1 << log_cnt;
336 int correction = 0;
337 const float v_f = (float)v;
338 const uint32_t orig_v = v;
339 v >>= log_cnt;
340#else
341 int log_cnt = 0;
342 uint32_t y = 1;
343 int correction = 0;
344 const float v_f = (float)v;
345 const uint32_t orig_v = v;
346 do {
347 ++log_cnt;
348 v = v >> 1;
349 y = y << 1;
350 } while (v >= LOG_LOOKUP_IDX_MAX);
351#endif
352 // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
353 // Xf = floor(Xf) * (1 + (v % y) / v)
354 // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
355 // The correction factor: log(1 + d) ~ d; for very small d values, so
356 // log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v
357 // LOG_2_RECIPROCAL ~ 23/16
358 correction = (23 * (orig_v & (y - 1))) >> 4;
359 return v_f * (kLog2Table[v] + log_cnt) + correction;
360 } else {
361 return (float)(LOG_2_RECIPROCAL * v * log((double)v));
362 }
363}
364
365static float FastLog2Slow_C(uint32_t v) {
366 assert(v >= LOG_LOOKUP_IDX_MAX);
367 if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
368#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
369 // use clz if available
370 const int log_cnt = BitsLog2Floor(v) - 7;
371 const uint32_t y = 1 << log_cnt;
372 const uint32_t orig_v = v;
373 double log_2;
374 v >>= log_cnt;
375#else
376 int log_cnt = 0;
377 uint32_t y = 1;
378 const uint32_t orig_v = v;
379 double log_2;
380 do {
381 ++log_cnt;
382 v = v >> 1;
383 y = y << 1;
384 } while (v >= LOG_LOOKUP_IDX_MAX);
385#endif
386 log_2 = kLog2Table[v] + log_cnt;
387 if (orig_v >= APPROX_LOG_MAX) {
388 // Since the division is still expensive, add this correction factor only
389 // for large values of 'v'.
390 const int correction = (23 * (orig_v & (y - 1))) >> 4;
391 log_2 += (double)correction / orig_v;
392 }
393 return (float)log_2;
394 } else {
395 return (float)(LOG_2_RECIPROCAL * log((double)v));
396 }
397}
398
399//------------------------------------------------------------------------------
400// Methods to calculate Entropy (Shannon).
401
402// Compute the combined Shanon's entropy for distribution {X} and {X+Y}
403static float CombinedShannonEntropy_C(const int X[256], const int Y[256]) {
404 int i;
405 float retval = 0.f;
406 int sumX = 0, sumXY = 0;
407 for (i = 0; i < 256; ++i) {
408 const int x = X[i];
409 if (x != 0) {
410 const int xy = x + Y[i];
411 sumX += x;
412 retval -= VP8LFastSLog2(x);
413 sumXY += xy;
414 retval -= VP8LFastSLog2(xy);
415 } else if (Y[i] != 0) {
416 sumXY += Y[i];
417 retval -= VP8LFastSLog2(Y[i]);
418 }
419 }
420 retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
421 return retval;
422}
423
424void VP8LBitEntropyInit(VP8LBitEntropy* const entropy) {
425 entropy->entropy = 0.;
426 entropy->sum = 0;
427 entropy->nonzeros = 0;
428 entropy->max_val = 0;
429 entropy->nonzero_code = VP8L_NON_TRIVIAL_SYM;
430}
431
432void VP8LBitsEntropyUnrefined(const uint32_t* const array, int n,
433 VP8LBitEntropy* const entropy) {
434 int i;
435
436 VP8LBitEntropyInit(entropy);
437
438 for (i = 0; i < n; ++i) {
439 if (array[i] != 0) {
440 entropy->sum += array[i];
441 entropy->nonzero_code = i;
442 ++entropy->nonzeros;
443 entropy->entropy -= VP8LFastSLog2(array[i]);
444 if (entropy->max_val < array[i]) {
445 entropy->max_val = array[i];
446 }
447 }
448 }
449 entropy->entropy += VP8LFastSLog2(entropy->sum);
450}
451
452static WEBP_INLINE void GetEntropyUnrefinedHelper(
453 uint32_t val, int i, uint32_t* const val_prev, int* const i_prev,
454 VP8LBitEntropy* const bit_entropy, VP8LStreaks* const stats) {
455 const int streak = i - *i_prev;
456
457 // Gather info for the bit entropy.
458 if (*val_prev != 0) {
459 bit_entropy->sum += (*val_prev) * streak;
460 bit_entropy->nonzeros += streak;
461 bit_entropy->nonzero_code = *i_prev;
462 bit_entropy->entropy -= VP8LFastSLog2(*val_prev) * streak;
463 if (bit_entropy->max_val < *val_prev) {
464 bit_entropy->max_val = *val_prev;
465 }
466 }
467
468 // Gather info for the Huffman cost.
469 stats->counts[*val_prev != 0] += (streak > 3);
470 stats->streaks[*val_prev != 0][(streak > 3)] += streak;
471
472 *val_prev = val;
473 *i_prev = i;
474}
475
476static void GetEntropyUnrefined_C(const uint32_t X[], int length,
477 VP8LBitEntropy* const bit_entropy,
478 VP8LStreaks* const stats) {
479 int i;
480 int i_prev = 0;
481 uint32_t x_prev = X[0];
482
483 memset(stats, 0, sizeof(*stats));
484 VP8LBitEntropyInit(bit_entropy);
485
486 for (i = 1; i < length; ++i) {
487 const uint32_t x = X[i];
488 if (x != x_prev) {
489 GetEntropyUnrefinedHelper(x, i, &x_prev, &i_prev, bit_entropy, stats);
490 }
491 }
492 GetEntropyUnrefinedHelper(0, i, &x_prev, &i_prev, bit_entropy, stats);
493
494 bit_entropy->entropy += VP8LFastSLog2(bit_entropy->sum);
495}
496
497static void GetCombinedEntropyUnrefined_C(const uint32_t X[],
498 const uint32_t Y[],
499 int length,
500 VP8LBitEntropy* const bit_entropy,
501 VP8LStreaks* const stats) {
502 int i = 1;
503 int i_prev = 0;
504 uint32_t xy_prev = X[0] + Y[0];
505
506 memset(stats, 0, sizeof(*stats));
507 VP8LBitEntropyInit(bit_entropy);
508
509 for (i = 1; i < length; ++i) {
510 const uint32_t xy = X[i] + Y[i];
511 if (xy != xy_prev) {
512 GetEntropyUnrefinedHelper(xy, i, &xy_prev, &i_prev, bit_entropy, stats);
513 }
514 }
515 GetEntropyUnrefinedHelper(0, i, &xy_prev, &i_prev, bit_entropy, stats);
516
517 bit_entropy->entropy += VP8LFastSLog2(bit_entropy->sum);
518}
519
520//------------------------------------------------------------------------------
521
522void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
523 int i;
524 for (i = 0; i < num_pixels; ++i) {
525 const int argb = (int)argb_data[i];
526 const int green = (argb >> 8) & 0xff;
527 const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
528 const uint32_t new_b = (((argb >> 0) & 0xff) - green) & 0xff;
529 argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b;
530 }
531}
532
533static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) {
534 return ((int)color_pred * color) >> 5;
535}
536
537static WEBP_INLINE int8_t U32ToS8(uint32_t v) {
538 return (int8_t)(v & 0xff);
539}
540
541void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
542 int num_pixels) {
543 int i;
544 for (i = 0; i < num_pixels; ++i) {
545 const uint32_t argb = data[i];
546 const int8_t green = U32ToS8(argb >> 8);
547 const int8_t red = U32ToS8(argb >> 16);
548 int new_red = red & 0xff;
549 int new_blue = argb & 0xff;
550 new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green);
551 new_red &= 0xff;
552 new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green);
553 new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red);
554 new_blue &= 0xff;
555 data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
556 }
557}
558
559static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
560 uint32_t argb) {
561 const int8_t green = U32ToS8(argb >> 8);
562 int new_red = argb >> 16;
563 new_red -= ColorTransformDelta((int8_t)green_to_red, green);
564 return (new_red & 0xff);
565}
566
567static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
568 uint8_t red_to_blue,
569 uint32_t argb) {
570 const int8_t green = U32ToS8(argb >> 8);
571 const int8_t red = U32ToS8(argb >> 16);
572 int new_blue = argb & 0xff;
573 new_blue -= ColorTransformDelta((int8_t)green_to_blue, green);
574 new_blue -= ColorTransformDelta((int8_t)red_to_blue, red);
575 return (new_blue & 0xff);
576}
577
578void VP8LCollectColorRedTransforms_C(const uint32_t* argb, int stride,
579 int tile_width, int tile_height,
580 int green_to_red, int histo[]) {
581 while (tile_height-- > 0) {
582 int x;
583 for (x = 0; x < tile_width; ++x) {
584 ++histo[TransformColorRed((uint8_t)green_to_red, argb[x])];
585 }
586 argb += stride;
587 }
588}
589
590void VP8LCollectColorBlueTransforms_C(const uint32_t* argb, int stride,
591 int tile_width, int tile_height,
592 int green_to_blue, int red_to_blue,
593 int histo[]) {
594 while (tile_height-- > 0) {
595 int x;
596 for (x = 0; x < tile_width; ++x) {
597 ++histo[TransformColorBlue((uint8_t)green_to_blue, (uint8_t)red_to_blue,
598 argb[x])];
599 }
600 argb += stride;
601 }
602}
603
604//------------------------------------------------------------------------------
605
606static int VectorMismatch_C(const uint32_t* const array1,
607 const uint32_t* const array2, int length) {
608 int match_len = 0;
609
610 while (match_len < length && array1[match_len] == array2[match_len]) {
611 ++match_len;
612 }
613 return match_len;
614}
615
616// Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
617void VP8LBundleColorMap_C(const uint8_t* const row, int width, int xbits,
618 uint32_t* dst) {
619 int x;
620 if (xbits > 0) {
621 const int bit_depth = 1 << (3 - xbits);
622 const int mask = (1 << xbits) - 1;
623 uint32_t code = 0xff000000;
624 for (x = 0; x < width; ++x) {
625 const int xsub = x & mask;
626 if (xsub == 0) {
627 code = 0xff000000;
628 }
629 code |= row[x] << (8 + bit_depth * xsub);
630 dst[x >> xbits] = code;
631 }
632 } else {
633 for (x = 0; x < width; ++x) dst[x] = 0xff000000 | (row[x] << 8);
634 }
635}
636
637//------------------------------------------------------------------------------
638
639static float ExtraCost_C(const uint32_t* population, int length) {
640 int i;
641 float cost = 0.f;
642 for (i = 2; i < length - 2; ++i) cost += (i >> 1) * population[i + 2];
643 return cost;
644}
645
646static float ExtraCostCombined_C(const uint32_t* X, const uint32_t* Y,
647 int length) {
648 int i;
649 float cost = 0.f;
650 for (i = 2; i < length - 2; ++i) {
651 const int xy = X[i + 2] + Y[i + 2];
652 cost += (i >> 1) * xy;
653 }
654 return cost;
655}
656
657//------------------------------------------------------------------------------
658
659static void AddVector_C(const uint32_t* a, const uint32_t* b, uint32_t* out,
660 int size) {
661 int i;
662 for (i = 0; i < size; ++i) out[i] = a[i] + b[i];
663}
664
665static void AddVectorEq_C(const uint32_t* a, uint32_t* out, int size) {
666 int i;
667 for (i = 0; i < size; ++i) out[i] += a[i];
668}
669
670#define ADD(X, ARG, LEN) do { \
671 if (a->is_used_[X]) { \
672 if (b->is_used_[X]) { \
673 VP8LAddVector(a->ARG, b->ARG, out->ARG, (LEN)); \
674 } else { \
675 memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0])); \
676 } \
677 } else if (b->is_used_[X]) { \
678 memcpy(&out->ARG[0], &b->ARG[0], (LEN) * sizeof(out->ARG[0])); \
679 } else { \
680 memset(&out->ARG[0], 0, (LEN) * sizeof(out->ARG[0])); \
681 } \
682} while (0)
683
684#define ADD_EQ(X, ARG, LEN) do { \
685 if (a->is_used_[X]) { \
686 if (out->is_used_[X]) { \
687 VP8LAddVectorEq(a->ARG, out->ARG, (LEN)); \
688 } else { \
689 memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0])); \
690 } \
691 } \
692} while (0)
693
694void VP8LHistogramAdd(const VP8LHistogram* const a,
695 const VP8LHistogram* const b, VP8LHistogram* const out) {
696 int i;
697 const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
698 assert(a->palette_code_bits_ == b->palette_code_bits_);
699
700 if (b != out) {
701 ADD(0, literal_, literal_size);
702 ADD(1, red_, NUM_LITERAL_CODES);
703 ADD(2, blue_, NUM_LITERAL_CODES);
704 ADD(3, alpha_, NUM_LITERAL_CODES);
705 ADD(4, distance_, NUM_DISTANCE_CODES);
706 for (i = 0; i < 5; ++i) {
707 out->is_used_[i] = (a->is_used_[i] | b->is_used_[i]);
708 }
709 } else {
710 ADD_EQ(0, literal_, literal_size);
711 ADD_EQ(1, red_, NUM_LITERAL_CODES);
712 ADD_EQ(2, blue_, NUM_LITERAL_CODES);
713 ADD_EQ(3, alpha_, NUM_LITERAL_CODES);
714 ADD_EQ(4, distance_, NUM_DISTANCE_CODES);
715 for (i = 0; i < 5; ++i) out->is_used_[i] |= a->is_used_[i];
716 }
717}
718#undef ADD
719#undef ADD_EQ
720
721//------------------------------------------------------------------------------
722// Image transforms.
723
724static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,
725 int num_pixels, uint32_t* out) {
726 int i;
727 for (i = 0; i < num_pixels; ++i) out[i] = VP8LSubPixels(in[i], ARGB_BLACK);
728 (void)upper;
729}
730
731static void PredictorSub1_C(const uint32_t* in, const uint32_t* upper,
732 int num_pixels, uint32_t* out) {
733 int i;
734 for (i = 0; i < num_pixels; ++i) out[i] = VP8LSubPixels(in[i], in[i - 1]);
735 (void)upper;
736}
737
738// It subtracts the prediction from the input pixel and stores the residual
739// in the output pixel.
740#define GENERATE_PREDICTOR_SUB(PREDICTOR_I) \
741static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
742 const uint32_t* upper, \
743 int num_pixels, uint32_t* out) { \
744 int x; \
745 assert(upper != NULL); \
746 for (x = 0; x < num_pixels; ++x) { \
747 const uint32_t pred = \
748 VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x); \
749 out[x] = VP8LSubPixels(in[x], pred); \
750 } \
751}
752
753GENERATE_PREDICTOR_SUB(2)
754GENERATE_PREDICTOR_SUB(3)
755GENERATE_PREDICTOR_SUB(4)
756GENERATE_PREDICTOR_SUB(5)
757GENERATE_PREDICTOR_SUB(6)
758GENERATE_PREDICTOR_SUB(7)
759GENERATE_PREDICTOR_SUB(8)
760GENERATE_PREDICTOR_SUB(9)
761GENERATE_PREDICTOR_SUB(10)
762GENERATE_PREDICTOR_SUB(11)
763GENERATE_PREDICTOR_SUB(12)
764GENERATE_PREDICTOR_SUB(13)
765
766//------------------------------------------------------------------------------
767
768VP8LProcessEncBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
769
770VP8LTransformColorFunc VP8LTransformColor;
771
772VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
773VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
774
775VP8LFastLog2SlowFunc VP8LFastLog2Slow;
776VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
777
778VP8LCostFunc VP8LExtraCost;
779VP8LCostCombinedFunc VP8LExtraCostCombined;
780VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;
781
782VP8LGetEntropyUnrefinedFunc VP8LGetEntropyUnrefined;
783VP8LGetCombinedEntropyUnrefinedFunc VP8LGetCombinedEntropyUnrefined;
784
785VP8LAddVectorFunc VP8LAddVector;
786VP8LAddVectorEqFunc VP8LAddVectorEq;
787
788VP8LVectorMismatchFunc VP8LVectorMismatch;
789VP8LBundleColorMapFunc VP8LBundleColorMap;
790
791VP8LPredictorAddSubFunc VP8LPredictorsSub[16];
792VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];
793
794extern VP8CPUInfo VP8GetCPUInfo;
795extern void VP8LEncDspInitSSE2(void);
796extern void VP8LEncDspInitSSE41(void);
797extern void VP8LEncDspInitNEON(void);
798extern void VP8LEncDspInitMIPS32(void);
799extern void VP8LEncDspInitMIPSdspR2(void);
800extern void VP8LEncDspInitMSA(void);
801
802WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
803 VP8LDspInit();
804
805#if !WEBP_NEON_OMIT_C_CODE
806 VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;
807
808 VP8LTransformColor = VP8LTransformColor_C;
809#endif
810
811 VP8LCollectColorBlueTransforms = VP8LCollectColorBlueTransforms_C;
812 VP8LCollectColorRedTransforms = VP8LCollectColorRedTransforms_C;
813
814 VP8LFastLog2Slow = FastLog2Slow_C;
815 VP8LFastSLog2Slow = FastSLog2Slow_C;
816
817 VP8LExtraCost = ExtraCost_C;
818 VP8LExtraCostCombined = ExtraCostCombined_C;
819 VP8LCombinedShannonEntropy = CombinedShannonEntropy_C;
820
821 VP8LGetEntropyUnrefined = GetEntropyUnrefined_C;
822 VP8LGetCombinedEntropyUnrefined = GetCombinedEntropyUnrefined_C;
823
824 VP8LAddVector = AddVector_C;
825 VP8LAddVectorEq = AddVectorEq_C;
826
827 VP8LVectorMismatch = VectorMismatch_C;
828 VP8LBundleColorMap = VP8LBundleColorMap_C;
829
830 VP8LPredictorsSub[0] = PredictorSub0_C;
831 VP8LPredictorsSub[1] = PredictorSub1_C;
832 VP8LPredictorsSub[2] = PredictorSub2_C;
833 VP8LPredictorsSub[3] = PredictorSub3_C;
834 VP8LPredictorsSub[4] = PredictorSub4_C;
835 VP8LPredictorsSub[5] = PredictorSub5_C;
836 VP8LPredictorsSub[6] = PredictorSub6_C;
837 VP8LPredictorsSub[7] = PredictorSub7_C;
838 VP8LPredictorsSub[8] = PredictorSub8_C;
839 VP8LPredictorsSub[9] = PredictorSub9_C;
840 VP8LPredictorsSub[10] = PredictorSub10_C;
841 VP8LPredictorsSub[11] = PredictorSub11_C;
842 VP8LPredictorsSub[12] = PredictorSub12_C;
843 VP8LPredictorsSub[13] = PredictorSub13_C;
844 VP8LPredictorsSub[14] = PredictorSub0_C; // <- padding security sentinels
845 VP8LPredictorsSub[15] = PredictorSub0_C;
846
847 VP8LPredictorsSub_C[0] = PredictorSub0_C;
848 VP8LPredictorsSub_C[1] = PredictorSub1_C;
849 VP8LPredictorsSub_C[2] = PredictorSub2_C;
850 VP8LPredictorsSub_C[3] = PredictorSub3_C;
851 VP8LPredictorsSub_C[4] = PredictorSub4_C;
852 VP8LPredictorsSub_C[5] = PredictorSub5_C;
853 VP8LPredictorsSub_C[6] = PredictorSub6_C;
854 VP8LPredictorsSub_C[7] = PredictorSub7_C;
855 VP8LPredictorsSub_C[8] = PredictorSub8_C;
856 VP8LPredictorsSub_C[9] = PredictorSub9_C;
857 VP8LPredictorsSub_C[10] = PredictorSub10_C;
858 VP8LPredictorsSub_C[11] = PredictorSub11_C;
859 VP8LPredictorsSub_C[12] = PredictorSub12_C;
860 VP8LPredictorsSub_C[13] = PredictorSub13_C;
861 VP8LPredictorsSub_C[14] = PredictorSub0_C; // <- padding security sentinels
862 VP8LPredictorsSub_C[15] = PredictorSub0_C;
863
864 // If defined, use CPUInfo() to overwrite some pointers with faster versions.
865 if (VP8GetCPUInfo != NULL) {
866#if defined(WEBP_HAVE_SSE2)
867 if (VP8GetCPUInfo(kSSE2)) {
868 VP8LEncDspInitSSE2();
869#if defined(WEBP_HAVE_SSE41)
870 if (VP8GetCPUInfo(kSSE4_1)) {
871 VP8LEncDspInitSSE41();
872 }
873#endif
874 }
875#endif
876#if defined(WEBP_USE_MIPS32)
877 if (VP8GetCPUInfo(kMIPS32)) {
878 VP8LEncDspInitMIPS32();
879 }
880#endif
881#if defined(WEBP_USE_MIPS_DSP_R2)
882 if (VP8GetCPUInfo(kMIPSdspR2)) {
883 VP8LEncDspInitMIPSdspR2();
884 }
885#endif
886#if defined(WEBP_USE_MSA)
887 if (VP8GetCPUInfo(kMSA)) {
888 VP8LEncDspInitMSA();
889 }
890#endif
891 }
892
893#if defined(WEBP_HAVE_NEON)
894 if (WEBP_NEON_OMIT_C_CODE ||
895 (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
896 VP8LEncDspInitNEON();
897 }
898#endif
899
900 assert(VP8LSubtractGreenFromBlueAndRed != NULL);
901 assert(VP8LTransformColor != NULL);
902 assert(VP8LCollectColorBlueTransforms != NULL);
903 assert(VP8LCollectColorRedTransforms != NULL);
904 assert(VP8LFastLog2Slow != NULL);
905 assert(VP8LFastSLog2Slow != NULL);
906 assert(VP8LExtraCost != NULL);
907 assert(VP8LExtraCostCombined != NULL);
908 assert(VP8LCombinedShannonEntropy != NULL);
909 assert(VP8LGetEntropyUnrefined != NULL);
910 assert(VP8LGetCombinedEntropyUnrefined != NULL);
911 assert(VP8LAddVector != NULL);
912 assert(VP8LAddVectorEq != NULL);
913 assert(VP8LVectorMismatch != NULL);
914 assert(VP8LBundleColorMap != NULL);
915 assert(VP8LPredictorsSub[0] != NULL);
916 assert(VP8LPredictorsSub[1] != NULL);
917 assert(VP8LPredictorsSub[2] != NULL);
918 assert(VP8LPredictorsSub[3] != NULL);
919 assert(VP8LPredictorsSub[4] != NULL);
920 assert(VP8LPredictorsSub[5] != NULL);
921 assert(VP8LPredictorsSub[6] != NULL);
922 assert(VP8LPredictorsSub[7] != NULL);
923 assert(VP8LPredictorsSub[8] != NULL);
924 assert(VP8LPredictorsSub[9] != NULL);
925 assert(VP8LPredictorsSub[10] != NULL);
926 assert(VP8LPredictorsSub[11] != NULL);
927 assert(VP8LPredictorsSub[12] != NULL);
928 assert(VP8LPredictorsSub[13] != NULL);
929 assert(VP8LPredictorsSub[14] != NULL);
930 assert(VP8LPredictorsSub[15] != NULL);
931 assert(VP8LPredictorsSub_C[0] != NULL);
932 assert(VP8LPredictorsSub_C[1] != NULL);
933 assert(VP8LPredictorsSub_C[2] != NULL);
934 assert(VP8LPredictorsSub_C[3] != NULL);
935 assert(VP8LPredictorsSub_C[4] != NULL);
936 assert(VP8LPredictorsSub_C[5] != NULL);
937 assert(VP8LPredictorsSub_C[6] != NULL);
938 assert(VP8LPredictorsSub_C[7] != NULL);
939 assert(VP8LPredictorsSub_C[8] != NULL);
940 assert(VP8LPredictorsSub_C[9] != NULL);
941 assert(VP8LPredictorsSub_C[10] != NULL);
942 assert(VP8LPredictorsSub_C[11] != NULL);
943 assert(VP8LPredictorsSub_C[12] != NULL);
944 assert(VP8LPredictorsSub_C[13] != NULL);
945 assert(VP8LPredictorsSub_C[14] != NULL);
946 assert(VP8LPredictorsSub_C[15] != NULL);
947}
948
949//------------------------------------------------------------------------------
950