]>
Commit | Line | Data |
---|---|---|
11b7501a SB |
1 | /* Copyright 2010 Google Inc. All Rights Reserved.\r |
2 | \r | |
3 | Distributed under MIT license.\r | |
4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\r | |
5 | */\r | |
6 | \r | |
7 | /* A (forgetful) hash table to the data seen by the compressor, to\r | |
8 | help create backward references to previous data. */\r | |
9 | \r | |
10 | #ifndef BROTLI_ENC_HASH_H_\r | |
11 | #define BROTLI_ENC_HASH_H_\r | |
12 | \r | |
13 | #include <string.h> /* memcmp, memset */\r | |
14 | \r | |
15 | #include "../common/constants.h"\r | |
16 | #include "../common/dictionary.h"\r | |
dd4f667e LG |
17 | #include "../common/platform.h"\r |
18 | #include <brotli/types.h>\r | |
19 | #include "./encoder_dict.h"\r | |
11b7501a SB |
20 | #include "./fast_log.h"\r |
21 | #include "./find_match_length.h"\r | |
22 | #include "./memory.h"\r | |
11b7501a SB |
23 | #include "./quality.h"\r |
24 | #include "./static_dict.h"\r | |
25 | \r | |
26 | #if defined(__cplusplus) || defined(c_plusplus)\r | |
27 | extern "C" {\r | |
28 | #endif\r | |
29 | \r | |
dd4f667e LG |
30 | /* Pointer to hasher data.\r |
31 | *\r | |
32 | * Excluding initialization and destruction, hasher can be passed as\r | |
33 | * HasherHandle by value.\r | |
34 | *\r | |
35 | * Typically hasher data consists of 3 sections:\r | |
36 | * * HasherCommon structure\r | |
37 | * * private structured hasher data, depending on hasher type\r | |
38 | * * private dynamic hasher data, depending on hasher type and parameters\r | |
39 | *\r | |
40 | * Using "define" instead of "typedef", because on MSVC __restrict does not work\r | |
41 | * on typedef pointer types. */\r | |
42 | #define HasherHandle uint8_t*\r | |
43 | \r | |
44 | typedef struct {\r | |
45 | BrotliHasherParams params;\r | |
46 | \r | |
47 | /* False if hasher needs to be "prepared" before use. */\r | |
48 | BROTLI_BOOL is_prepared_;\r | |
49 | \r | |
50 | size_t dict_num_lookups;\r | |
51 | size_t dict_num_matches;\r | |
52 | } HasherCommon;\r | |
53 | \r | |
54 | static BROTLI_INLINE HasherCommon* GetHasherCommon(HasherHandle handle) {\r | |
55 | return (HasherCommon*)handle;\r | |
56 | }\r | |
11b7501a | 57 | \r |
dd4f667e | 58 | #define score_t size_t\r |
11b7501a SB |
59 | \r |
60 | static const uint32_t kCutoffTransformsCount = 10;\r | |
dd4f667e LG |
61 | /* 0, 12, 27, 23, 42, 63, 56, 48, 59, 64 */\r |
62 | /* 0+0, 4+8, 8+19, 12+11, 16+26, 20+43, 24+32, 28+20, 32+27, 36+28 */\r | |
63 | static const uint64_t kCutoffTransforms =\r | |
64 | BROTLI_MAKE_UINT64_T(0x071B520A, 0xDA2D3200);\r | |
11b7501a SB |
65 | \r |
66 | typedef struct HasherSearchResult {\r | |
67 | size_t len;\r | |
11b7501a SB |
68 | size_t distance;\r |
69 | score_t score;\r | |
dd4f667e | 70 | int len_code_delta; /* == len_code - len */\r |
11b7501a SB |
71 | } HasherSearchResult;\r |
72 | \r | |
11b7501a SB |
73 | /* kHashMul32 multiplier has these properties:\r |
74 | * The multiplier must be odd. Otherwise we may lose the highest bit.\r | |
dd4f667e | 75 | * No long streaks of ones or zeros.\r |
11b7501a SB |
76 | * There is no effort to ensure that it is a prime, the oddity is enough\r |
77 | for this use.\r | |
78 | * The number has been tuned heuristically against compression benchmarks. */\r | |
dd4f667e LG |
79 | static const uint32_t kHashMul32 = 0x1E35A7BD;\r |
80 | static const uint64_t kHashMul64 = BROTLI_MAKE_UINT64_T(0x1E35A7BD, 0x1E35A7BD);\r | |
81 | static const uint64_t kHashMul64Long =\r | |
82 | BROTLI_MAKE_UINT64_T(0x1FE35A7Bu, 0xD3579BD3u);\r | |
11b7501a SB |
83 | \r |
84 | static BROTLI_INLINE uint32_t Hash14(const uint8_t* data) {\r | |
dd4f667e | 85 | uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;\r |
11b7501a SB |
86 | /* The higher bits contain more mixture from the multiplication,\r |
87 | so we take our results from there. */\r | |
88 | return h >> (32 - 14);\r | |
89 | }\r | |
90 | \r | |
dd4f667e LG |
91 | static BROTLI_INLINE void PrepareDistanceCache(\r |
92 | int* BROTLI_RESTRICT distance_cache, const int num_distances) {\r | |
93 | if (num_distances > 4) {\r | |
94 | int last_distance = distance_cache[0];\r | |
95 | distance_cache[4] = last_distance - 1;\r | |
96 | distance_cache[5] = last_distance + 1;\r | |
97 | distance_cache[6] = last_distance - 2;\r | |
98 | distance_cache[7] = last_distance + 2;\r | |
99 | distance_cache[8] = last_distance - 3;\r | |
100 | distance_cache[9] = last_distance + 3;\r | |
101 | if (num_distances > 10) {\r | |
102 | int next_last_distance = distance_cache[1];\r | |
103 | distance_cache[10] = next_last_distance - 1;\r | |
104 | distance_cache[11] = next_last_distance + 1;\r | |
105 | distance_cache[12] = next_last_distance - 2;\r | |
106 | distance_cache[13] = next_last_distance + 2;\r | |
107 | distance_cache[14] = next_last_distance - 3;\r | |
108 | distance_cache[15] = next_last_distance + 3;\r | |
109 | }\r | |
110 | }\r | |
111 | }\r | |
112 | \r | |
113 | #define BROTLI_LITERAL_BYTE_SCORE 135\r | |
114 | #define BROTLI_DISTANCE_BIT_PENALTY 30\r | |
11b7501a SB |
115 | /* Score must be positive after applying maximal penalty. */\r |
116 | #define BROTLI_SCORE_BASE (BROTLI_DISTANCE_BIT_PENALTY * 8 * sizeof(size_t))\r | |
117 | \r | |
118 | /* Usually, we always choose the longest backward reference. This function\r | |
119 | allows for the exception of that rule.\r | |
120 | \r | |
121 | If we choose a backward reference that is further away, it will\r | |
122 | usually be coded with more bits. We approximate this by assuming\r | |
123 | log2(distance). If the distance can be expressed in terms of the\r | |
124 | last four distances, we use some heuristic constants to estimate\r | |
125 | the bits cost. For the first up to four literals we use the bit\r | |
126 | cost of the literals from the literal cost model, after that we\r | |
127 | use the average bit cost of the cost model.\r | |
128 | \r | |
129 | This function is used to sometimes discard a longer backward reference\r | |
130 | when it is not much longer and the bit cost for encoding it is more\r | |
131 | than the saved literals.\r | |
132 | \r | |
133 | backward_reference_offset MUST be positive. */\r | |
134 | static BROTLI_INLINE score_t BackwardReferenceScore(\r | |
135 | size_t copy_length, size_t backward_reference_offset) {\r | |
136 | return BROTLI_SCORE_BASE + BROTLI_LITERAL_BYTE_SCORE * (score_t)copy_length -\r | |
137 | BROTLI_DISTANCE_BIT_PENALTY * Log2FloorNonZero(backward_reference_offset);\r | |
138 | }\r | |
139 | \r | |
11b7501a | 140 | static BROTLI_INLINE score_t BackwardReferenceScoreUsingLastDistance(\r |
dd4f667e | 141 | size_t copy_length) {\r |
11b7501a | 142 | return BROTLI_LITERAL_BYTE_SCORE * (score_t)copy_length +\r |
dd4f667e | 143 | BROTLI_SCORE_BASE + 15;\r |
11b7501a SB |
144 | }\r |
145 | \r | |
dd4f667e LG |
146 | static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance(\r |
147 | size_t distance_short_code) {\r | |
148 | return (score_t)39 + ((0x1CA10 >> (distance_short_code & 0xE)) & 0xE);\r | |
11b7501a SB |
149 | }\r |
150 | \r | |
151 | static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(\r | |
dd4f667e LG |
152 | const BrotliEncoderDictionary* dictionary, size_t item, const uint8_t* data,\r |
153 | size_t max_length, size_t max_backward, size_t max_distance,\r | |
11b7501a SB |
154 | HasherSearchResult* out) {\r |
155 | size_t len;\r | |
dd4f667e | 156 | size_t word_idx;\r |
11b7501a SB |
157 | size_t offset;\r |
158 | size_t matchlen;\r | |
159 | size_t backward;\r | |
160 | score_t score;\r | |
dd4f667e LG |
161 | len = item & 0x1F;\r |
162 | word_idx = item >> 5;\r | |
163 | offset = dictionary->words->offsets_by_length[len] + len * word_idx;\r | |
11b7501a SB |
164 | if (len > max_length) {\r |
165 | return BROTLI_FALSE;\r | |
166 | }\r | |
167 | \r | |
dd4f667e LG |
168 | matchlen =\r |
169 | FindMatchLengthWithLimit(data, &dictionary->words->data[offset], len);\r | |
170 | if (matchlen + dictionary->cutoffTransformsCount <= len || matchlen == 0) {\r | |
11b7501a SB |
171 | return BROTLI_FALSE;\r |
172 | }\r | |
173 | {\r | |
dd4f667e LG |
174 | size_t cut = len - matchlen;\r |
175 | size_t transform_id = (cut << 2) +\r | |
176 | (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F);\r | |
177 | backward = max_backward + 1 + word_idx +\r | |
178 | (transform_id << dictionary->words->size_bits_by_length[len]);\r | |
179 | }\r | |
180 | if (backward > max_distance) {\r | |
181 | return BROTLI_FALSE;\r | |
11b7501a SB |
182 | }\r |
183 | score = BackwardReferenceScore(matchlen, backward);\r | |
184 | if (score < out->score) {\r | |
185 | return BROTLI_FALSE;\r | |
186 | }\r | |
187 | out->len = matchlen;\r | |
dd4f667e | 188 | out->len_code_delta = (int)len - (int)matchlen;\r |
11b7501a SB |
189 | out->distance = backward;\r |
190 | out->score = score;\r | |
191 | return BROTLI_TRUE;\r | |
192 | }\r | |
193 | \r | |
dd4f667e LG |
194 | static BROTLI_INLINE void SearchInStaticDictionary(\r |
195 | const BrotliEncoderDictionary* dictionary,\r | |
196 | HasherHandle handle, const uint8_t* data, size_t max_length,\r | |
197 | size_t max_backward, size_t max_distance,\r | |
198 | HasherSearchResult* out, BROTLI_BOOL shallow) {\r | |
11b7501a SB |
199 | size_t key;\r |
200 | size_t i;\r | |
dd4f667e LG |
201 | HasherCommon* self = GetHasherCommon(handle);\r |
202 | if (self->dict_num_matches < (self->dict_num_lookups >> 7)) {\r | |
203 | return;\r | |
11b7501a SB |
204 | }\r |
205 | key = Hash14(data) << 1;\r | |
dd4f667e LG |
206 | for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) {\r |
207 | size_t item = dictionary->hash_table[key];\r | |
208 | self->dict_num_lookups++;\r | |
209 | if (item != 0) {\r | |
210 | BROTLI_BOOL item_matches = TestStaticDictionaryItem(\r | |
211 | dictionary, item, data, max_length, max_backward, max_distance, out);\r | |
212 | if (item_matches) {\r | |
213 | self->dict_num_matches++;\r | |
214 | }\r | |
11b7501a SB |
215 | }\r |
216 | }\r | |
11b7501a SB |
217 | }\r |
218 | \r | |
219 | typedef struct BackwardMatch {\r | |
220 | uint32_t distance;\r | |
221 | uint32_t length_and_code;\r | |
222 | } BackwardMatch;\r | |
223 | \r | |
224 | static BROTLI_INLINE void InitBackwardMatch(BackwardMatch* self,\r | |
225 | size_t dist, size_t len) {\r | |
226 | self->distance = (uint32_t)dist;\r | |
227 | self->length_and_code = (uint32_t)(len << 5);\r | |
228 | }\r | |
229 | \r | |
230 | static BROTLI_INLINE void InitDictionaryBackwardMatch(BackwardMatch* self,\r | |
231 | size_t dist, size_t len, size_t len_code) {\r | |
232 | self->distance = (uint32_t)dist;\r | |
233 | self->length_and_code =\r | |
234 | (uint32_t)((len << 5) | (len == len_code ? 0 : len_code));\r | |
235 | }\r | |
236 | \r | |
237 | static BROTLI_INLINE size_t BackwardMatchLength(const BackwardMatch* self) {\r | |
238 | return self->length_and_code >> 5;\r | |
239 | }\r | |
240 | \r | |
241 | static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {\r | |
242 | size_t code = self->length_and_code & 31;\r | |
243 | return code ? code : BackwardMatchLength(self);\r | |
244 | }\r | |
245 | \r | |
246 | #define EXPAND_CAT(a, b) CAT(a, b)\r | |
247 | #define CAT(a, b) a ## b\r | |
248 | #define FN(X) EXPAND_CAT(X, HASHER())\r | |
249 | \r | |
11b7501a | 250 | #define HASHER() H10\r |
11b7501a | 251 | #define BUCKET_BITS 17\r |
dd4f667e LG |
252 | #define MAX_TREE_SEARCH_DEPTH 64\r |
253 | #define MAX_TREE_COMP_LENGTH 128\r | |
254 | #include "./hash_to_binary_tree_inc.h" /* NOLINT(build/include) */\r | |
255 | #undef MAX_TREE_SEARCH_DEPTH\r | |
256 | #undef MAX_TREE_COMP_LENGTH\r | |
11b7501a | 257 | #undef BUCKET_BITS\r |
11b7501a | 258 | #undef HASHER\r |
dd4f667e LG |
259 | /* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */\r |
260 | #define MAX_NUM_MATCHES_H10 128\r | |
11b7501a SB |
261 | \r |
262 | /* For BUCKET_SWEEP == 1, enabling the dictionary lookup makes compression\r | |
263 | a little faster (0.5% - 1%) and it compresses 0.15% better on small text\r | |
dd4f667e | 264 | and HTML inputs. */\r |
11b7501a SB |
265 | \r |
266 | #define HASHER() H2\r | |
267 | #define BUCKET_BITS 16\r | |
268 | #define BUCKET_SWEEP 1\r | |
dd4f667e | 269 | #define HASH_LEN 5\r |
11b7501a SB |
270 | #define USE_DICTIONARY 1\r |
271 | #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */\r | |
272 | #undef BUCKET_SWEEP\r | |
273 | #undef USE_DICTIONARY\r | |
274 | #undef HASHER\r | |
275 | \r | |
276 | #define HASHER() H3\r | |
277 | #define BUCKET_SWEEP 2\r | |
278 | #define USE_DICTIONARY 0\r | |
279 | #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */\r | |
280 | #undef USE_DICTIONARY\r | |
281 | #undef BUCKET_SWEEP\r | |
282 | #undef BUCKET_BITS\r | |
283 | #undef HASHER\r | |
284 | \r | |
285 | #define HASHER() H4\r | |
286 | #define BUCKET_BITS 17\r | |
287 | #define BUCKET_SWEEP 4\r | |
288 | #define USE_DICTIONARY 1\r | |
289 | #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */\r | |
290 | #undef USE_DICTIONARY\r | |
dd4f667e | 291 | #undef HASH_LEN\r |
11b7501a SB |
292 | #undef BUCKET_SWEEP\r |
293 | #undef BUCKET_BITS\r | |
294 | #undef HASHER\r | |
295 | \r | |
296 | #define HASHER() H5\r | |
11b7501a | 297 | #include "./hash_longest_match_inc.h" /* NOLINT(build/include) */\r |
11b7501a SB |
298 | #undef HASHER\r |
299 | \r | |
300 | #define HASHER() H6\r | |
dd4f667e | 301 | #include "./hash_longest_match64_inc.h" /* NOLINT(build/include) */\r |
11b7501a SB |
302 | #undef HASHER\r |
303 | \r | |
304 | #define BUCKET_BITS 15\r | |
305 | \r | |
306 | #define NUM_LAST_DISTANCES_TO_CHECK 4\r | |
307 | #define NUM_BANKS 1\r | |
308 | #define BANK_BITS 16\r | |
309 | #define HASHER() H40\r | |
310 | #include "./hash_forgetful_chain_inc.h" /* NOLINT(build/include) */\r | |
311 | #undef HASHER\r | |
312 | #undef NUM_LAST_DISTANCES_TO_CHECK\r | |
313 | \r | |
314 | #define NUM_LAST_DISTANCES_TO_CHECK 10\r | |
315 | #define HASHER() H41\r | |
316 | #include "./hash_forgetful_chain_inc.h" /* NOLINT(build/include) */\r | |
317 | #undef HASHER\r | |
318 | #undef NUM_LAST_DISTANCES_TO_CHECK\r | |
319 | #undef NUM_BANKS\r | |
320 | #undef BANK_BITS\r | |
321 | \r | |
322 | #define NUM_LAST_DISTANCES_TO_CHECK 16\r | |
323 | #define NUM_BANKS 512\r | |
324 | #define BANK_BITS 9\r | |
325 | #define HASHER() H42\r | |
326 | #include "./hash_forgetful_chain_inc.h" /* NOLINT(build/include) */\r | |
327 | #undef HASHER\r | |
328 | #undef NUM_LAST_DISTANCES_TO_CHECK\r | |
329 | #undef NUM_BANKS\r | |
330 | #undef BANK_BITS\r | |
331 | \r | |
332 | #undef BUCKET_BITS\r | |
333 | \r | |
dd4f667e LG |
334 | #define HASHER() H54\r |
335 | #define BUCKET_BITS 20\r | |
336 | #define BUCKET_SWEEP 4\r | |
337 | #define HASH_LEN 7\r | |
338 | #define USE_DICTIONARY 0\r | |
339 | #include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */\r | |
340 | #undef USE_DICTIONARY\r | |
341 | #undef HASH_LEN\r | |
342 | #undef BUCKET_SWEEP\r | |
343 | #undef BUCKET_BITS\r | |
344 | #undef HASHER\r | |
345 | \r | |
346 | /* fast large window hashers */\r | |
347 | \r | |
348 | #define HASHER() HROLLING_FAST\r | |
349 | #define CHUNKLEN 32\r | |
350 | #define JUMP 4\r | |
351 | #define NUMBUCKETS 16777216\r | |
352 | #define MASK ((NUMBUCKETS * 64) - 1)\r | |
353 | #include "./hash_rolling_inc.h" /* NOLINT(build/include) */\r | |
354 | #undef JUMP\r | |
355 | #undef HASHER\r | |
356 | \r | |
357 | \r | |
358 | #define HASHER() HROLLING\r | |
359 | #define JUMP 1\r | |
360 | #include "./hash_rolling_inc.h" /* NOLINT(build/include) */\r | |
361 | #undef MASK\r | |
362 | #undef NUMBUCKETS\r | |
363 | #undef JUMP\r | |
364 | #undef CHUNKLEN\r | |
365 | #undef HASHER\r | |
366 | \r | |
367 | #define HASHER() H35\r | |
368 | #define HASHER_A H3\r | |
369 | #define HASHER_B HROLLING_FAST\r | |
370 | #include "./hash_composite_inc.h" /* NOLINT(build/include) */\r | |
371 | #undef HASHER_A\r | |
372 | #undef HASHER_B\r | |
373 | #undef HASHER\r | |
374 | \r | |
375 | #define HASHER() H55\r | |
376 | #define HASHER_A H54\r | |
377 | #define HASHER_B HROLLING_FAST\r | |
378 | #include "./hash_composite_inc.h" /* NOLINT(build/include) */\r | |
379 | #undef HASHER_A\r | |
380 | #undef HASHER_B\r | |
381 | #undef HASHER\r | |
382 | \r | |
383 | #define HASHER() H65\r | |
384 | #define HASHER_A H6\r | |
385 | #define HASHER_B HROLLING\r | |
386 | #include "./hash_composite_inc.h" /* NOLINT(build/include) */\r | |
387 | #undef HASHER_A\r | |
388 | #undef HASHER_B\r | |
389 | #undef HASHER\r | |
390 | \r | |
11b7501a SB |
391 | #undef FN\r |
392 | #undef CAT\r | |
393 | #undef EXPAND_CAT\r | |
394 | \r | |
dd4f667e LG |
395 | #define FOR_GENERIC_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)\\r |
396 | H(35) H(55) H(65)\r | |
11b7501a SB |
397 | #define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10)\r |
398 | \r | |
dd4f667e LG |
399 | static BROTLI_INLINE void DestroyHasher(\r |
400 | MemoryManager* m, HasherHandle* handle) {\r | |
401 | if (*handle == NULL) return;\r | |
402 | BROTLI_FREE(m, *handle);\r | |
11b7501a SB |
403 | }\r |
404 | \r | |
dd4f667e LG |
405 | static BROTLI_INLINE void HasherReset(HasherHandle handle) {\r |
406 | if (handle == NULL) return;\r | |
407 | GetHasherCommon(handle)->is_prepared_ = BROTLI_FALSE;\r | |
11b7501a SB |
408 | }\r |
409 | \r | |
dd4f667e LG |
410 | static BROTLI_INLINE size_t HasherSize(const BrotliEncoderParams* params,\r |
411 | BROTLI_BOOL one_shot, const size_t input_size) {\r | |
412 | size_t result = sizeof(HasherCommon);\r | |
413 | switch (params->hasher.type) {\r | |
414 | #define SIZE_(N) \\r | |
415 | case N: \\r | |
416 | result += HashMemAllocInBytesH ## N(params, one_shot, input_size); \\r | |
417 | break;\r | |
418 | FOR_ALL_HASHERS(SIZE_)\r | |
419 | #undef SIZE_\r | |
420 | default:\r | |
421 | break;\r | |
11b7501a | 422 | }\r |
dd4f667e | 423 | return result;\r |
11b7501a SB |
424 | }\r |
425 | \r | |
dd4f667e LG |
426 | static BROTLI_INLINE void HasherSetup(MemoryManager* m, HasherHandle* handle,\r |
427 | BrotliEncoderParams* params, const uint8_t* data, size_t position,\r | |
428 | size_t input_size, BROTLI_BOOL is_last) {\r | |
429 | HasherHandle self = NULL;\r | |
430 | HasherCommon* common = NULL;\r | |
431 | BROTLI_BOOL one_shot = (position == 0 && is_last);\r | |
432 | if (*handle == NULL) {\r | |
433 | size_t alloc_size;\r | |
434 | ChooseHasher(params, ¶ms->hasher);\r | |
435 | alloc_size = HasherSize(params, one_shot, input_size);\r | |
436 | self = BROTLI_ALLOC(m, uint8_t, alloc_size);\r | |
437 | if (BROTLI_IS_OOM(m)) return;\r | |
438 | *handle = self;\r | |
439 | common = GetHasherCommon(self);\r | |
440 | common->params = params->hasher;\r | |
441 | switch (common->params.type) {\r | |
442 | #define INITIALIZE_(N) \\r | |
443 | case N: \\r | |
444 | InitializeH ## N(*handle, params); \\r | |
445 | break;\r | |
446 | FOR_ALL_HASHERS(INITIALIZE_);\r | |
447 | #undef INITIALIZE_\r | |
448 | default:\r | |
449 | break;\r | |
450 | }\r | |
451 | HasherReset(*handle);\r | |
11b7501a | 452 | }\r |
11b7501a | 453 | \r |
dd4f667e LG |
454 | self = *handle;\r |
455 | common = GetHasherCommon(self);\r | |
456 | if (!common->is_prepared_) {\r | |
457 | switch (common->params.type) {\r | |
458 | #define PREPARE_(N) \\r | |
459 | case N: \\r | |
460 | PrepareH ## N(self, one_shot, input_size, data); \\r | |
461 | break;\r | |
462 | FOR_ALL_HASHERS(PREPARE_)\r | |
463 | #undef PREPARE_\r | |
464 | default: break;\r | |
465 | }\r | |
466 | if (position == 0) {\r | |
467 | common->dict_num_lookups = 0;\r | |
468 | common->dict_num_matches = 0;\r | |
469 | }\r | |
470 | common->is_prepared_ = BROTLI_TRUE;\r | |
471 | }\r | |
11b7501a | 472 | }\r |
dd4f667e LG |
473 | \r |
474 | static BROTLI_INLINE void InitOrStitchToPreviousBlock(\r | |
475 | MemoryManager* m, HasherHandle* handle, const uint8_t* data, size_t mask,\r | |
476 | BrotliEncoderParams* params, size_t position, size_t input_size,\r | |
477 | BROTLI_BOOL is_last) {\r | |
478 | HasherHandle self;\r | |
479 | HasherSetup(m, handle, params, data, position, input_size, is_last);\r | |
480 | if (BROTLI_IS_OOM(m)) return;\r | |
481 | self = *handle;\r | |
482 | switch (GetHasherCommon(self)->params.type) {\r | |
483 | #define INIT_(N) \\r | |
484 | case N: \\r | |
485 | StitchToPreviousBlockH ## N(self, input_size, position, data, mask); \\r | |
486 | break;\r | |
487 | FOR_ALL_HASHERS(INIT_)\r | |
488 | #undef INIT_\r | |
11b7501a SB |
489 | default: break;\r |
490 | }\r | |
11b7501a SB |
491 | }\r |
492 | \r | |
11b7501a SB |
493 | #if defined(__cplusplus) || defined(c_plusplus)\r |
494 | } /* extern "C" */\r | |
495 | #endif\r | |
496 | \r | |
497 | #endif /* BROTLI_ENC_HASH_H_ */\r |