1*e47783fdSXin Li /*
2*e47783fdSXin Li Copyright 2016 Google Inc. All Rights Reserved.
3*e47783fdSXin Li
4*e47783fdSXin Li Licensed under the Apache License, Version 2.0 (the "License");
5*e47783fdSXin Li you may not use this file except in compliance with the License.
6*e47783fdSXin Li You may obtain a copy of the License at
7*e47783fdSXin Li
8*e47783fdSXin Li http://www.apache.org/licenses/LICENSE-2.0
9*e47783fdSXin Li
10*e47783fdSXin Li Unless required by applicable law or agreed to in writing, software
11*e47783fdSXin Li distributed under the License is distributed on an "AS IS" BASIS,
12*e47783fdSXin Li WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e47783fdSXin Li See the License for the specific language governing permissions and
14*e47783fdSXin Li limitations under the License.
15*e47783fdSXin Li
16*e47783fdSXin Li Author: [email protected] (Lode Vandevenne)
17*e47783fdSXin Li Author: [email protected] (Jyrki Alakuijala)
18*e47783fdSXin Li */
19*e47783fdSXin Li
20*e47783fdSXin Li /*
21*e47783fdSXin Li Utilities for using the lz77 symbols of the deflate spec.
22*e47783fdSXin Li */
23*e47783fdSXin Li
24*e47783fdSXin Li #ifndef ZOPFLI_SYMBOLS_H_
25*e47783fdSXin Li #define ZOPFLI_SYMBOLS_H_
26*e47783fdSXin Li
27*e47783fdSXin Li /* __has_builtin available in clang */
28*e47783fdSXin Li #ifdef __has_builtin
29*e47783fdSXin Li # if __has_builtin(__builtin_clz)
30*e47783fdSXin Li # define ZOPFLI_HAS_BUILTIN_CLZ
31*e47783fdSXin Li # endif
32*e47783fdSXin Li /* __builtin_clz available beginning with GCC 3.4 */
33*e47783fdSXin Li #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 304
34*e47783fdSXin Li # define ZOPFLI_HAS_BUILTIN_CLZ
35*e47783fdSXin Li #endif
36*e47783fdSXin Li
37*e47783fdSXin Li /* Gets the amount of extra bits for the given dist, cfr. the DEFLATE spec. */
ZopfliGetDistExtraBits(int dist)38*e47783fdSXin Li static int ZopfliGetDistExtraBits(int dist) {
39*e47783fdSXin Li #ifdef ZOPFLI_HAS_BUILTIN_CLZ
40*e47783fdSXin Li if (dist < 5) return 0;
41*e47783fdSXin Li return (31 ^ __builtin_clz(dist - 1)) - 1; /* log2(dist - 1) - 1 */
42*e47783fdSXin Li #else
43*e47783fdSXin Li if (dist < 5) return 0;
44*e47783fdSXin Li else if (dist < 9) return 1;
45*e47783fdSXin Li else if (dist < 17) return 2;
46*e47783fdSXin Li else if (dist < 33) return 3;
47*e47783fdSXin Li else if (dist < 65) return 4;
48*e47783fdSXin Li else if (dist < 129) return 5;
49*e47783fdSXin Li else if (dist < 257) return 6;
50*e47783fdSXin Li else if (dist < 513) return 7;
51*e47783fdSXin Li else if (dist < 1025) return 8;
52*e47783fdSXin Li else if (dist < 2049) return 9;
53*e47783fdSXin Li else if (dist < 4097) return 10;
54*e47783fdSXin Li else if (dist < 8193) return 11;
55*e47783fdSXin Li else if (dist < 16385) return 12;
56*e47783fdSXin Li else return 13;
57*e47783fdSXin Li #endif
58*e47783fdSXin Li }
59*e47783fdSXin Li
60*e47783fdSXin Li /* Gets value of the extra bits for the given dist, cfr. the DEFLATE spec. */
ZopfliGetDistExtraBitsValue(int dist)61*e47783fdSXin Li static int ZopfliGetDistExtraBitsValue(int dist) {
62*e47783fdSXin Li #ifdef ZOPFLI_HAS_BUILTIN_CLZ
63*e47783fdSXin Li if (dist < 5) {
64*e47783fdSXin Li return 0;
65*e47783fdSXin Li } else {
66*e47783fdSXin Li int l = 31 ^ __builtin_clz(dist - 1); /* log2(dist - 1) */
67*e47783fdSXin Li return (dist - (1 + (1 << l))) & ((1 << (l - 1)) - 1);
68*e47783fdSXin Li }
69*e47783fdSXin Li #else
70*e47783fdSXin Li if (dist < 5) return 0;
71*e47783fdSXin Li else if (dist < 9) return (dist - 5) & 1;
72*e47783fdSXin Li else if (dist < 17) return (dist - 9) & 3;
73*e47783fdSXin Li else if (dist < 33) return (dist - 17) & 7;
74*e47783fdSXin Li else if (dist < 65) return (dist - 33) & 15;
75*e47783fdSXin Li else if (dist < 129) return (dist - 65) & 31;
76*e47783fdSXin Li else if (dist < 257) return (dist - 129) & 63;
77*e47783fdSXin Li else if (dist < 513) return (dist - 257) & 127;
78*e47783fdSXin Li else if (dist < 1025) return (dist - 513) & 255;
79*e47783fdSXin Li else if (dist < 2049) return (dist - 1025) & 511;
80*e47783fdSXin Li else if (dist < 4097) return (dist - 2049) & 1023;
81*e47783fdSXin Li else if (dist < 8193) return (dist - 4097) & 2047;
82*e47783fdSXin Li else if (dist < 16385) return (dist - 8193) & 4095;
83*e47783fdSXin Li else return (dist - 16385) & 8191;
84*e47783fdSXin Li #endif
85*e47783fdSXin Li }
86*e47783fdSXin Li
87*e47783fdSXin Li /* Gets the symbol for the given dist, cfr. the DEFLATE spec. */
ZopfliGetDistSymbol(int dist)88*e47783fdSXin Li static int ZopfliGetDistSymbol(int dist) {
89*e47783fdSXin Li #ifdef ZOPFLI_HAS_BUILTIN_CLZ
90*e47783fdSXin Li if (dist < 5) {
91*e47783fdSXin Li return dist - 1;
92*e47783fdSXin Li } else {
93*e47783fdSXin Li int l = (31 ^ __builtin_clz(dist - 1)); /* log2(dist - 1) */
94*e47783fdSXin Li int r = ((dist - 1) >> (l - 1)) & 1;
95*e47783fdSXin Li return l * 2 + r;
96*e47783fdSXin Li }
97*e47783fdSXin Li #else
98*e47783fdSXin Li if (dist < 193) {
99*e47783fdSXin Li if (dist < 13) { /* dist 0..13. */
100*e47783fdSXin Li if (dist < 5) return dist - 1;
101*e47783fdSXin Li else if (dist < 7) return 4;
102*e47783fdSXin Li else if (dist < 9) return 5;
103*e47783fdSXin Li else return 6;
104*e47783fdSXin Li } else { /* dist 13..193. */
105*e47783fdSXin Li if (dist < 17) return 7;
106*e47783fdSXin Li else if (dist < 25) return 8;
107*e47783fdSXin Li else if (dist < 33) return 9;
108*e47783fdSXin Li else if (dist < 49) return 10;
109*e47783fdSXin Li else if (dist < 65) return 11;
110*e47783fdSXin Li else if (dist < 97) return 12;
111*e47783fdSXin Li else if (dist < 129) return 13;
112*e47783fdSXin Li else return 14;
113*e47783fdSXin Li }
114*e47783fdSXin Li } else {
115*e47783fdSXin Li if (dist < 2049) { /* dist 193..2049. */
116*e47783fdSXin Li if (dist < 257) return 15;
117*e47783fdSXin Li else if (dist < 385) return 16;
118*e47783fdSXin Li else if (dist < 513) return 17;
119*e47783fdSXin Li else if (dist < 769) return 18;
120*e47783fdSXin Li else if (dist < 1025) return 19;
121*e47783fdSXin Li else if (dist < 1537) return 20;
122*e47783fdSXin Li else return 21;
123*e47783fdSXin Li } else { /* dist 2049..32768. */
124*e47783fdSXin Li if (dist < 3073) return 22;
125*e47783fdSXin Li else if (dist < 4097) return 23;
126*e47783fdSXin Li else if (dist < 6145) return 24;
127*e47783fdSXin Li else if (dist < 8193) return 25;
128*e47783fdSXin Li else if (dist < 12289) return 26;
129*e47783fdSXin Li else if (dist < 16385) return 27;
130*e47783fdSXin Li else if (dist < 24577) return 28;
131*e47783fdSXin Li else return 29;
132*e47783fdSXin Li }
133*e47783fdSXin Li }
134*e47783fdSXin Li #endif
135*e47783fdSXin Li }
136*e47783fdSXin Li
137*e47783fdSXin Li /* Gets the amount of extra bits for the given length, cfr. the DEFLATE spec. */
ZopfliGetLengthExtraBits(int l)138*e47783fdSXin Li static int ZopfliGetLengthExtraBits(int l) {
139*e47783fdSXin Li static const int table[259] = {
140*e47783fdSXin Li 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
141*e47783fdSXin Li 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
142*e47783fdSXin Li 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
143*e47783fdSXin Li 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
144*e47783fdSXin Li 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
145*e47783fdSXin Li 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
146*e47783fdSXin Li 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
147*e47783fdSXin Li 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
148*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
149*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
150*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
151*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
152*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
153*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
154*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
155*e47783fdSXin Li 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
156*e47783fdSXin Li };
157*e47783fdSXin Li return table[l];
158*e47783fdSXin Li }
159*e47783fdSXin Li
160*e47783fdSXin Li /* Gets value of the extra bits for the given length, cfr. the DEFLATE spec. */
ZopfliGetLengthExtraBitsValue(int l)161*e47783fdSXin Li static int ZopfliGetLengthExtraBitsValue(int l) {
162*e47783fdSXin Li static const int table[259] = {
163*e47783fdSXin Li 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 0,
164*e47783fdSXin Li 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5,
165*e47783fdSXin Li 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6,
166*e47783fdSXin Li 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
167*e47783fdSXin Li 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2,
168*e47783fdSXin Li 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
169*e47783fdSXin Li 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
170*e47783fdSXin Li 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
171*e47783fdSXin Li 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6,
172*e47783fdSXin Li 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
173*e47783fdSXin Li 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
174*e47783fdSXin Li 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0
175*e47783fdSXin Li };
176*e47783fdSXin Li return table[l];
177*e47783fdSXin Li }
178*e47783fdSXin Li
179*e47783fdSXin Li /*
180*e47783fdSXin Li Gets the symbol for the given length, cfr. the DEFLATE spec.
181*e47783fdSXin Li Returns the symbol in the range [257-285] (inclusive)
182*e47783fdSXin Li */
ZopfliGetLengthSymbol(int l)183*e47783fdSXin Li static int ZopfliGetLengthSymbol(int l) {
184*e47783fdSXin Li static const int table[259] = {
185*e47783fdSXin Li 0, 0, 0, 257, 258, 259, 260, 261, 262, 263, 264,
186*e47783fdSXin Li 265, 265, 266, 266, 267, 267, 268, 268,
187*e47783fdSXin Li 269, 269, 269, 269, 270, 270, 270, 270,
188*e47783fdSXin Li 271, 271, 271, 271, 272, 272, 272, 272,
189*e47783fdSXin Li 273, 273, 273, 273, 273, 273, 273, 273,
190*e47783fdSXin Li 274, 274, 274, 274, 274, 274, 274, 274,
191*e47783fdSXin Li 275, 275, 275, 275, 275, 275, 275, 275,
192*e47783fdSXin Li 276, 276, 276, 276, 276, 276, 276, 276,
193*e47783fdSXin Li 277, 277, 277, 277, 277, 277, 277, 277,
194*e47783fdSXin Li 277, 277, 277, 277, 277, 277, 277, 277,
195*e47783fdSXin Li 278, 278, 278, 278, 278, 278, 278, 278,
196*e47783fdSXin Li 278, 278, 278, 278, 278, 278, 278, 278,
197*e47783fdSXin Li 279, 279, 279, 279, 279, 279, 279, 279,
198*e47783fdSXin Li 279, 279, 279, 279, 279, 279, 279, 279,
199*e47783fdSXin Li 280, 280, 280, 280, 280, 280, 280, 280,
200*e47783fdSXin Li 280, 280, 280, 280, 280, 280, 280, 280,
201*e47783fdSXin Li 281, 281, 281, 281, 281, 281, 281, 281,
202*e47783fdSXin Li 281, 281, 281, 281, 281, 281, 281, 281,
203*e47783fdSXin Li 281, 281, 281, 281, 281, 281, 281, 281,
204*e47783fdSXin Li 281, 281, 281, 281, 281, 281, 281, 281,
205*e47783fdSXin Li 282, 282, 282, 282, 282, 282, 282, 282,
206*e47783fdSXin Li 282, 282, 282, 282, 282, 282, 282, 282,
207*e47783fdSXin Li 282, 282, 282, 282, 282, 282, 282, 282,
208*e47783fdSXin Li 282, 282, 282, 282, 282, 282, 282, 282,
209*e47783fdSXin Li 283, 283, 283, 283, 283, 283, 283, 283,
210*e47783fdSXin Li 283, 283, 283, 283, 283, 283, 283, 283,
211*e47783fdSXin Li 283, 283, 283, 283, 283, 283, 283, 283,
212*e47783fdSXin Li 283, 283, 283, 283, 283, 283, 283, 283,
213*e47783fdSXin Li 284, 284, 284, 284, 284, 284, 284, 284,
214*e47783fdSXin Li 284, 284, 284, 284, 284, 284, 284, 284,
215*e47783fdSXin Li 284, 284, 284, 284, 284, 284, 284, 284,
216*e47783fdSXin Li 284, 284, 284, 284, 284, 284, 284, 285
217*e47783fdSXin Li };
218*e47783fdSXin Li return table[l];
219*e47783fdSXin Li }
220*e47783fdSXin Li
221*e47783fdSXin Li /* Gets the amount of extra bits for the given length symbol. */
ZopfliGetLengthSymbolExtraBits(int s)222*e47783fdSXin Li static int ZopfliGetLengthSymbolExtraBits(int s) {
223*e47783fdSXin Li static const int table[29] = {
224*e47783fdSXin Li 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
225*e47783fdSXin Li 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
226*e47783fdSXin Li };
227*e47783fdSXin Li return table[s - 257];
228*e47783fdSXin Li }
229*e47783fdSXin Li
230*e47783fdSXin Li /* Gets the amount of extra bits for the given distance symbol. */
ZopfliGetDistSymbolExtraBits(int s)231*e47783fdSXin Li static int ZopfliGetDistSymbolExtraBits(int s) {
232*e47783fdSXin Li static const int table[30] = {
233*e47783fdSXin Li 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
234*e47783fdSXin Li 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
235*e47783fdSXin Li };
236*e47783fdSXin Li return table[s];
237*e47783fdSXin Li }
238*e47783fdSXin Li
239*e47783fdSXin Li #endif /* ZOPFLI_SYMBOLS_H_ */
240