/src/libjxl/lib/jxl/entropy_coder.cc
Line | Count | Source |
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/entropy_coder.h" |
7 | | |
8 | | #include <jxl/memory_manager.h> |
9 | | |
10 | | #include <cstdint> |
11 | | #include <vector> |
12 | | |
13 | | #include "lib/jxl/ac_context.h" |
14 | | #include "lib/jxl/base/compiler_specific.h" |
15 | | #include "lib/jxl/base/status.h" |
16 | | #include "lib/jxl/coeff_order.h" |
17 | | #include "lib/jxl/coeff_order_fwd.h" |
18 | | #include "lib/jxl/dec_bit_reader.h" |
19 | | #include "lib/jxl/dec_context_map.h" |
20 | | #include "lib/jxl/fields.h" |
21 | | #include "lib/jxl/pack_signed.h" |
22 | | |
23 | | namespace jxl { |
24 | | |
25 | | Status DecodeBlockCtxMap(JxlMemoryManager* memory_manager, BitReader* br, |
26 | 4.77k | BlockCtxMap* block_ctx_map) { |
27 | 4.77k | auto& dct = block_ctx_map->dc_thresholds; |
28 | 4.77k | auto& qft = block_ctx_map->qf_thresholds; |
29 | 4.77k | auto& ctx_map = block_ctx_map->ctx_map; |
30 | 4.77k | bool is_default = static_cast<bool>(br->ReadFixedBits<1>()); |
31 | 4.77k | if (is_default) { |
32 | 3.22k | *block_ctx_map = BlockCtxMap(); |
33 | 3.22k | return true; |
34 | 3.22k | } |
35 | 1.55k | block_ctx_map->num_dc_ctxs = 1; |
36 | 4.65k | for (int j : {0, 1, 2}) { |
37 | 4.65k | dct[j].resize(br->ReadFixedBits<4>()); |
38 | 4.65k | block_ctx_map->num_dc_ctxs *= dct[j].size() + 1; |
39 | 7.23k | for (int& i : dct[j]) { |
40 | 7.23k | i = UnpackSigned(U32Coder::Read(kDCThresholdDist, br)); |
41 | 7.23k | } |
42 | 4.65k | } |
43 | 1.55k | qft.resize(br->ReadFixedBits<4>()); |
44 | 3.13k | for (uint32_t& i : qft) { |
45 | 3.13k | i = U32Coder::Read(kQFThresholdDist, br) + 1; |
46 | 3.13k | } |
47 | | |
48 | 1.55k | if (block_ctx_map->num_dc_ctxs * (qft.size() + 1) > 64) { |
49 | 8 | return JXL_FAILURE("Invalid block context map: too big"); |
50 | 8 | } |
51 | | |
52 | 1.54k | ctx_map.resize(3 * kNumOrders * block_ctx_map->num_dc_ctxs * |
53 | 1.54k | (qft.size() + 1)); |
54 | 1.54k | JXL_RETURN_IF_ERROR( |
55 | 1.54k | DecodeContextMap(memory_manager, &ctx_map, &block_ctx_map->num_ctxs, br)); |
56 | 1.51k | if (block_ctx_map->num_ctxs > 16) { |
57 | 1 | return JXL_FAILURE("Invalid block context map: too many distinct contexts"); |
58 | 1 | } |
59 | 1.51k | return true; |
60 | 1.51k | } |
61 | | |
62 | | #if JXL_CXX_LANG < JXL_CXX_17 |
63 | | constexpr uint8_t BlockCtxMap::kDefaultCtxMap[]; // from ac_context.h |
64 | | #endif |
65 | | |
66 | | } // namespace jxl |