• 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)
28 const 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 
159 const 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 
226 const 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 
293 const 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 
FastSLog2Slow_C(uint32_t v)329 static 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 
FastLog2Slow_C(uint32_t v)365 static 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}
CombinedShannonEntropy_C(const int X[256],const int Y[256])403 static 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 
VP8LBitEntropyInit(VP8LBitEntropy * const entropy)424 void 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 
VP8LBitsEntropyUnrefined(const uint32_t * const array,int n,VP8LBitEntropy * const entropy)432 void 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 
GetEntropyUnrefinedHelper(uint32_t val,int i,uint32_t * const val_prev,int * const i_prev,VP8LBitEntropy * const bit_entropy,VP8LStreaks * const stats)452 static 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 
GetEntropyUnrefined_C(const uint32_t X[],int length,VP8LBitEntropy * const bit_entropy,VP8LStreaks * const stats)476 static 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 
GetCombinedEntropyUnrefined_C(const uint32_t X[],const uint32_t Y[],int length,VP8LBitEntropy * const bit_entropy,VP8LStreaks * const stats)497 static 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 
VP8LSubtractGreenFromBlueAndRed_C(uint32_t * argb_data,int num_pixels)522 void 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 
ColorTransformDelta(int8_t color_pred,int8_t color)533 static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) {
534   return ((int)color_pred * color) >> 5;
535 }
536 
U32ToS8(uint32_t v)537 static WEBP_INLINE int8_t U32ToS8(uint32_t v) {
538   return (int8_t)(v & 0xff);
539 }
540 
VP8LTransformColor_C(const VP8LMultipliers * const m,uint32_t * data,int num_pixels)541 void 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 
TransformColorRed(uint8_t green_to_red,uint32_t argb)559 static 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 
TransformColorBlue(uint8_t green_to_blue,uint8_t red_to_blue,uint32_t argb)567 static 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 
VP8LCollectColorRedTransforms_C(const uint32_t * argb,int stride,int tile_width,int tile_height,int green_to_red,int histo[])578 void 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 
VP8LCollectColorBlueTransforms_C(const uint32_t * argb,int stride,int tile_width,int tile_height,int green_to_blue,int red_to_blue,int histo[])590 void 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 
VectorMismatch_C(const uint32_t * const array1,const uint32_t * const array2,int length)606 static 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.
VP8LBundleColorMap_C(const uint8_t * const row,int width,int xbits,uint32_t * dst)617 void 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 
ExtraCost_C(const uint32_t * population,int length)639 static 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 
ExtraCostCombined_C(const uint32_t * X,const uint32_t * Y,int length)646 static 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 
AddVector_C(const uint32_t * a,const uint32_t * b,uint32_t * out,int size)659 static 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 
AddVectorEq_C(const uint32_t * a,uint32_t * out,int size)665 static 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 
VP8LHistogramAdd(const VP8LHistogram * const a,const VP8LHistogram * const b,VP8LHistogram * const out)694 void 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 
PredictorSub0_C(const uint32_t * in,const uint32_t * upper,int num_pixels,uint32_t * out)724 static 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 
PredictorSub1_C(const uint32_t * in,const uint32_t * upper,int num_pixels,uint32_t * out)731 static 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)                                \
741 static 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 
753 GENERATE_PREDICTOR_SUB(2)
754 GENERATE_PREDICTOR_SUB(3)
755 GENERATE_PREDICTOR_SUB(4)
756 GENERATE_PREDICTOR_SUB(5)
757 GENERATE_PREDICTOR_SUB(6)
758 GENERATE_PREDICTOR_SUB(7)
759 GENERATE_PREDICTOR_SUB(8)
760 GENERATE_PREDICTOR_SUB(9)
761 GENERATE_PREDICTOR_SUB(10)
762 GENERATE_PREDICTOR_SUB(11)
763 GENERATE_PREDICTOR_SUB(12)
764 GENERATE_PREDICTOR_SUB(13)
765 
766 //------------------------------------------------------------------------------
767 
768 VP8LProcessEncBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
769 
770 VP8LTransformColorFunc VP8LTransformColor;
771 
772 VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
773 VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
774 
775 VP8LFastLog2SlowFunc VP8LFastLog2Slow;
776 VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
777 
778 VP8LCostFunc VP8LExtraCost;
779 VP8LCostCombinedFunc VP8LExtraCostCombined;
780 VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;
781 
782 VP8LGetEntropyUnrefinedFunc VP8LGetEntropyUnrefined;
783 VP8LGetCombinedEntropyUnrefinedFunc VP8LGetCombinedEntropyUnrefined;
784 
785 VP8LAddVectorFunc VP8LAddVector;
786 VP8LAddVectorEqFunc VP8LAddVectorEq;
787 
788 VP8LVectorMismatchFunc VP8LVectorMismatch;
789 VP8LBundleColorMapFunc VP8LBundleColorMap;
790 
791 VP8LPredictorAddSubFunc VP8LPredictorsSub[16];
792 VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];
793 
794 extern void VP8LEncDspInitSSE2(void);
795 extern void VP8LEncDspInitSSE41(void);
796 extern void VP8LEncDspInitNEON(void);
797 extern void VP8LEncDspInitMIPS32(void);
798 extern void VP8LEncDspInitMIPSdspR2(void);
799 extern void VP8LEncDspInitMSA(void);
800 
WEBP_DSP_INIT_FUNC(VP8LEncDspInit)801 WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
802   VP8LDspInit();
803 
804 #if !WEBP_NEON_OMIT_C_CODE
805   VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;
806 
807   VP8LTransformColor = VP8LTransformColor_C;
808 #endif
809 
810   VP8LCollectColorBlueTransforms = VP8LCollectColorBlueTransforms_C;
811   VP8LCollectColorRedTransforms = VP8LCollectColorRedTransforms_C;
812 
813   VP8LFastLog2Slow = FastLog2Slow_C;
814   VP8LFastSLog2Slow = FastSLog2Slow_C;
815 
816   VP8LExtraCost = ExtraCost_C;
817   VP8LExtraCostCombined = ExtraCostCombined_C;
818   VP8LCombinedShannonEntropy = CombinedShannonEntropy_C;
819 
820   VP8LGetEntropyUnrefined = GetEntropyUnrefined_C;
821   VP8LGetCombinedEntropyUnrefined = GetCombinedEntropyUnrefined_C;
822 
823   VP8LAddVector = AddVector_C;
824   VP8LAddVectorEq = AddVectorEq_C;
825 
826   VP8LVectorMismatch = VectorMismatch_C;
827   VP8LBundleColorMap = VP8LBundleColorMap_C;
828 
829   VP8LPredictorsSub[0] = PredictorSub0_C;
830   VP8LPredictorsSub[1] = PredictorSub1_C;
831   VP8LPredictorsSub[2] = PredictorSub2_C;
832   VP8LPredictorsSub[3] = PredictorSub3_C;
833   VP8LPredictorsSub[4] = PredictorSub4_C;
834   VP8LPredictorsSub[5] = PredictorSub5_C;
835   VP8LPredictorsSub[6] = PredictorSub6_C;
836   VP8LPredictorsSub[7] = PredictorSub7_C;
837   VP8LPredictorsSub[8] = PredictorSub8_C;
838   VP8LPredictorsSub[9] = PredictorSub9_C;
839   VP8LPredictorsSub[10] = PredictorSub10_C;
840   VP8LPredictorsSub[11] = PredictorSub11_C;
841   VP8LPredictorsSub[12] = PredictorSub12_C;
842   VP8LPredictorsSub[13] = PredictorSub13_C;
843   VP8LPredictorsSub[14] = PredictorSub0_C;  // <- padding security sentinels
844   VP8LPredictorsSub[15] = PredictorSub0_C;
845 
846   VP8LPredictorsSub_C[0] = PredictorSub0_C;
847   VP8LPredictorsSub_C[1] = PredictorSub1_C;
848   VP8LPredictorsSub_C[2] = PredictorSub2_C;
849   VP8LPredictorsSub_C[3] = PredictorSub3_C;
850   VP8LPredictorsSub_C[4] = PredictorSub4_C;
851   VP8LPredictorsSub_C[5] = PredictorSub5_C;
852   VP8LPredictorsSub_C[6] = PredictorSub6_C;
853   VP8LPredictorsSub_C[7] = PredictorSub7_C;
854   VP8LPredictorsSub_C[8] = PredictorSub8_C;
855   VP8LPredictorsSub_C[9] = PredictorSub9_C;
856   VP8LPredictorsSub_C[10] = PredictorSub10_C;
857   VP8LPredictorsSub_C[11] = PredictorSub11_C;
858   VP8LPredictorsSub_C[12] = PredictorSub12_C;
859   VP8LPredictorsSub_C[13] = PredictorSub13_C;
860   VP8LPredictorsSub_C[14] = PredictorSub0_C;  // <- padding security sentinels
861   VP8LPredictorsSub_C[15] = PredictorSub0_C;
862 
863   // If defined, use CPUInfo() to overwrite some pointers with faster versions.
864   if (VP8GetCPUInfo != NULL) {
865 #if defined(WEBP_HAVE_SSE2)
866     if (VP8GetCPUInfo(kSSE2)) {
867       VP8LEncDspInitSSE2();
868 #if defined(WEBP_HAVE_SSE41)
869       if (VP8GetCPUInfo(kSSE4_1)) {
870         VP8LEncDspInitSSE41();
871       }
872 #endif
873     }
874 #endif
875 #if defined(WEBP_USE_MIPS32)
876     if (VP8GetCPUInfo(kMIPS32)) {
877       VP8LEncDspInitMIPS32();
878     }
879 #endif
880 #if defined(WEBP_USE_MIPS_DSP_R2)
881     if (VP8GetCPUInfo(kMIPSdspR2)) {
882       VP8LEncDspInitMIPSdspR2();
883     }
884 #endif
885 #if defined(WEBP_USE_MSA)
886     if (VP8GetCPUInfo(kMSA)) {
887       VP8LEncDspInitMSA();
888     }
889 #endif
890   }
891 
892 #if defined(WEBP_HAVE_NEON)
893   if (WEBP_NEON_OMIT_C_CODE ||
894       (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
895     VP8LEncDspInitNEON();
896   }
897 #endif
898 
899   assert(VP8LSubtractGreenFromBlueAndRed != NULL);
900   assert(VP8LTransformColor != NULL);
901   assert(VP8LCollectColorBlueTransforms != NULL);
902   assert(VP8LCollectColorRedTransforms != NULL);
903   assert(VP8LFastLog2Slow != NULL);
904   assert(VP8LFastSLog2Slow != NULL);
905   assert(VP8LExtraCost != NULL);
906   assert(VP8LExtraCostCombined != NULL);
907   assert(VP8LCombinedShannonEntropy != NULL);
908   assert(VP8LGetEntropyUnrefined != NULL);
909   assert(VP8LGetCombinedEntropyUnrefined != NULL);
910   assert(VP8LAddVector != NULL);
911   assert(VP8LAddVectorEq != NULL);
912   assert(VP8LVectorMismatch != NULL);
913   assert(VP8LBundleColorMap != NULL);
914   assert(VP8LPredictorsSub[0] != NULL);
915   assert(VP8LPredictorsSub[1] != NULL);
916   assert(VP8LPredictorsSub[2] != NULL);
917   assert(VP8LPredictorsSub[3] != NULL);
918   assert(VP8LPredictorsSub[4] != NULL);
919   assert(VP8LPredictorsSub[5] != NULL);
920   assert(VP8LPredictorsSub[6] != NULL);
921   assert(VP8LPredictorsSub[7] != NULL);
922   assert(VP8LPredictorsSub[8] != NULL);
923   assert(VP8LPredictorsSub[9] != NULL);
924   assert(VP8LPredictorsSub[10] != NULL);
925   assert(VP8LPredictorsSub[11] != NULL);
926   assert(VP8LPredictorsSub[12] != NULL);
927   assert(VP8LPredictorsSub[13] != NULL);
928   assert(VP8LPredictorsSub[14] != NULL);
929   assert(VP8LPredictorsSub[15] != NULL);
930   assert(VP8LPredictorsSub_C[0] != NULL);
931   assert(VP8LPredictorsSub_C[1] != NULL);
932   assert(VP8LPredictorsSub_C[2] != NULL);
933   assert(VP8LPredictorsSub_C[3] != NULL);
934   assert(VP8LPredictorsSub_C[4] != NULL);
935   assert(VP8LPredictorsSub_C[5] != NULL);
936   assert(VP8LPredictorsSub_C[6] != NULL);
937   assert(VP8LPredictorsSub_C[7] != NULL);
938   assert(VP8LPredictorsSub_C[8] != NULL);
939   assert(VP8LPredictorsSub_C[9] != NULL);
940   assert(VP8LPredictorsSub_C[10] != NULL);
941   assert(VP8LPredictorsSub_C[11] != NULL);
942   assert(VP8LPredictorsSub_C[12] != NULL);
943   assert(VP8LPredictorsSub_C[13] != NULL);
944   assert(VP8LPredictorsSub_C[14] != NULL);
945   assert(VP8LPredictorsSub_C[15] != NULL);
946 }
947 
948 //------------------------------------------------------------------------------
949