/src/avm/av2/decoder/detokenize.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 3-Clause Clear License |
5 | | * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear |
6 | | * License was not distributed with this source code in the LICENSE file, you |
7 | | * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the |
8 | | * Alliance for Open Media Patent License 1.0 was not distributed with this |
9 | | * source code in the PATENTS file, you can obtain it at |
10 | | * aomedia.org/license/patent-license/. |
11 | | */ |
12 | | |
13 | | #include "config/avm_config.h" |
14 | | |
15 | | #include "avm_mem/avm_mem.h" |
16 | | #include "avm_ports/mem.h" |
17 | | #include "av2/common/blockd.h" |
18 | | #include "av2/decoder/detokenize.h" |
19 | | |
20 | | #include "av2/common/common.h" |
21 | | #include "av2/common/entropy.h" |
22 | | #include "av2/common/idct.h" |
23 | | |
24 | | // Read direction flag, then read line flags, and palette tokens one line at at |
25 | | // a time. Returns 1 for sucess. |
26 | 22.4k | static int decode_color_map_tokens(Av2ColorMapParam *param, avm_reader *r) { |
27 | 22.4k | uint8_t color_order[PALETTE_MAX_SIZE]; |
28 | 22.4k | const int num_colors = param->n_colors; |
29 | 22.4k | uint8_t *const color_map = param->color_map; |
30 | 22.4k | MapCdf color_map_cdf = param->map_cdf; |
31 | 22.4k | int plane_block_width = param->plane_width; |
32 | 22.4k | int plane_block_height = param->plane_height; |
33 | 22.4k | int rows = param->rows; |
34 | 22.4k | int cols = param->cols; |
35 | 22.4k | const bool transverse_allowed = |
36 | 22.4k | plane_block_width < 64 && plane_block_height < 64; |
37 | 22.4k | int direction; |
38 | 22.4k | if (transverse_allowed) { |
39 | 18.5k | direction = avm_read_bit(r, ACCT_INFO()); |
40 | 18.5k | } else { |
41 | 3.87k | direction = 0; |
42 | 3.87k | } |
43 | 22.4k | const int axis1_limit = direction ? rows : cols; |
44 | 22.4k | const int axis2_limit = direction ? cols : rows; |
45 | | |
46 | 22.4k | IdentityRowCdf identity_row_cdf = param->identity_row_cdf; |
47 | 22.4k | int prev_identity_row_flag = 0; |
48 | 488k | for (int ax2 = 0; ax2 < axis2_limit; ax2++) { |
49 | 465k | const int ctx = ax2 == 0 ? 3 : prev_identity_row_flag; |
50 | 465k | int identity_row_flag = |
51 | 465k | avm_read_symbol(r, identity_row_cdf[ctx], 3, ACCT_INFO()); |
52 | | |
53 | | // Copying previous line cannot be done on the first line of a block. |
54 | 465k | if (identity_row_flag == 2 && ax2 == 0) { |
55 | 5 | return 0; |
56 | 5 | } |
57 | | |
58 | 13.0M | for (int ax1 = 0; ax1 < axis1_limit; ax1++) { |
59 | 12.5M | const int y = direction ? ax1 : ax2; |
60 | 12.5M | const int x = direction ? ax2 : ax1; |
61 | 12.5M | if (identity_row_flag == 2) { |
62 | 8.98M | if (direction) { |
63 | | // Vertical |
64 | 1.67M | color_map[y * plane_block_width + x] = |
65 | 1.67M | color_map[y * plane_block_width + (x - 1)]; |
66 | 7.31M | } else { |
67 | | // horizontal |
68 | 7.31M | color_map[y * plane_block_width + x] = |
69 | 7.31M | color_map[(y - 1) * plane_block_width + x]; |
70 | 7.31M | } |
71 | 8.98M | } else if (identity_row_flag == 1 && ax1 > 0) { |
72 | 722k | if (direction) { |
73 | | // Vertical |
74 | 150k | color_map[y * plane_block_width + x] = |
75 | 150k | color_map[(y - 1) * plane_block_width + x]; |
76 | 571k | } else { |
77 | | // horizontal |
78 | 571k | color_map[y * plane_block_width + x] = |
79 | 571k | color_map[y * plane_block_width + x - 1]; |
80 | 571k | } |
81 | 2.84M | } else if (ax2 == 0 && ax1 == 0) { |
82 | 22.4k | color_map[0] = av2_read_uniform(r, num_colors); |
83 | 2.81M | } else { |
84 | 2.81M | const int color_ctx = av2_get_palette_color_index_context( |
85 | 2.81M | color_map, plane_block_width, y, x, color_order, NULL); |
86 | 2.81M | const int color_idx = avm_read_symbol( |
87 | 2.81M | r, color_map_cdf[num_colors - PALETTE_MIN_SIZE][color_ctx], |
88 | 2.81M | num_colors, ACCT_INFO()); |
89 | 2.81M | assert(color_idx >= 0 && color_idx < num_colors); |
90 | 2.81M | color_map[y * plane_block_width + x] = color_order[color_idx]; |
91 | | // color_map[ax2 * stride + ax1] = color_order[color_idx]; |
92 | 2.81M | } |
93 | 12.5M | } |
94 | 465k | prev_identity_row_flag = identity_row_flag; |
95 | 465k | } |
96 | | // Copy last column to extra columns. |
97 | 22.4k | if (cols < plane_block_width) { |
98 | 2.94k | for (int i = 0; i < rows; ++i) { |
99 | 2.89k | memset(color_map + i * plane_block_width + cols, |
100 | 2.89k | color_map[i * plane_block_width + cols - 1], |
101 | 2.89k | (plane_block_width - cols)); |
102 | 2.89k | } |
103 | 51 | } |
104 | | // Copy last row to extra rows. |
105 | 23.6k | for (int i = rows; i < plane_block_height; ++i) { |
106 | 1.22k | memcpy(color_map + i * plane_block_width, |
107 | 1.22k | color_map + (rows - 1) * plane_block_width, plane_block_width); |
108 | 1.22k | } |
109 | 22.4k | return 1; |
110 | 22.4k | } |
111 | | |
112 | | void av2_decode_palette_tokens(MACROBLOCKD *const xd, int plane, |
113 | 22.4k | avm_reader *r) { |
114 | 22.4k | assert(plane == 0 || plane == 1); |
115 | 22.4k | Av2ColorMapParam params; |
116 | 22.4k | params.color_map = |
117 | 22.4k | xd->plane[plane].color_index_map + xd->color_index_map_offset[plane]; |
118 | 22.4k | params.map_cdf = xd->tile_ctx->palette_y_color_index_cdf; |
119 | 22.4k | params.identity_row_cdf = plane ? xd->tile_ctx->identity_row_cdf_uv |
120 | 22.4k | : xd->tile_ctx->identity_row_cdf_y; |
121 | 22.4k | const MB_MODE_INFO *const mbmi = xd->mi[0]; |
122 | 22.4k | params.n_colors = mbmi->palette_mode_info.palette_size[plane]; |
123 | 22.4k | av2_get_block_dimensions(mbmi->sb_type[plane > 0], plane, xd, |
124 | 22.4k | ¶ms.plane_width, ¶ms.plane_height, |
125 | 22.4k | ¶ms.rows, ¶ms.cols); |
126 | 22.4k | if (!decode_color_map_tokens(¶ms, r)) { |
127 | 5 | avm_internal_error(xd->error_info, AVM_CODEC_ERROR, |
128 | 5 | "Error decoding palette tokens"); |
129 | 5 | } |
130 | 22.4k | } |