Coverage Report

Created: 2022-08-24 06:33

/src/libjxl/lib/jxl/dec_frame.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2
//
3
// Use of this source code is governed by a BSD-style
4
// license that can be found in the LICENSE file.
5
6
#include "lib/jxl/dec_frame.h"
7
8
#include <stddef.h>
9
#include <stdint.h>
10
11
#include <algorithm>
12
#include <atomic>
13
#include <hwy/aligned_allocator.h>
14
#include <numeric>
15
#include <utility>
16
#include <vector>
17
18
#include "jxl/types.h"
19
#include "lib/jxl/ac_context.h"
20
#include "lib/jxl/ac_strategy.h"
21
#include "lib/jxl/ans_params.h"
22
#include "lib/jxl/base/bits.h"
23
#include "lib/jxl/base/compiler_specific.h"
24
#include "lib/jxl/base/data_parallel.h"
25
#include "lib/jxl/base/printf_macros.h"
26
#include "lib/jxl/base/profiler.h"
27
#include "lib/jxl/base/status.h"
28
#include "lib/jxl/chroma_from_luma.h"
29
#include "lib/jxl/coeff_order.h"
30
#include "lib/jxl/coeff_order_fwd.h"
31
#include "lib/jxl/color_management.h"
32
#include "lib/jxl/common.h"
33
#include "lib/jxl/compressed_dc.h"
34
#include "lib/jxl/dec_ans.h"
35
#include "lib/jxl/dec_bit_reader.h"
36
#include "lib/jxl/dec_cache.h"
37
#include "lib/jxl/dec_group.h"
38
#include "lib/jxl/dec_modular.h"
39
#include "lib/jxl/dec_patch_dictionary.h"
40
#include "lib/jxl/dec_xyb.h"
41
#include "lib/jxl/epf.h"
42
#include "lib/jxl/fields.h"
43
#include "lib/jxl/frame_header.h"
44
#include "lib/jxl/image.h"
45
#include "lib/jxl/image_bundle.h"
46
#include "lib/jxl/image_ops.h"
47
#include "lib/jxl/jpeg/jpeg_data.h"
48
#include "lib/jxl/loop_filter.h"
49
#include "lib/jxl/luminance.h"
50
#include "lib/jxl/passes_state.h"
51
#include "lib/jxl/quant_weights.h"
52
#include "lib/jxl/quantizer.h"
53
#include "lib/jxl/sanitizers.h"
54
#include "lib/jxl/splines.h"
55
#include "lib/jxl/toc.h"
56
57
namespace jxl {
58
59
namespace {
60
Status DecodeGlobalDCInfo(BitReader* reader, bool is_jpeg,
61
2.98k
                          PassesDecoderState* state, ThreadPool* pool) {
62
2.98k
  PROFILER_FUNC;
63
2.98k
  JXL_RETURN_IF_ERROR(state->shared_storage.quantizer.Decode(reader));
64
65
2.97k
  JXL_RETURN_IF_ERROR(
66
2.97k
      DecodeBlockCtxMap(reader, &state->shared_storage.block_ctx_map));
67
68
2.93k
  JXL_RETURN_IF_ERROR(state->shared_storage.cmap.DecodeDC(reader));
69
70
  // Pre-compute info for decoding a group.
71
2.92k
  if (is_jpeg) {
72
0
    state->shared_storage.quantizer.ClearDCMul();  // Don't dequant DC
73
0
  }
74
75
2.92k
  state->shared_storage.ac_strategy.FillInvalid();
76
2.92k
  return true;
77
2.93k
}
78
}  // namespace
79
80
Status DecodeFrame(PassesDecoderState* dec_state, ThreadPool* JXL_RESTRICT pool,
81
                   const uint8_t* next_in, size_t avail_in,
82
                   ImageBundle* decoded, const CodecMetadata& metadata,
83
0
                   bool use_slow_rendering_pipeline) {
84
0
  FrameDecoder frame_decoder(dec_state, metadata, pool,
85
0
                             use_slow_rendering_pipeline);
86
87
0
  BitReader reader(Span<const uint8_t>(next_in, avail_in));
88
0
  JXL_RETURN_IF_ERROR(frame_decoder.InitFrame(&reader, decoded,
89
0
                                              /*is_preview=*/false,
90
0
                                              /*output_needed=*/true));
91
0
  JXL_RETURN_IF_ERROR(reader.AllReadsWithinBounds());
92
0
  size_t header_bytes = reader.TotalBitsConsumed() / kBitsPerByte;
93
0
  JXL_RETURN_IF_ERROR(reader.Close());
94
95
0
  size_t processed_bytes = header_bytes;
96
0
  Status close_ok = true;
97
0
  std::vector<std::unique_ptr<BitReader>> section_readers;
98
0
  {
99
0
    std::vector<std::unique_ptr<BitReaderScopedCloser>> section_closers;
100
0
    std::vector<FrameDecoder::SectionInfo> section_info;
101
0
    std::vector<FrameDecoder::SectionStatus> section_status;
102
0
    size_t pos = header_bytes;
103
0
    for (auto toc_entry : frame_decoder.Toc()) {
104
0
      JXL_RETURN_IF_ERROR(pos + toc_entry.size <= avail_in);
105
0
      auto br = make_unique<BitReader>(
106
0
          Span<const uint8_t>(next_in + pos, toc_entry.size));
107
0
      section_info.emplace_back(
108
0
          FrameDecoder::SectionInfo{br.get(), toc_entry.id});
109
0
      section_closers.emplace_back(
110
0
          make_unique<BitReaderScopedCloser>(br.get(), &close_ok));
111
0
      section_readers.emplace_back(std::move(br));
112
0
      pos += toc_entry.size;
113
0
    }
114
0
    section_status.resize(section_info.size());
115
0
    JXL_RETURN_IF_ERROR(frame_decoder.ProcessSections(
116
0
        section_info.data(), section_info.size(), section_status.data()));
117
0
    for (size_t i = 0; i < section_status.size(); i++) {
118
0
      JXL_RETURN_IF_ERROR(section_status[i] == FrameDecoder::kDone);
119
0
      processed_bytes += frame_decoder.Toc()[i].size;
120
0
    }
121
0
  }
122
0
  JXL_RETURN_IF_ERROR(close_ok);
123
0
  JXL_RETURN_IF_ERROR(frame_decoder.FinalizeFrame());
124
0
  decoded->SetDecodedBytes(processed_bytes);
125
0
  return true;
126
0
}
127
128
Status FrameDecoder::InitFrame(BitReader* JXL_RESTRICT br, ImageBundle* decoded,
129
120k
                               bool is_preview, bool output_needed) {
130
120k
  PROFILER_FUNC;
131
120k
  decoded_ = decoded;
132
120k
  JXL_ASSERT(is_finalized_);
133
134
  // Reset the dequantization matrices to their default values.
135
120k
  dec_state_->shared_storage.matrices = DequantMatrices();
136
137
120k
  frame_header_.nonserialized_is_preview = is_preview;
138
120k
  JXL_ASSERT(frame_header_.nonserialized_metadata != nullptr);
139
120k
  JXL_RETURN_IF_ERROR(ReadFrameHeader(br, &frame_header_));
140
71.9k
  frame_dim_ = frame_header_.ToFrameDimensions();
141
71.9k
  JXL_DEBUG_V(2, "FrameHeader: %s", frame_header_.DebugString().c_str());
142
143
71.9k
  const size_t num_passes = frame_header_.passes.num_passes;
144
71.9k
  const size_t num_groups = frame_dim_.num_groups;
145
146
  // If the previous frame was not a kRegularFrame, `decoded` may have different
147
  // dimensions; must reset to avoid errors.
148
71.9k
  decoded->RemoveColor();
149
71.9k
  decoded->ClearExtraChannels();
150
151
71.9k
  decoded->duration = frame_header_.animation_frame.duration;
152
153
71.9k
  if (!frame_header_.nonserialized_is_preview &&
154
71.9k
      (frame_header_.is_last || frame_header_.animation_frame.duration > 0) &&
155
71.9k
      (frame_header_.frame_type == kRegularFrame ||
156
24.1k
       frame_header_.frame_type == kSkipProgressive)) {
157
24.1k
    ++dec_state_->visible_frame_index;
158
24.1k
    dec_state_->nonvisible_frame_index = 0;
159
47.8k
  } else {
160
47.8k
    ++dec_state_->nonvisible_frame_index;
161
47.8k
  }
162
163
  // Read TOC.
164
71.9k
  const bool has_ac_global = true;
165
71.9k
  const size_t toc_entries = NumTocEntries(num_groups, frame_dim_.num_dc_groups,
166
71.9k
                                           num_passes, has_ac_global);
167
71.9k
  std::vector<uint32_t> sizes;
168
71.9k
  std::vector<coeff_order_t> permutation;
169
71.9k
  JXL_RETURN_IF_ERROR(ReadToc(toc_entries, br, &sizes, &permutation));
170
24.0k
  bool have_permutation = !permutation.empty();
171
24.0k
  toc_.resize(toc_entries);
172
24.0k
  section_sizes_sum_ = 0;
173
428k
  for (size_t i = 0; i < toc_entries; ++i) {
174
403k
    toc_[i].size = sizes[i];
175
403k
    size_t index = have_permutation ? permutation[i] : i;
176
403k
    toc_[index].id = i;
177
403k
    if (section_sizes_sum_ + toc_[i].size < section_sizes_sum_) {
178
0
      return JXL_FAILURE("group offset overflow");
179
0
    }
180
403k
    section_sizes_sum_ += toc_[i].size;
181
403k
  }
182
183
24.0k
  JXL_DASSERT((br->TotalBitsConsumed() % kBitsPerByte) == 0);
184
24.0k
  const size_t group_codes_begin = br->TotalBitsConsumed() / kBitsPerByte;
185
24.0k
  JXL_DASSERT(!toc_.empty());
186
187
  // Overflow check.
188
24.0k
  if (group_codes_begin + section_sizes_sum_ < group_codes_begin) {
189
0
    return JXL_FAILURE("Invalid group codes");
190
0
  }
191
192
24.0k
  if (!frame_header_.chroma_subsampling.Is444() &&
193
24.0k
      !(frame_header_.flags & FrameHeader::kSkipAdaptiveDCSmoothing) &&
194
24.0k
      frame_header_.encoding == FrameEncoding::kVarDCT) {
195
6
    return JXL_FAILURE(
196
6
        "Non-444 chroma subsampling is not allowed when adaptive DC "
197
6
        "smoothing is enabled");
198
6
  }
199
200
24.0k
  if (!output_needed) return true;
201
24.0k
  JXL_RETURN_IF_ERROR(
202
24.0k
      InitializePassesSharedState(frame_header_, &dec_state_->shared_storage));
203
24.0k
  JXL_RETURN_IF_ERROR(dec_state_->Init());
204
24.0k
  modular_frame_decoder_.Init(frame_dim_);
205
206
24.0k
  if (decoded->IsJPEG()) {
207
0
    if (frame_header_.encoding == FrameEncoding::kModular) {
208
0
      return JXL_FAILURE("Cannot output JPEG from Modular");
209
0
    }
210
0
    jpeg::JPEGData* jpeg_data = decoded->jpeg_data.get();
211
0
    size_t num_components = jpeg_data->components.size();
212
0
    if (num_components != 1 && num_components != 3) {
213
0
      return JXL_FAILURE("Invalid number of components");
214
0
    }
215
0
    if (frame_header_.nonserialized_metadata->m.xyb_encoded) {
216
0
      return JXL_FAILURE("Cannot decode to JPEG an XYB image");
217
0
    }
218
0
    auto jpeg_c_map = JpegOrder(ColorTransform::kYCbCr, num_components == 1);
219
0
    decoded->jpeg_data->width = frame_dim_.xsize;
220
0
    decoded->jpeg_data->height = frame_dim_.ysize;
221
0
    for (size_t c = 0; c < num_components; c++) {
222
0
      auto& component = jpeg_data->components[jpeg_c_map[c]];
223
0
      component.width_in_blocks =
224
0
          frame_dim_.xsize_blocks >> frame_header_.chroma_subsampling.HShift(c);
225
0
      component.height_in_blocks =
226
0
          frame_dim_.ysize_blocks >> frame_header_.chroma_subsampling.VShift(c);
227
0
      component.h_samp_factor =
228
0
          1 << frame_header_.chroma_subsampling.RawHShift(c);
229
0
      component.v_samp_factor =
230
0
          1 << frame_header_.chroma_subsampling.RawVShift(c);
231
0
      component.coeffs.resize(component.width_in_blocks *
232
0
                              component.height_in_blocks * jxl::kDCTBlockSize);
233
0
    }
234
0
  }
235
236
  // Clear the state.
237
24.0k
  decoded_dc_global_ = false;
238
24.0k
  decoded_ac_global_ = false;
239
24.0k
  is_finalized_ = false;
240
24.0k
  finalized_dc_ = false;
241
24.0k
  num_sections_done_ = 0;
242
24.0k
  decoded_dc_groups_.clear();
243
24.0k
  decoded_dc_groups_.resize(frame_dim_.num_dc_groups);
244
24.0k
  decoded_passes_per_ac_group_.clear();
245
24.0k
  decoded_passes_per_ac_group_.resize(frame_dim_.num_groups, 0);
246
24.0k
  processed_section_.clear();
247
24.0k
  processed_section_.resize(toc_.size());
248
24.0k
  allocated_ = false;
249
24.0k
  return true;
250
24.0k
}
251
252
23.3k
Status FrameDecoder::ProcessDCGlobal(BitReader* br) {
253
23.3k
  PROFILER_FUNC;
254
23.3k
  PassesSharedState& shared = dec_state_->shared_storage;
255
23.3k
  if (shared.frame_header.flags & FrameHeader::kPatches) {
256
555
    bool uses_extra_channels = false;
257
555
    JXL_RETURN_IF_ERROR(shared.image_features.patches.Decode(
258
555
        br, frame_dim_.xsize_padded, frame_dim_.ysize_padded,
259
555
        &uses_extra_channels));
260
508
    if (uses_extra_channels && frame_header_.upsampling != 1) {
261
10
      for (size_t ecups : frame_header_.extra_channel_upsampling) {
262
0
        if (ecups != frame_header_.upsampling) {
263
0
          return JXL_FAILURE(
264
0
              "Cannot use extra channels in patches if color channels are "
265
0
              "subsampled differently from extra channels");
266
0
        }
267
0
      }
268
10
    }
269
22.8k
  } else {
270
22.8k
    shared.image_features.patches.Clear();
271
22.8k
  }
272
23.3k
  shared.image_features.splines.Clear();
273
23.3k
  if (shared.frame_header.flags & FrameHeader::kSplines) {
274
867
    JXL_RETURN_IF_ERROR(shared.image_features.splines.Decode(
275
867
        br, frame_dim_.xsize * frame_dim_.ysize));
276
867
  }
277
23.2k
  if (shared.frame_header.flags & FrameHeader::kNoise) {
278
2.03k
    JXL_RETURN_IF_ERROR(DecodeNoise(br, &shared.image_features.noise_params));
279
2.03k
  }
280
23.2k
  JXL_RETURN_IF_ERROR(dec_state_->shared_storage.matrices.DecodeDC(br));
281
282
22.7k
  if (frame_header_.encoding == FrameEncoding::kVarDCT) {
283
2.98k
    JXL_RETURN_IF_ERROR(
284
2.98k
        jxl::DecodeGlobalDCInfo(br, decoded_->IsJPEG(), dec_state_, pool_));
285
2.98k
  }
286
  // Splines' draw cache uses the color correlation map.
287
22.6k
  if (shared.frame_header.flags & FrameHeader::kSplines) {
288
683
    JXL_RETURN_IF_ERROR(shared.image_features.splines.InitializeDrawCache(
289
683
        frame_dim_.xsize_upsampled, frame_dim_.ysize_upsampled,
290
683
        dec_state_->shared->cmap));
291
683
  }
292
22.5k
  Status dec_status = modular_frame_decoder_.DecodeGlobalInfo(
293
22.5k
      br, frame_header_, /*allow_truncated_group=*/false);
294
22.5k
  if (dec_status.IsFatalError()) return dec_status;
295
21.6k
  if (dec_status) {
296
21.5k
    decoded_dc_global_ = true;
297
21.5k
  }
298
21.6k
  return dec_status;
299
22.5k
}
300
301
33.2k
Status FrameDecoder::ProcessDCGroup(size_t dc_group_id, BitReader* br) {
302
33.2k
  PROFILER_FUNC;
303
33.2k
  const size_t gx = dc_group_id % frame_dim_.xsize_dc_groups;
304
33.2k
  const size_t gy = dc_group_id / frame_dim_.xsize_dc_groups;
305
33.2k
  const LoopFilter& lf = dec_state_->shared->frame_header.loop_filter;
306
33.2k
  if (frame_header_.encoding == FrameEncoding::kVarDCT &&
307
33.2k
      !(frame_header_.flags & FrameHeader::kUseDcFrame)) {
308
11.9k
    JXL_RETURN_IF_ERROR(
309
11.9k
        modular_frame_decoder_.DecodeVarDCTDC(dc_group_id, br, dec_state_));
310
11.9k
  }
311
29.5k
  const Rect mrect(gx * frame_dim_.dc_group_dim, gy * frame_dim_.dc_group_dim,
312
29.5k
                   frame_dim_.dc_group_dim, frame_dim_.dc_group_dim);
313
29.5k
  JXL_RETURN_IF_ERROR(modular_frame_decoder_.DecodeGroup(
314
29.5k
      mrect, br, 3, 1000, ModularStreamId::ModularDC(dc_group_id),
315
29.5k
      /*zerofill=*/false, nullptr, nullptr,
316
29.5k
      /*allow_truncated=*/false));
317
29.5k
  if (frame_header_.encoding == FrameEncoding::kVarDCT) {
318
8.24k
    JXL_RETURN_IF_ERROR(
319
8.24k
        modular_frame_decoder_.DecodeAcMetadata(dc_group_id, br, dec_state_));
320
21.2k
  } else if (lf.epf_iters > 0) {
321
4.89k
    FillImage(kInvSigmaNum / lf.epf_sigma_for_modular, &dec_state_->sigma);
322
4.89k
  }
323
24.8k
  decoded_dc_groups_[dc_group_id] = uint8_t{true};
324
24.8k
  return true;
325
29.5k
}
326
327
20.7k
void FrameDecoder::FinalizeDC() {
328
  // Do Adaptive DC smoothing if enabled. This *must* happen between all the
329
  // ProcessDCGroup and ProcessACGroup.
330
20.7k
  if (frame_header_.encoding == FrameEncoding::kVarDCT &&
331
20.7k
      !(frame_header_.flags & FrameHeader::kSkipAdaptiveDCSmoothing) &&
332
20.7k
      !(frame_header_.flags & FrameHeader::kUseDcFrame)) {
333
2.13k
    AdaptiveDCSmoothing(dec_state_->shared->quantizer.MulDC(),
334
2.13k
                        &dec_state_->shared_storage.dc_storage, pool_);
335
2.13k
  }
336
337
20.7k
  finalized_dc_ = true;
338
20.7k
}
339
340
20.9k
Status FrameDecoder::AllocateOutput() {
341
20.9k
  if (allocated_) return true;
342
20.7k
  modular_frame_decoder_.MaybeDropFullImage();
343
20.7k
  decoded_->origin = dec_state_->shared->frame_header.frame_origin;
344
20.7k
  JXL_RETURN_IF_ERROR(dec_state_->InitForAC(nullptr));
345
20.7k
  allocated_ = true;
346
20.7k
  return true;
347
20.7k
}
348
349
20.7k
Status FrameDecoder::ProcessACGlobal(BitReader* br) {
350
20.7k
  JXL_CHECK(finalized_dc_);
351
352
  // Decode AC group.
353
20.7k
  if (frame_header_.encoding == FrameEncoding::kVarDCT) {
354
2.17k
    JXL_RETURN_IF_ERROR(dec_state_->shared_storage.matrices.Decode(
355
2.17k
        br, &modular_frame_decoder_));
356
1.98k
    JXL_RETURN_IF_ERROR(dec_state_->shared_storage.matrices.EnsureComputed(
357
1.98k
        dec_state_->used_acs));
358
359
1.89k
    size_t num_histo_bits =
360
1.89k
        CeilLog2Nonzero(dec_state_->shared->frame_dim.num_groups);
361
1.89k
    dec_state_->shared_storage.num_histograms =
362
1.89k
        1 + br->ReadBits(num_histo_bits);
363
364
1.89k
    dec_state_->code.resize(kMaxNumPasses);
365
1.89k
    dec_state_->context_map.resize(kMaxNumPasses);
366
    // Read coefficient orders and histograms.
367
1.89k
    size_t max_num_bits_ac = 0;
368
1.89k
    for (size_t i = 0;
369
3.73k
         i < dec_state_->shared_storage.frame_header.passes.num_passes; i++) {
370
1.91k
      uint16_t used_orders = U32Coder::Read(kOrderEnc, br);
371
1.91k
      JXL_RETURN_IF_ERROR(DecodeCoeffOrders(
372
1.91k
          used_orders, dec_state_->used_acs,
373
1.91k
          &dec_state_->shared_storage
374
1.91k
               .coeff_orders[i * dec_state_->shared_storage.coeff_order_size],
375
1.91k
          br));
376
1.86k
      size_t num_contexts =
377
1.86k
          dec_state_->shared->num_histograms *
378
1.86k
          dec_state_->shared_storage.block_ctx_map.NumACContexts();
379
1.86k
      JXL_RETURN_IF_ERROR(DecodeHistograms(
380
1.86k
          br, num_contexts, &dec_state_->code[i], &dec_state_->context_map[i]));
381
      // Add extra values to enable the cheat in hot loop of DecodeACVarBlock.
382
1.83k
      dec_state_->context_map[i].resize(
383
1.83k
          num_contexts + kZeroDensityContextLimit - kZeroDensityContextCount);
384
1.83k
      max_num_bits_ac =
385
1.83k
          std::max(max_num_bits_ac, dec_state_->code[i].max_num_bits);
386
1.83k
    }
387
1.82k
    max_num_bits_ac += CeilLog2Nonzero(
388
1.82k
        dec_state_->shared_storage.frame_header.passes.num_passes);
389
    // 16-bit buffer for decoding to JPEG are not implemented.
390
    // TODO(veluca): figure out the exact limit - 16 should still work with
391
    // 16-bit buffers, but we are excluding it for safety.
392
1.82k
    bool use_16_bit = max_num_bits_ac < 16 && !decoded_->IsJPEG();
393
1.82k
    bool store = frame_header_.passes.num_passes > 1;
394
1.82k
    size_t xs = store ? kGroupDim * kGroupDim : 0;
395
1.82k
    size_t ys = store ? frame_dim_.num_groups : 0;
396
1.82k
    if (use_16_bit) {
397
1.52k
      dec_state_->coefficients = make_unique<ACImageT<int16_t>>(xs, ys);
398
1.52k
    } else {
399
299
      dec_state_->coefficients = make_unique<ACImageT<int32_t>>(xs, ys);
400
299
    }
401
1.82k
    if (store) {
402
16
      dec_state_->coefficients->ZeroFill();
403
16
    }
404
1.82k
  }
405
406
  // Set JPEG decoding data.
407
20.3k
  if (decoded_->IsJPEG()) {
408
0
    decoded_->color_transform = frame_header_.color_transform;
409
0
    decoded_->chroma_subsampling = frame_header_.chroma_subsampling;
410
0
    const std::vector<QuantEncoding>& qe =
411
0
        dec_state_->shared_storage.matrices.encodings();
412
0
    if (qe.empty() || qe[0].mode != QuantEncoding::Mode::kQuantModeRAW ||
413
0
        std::abs(qe[0].qraw.qtable_den - 1.f / (8 * 255)) > 1e-8f) {
414
0
      return JXL_FAILURE(
415
0
          "Quantization table is not a JPEG quantization table.");
416
0
    }
417
0
    jpeg::JPEGData* jpeg_data = decoded_->jpeg_data.get();
418
0
    size_t num_components = jpeg_data->components.size();
419
0
    bool is_gray = (num_components == 1);
420
0
    auto jpeg_c_map = JpegOrder(frame_header_.color_transform, is_gray);
421
0
    size_t qt_set = 0;
422
0
    for (size_t c = 0; c < num_components; c++) {
423
      // TODO(eustas): why 1-st quant table for gray?
424
0
      size_t quant_c = is_gray ? 1 : c;
425
0
      size_t qpos = jpeg_data->components[jpeg_c_map[c]].quant_idx;
426
0
      JXL_CHECK(qpos != jpeg_data->quant.size());
427
0
      qt_set |= 1 << qpos;
428
0
      for (size_t x = 0; x < 8; x++) {
429
0
        for (size_t y = 0; y < 8; y++) {
430
0
          jpeg_data->quant[qpos].values[x * 8 + y] =
431
0
              (*qe[0].qraw.qtable)[quant_c * 64 + y * 8 + x];
432
0
        }
433
0
      }
434
0
    }
435
0
    for (size_t i = 0; i < jpeg_data->quant.size(); i++) {
436
0
      if (qt_set & (1 << i)) continue;
437
0
      if (i == 0) return JXL_FAILURE("First quant table unused.");
438
      // Unused quant table is set to copy of previous quant table
439
0
      for (size_t j = 0; j < 64; j++) {
440
0
        jpeg_data->quant[i].values[j] = jpeg_data->quant[i - 1].values[j];
441
0
      }
442
0
    }
443
0
  }
444
20.3k
  decoded_ac_global_ = true;
445
20.3k
  return true;
446
20.3k
}
447
448
Status FrameDecoder::ProcessACGroup(size_t ac_group_id,
449
                                    BitReader* JXL_RESTRICT* br,
450
                                    size_t num_passes, size_t thread,
451
52.6k
                                    bool force_draw, bool dc_only) {
452
52.6k
  PROFILER_ZONE("process_group");
453
52.6k
  size_t group_dim = frame_dim_.group_dim;
454
52.6k
  const size_t gx = ac_group_id % frame_dim_.xsize_groups;
455
52.6k
  const size_t gy = ac_group_id / frame_dim_.xsize_groups;
456
52.6k
  const size_t x = gx * group_dim;
457
52.6k
  const size_t y = gy * group_dim;
458
52.6k
  JXL_DEBUG_V(3,
459
52.6k
              "Processing AC group %" PRIuS "(%" PRIuS ",%" PRIuS
460
52.6k
              ") group_dim: %" PRIuS " decoded passes: %u new passes: %" PRIuS,
461
52.6k
              ac_group_id, gx, gy, group_dim,
462
52.6k
              decoded_passes_per_ac_group_[ac_group_id], num_passes);
463
464
52.6k
  RenderPipelineInput render_pipeline_input =
465
52.6k
      dec_state_->render_pipeline->GetInputBuffers(ac_group_id, thread);
466
467
52.6k
  bool should_run_pipeline = true;
468
469
52.6k
  if (frame_header_.encoding == FrameEncoding::kVarDCT) {
470
13.4k
    group_dec_caches_[thread].InitOnce(frame_header_.passes.num_passes,
471
13.4k
                                       dec_state_->used_acs);
472
13.4k
    JXL_RETURN_IF_ERROR(DecodeGroup(br, num_passes, ac_group_id, dec_state_,
473
13.4k
                                    &group_dec_caches_[thread], thread,
474
13.4k
                                    render_pipeline_input, decoded_,
475
13.4k
                                    decoded_passes_per_ac_group_[ac_group_id],
476
13.4k
                                    force_draw, dc_only, &should_run_pipeline));
477
13.4k
  }
478
479
  // don't limit to image dimensions here (is done in DecodeGroup)
480
51.4k
  const Rect mrect(x, y, group_dim, group_dim);
481
51.4k
  bool modular_ready = false;
482
51.4k
  size_t pass0 = decoded_passes_per_ac_group_[ac_group_id];
483
51.4k
  size_t pass1 =
484
51.4k
      force_draw ? frame_header_.passes.num_passes : pass0 + num_passes;
485
94.3k
  for (size_t i = pass0; i < pass1; ++i) {
486
55.3k
    int minShift, maxShift;
487
55.3k
    frame_header_.passes.GetDownsamplingBracket(i, minShift, maxShift);
488
55.3k
    bool modular_pass_ready = true;
489
55.3k
    if (i < pass0 + num_passes) {
490
52.2k
      JXL_RETURN_IF_ERROR(modular_frame_decoder_.DecodeGroup(
491
52.2k
          mrect, br[i - pass0], minShift, maxShift,
492
52.2k
          ModularStreamId::ModularAC(ac_group_id, i),
493
52.2k
          /*zerofill=*/false, dec_state_, &render_pipeline_input,
494
52.2k
          /*allow_truncated=*/false, &modular_pass_ready));
495
52.2k
    } else {
496
3.09k
      JXL_RETURN_IF_ERROR(modular_frame_decoder_.DecodeGroup(
497
3.09k
          mrect, nullptr, minShift, maxShift,
498
3.09k
          ModularStreamId::ModularAC(ac_group_id, i), /*zerofill=*/true,
499
3.09k
          dec_state_, &render_pipeline_input,
500
3.09k
          /*allow_truncated=*/false, &modular_pass_ready));
501
3.09k
    }
502
42.9k
    if (modular_pass_ready) modular_ready = true;
503
42.9k
  }
504
39.0k
  decoded_passes_per_ac_group_[ac_group_id] += num_passes;
505
506
39.0k
  if ((frame_header_.flags & FrameHeader::kNoise) != 0) {
507
3.59k
    PROFILER_ZONE("GenerateNoise");
508
3.59k
    size_t noise_c_start =
509
3.59k
        3 + frame_header_.nonserialized_metadata->m.num_extra_channels;
510
    // When the color channels are downsampled, we need to generate more noise
511
    // input for the current group than just the group dimensions.
512
3.59k
    std::pair<ImageF*, Rect> rects[3];
513
10.0k
    for (size_t iy = 0; iy < frame_header_.upsampling; iy++) {
514
23.6k
      for (size_t ix = 0; ix < frame_header_.upsampling; ix++) {
515
68.8k
        for (size_t c = 0; c < 3; c++) {
516
51.6k
          auto r = render_pipeline_input.GetBuffer(noise_c_start + c);
517
51.6k
          rects[c].first = r.first;
518
51.6k
          size_t x1 = r.second.x0() + r.second.xsize();
519
51.6k
          size_t y1 = r.second.y0() + r.second.ysize();
520
51.6k
          rects[c].second = Rect(r.second.x0() + ix * group_dim,
521
51.6k
                                 r.second.y0() + iy * group_dim, group_dim,
522
51.6k
                                 group_dim, x1, y1);
523
51.6k
        }
524
17.2k
        Random3Planes(dec_state_->visible_frame_index,
525
17.2k
                      dec_state_->nonvisible_frame_index,
526
17.2k
                      (gx * frame_header_.upsampling + ix) * group_dim,
527
17.2k
                      (gy * frame_header_.upsampling + iy) * group_dim,
528
17.2k
                      rects[0], rects[1], rects[2]);
529
17.2k
      }
530
6.46k
    }
531
3.59k
  }
532
533
39.0k
  if (!modular_frame_decoder_.UsesFullImage() && !decoded_->IsJPEG()) {
534
13.8k
    if (should_run_pipeline && modular_ready) {
535
12.1k
      render_pipeline_input.Done();
536
12.1k
    } else if (force_draw) {
537
3
      return JXL_FAILURE("Modular group decoding failed.");
538
3
    }
539
13.8k
  }
540
39.0k
  return true;
541
39.0k
}
542
543
void FrameDecoder::MarkSections(const SectionInfo* sections, size_t num,
544
29.6k
                                SectionStatus* section_status) {
545
29.6k
  num_sections_done_ += num;
546
80.7k
  for (size_t i = 0; i < num; i++) {
547
51.0k
    if (section_status[i] != SectionStatus::kDone) {
548
10.1k
      processed_section_[sections[i].id] = false;
549
10.1k
      num_sections_done_--;
550
10.1k
    }
551
51.0k
  }
552
29.6k
}
553
554
Status FrameDecoder::ProcessSections(const SectionInfo* sections, size_t num,
555
264k
                                     SectionStatus* section_status) {
556
264k
  if (num == 0) return true;  // Nothing to process
557
33.4k
  std::fill(section_status, section_status + num, SectionStatus::kSkipped);
558
33.4k
  size_t dc_global_sec = num;
559
33.4k
  size_t ac_global_sec = num;
560
33.4k
  std::vector<size_t> dc_group_sec(frame_dim_.num_dc_groups, num);
561
33.4k
  std::vector<std::vector<size_t>> ac_group_sec(
562
33.4k
      frame_dim_.num_groups,
563
33.4k
      std::vector<size_t>(frame_header_.passes.num_passes, num));
564
  // This keeps track of the number of ac passes we want to process during this
565
  // call of ProcessSections.
566
33.4k
  std::vector<size_t> desired_num_ac_passes(frame_dim_.num_groups);
567
33.4k
  bool single_section =
568
33.4k
      frame_dim_.num_groups == 1 && frame_header_.passes.num_passes == 1;
569
33.4k
  if (single_section) {
570
20.1k
    JXL_ASSERT(num == 1);
571
20.1k
    JXL_ASSERT(sections[0].id == 0);
572
20.1k
    if (processed_section_[0] == false) {
573
20.1k
      processed_section_[0] = true;
574
20.1k
      ac_group_sec[0].resize(1);
575
20.1k
      dc_global_sec = ac_global_sec = dc_group_sec[0] = ac_group_sec[0][0] = 0;
576
20.1k
      desired_num_ac_passes[0] = 1;
577
20.1k
    } else {
578
0
      section_status[0] = SectionStatus::kDuplicate;
579
0
    }
580
20.1k
  } else {
581
13.3k
    size_t ac_global_index = frame_dim_.num_dc_groups + 1;
582
80.1k
    for (size_t i = 0; i < num; i++) {
583
66.8k
      JXL_ASSERT(sections[i].id < processed_section_.size());
584
66.8k
      if (processed_section_[sections[i].id]) {
585
14
        section_status[i] = SectionStatus::kDuplicate;
586
14
        continue;
587
14
      }
588
66.8k
      if (sections[i].id == 0) {
589
3.24k
        dc_global_sec = i;
590
63.5k
      } else if (sections[i].id < ac_global_index) {
591
16.0k
        dc_group_sec[sections[i].id - 1] = i;
592
47.5k
      } else if (sections[i].id == ac_global_index) {
593
3.07k
        ac_global_sec = i;
594
44.5k
      } else {
595
44.5k
        size_t ac_idx = sections[i].id - ac_global_index - 1;
596
44.5k
        size_t acg = ac_idx % frame_dim_.num_groups;
597
44.5k
        size_t acp = ac_idx / frame_dim_.num_groups;
598
44.5k
        if (acp >= frame_header_.passes.num_passes) {
599
0
          return JXL_FAILURE("Invalid section ID");
600
0
        }
601
44.5k
        ac_group_sec[acg][acp] = i;
602
44.5k
      }
603
66.8k
      processed_section_[sections[i].id] = true;
604
66.8k
    }
605
    // Count number of new passes per group.
606
522k
    for (size_t g = 0; g < ac_group_sec.size(); g++) {
607
509k
      size_t j = 0;
608
553k
      for (; j + decoded_passes_per_ac_group_[g] <
609
553k
             frame_header_.passes.num_passes;
610
509k
           j++) {
611
436k
        if (ac_group_sec[g][j + decoded_passes_per_ac_group_[g]] == num) {
612
392k
          break;
613
392k
        }
614
436k
      }
615
509k
      desired_num_ac_passes[g] = j;
616
509k
    }
617
13.3k
  }
618
33.4k
  if (dc_global_sec != num) {
619
23.3k
    Status dc_global_status = ProcessDCGlobal(sections[dc_global_sec].br);
620
23.3k
    if (dc_global_status.IsFatalError()) return dc_global_status;
621
21.7k
    if (dc_global_status) {
622
21.5k
      section_status[dc_global_sec] = SectionStatus::kDone;
623
21.5k
    } else {
624
230
      section_status[dc_global_sec] = SectionStatus::kPartial;
625
230
    }
626
21.7k
  }
627
628
31.8k
  std::atomic<bool> has_error{false};
629
31.8k
  if (decoded_dc_global_) {
630
28.1k
    JXL_RETURN_IF_ERROR(RunOnPool(
631
28.1k
        pool_, 0, dc_group_sec.size(), ThreadPool::NoInit,
632
28.1k
        [this, &dc_group_sec, &num, &sections, &section_status, &has_error](
633
28.1k
            size_t i, size_t thread) {
634
28.1k
          if (dc_group_sec[i] != num) {
635
28.1k
            if (!ProcessDCGroup(i, sections[dc_group_sec[i]].br)) {
636
28.1k
              has_error = true;
637
28.1k
            } else {
638
28.1k
              section_status[dc_group_sec[i]] = SectionStatus::kDone;
639
28.1k
            }
640
28.1k
          }
641
28.1k
        },
642
28.1k
        "DecodeDCGroup"));
643
28.1k
  }
644
31.8k
  if (has_error) return JXL_FAILURE("Error in DC group");
645
646
31.1k
  if (*std::min_element(decoded_dc_groups_.begin(), decoded_dc_groups_.end()) &&
647
31.1k
      !finalized_dc_) {
648
20.8k
    PassesDecoderState::PipelineOptions pipeline_options;
649
20.8k
    pipeline_options.use_slow_render_pipeline = use_slow_rendering_pipeline_;
650
20.8k
    pipeline_options.coalescing = coalescing_;
651
20.8k
    pipeline_options.render_spotcolors = render_spotcolors_;
652
20.8k
    JXL_RETURN_IF_ERROR(
653
20.8k
        dec_state_->PreparePipeline(decoded_, pipeline_options));
654
20.7k
    FinalizeDC();
655
20.7k
    JXL_RETURN_IF_ERROR(AllocateOutput());
656
20.7k
    if (progressive_detail_ >= JxlProgressiveDetail::kDC) {
657
0
      MarkSections(sections, num, section_status);
658
0
      return true;
659
0
    }
660
20.7k
  }
661
662
31.1k
  if (finalized_dc_ && ac_global_sec != num && !decoded_ac_global_) {
663
20.7k
    JXL_RETURN_IF_ERROR(ProcessACGlobal(sections[ac_global_sec].br));
664
20.3k
    section_status[ac_global_sec] = SectionStatus::kDone;
665
20.3k
  }
666
667
30.7k
  if (progressive_detail_ >= JxlProgressiveDetail::kLastPasses) {
668
    // Mark that we only want the next progression pass.
669
0
    size_t target_complete_passes = NextNumPassesToPause();
670
0
    for (size_t i = 0; i < ac_group_sec.size(); i++) {
671
0
      desired_num_ac_passes[i] =
672
0
          std::min(desired_num_ac_passes[i],
673
0
                   target_complete_passes - decoded_passes_per_ac_group_[i]);
674
0
    }
675
0
  }
676
677
30.7k
  if (decoded_ac_global_) {
678
    // Mark all the AC groups that we received as not complete yet.
679
315k
    for (size_t i = 0; i < ac_group_sec.size(); i++) {
680
290k
      if (desired_num_ac_passes[i] != 0) {
681
51.2k
        dec_state_->render_pipeline->ClearDone(i);
682
51.2k
      }
683
290k
    }
684
685
25.7k
    JXL_RETURN_IF_ERROR(RunOnPool(
686
25.7k
        pool_, 0, ac_group_sec.size(),
687
25.7k
        [this](size_t num_threads) {
688
25.7k
          return PrepareStorage(num_threads,
689
25.7k
                                decoded_passes_per_ac_group_.size());
690
25.7k
        },
691
25.7k
        [this, &ac_group_sec, &desired_num_ac_passes, &num, &sections,
692
25.7k
         &section_status, &has_error](size_t g, size_t thread) {
693
25.7k
          if (desired_num_ac_passes[g] == 0) {
694
            // no new AC pass, nothing to do
695
25.7k
            return;
696
25.7k
          }
697
25.7k
          (void)num;
698
25.7k
          size_t first_pass = decoded_passes_per_ac_group_[g];
699
25.7k
          BitReader* JXL_RESTRICT readers[kMaxNumPasses];
700
25.7k
          for (size_t i = 0; i < desired_num_ac_passes[g]; i++) {
701
25.7k
            JXL_ASSERT(ac_group_sec[g][first_pass + i] != num);
702
25.7k
            readers[i] = sections[ac_group_sec[g][first_pass + i]].br;
703
25.7k
          }
704
25.7k
          if (!ProcessACGroup(g, readers, desired_num_ac_passes[g],
705
25.7k
                              GetStorageLocation(thread, g),
706
25.7k
                              /*force_draw=*/false, /*dc_only=*/false)) {
707
25.7k
            has_error = true;
708
25.7k
          } else {
709
25.7k
            for (size_t i = 0; i < desired_num_ac_passes[g]; i++) {
710
25.7k
              section_status[ac_group_sec[g][first_pass + i]] =
711
25.7k
                  SectionStatus::kDone;
712
25.7k
            }
713
25.7k
          }
714
25.7k
        },
715
25.7k
        "DecodeGroup"));
716
25.7k
  }
717
30.7k
  if (has_error) return JXL_FAILURE("Error in AC group");
718
719
29.6k
  MarkSections(sections, num, section_status);
720
29.6k
  return true;
721
30.7k
}
722
723
176
Status FrameDecoder::Flush() {
724
176
  bool has_blending = frame_header_.blending_info.mode != BlendMode::kReplace ||
725
176
                      frame_header_.custom_size_or_origin;
726
176
  for (const auto& blending_info_ec :
727
176
       frame_header_.extra_channel_blending_info) {
728
11
    if (blending_info_ec.mode != BlendMode::kReplace) has_blending = true;
729
11
  }
730
  // No early Flush() if blending is enabled.
731
176
  if (has_blending && !is_finalized_) {
732
27
    return false;
733
27
  }
734
  // No early Flush() - nothing to do - if the frame is a kSkipProgressive
735
  // frame.
736
149
  if (frame_header_.frame_type == FrameType::kSkipProgressive &&
737
149
      !is_finalized_) {
738
0
    return true;
739
0
  }
740
149
  if (decoded_->IsJPEG()) {
741
    // Nothing to do.
742
0
    return true;
743
0
  }
744
149
  JXL_RETURN_IF_ERROR(AllocateOutput());
745
746
149
  uint32_t completely_decoded_ac_pass = *std::min_element(
747
149
      decoded_passes_per_ac_group_.begin(), decoded_passes_per_ac_group_.end());
748
149
  if (completely_decoded_ac_pass < frame_header_.passes.num_passes) {
749
    // We don't have all AC yet: force a draw of all the missing areas.
750
    // Mark all sections as not complete.
751
1.57k
    for (size_t i = 0; i < decoded_passes_per_ac_group_.size(); i++) {
752
1.42k
      if (decoded_passes_per_ac_group_[i] < frame_header_.passes.num_passes) {
753
1.41k
        dec_state_->render_pipeline->ClearDone(i);
754
1.41k
      }
755
1.42k
    }
756
149
    std::atomic<bool> has_error{false};
757
149
    JXL_RETURN_IF_ERROR(RunOnPool(
758
149
        pool_, 0, decoded_passes_per_ac_group_.size(),
759
149
        [this](const size_t num_threads) {
760
149
          return PrepareStorage(num_threads,
761
149
                                decoded_passes_per_ac_group_.size());
762
149
        },
763
149
        [this, &has_error](const uint32_t g, size_t thread) {
764
149
          if (decoded_passes_per_ac_group_[g] ==
765
149
              frame_header_.passes.num_passes) {
766
            // This group was drawn already, nothing to do.
767
149
            return;
768
149
          }
769
149
          BitReader* JXL_RESTRICT readers[kMaxNumPasses] = {};
770
149
          bool ok = ProcessACGroup(
771
149
              g, readers, /*num_passes=*/0, GetStorageLocation(thread, g),
772
149
              /*force_draw=*/true, /*dc_only=*/!decoded_ac_global_);
773
149
          if (!ok) has_error = true;
774
149
        },
775
149
        "ForceDrawGroup"));
776
149
    if (has_error) {
777
2
      return JXL_FAILURE("Drawing groups failed");
778
2
    }
779
149
  }
780
781
  // undo global modular transforms and copy int pixel buffers to float ones
782
147
  JXL_RETURN_IF_ERROR(modular_frame_decoder_.FinalizeDecoding(dec_state_, pool_,
783
147
                                                              is_finalized_));
784
785
147
  return true;
786
147
}
787
788
21.5k
int FrameDecoder::SavedAs(const FrameHeader& header) {
789
21.5k
  if (header.frame_type == FrameType::kDCFrame) {
790
    // bits 16, 32, 64, 128 for DC level
791
1.17k
    return 16 << (header.dc_level - 1);
792
20.4k
  } else if (header.CanBeReferenced()) {
793
    // bits 1, 2, 4 and 8 for the references
794
18.5k
    return 1 << header.save_as_reference;
795
18.5k
  }
796
797
1.87k
  return 0;
798
21.5k
}
799
800
17.4k
bool FrameDecoder::HasEverything() const {
801
17.4k
  if (!decoded_dc_global_) return false;
802
17.4k
  if (!decoded_ac_global_) return false;
803
18.4k
  for (auto& have_dc_group : decoded_dc_groups_) {
804
18.4k
    if (!have_dc_group) return false;
805
18.4k
  }
806
27.9k
  for (auto& nb_passes : decoded_passes_per_ac_group_) {
807
27.9k
    if (nb_passes < frame_header_.passes.num_passes) return false;
808
27.9k
  }
809
17.4k
  return true;
810
17.4k
}
811
812
17.4k
int FrameDecoder::References() const {
813
17.4k
  if (is_finalized_) {
814
0
    return 0;
815
0
  }
816
17.4k
  if (!HasEverything()) return 0;
817
818
17.4k
  int result = 0;
819
820
  // Blending
821
17.4k
  if (frame_header_.frame_type == FrameType::kRegularFrame ||
822
17.4k
      frame_header_.frame_type == FrameType::kSkipProgressive) {
823
16.5k
    bool cropped = frame_header_.custom_size_or_origin;
824
16.5k
    if (cropped || frame_header_.blending_info.mode != BlendMode::kReplace) {
825
12.4k
      result |= (1 << frame_header_.blending_info.source);
826
12.4k
    }
827
16.5k
    const auto& extra = frame_header_.extra_channel_blending_info;
828
65.2k
    for (size_t i = 0; i < extra.size(); ++i) {
829
48.6k
      if (cropped || extra[i].mode != BlendMode::kReplace) {
830
8.12k
        result |= (1 << extra[i].source);
831
8.12k
      }
832
48.6k
    }
833
16.5k
  }
834
835
  // Patches
836
17.4k
  if (frame_header_.flags & FrameHeader::kPatches) {
837
163
    result |= dec_state_->shared->image_features.patches.GetReferences();
838
163
  }
839
840
  // DC Level
841
17.4k
  if (frame_header_.flags & FrameHeader::kUseDcFrame) {
842
    // Reads from the next dc level
843
67
    int dc_level = frame_header_.dc_level + 1;
844
    // bits 16, 32, 64, 128 for DC level
845
67
    result |= (16 << (dc_level - 1));
846
67
  }
847
848
17.4k
  return result;
849
17.4k
}
850
851
18.5k
Status FrameDecoder::FinalizeFrame() {
852
18.5k
  if (is_finalized_) {
853
0
    return JXL_FAILURE("FinalizeFrame called multiple times");
854
0
  }
855
18.5k
  is_finalized_ = true;
856
18.5k
  if (decoded_->IsJPEG()) {
857
    // Nothing to do.
858
0
    return true;
859
0
  }
860
861
  // undo global modular transforms and copy int pixel buffers to float ones
862
18.5k
  JXL_RETURN_IF_ERROR(
863
18.5k
      modular_frame_decoder_.FinalizeDecoding(dec_state_, pool_,
864
18.5k
                                              /*inplace=*/true));
865
866
18.5k
  if (frame_header_.CanBeReferenced()) {
867
16.3k
    auto& info = dec_state_->shared_storage
868
16.3k
                     .reference_frames[frame_header_.save_as_reference];
869
16.3k
    info.storage = std::move(dec_state_->frame_storage_for_referencing);
870
16.3k
    info.ib_is_in_xyb = frame_header_.save_before_color_transform;
871
16.3k
    info.frame = &info.storage;
872
16.3k
  }
873
18.5k
  return true;
874
18.5k
}
875
876
}  // namespace jxl