1771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov/* Copyright 2013 Google Inc. All Rights Reserved. 2771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov 324ffa78414663b545b66be392caff7eb5574a62cEugene Klyuchnikov Distributed under MIT license. 4771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov*/ 6771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov 7352b0b2836504f59c4915b20eee11a770b415a47Eugene Kliuchnikov/* Function to find backward reference copies. */ 8c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 9c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka#include "./backward_references.h" 10c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 11b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "../common/constants.h" 12cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov#include "../common/dictionary.h" 1381480011581d1bb40e2ed26566a95d060f2767b3Eugene Kliuchnikov#include <brotli/types.h> 14c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka#include "./command.h" 15cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov#include "./dictionary_hash.h" 16b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./memory.h" 17b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./port.h" 182048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#include "./quality.h" 19c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 20b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#if defined(__cplusplus) || defined(c_plusplus) 21b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikovextern "C" { 22b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#endif 23c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 24b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikovstatic BROTLI_INLINE size_t ComputeDistanceCode(size_t distance, 25b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov size_t max_distance, 26b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov const int* dist_cache) { 27b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka if (distance <= max_distance) { 282048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov size_t distance_plus_3 = distance + 3; 292048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov size_t offset0 = distance_plus_3 - (size_t)dist_cache[0]; 302048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov size_t offset1 = distance_plus_3 - (size_t)dist_cache[1]; 31b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov if (distance == (size_t)dist_cache[0]) { 32b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka return 0; 33b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov } else if (distance == (size_t)dist_cache[1]) { 34b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka return 1; 352048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov } else if (offset0 < 7) { 362048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov return (0x9750468 >> (4 * offset0)) & 0xF; 372048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov } else if (offset1 < 7) { 382048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov return (0xFDB1ACE >> (4 * offset1)) & 0xF; 39b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov } else if (distance == (size_t)dist_cache[2]) { 40b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka return 2; 41b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov } else if (distance == (size_t)dist_cache[3]) { 42b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka return 3; 43b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka } 44b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka } 459521d968f312c14a3a30888575d14b5515f9cb40Eugene Kliuchnikov return distance + BROTLI_NUM_DISTANCE_SHORT_CODES - 1; 46b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka} 47b3d3723f62e0ae088d38d9effaf3bd1d0b3acf21Zoltan Szabadka 48b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define EXPAND_CAT(a, b) CAT(a, b) 49b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define CAT(a, b) a ## b 50b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define FN(X) EXPAND_CAT(X, HASHER()) 51d63e8f75f5c16a6d7c8308bfd28c43cbdb6ad390Eugene Kliuchnikov#define EXPORT_FN(X) EXPAND_CAT(X, EXPAND_CAT(PREFIX(), HASHER())) 52d63e8f75f5c16a6d7c8308bfd28c43cbdb6ad390Eugene Kliuchnikov#define PREFIX() N 53b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 54b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define HASHER() H2 55b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 56b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./backward_references_inc.h" 57b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef HASHER 58b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 59b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define HASHER() H3 60b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 61b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./backward_references_inc.h" 62b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef HASHER 63b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 64b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define HASHER() H4 65b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 66b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./backward_references_inc.h" 67b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef HASHER 68b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 69b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define HASHER() H5 70b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 71b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./backward_references_inc.h" 72b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef HASHER 73b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 74b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#define HASHER() H6 75b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 76b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#include "./backward_references_inc.h" 77b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef HASHER 78b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 792048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#define HASHER() H40 802048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 812048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#include "./backward_references_inc.h" 822048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#undef HASHER 832048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov 842048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#define HASHER() H41 852048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 862048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#include "./backward_references_inc.h" 872048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#undef HASHER 882048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov 892048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#define HASHER() H42 902048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 912048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#include "./backward_references_inc.h" 922048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov#undef HASHER 932048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov 9411df843cf019e0a18f5efce660693a30f487fb06Eugene Kliuchnikov#define HASHER() H54 9511df843cf019e0a18f5efce660693a30f487fb06Eugene Kliuchnikov/* NOLINTNEXTLINE(build/include) */ 9611df843cf019e0a18f5efce660693a30f487fb06Eugene Kliuchnikov#include "./backward_references_inc.h" 9711df843cf019e0a18f5efce660693a30f487fb06Eugene Kliuchnikov#undef HASHER 9811df843cf019e0a18f5efce660693a30f487fb06Eugene Kliuchnikov 99d63e8f75f5c16a6d7c8308bfd28c43cbdb6ad390Eugene Kliuchnikov#undef PREFIX 100d63e8f75f5c16a6d7c8308bfd28c43cbdb6ad390Eugene Kliuchnikov#undef EXPORT_FN 101b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef FN 102b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef CAT 103b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#undef EXPAND_CAT 104b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov 105cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikovvoid BrotliCreateBackwardReferences(const BrotliDictionary* dictionary, 106cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov size_t num_bytes, 107b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov size_t position, 108b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov const uint8_t* ringbuffer, 109b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov size_t ringbuffer_mask, 1102048189048f130b0e8fb60307277379743dc5a2dEugene Kliuchnikov const BrotliEncoderParams* params, 111cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov HasherHandle hasher, 112b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov int* dist_cache, 113b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov size_t* last_insert_len, 114b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov Command* commands, 115b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov size_t* num_commands, 116b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov size_t* num_literals) { 117cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov switch (params->hasher.type) { 118cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov#define CASE_(N) \ 119cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov case N: \ 120d63e8f75f5c16a6d7c8308bfd28c43cbdb6ad390Eugene Kliuchnikov CreateBackwardReferencesNH ## N(dictionary, \ 121cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov kStaticDictionaryHash, num_bytes, position, ringbuffer, \ 122cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov ringbuffer_mask, params, hasher, dist_cache, \ 123cdca91b6f59dd7632985667d2cd585ab68937b48Eugene Kliuchnikov last_insert_len, commands, num_commands, num_literals); \ 124d63e8f75f5c16a6d7c8308bfd28c43cbdb6ad390Eugene Kliuchnikov return; 125801f5f37ee73c558e1944235d2a2c6fa7d7a9719Eugene Kliuchnikov FOR_GENERIC_HASHERS(CASE_) 126801f5f37ee73c558e1944235d2a2c6fa7d7a9719Eugene Kliuchnikov#undef CASE_ 127e7650080a8cedc159fc4e89d7f144c28f4b028b4Zoltan Szabadka default: 128e7650080a8cedc159fc4e89d7f144c28f4b028b4Zoltan Szabadka break; 129e7650080a8cedc159fc4e89d7f144c28f4b028b4Zoltan Szabadka } 130e7650080a8cedc159fc4e89d7f144c28f4b028b4Zoltan Szabadka} 131e7650080a8cedc159fc4e89d7f144c28f4b028b4Zoltan Szabadka 132b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#if defined(__cplusplus) || defined(c_plusplus) 133b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov} /* extern "C" */ 134b972c67780f03256a3fbf81dc3350a4bf00aa4adEugene Kliuchnikov#endif 135