Coverage Report

Created: 2026-09-01 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brunsli/c/dec/state_internal.h
Line
Count
Source
1
// Copyright (c) Google LLC 2020
2
//
3
// Use of this source code is governed by an MIT-style
4
// license that can be found in the LICENSE file or at
5
// https://opensource.org/licenses/MIT.
6
7
#ifndef BRUNSLI_DEC_STATE_INTERNAL_H_
8
#define BRUNSLI_DEC_STATE_INTERNAL_H_
9
10
#include <brunsli/status.h>
11
#include <brunsli/types.h>
12
13
#include <array>
14
#include <limits>
15
#include <memory>
16
#include <vector>
17
18
#include "../common/context.h"
19
#include "../common/lehmer_code.h"
20
#include "./ans_decode.h"
21
#include "./arith_decode.h"
22
#include "./bit_reader.h"
23
#include "./brunsli_input.h"
24
#include "./huffman_decode.h"
25
#include "./huffman_table.h"
26
#include "./serialization_state.h"
27
#include "./state.h"
28
29
struct BrotliDecoderStateStruct;
30
31
namespace brunsli {
32
33
struct HuffmanDecodingData;
34
35
namespace internal {
36
namespace dec {
37
38
struct AcDcState {
39
  int next_mcu_y = 0;
40
  size_t next_component = 0;
41
  int next_iy = 0;
42
  int next_x = 0;
43
  bool ac_coeffs_order_decoded = false;
44
45
  std::vector<ComponentState> ac;
46
  std::vector<ComponentStateDC> dc;
47
};
48
49
// Aid for section / subsection parsing.
50
struct SectionState {
51
  // Current value tag and type.
52
  size_t tag = 0;
53
  // True, if section is entered.
54
  bool is_active = false;
55
  // True, if "message" is actually "section", not a primitive value.
56
  bool is_section = false;
57
58
  // Encountered tags tracker.
59
  uint32_t tags_met = 0;
60
61
  // Remaining section length. Actual only when outside of workflow.
62
  size_t remaining = 0;
63
64
  // Position in current input, for which |remaining| was actual.
65
  size_t milestone = 0;
66
67
  // Projected section end, given enough input is provided.
68
  // |projected_end| == |milestone| + |provided|
69
  size_t projected_end = 0;
70
};
71
72
// Fields used for "Header" section parsing.
73
struct HeaderState {
74
  enum Stage {
75
    // Check section tag.
76
    READ_TAG,
77
    // Read section length.
78
    ENTER_SECTION,
79
    // Read value marker.
80
    ITEM_READ_TAG,
81
    // Read subsection length.
82
    ITEM_ENTER_SECTION,
83
    // Skip subsection payload.
84
    ITEM_SKIP_CONTENTS,
85
    // Read value.
86
    ITEM_READ_VALUE,
87
    // Verify values and apply to decoder state
88
    FINALE,
89
    // Finish section decoding.
90
    DONE
91
  };
92
93
  size_t stage = READ_TAG;
94
95
  // Subsection properties.
96
  SectionState section;
97
  // Length of subsection remaining to skip.
98
  size_t remaining_skip_length = 0;
99
100
  // Collected data (values).
101
  std::array<size_t, 16> varint_values;
102
};
103
104
// Fields used for "Fallback" section parsing.
105
struct FallbackState {
106
  enum Stage {
107
    // Check section tag.
108
    READ_TAG,
109
    // Read section length.
110
    ENTER_SECTION,
111
    // Copy "original JPEG" contents to internal storage (if necessary).
112
    READ_CONTENTS,
113
    // Finish section decoding.
114
    DONE
115
  };
116
117
  enum class Policy {
118
    // Copy reference to external data; might become dangling reference.
119
    // Also requires that input is complete (one-shot decoding).
120
    BORROW,
121
    // Copy contents to internal storage.
122
    COPY
123
  };
124
125
  size_t stage = READ_TAG;
126
  Policy policy = Policy::COPY;
127
128
  // Storage for original JPEG contents.
129
  std::vector<uint8_t> storage;
130
};
131
132
// Fields used for section header parsing.
133
struct SectionHeaderState {
134
  enum Stage {
135
    // Check section tag.
136
    READ_TAG,
137
    // Read (unused) value.
138
    READ_VALUE,
139
    // Read section length.
140
    ENTER_SECTION,
141
    // Finish section header decoding.
142
    DONE
143
  };
144
145
  size_t stage = READ_TAG;
146
};
147
148
enum class MetadataDecompressionStage {
149
  // Initial state in which it is decided which one of 3 processing variants to
150
  // use.
151
  INITIAL,
152
  // Read the length of uncompressed payload.
153
  READ_LENGTH,
154
  // Continuing as stream-decompressing/-parsing of Brotli-compressed metadata.
155
  DECOMPRESSING,
156
  // Parsing is finished, no further processing expected.
157
  DONE,
158
};
159
160
struct MetadataState {
161
  enum Stage {
162
    // Parse sequence type.
163
    READ_MARKER,
164
    // Dump the remaining of metadata to tail sequence.
165
    READ_TAIL,
166
    // Parse second byte of 2-byte sequence.
167
    READ_CODE,
168
    // Parse multi-byte sequence length.
169
    READ_LENGTH_HI,
170
    READ_LENGTH_LO,
171
    // Parse multi-byte sequence.
172
    READ_MULTIBYTE,
173
  };
174
175
  size_t short_marker_count = 0;
176
  uint8_t marker;
177
  uint8_t length_hi;
178
  size_t remaining_multibyte_length;
179
  std::vector<uint8_t>* multibyte_sink;
180
  size_t stage = READ_MARKER;
181
182
  BrotliDecoderStateStruct* brotli = nullptr;
183
  size_t metadata_size = 0;
184
  size_t metadata_size_limit = std::numeric_limits<size_t>::max();
185
  size_t decompressed_size = 0;
186
  BrunsliStatus result = BRUNSLI_DECOMPRESSION_ERROR;
187
  MetadataDecompressionStage decompression_stage =
188
      MetadataDecompressionStage::INITIAL;
189
190
  ~MetadataState();
191
192
30
  bool CanFinish() { return (stage == READ_MARKER) || (stage == READ_TAIL); }
193
};
194
195
/**
196
 * Fits both DecodeVarint and DecodeLimitedVarint workflows.
197
 *
198
 * TODO(eustas): we could turn those methods back to stateless,
199
 * when "mark / rewind" utilities are added to BrunsliBitReader, and outer
200
 * parsing workflow supports input buffering.
201
 */
202
struct VarintState {
203
  enum Stage { INIT, READ_CONTINUATION, READ_DATA };
204
205
  Stage stage = INIT;
206
  size_t value;
207
  size_t i;
208
};
209
210
struct JpegInternalsState {
211
  enum Stage {
212
    INIT = 0,
213
    READ_MARKERS,
214
    READ_DRI,
215
216
    DECODE_HUFFMAN_MASK = 0x10,
217
    READ_HUFFMAN_LAST,
218
    READ_HUFFMAN_SIMPLE,
219
    READ_HUFFMAN_MAX_LEN,
220
    READ_HUFFMAN_COUNT,
221
    READ_HUFFMAN_PERMUTATION,
222
    HUFFMAN_UPDATE,
223
224
    PREPARE_READ_SCANS = 0x20,
225
226
    DECODE_SCAN_MASK = 0x40,
227
    READ_SCAN_COMMON,
228
    READ_SCAN_COMPONENT,
229
    READ_SCAN_RESET_POINT_CONTINUATION,
230
    READ_SCAN_RESET_POINT_DATA,
231
    READ_SCAN_ZERO_RUN_CONTINUATION,
232
    READ_SCAN_ZERO_RUN_DATA,
233
234
    READ_NUM_QUANT = 0x80,
235
    READ_QUANT,
236
    READ_COMP_ID_SCHEME,
237
    READ_COMP_ID,
238
    READ_NUM_PADDING_BITS,
239
    READ_PADDING_BITS,
240
241
    ITERATE_MARKERS,
242
    READ_INTERMARKER_LENGTH,
243
    READ_INTERMARKER_DATA,
244
245
    DONE
246
  };
247
248
  Stage stage = INIT;
249
250
  bool have_dri = false;
251
  size_t num_scans = 0;
252
  size_t dht_count = 0;
253
254
  BrunsliBitReader br;
255
  size_t is_known_last_huffman_code;
256
  size_t terminal_huffman_code_count = 0;
257
  bool is_dc_table;
258
  size_t total_count;
259
  size_t space;
260
  size_t max_len;
261
  size_t max_count;
262
  size_t i;
263
  PermutationCoder p;
264
  VarintState varint;
265
266
  size_t j;
267
  int last_block_idx;
268
  int last_num;
269
270
  size_t num_padding_bits;
271
  size_t intermarker_length;
272
};
273
274
struct QuantDataState {
275
  enum Stage {
276
    INIT,
277
278
    READ_NUM_QUANT,
279
280
    READ_STOCK,
281
    READ_Q_FACTOR,
282
    READ_DIFF_IS_ZERO,
283
    READ_DIFF_SIGN,
284
    READ_DIFF,
285
    APPLY_DIFF,
286
    UPDATE,
287
288
    READ_QUANT_IDX,
289
290
    FINISH
291
  };
292
293
  Stage stage = INIT;
294
295
  BrunsliBitReader br;
296
  size_t i;
297
  size_t j;
298
  uint8_t data_precision;
299
  VarintState vs;
300
  int delta;
301
  int sign;
302
  std::vector<uint8_t> predictor;
303
};
304
305
struct HistogramDataState {
306
  enum Stage {
307
    INIT,
308
309
    READ_SCHEME,
310
    READ_NUM_HISTOGRAMS,
311
    READ_CONTEXT_MAP_CODE,
312
    READ_CONTEXT_MAP,
313
    READ_HISTOGRAMS,
314
315
    SKIP_CONTENT,
316
317
    DONE
318
  };
319
320
  Stage stage = INIT;
321
322
  BrunsliBitReader br;
323
  size_t max_run_length_prefix;
324
  std::unique_ptr<HuffmanDecodingData> entropy;
325
  size_t i;
326
  std::vector<uint32_t> counts;
327
  Arena<HuffmanCode> arena;
328
};
329
330
struct Buffer {
331
  size_t data_len = 0;
332
  size_t borrowed_len;
333
  std::vector<uint8_t> data;
334
335
  const uint8_t* external_data;
336
  size_t external_pos;
337
  size_t external_len;
338
};
339
340
struct InternalState {
341
  /* Parsing */
342
343
  AcDcState ac_dc;
344
  SectionState section;
345
346
  // Sections.
347
  HeaderState header;
348
  FallbackState fallback;
349
  SectionHeaderState section_header;
350
  MetadataState metadata;
351
  JpegInternalsState internals;
352
  QuantDataState quant;
353
  HistogramDataState histogram;
354
355
  // "JPEGDecodingState" storage.
356
  std::vector<uint8_t> context_map_;
357
  std::vector<ANSDecodingData> entropy_codes_;
358
  std::vector<std::vector<uint8_t>> block_state_;
359
360
  bool is_meta_warm = false;
361
362
  // For "estimate peak memory".
363
  bool shallow_histograms = false;
364
  bool shallow_metadata = false;
365
  int8_t metadata_brotli_lgwin = -1;  // -1 means an error / not set.
366
  size_t num_contexts = 0;
367
  size_t num_histograms = 0;
368
369
  // Sub-decoders.
370
  bool subdecoders_initialized = false;
371
  ANSDecoder ans_decoder;
372
  BitSource bit_reader;
373
  BinaryArithmeticDecoder arith_decoder;
374
375
  BrunsliStatus result = BRUNSLI_OK;
376
377
  Stage last_stage = Stage::ERROR;
378
379
  Buffer buffer;
380
381
  /* Serialization */
382
383
  SerializationState serialization;
384
};
385
386
}  // namespace dec
387
}  // namespace internal
388
}  // namespace brunsli
389
390
#endif  // BRUNSLI_DEC_STATE_INTERNAL_H_