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