11 size_t num_bytes,
size_t position,
12 const uint8_t* ringbuffer,
size_t ringbuffer_mask,
14 Hasher* hasher,
int* dist_cache,
size_t* last_insert_len,
15 Command* commands,
size_t* num_commands,
size_t* num_literals) {
16 HASHER()* privat = &hasher->privat.FN(
_);
19 const size_t position_offset = params->stream_offset;
21 const Command*
const orig_commands = commands;
22 size_t insert_length = *last_insert_len;
23 const size_t pos_end = position + num_bytes;
24 const size_t store_end = num_bytes >=
FN(StoreLookahead)() ?
25 position + num_bytes -
FN(StoreLookahead)() + 1 : position;
28 const size_t random_heuristics_window_size =
29 LiteralSpreeLengthForSparseSearch(params);
30 size_t apply_random_heuristics = position + random_heuristics_window_size;
31 const size_t gap = params->dictionary.compound.total_size;
36 FN(PrepareDistanceCache)(privat, dist_cache);
38 while (position +
FN(HashTypeLength)() < pos_end) {
39 size_t max_length = pos_end - position;
40 size_t max_distance =
BROTLI_MIN(
size_t, position, max_backward_limit);
42 position + position_offset, max_backward_limit);
47 if (params->dictionary.contextual.context_based) {
49 ringbuffer[(size_t)(position - 1) & ringbuffer_mask] : 0;
51 ringbuffer[(size_t)(position - 2) & ringbuffer_mask] : 0;
52 dict_id = params->dictionary.contextual.context_map[
59 FN(FindLongestMatch)(privat, params->dictionary.contextual.dict[dict_id],
60 ringbuffer, ringbuffer_mask, dist_cache, position, max_length,
61 max_distance, dictionary_start + gap, params->dist.max_distance, &sr);
63 LookupCompoundDictionaryMatch(¶ms->dictionary.compound, ringbuffer,
64 ringbuffer_mask, dist_cache, position, max_length,
65 dictionary_start, params->dist.max_distance, &sr);
67 if (sr.
score > kMinScore) {
69 int delayed_backward_references_in_row = 0;
71 for (;; --max_length) {
72 const score_t cost_diff_lazy = 175;
78 sr2.
score = kMinScore;
79 max_distance =
BROTLI_MIN(
size_t, position + 1, max_backward_limit);
81 position + 1 + position_offset, max_backward_limit);
82 if (params->dictionary.contextual.context_based) {
84 p1 = ringbuffer[position & ringbuffer_mask];
85 dict_id = params->dictionary.contextual.context_map[
88 FN(FindLongestMatch)(privat,
89 params->dictionary.contextual.dict[dict_id],
90 ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length,
91 max_distance, dictionary_start + gap, params->dist.max_distance,
94 LookupCompoundDictionaryMatch(
95 ¶ms->dictionary.compound, ringbuffer,
96 ringbuffer_mask, dist_cache, position + 1, max_length,
97 dictionary_start, params->dist.max_distance, &sr2);
105 if (++delayed_backward_references_in_row < 4 &&
106 position +
FN(HashTypeLength)() < pos_end) {
112 apply_random_heuristics =
113 position + 2 * sr.
len + random_heuristics_window_size;
115 position + position_offset, max_backward_limit);
119 size_t distance_code = ComputeDistanceCode(
120 sr.
distance, dictionary_start + gap, dist_cache);
121 if ((sr.
distance <= (dictionary_start + gap)) && distance_code > 0) {
122 dist_cache[3] = dist_cache[2];
123 dist_cache[2] = dist_cache[1];
124 dist_cache[1] = dist_cache[0];
126 FN(PrepareDistanceCache)(privat, dist_cache);
128 InitCommand(commands++, ¶ms->dist, insert_length,
131 *num_literals += insert_length;
138 size_t range_start = position + 2;
139 size_t range_end =
BROTLI_MIN(
size_t, position + sr.
len, store_end);
142 range_start, position + sr.
len - (sr.
distance << 2)));
144 FN(StoreRange)(privat, ringbuffer, ringbuffer_mask, range_start,
155 if (position > apply_random_heuristics) {
158 apply_random_heuristics + 4 * random_heuristics_window_size) {
165 const size_t kMargin =
168 BROTLI_MIN(
size_t, position + 16, pos_end - kMargin);
169 for (; position < pos_jump; position += 4) {
170 FN(Store)(privat, ringbuffer, ringbuffer_mask, position);
174 const size_t kMargin =
177 BROTLI_MIN(
size_t, position + 8, pos_end - kMargin);
178 for (; position < pos_jump; position += 2) {
179 FN(Store)(privat, ringbuffer, ringbuffer_mask, position);
186 insert_length += pos_end - position;
187 *last_insert_len = insert_length;
188 *num_commands += (size_t)(commands - orig_commands);
#define BROTLI_MAX_BACKWARD_LIMIT(W)
Definition constants.h:103
const uint8_t * ContextLut
Definition context.h:105
#define BROTLI_CONTEXT(P1, P2, LUT)
Definition context.h:111
#define EXPORT_FN(X)
Definition backward_references.c:52
#define FN(X)
Definition backward_references.c:51
#define HASHER()
Definition backward_references.c:56
#define BROTLI_SCORE_BASE
Definition hash.h:101
#define score_t
Definition hash.h:43
#define MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH
Definition quality.h:26
#define ENABLE_COMPOUND_DICTIONARY
Definition backward_references.c:57
score_t score
Definition hash.h:54
size_t distance
Definition hash.h:53
size_t len
Definition hash.h:52
int len_code_delta
Definition hash.h:55
#define _(msgid)
Definition getopt.c:49