Coverage Report

Created: 2026-10-28 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
                           &params.plane_width, &params.plane_height,
125
22.4k
                           &params.rows, &params.cols);
126
22.4k
  if (!decode_color_map_tokens(&params, r)) {
127
5
    avm_internal_error(xd->error_info, AVM_CODEC_ERROR,
128
5
                       "Error decoding palette tokens");
129
5
  }
130
22.4k
}