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