11cb0ef41Sopenharmony_ci/* NOLINT(build/header_guard) */ 21cb0ef41Sopenharmony_ci/* Copyright 2018 Google Inc. All Rights Reserved. 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ci Distributed under MIT license. 51cb0ef41Sopenharmony_ci See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 61cb0ef41Sopenharmony_ci*/ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci/* template parameters: FN, HASHER_A, HASHER_B */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A 111cb0ef41Sopenharmony_ci and HASHER_B. */ 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci#define HashComposite HASHER() 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#define FN_A(X) EXPAND_CAT(X, HASHER_A) 161cb0ef41Sopenharmony_ci#define FN_B(X) EXPAND_CAT(X, HASHER_B) 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t FN(HashTypeLength)(void) { 191cb0ef41Sopenharmony_ci size_t a = FN_A(HashTypeLength)(); 201cb0ef41Sopenharmony_ci size_t b = FN_B(HashTypeLength)(); 211cb0ef41Sopenharmony_ci return a > b ? a : b; 221cb0ef41Sopenharmony_ci} 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t FN(StoreLookahead)(void) { 251cb0ef41Sopenharmony_ci size_t a = FN_A(StoreLookahead)(); 261cb0ef41Sopenharmony_ci size_t b = FN_B(StoreLookahead)(); 271cb0ef41Sopenharmony_ci return a > b ? a : b; 281cb0ef41Sopenharmony_ci} 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_citypedef struct HashComposite { 311cb0ef41Sopenharmony_ci HASHER_A ha; 321cb0ef41Sopenharmony_ci HASHER_B hb; 331cb0ef41Sopenharmony_ci HasherCommon hb_common; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci /* Shortcuts. */ 361cb0ef41Sopenharmony_ci void* extra; 371cb0ef41Sopenharmony_ci HasherCommon* common; 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci BROTLI_BOOL fresh; 401cb0ef41Sopenharmony_ci const BrotliEncoderParams* params; 411cb0ef41Sopenharmony_ci} HashComposite; 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cistatic void FN(Initialize)(HasherCommon* common, 441cb0ef41Sopenharmony_ci HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) { 451cb0ef41Sopenharmony_ci self->common = common; 461cb0ef41Sopenharmony_ci self->extra = common->extra; 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci self->hb_common = *self->common; 491cb0ef41Sopenharmony_ci self->fresh = BROTLI_TRUE; 501cb0ef41Sopenharmony_ci self->params = params; 511cb0ef41Sopenharmony_ci /* TODO: Initialize of the hashers is defered to Prepare (and params 521cb0ef41Sopenharmony_ci remembered here) because we don't get the one_shot and input_size params 531cb0ef41Sopenharmony_ci here that are needed to know the memory size of them. Instead provide 541cb0ef41Sopenharmony_ci those params to all hashers FN(Initialize) */ 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cistatic void FN(Prepare)( 581cb0ef41Sopenharmony_ci HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, 591cb0ef41Sopenharmony_ci size_t input_size, const uint8_t* BROTLI_RESTRICT data) { 601cb0ef41Sopenharmony_ci if (self->fresh) { 611cb0ef41Sopenharmony_ci self->fresh = BROTLI_FALSE; 621cb0ef41Sopenharmony_ci self->hb_common.extra = (uint8_t*)self->extra + 631cb0ef41Sopenharmony_ci FN_A(HashMemAllocInBytes)(self->params, one_shot, input_size); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci FN_A(Initialize)(self->common, &self->ha, self->params); 661cb0ef41Sopenharmony_ci FN_B(Initialize)(&self->hb_common, &self->hb, self->params); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci FN_A(Prepare)(&self->ha, one_shot, input_size, data); 691cb0ef41Sopenharmony_ci FN_B(Prepare)(&self->hb, one_shot, input_size, data); 701cb0ef41Sopenharmony_ci} 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t FN(HashMemAllocInBytes)( 731cb0ef41Sopenharmony_ci const BrotliEncoderParams* params, BROTLI_BOOL one_shot, 741cb0ef41Sopenharmony_ci size_t input_size) { 751cb0ef41Sopenharmony_ci return FN_A(HashMemAllocInBytes)(params, one_shot, input_size) + 761cb0ef41Sopenharmony_ci FN_B(HashMemAllocInBytes)(params, one_shot, input_size); 771cb0ef41Sopenharmony_ci} 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_cistatic BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self, 801cb0ef41Sopenharmony_ci const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { 811cb0ef41Sopenharmony_ci FN_A(Store)(&self->ha, data, mask, ix); 821cb0ef41Sopenharmony_ci FN_B(Store)(&self->hb, data, mask, ix); 831cb0ef41Sopenharmony_ci} 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_cistatic BROTLI_INLINE void FN(StoreRange)( 861cb0ef41Sopenharmony_ci HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, 871cb0ef41Sopenharmony_ci const size_t mask, const size_t ix_start, 881cb0ef41Sopenharmony_ci const size_t ix_end) { 891cb0ef41Sopenharmony_ci FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end); 901cb0ef41Sopenharmony_ci FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end); 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_cistatic BROTLI_INLINE void FN(StitchToPreviousBlock)( 941cb0ef41Sopenharmony_ci HashComposite* BROTLI_RESTRICT self, 951cb0ef41Sopenharmony_ci size_t num_bytes, size_t position, const uint8_t* ringbuffer, 961cb0ef41Sopenharmony_ci size_t ring_buffer_mask) { 971cb0ef41Sopenharmony_ci FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position, 981cb0ef41Sopenharmony_ci ringbuffer, ring_buffer_mask); 991cb0ef41Sopenharmony_ci FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position, 1001cb0ef41Sopenharmony_ci ringbuffer, ring_buffer_mask); 1011cb0ef41Sopenharmony_ci} 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_cistatic BROTLI_INLINE void FN(PrepareDistanceCache)( 1041cb0ef41Sopenharmony_ci HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) { 1051cb0ef41Sopenharmony_ci FN_A(PrepareDistanceCache)(&self->ha, distance_cache); 1061cb0ef41Sopenharmony_ci FN_B(PrepareDistanceCache)(&self->hb, distance_cache); 1071cb0ef41Sopenharmony_ci} 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_cistatic BROTLI_INLINE void FN(FindLongestMatch)( 1101cb0ef41Sopenharmony_ci HashComposite* BROTLI_RESTRICT self, 1111cb0ef41Sopenharmony_ci const BrotliEncoderDictionary* dictionary, 1121cb0ef41Sopenharmony_ci const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, 1131cb0ef41Sopenharmony_ci const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, 1141cb0ef41Sopenharmony_ci const size_t max_length, const size_t max_backward, 1151cb0ef41Sopenharmony_ci const size_t dictionary_distance, const size_t max_distance, 1161cb0ef41Sopenharmony_ci HasherSearchResult* BROTLI_RESTRICT out) { 1171cb0ef41Sopenharmony_ci FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask, 1181cb0ef41Sopenharmony_ci distance_cache, cur_ix, max_length, max_backward, dictionary_distance, 1191cb0ef41Sopenharmony_ci max_distance, out); 1201cb0ef41Sopenharmony_ci FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask, 1211cb0ef41Sopenharmony_ci distance_cache, cur_ix, max_length, max_backward, dictionary_distance, 1221cb0ef41Sopenharmony_ci max_distance, out); 1231cb0ef41Sopenharmony_ci} 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci#undef HashComposite 126