Coverage Report

Created: 2026-10-28 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brunsli/c/dec/context_map_decode.cc
Line
Count
Source
1
// Copyright (c) Google LLC 2019
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
#include "./context_map_decode.h"
8
9
#include <brunsli/status.h>
10
#include <brunsli/types.h>
11
12
#include <vector>
13
14
#include "../common/platform.h"
15
#include "./bit_reader.h"
16
#include "./huffman_decode.h"
17
18
namespace brunsli {
19
20
namespace {
21
22
1.15M
void MoveToFront(uint8_t* v, uint8_t index) {
23
1.15M
  uint8_t value = v[index];
24
1.15M
  uint8_t i = index;
25
61.1M
  for (; i; --i) v[i] = v[i - 1];
26
1.15M
  v[0] = value;
27
1.15M
}
28
29
681
void InverseMoveToFrontTransform(uint8_t* v, size_t v_len) {
30
681
  uint8_t mtf[256];
31
175k
  for (size_t i = 0; i < 256; ++i) {
32
174k
    mtf[i] = static_cast<uint8_t>(i);
33
174k
  }
34
1.22M
  for (size_t i = 0; i < v_len; ++i) {
35
1.22M
    uint8_t index = v[i];
36
1.22M
    v[i] = mtf[index];
37
1.22M
    if (index) MoveToFront(mtf, index);
38
1.22M
  }
39
681
}
40
41
}  // namespace
42
43
BrunsliStatus DecodeContextMap(const HuffmanDecodingData& entropy,
44
                               size_t max_run_length_prefix, size_t* index,
45
                               std::vector<uint8_t>* context_map,
46
5.60k
                               BrunsliBitReader* br) {
47
5.60k
  size_t& i = *index;
48
5.60k
  uint8_t* map = context_map->data();
49
5.60k
  const size_t length = context_map->size();
50
1.91M
  while (i < length) {
51
    // Check there is enough deta for Huffman code, RLE and IMTF bit.
52
1.91M
    if (!BrunsliBitReaderCanRead(br, 15 + max_run_length_prefix + 1)) {
53
4.29k
      return BRUNSLI_NOT_ENOUGH_DATA;
54
4.29k
    }
55
1.90M
    uint32_t code = entropy.ReadSymbol(br);
56
1.90M
    if (code == 0) {
57
244k
      map[i] = 0;
58
244k
      ++i;
59
1.66M
    } else if (code <= max_run_length_prefix) {
60
36.8k
      size_t reps = 1u + (1u << code) + (int)BrunsliBitReaderRead(br, code);
61
637k
      while (--reps) {
62
600k
        if (i >= length) return BRUNSLI_INVALID_BRN;
63
600k
        map[i] = 0;
64
600k
        ++i;
65
600k
      }
66
1.62M
    } else {
67
1.62M
      map[i] = (uint8_t)(code - max_run_length_prefix);
68
1.62M
      ++i;
69
1.62M
    }
70
1.90M
  }
71
1.17k
  if (BrunsliBitReaderRead(br, 1)) {
72
681
    InverseMoveToFrontTransform(map, length);
73
681
  }
74
1.17k
  return BrunsliBitReaderIsHealthy(br) ? BRUNSLI_OK : BRUNSLI_INVALID_BRN;
75
5.60k
}
76
77
}  // namespace brunsli