1/* Copyright 2013 Google Inc. All Rights Reserved.
2
3   Distributed under MIT license.
4   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5*/
6
7/* Function to find backward reference copies. */
8
9#include "./backward_references.h"
10
11#include "../common/constants.h"
12#include "../common/dictionary.h"
13#include <brotli/types.h>
14#include "./command.h"
15#include "./dictionary_hash.h"
16#include "./memory.h"
17#include "./port.h"
18#include "./quality.h"
19
20#if defined(__cplusplus) || defined(c_plusplus)
21extern "C" {
22#endif
23
24static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance,
25                                                size_t max_distance,
26                                                const int* dist_cache) {
27  if (distance <= max_distance) {
28    size_t distance_plus_3 = distance + 3;
29    size_t offset0 = distance_plus_3 - (size_t)dist_cache[0];
30    size_t offset1 = distance_plus_3 - (size_t)dist_cache[1];
31    if (distance == (size_t)dist_cache[0]) {
32      return 0;
33    } else if (distance == (size_t)dist_cache[1]) {
34      return 1;
35    } else if (offset0 < 7) {
36      return (0x9750468 >> (4 * offset0)) & 0xF;
37    } else if (offset1 < 7) {
38      return (0xFDB1ACE >> (4 * offset1)) & 0xF;
39    } else if (distance == (size_t)dist_cache[2]) {
40      return 2;
41    } else if (distance == (size_t)dist_cache[3]) {
42      return 3;
43    }
44  }
45  return distance + BROTLI_NUM_DISTANCE_SHORT_CODES - 1;
46}
47
48#define EXPAND_CAT(a, b) CAT(a, b)
49#define CAT(a, b) a ## b
50#define FN(X) EXPAND_CAT(X, HASHER())
51#define EXPORT_FN(X) EXPAND_CAT(X, EXPAND_CAT(PREFIX(), HASHER()))
52#define PREFIX() N
53
54#define HASHER() H2
55/* NOLINTNEXTLINE(build/include) */
56#include "./backward_references_inc.h"
57#undef HASHER
58
59#define HASHER() H3
60/* NOLINTNEXTLINE(build/include) */
61#include "./backward_references_inc.h"
62#undef HASHER
63
64#define HASHER() H4
65/* NOLINTNEXTLINE(build/include) */
66#include "./backward_references_inc.h"
67#undef HASHER
68
69#define HASHER() H5
70/* NOLINTNEXTLINE(build/include) */
71#include "./backward_references_inc.h"
72#undef HASHER
73
74#define HASHER() H6
75/* NOLINTNEXTLINE(build/include) */
76#include "./backward_references_inc.h"
77#undef HASHER
78
79#define HASHER() H40
80/* NOLINTNEXTLINE(build/include) */
81#include "./backward_references_inc.h"
82#undef HASHER
83
84#define HASHER() H41
85/* NOLINTNEXTLINE(build/include) */
86#include "./backward_references_inc.h"
87#undef HASHER
88
89#define HASHER() H42
90/* NOLINTNEXTLINE(build/include) */
91#include "./backward_references_inc.h"
92#undef HASHER
93
94#define HASHER() H54
95/* NOLINTNEXTLINE(build/include) */
96#include "./backward_references_inc.h"
97#undef HASHER
98
99#undef PREFIX
100#undef EXPORT_FN
101#undef FN
102#undef CAT
103#undef EXPAND_CAT
104
105void BrotliCreateBackwardReferences(const BrotliDictionary* dictionary,
106                                    size_t num_bytes,
107                                    size_t position,
108                                    const uint8_t* ringbuffer,
109                                    size_t ringbuffer_mask,
110                                    const BrotliEncoderParams* params,
111                                    HasherHandle hasher,
112                                    int* dist_cache,
113                                    size_t* last_insert_len,
114                                    Command* commands,
115                                    size_t* num_commands,
116                                    size_t* num_literals) {
117  switch (params->hasher.type) {
118#define CASE_(N)                                                  \
119    case N:                                                       \
120      CreateBackwardReferencesNH ## N(dictionary,                 \
121          kStaticDictionaryHash, num_bytes, position, ringbuffer, \
122          ringbuffer_mask, params, hasher, dist_cache,            \
123          last_insert_len, commands, num_commands, num_literals); \
124      return;
125    FOR_GENERIC_HASHERS(CASE_)
126#undef CASE_
127    default:
128      break;
129  }
130}
131
132#if defined(__cplusplus) || defined(c_plusplus)
133}  /* extern "C" */
134#endif
135