RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
AbstractPrefixCode.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2023 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#pragma once
22
23#include "rawspeedconfig.h"
24#include "adt/BitIterator.h"
25#include "adt/iterator_range.h"
27#include <cassert>
28#include <cstdint>
29#include <type_traits>
30#include <vector>
31
32namespace rawspeed {
33
34template <typename CodeTag> struct CodeTraits final {
35 // using CodeTy = uint<???>_t;
36 // static constexpr int MaxCodeLenghtBits = <???>;
37 // static constexpr int MaxNumCodeValues = <???>;
38
39 // using CodeValueTy = uint<???>_t;
40 // static constexpr int MaxCodeValueLenghtBits = <???>;
41 // static constexpr CodeValueTy MaxCodeValue = <???>;
42
43 // static constexpr int MaxDiffLengthBits = <???>;
44 // static constexpr CodeValueTy MaxDiffLength = <???>;
45
46 // static constexpr bool SupportsFullDecode = <???>;
47};
48
49struct BaselineCodeTag;
50
51template <> struct CodeTraits<BaselineCodeTag> final {
53 static constexpr int MaxCodeLenghtBits = 16;
54 static constexpr int MaxNumCodeValues = 162;
55
56 using CodeValueTy = uint8_t;
57 static constexpr int MaxCodeValueLenghtBits = 8;
58 static constexpr CodeValueTy MaxCodeValue = 255;
59
60 static constexpr int MaxDiffLengthBits = 5;
61 static constexpr CodeValueTy MaxDiffLength = 16;
62
63 static constexpr bool SupportsFullDecode = true;
64};
65
66struct VC5CodeTag;
67
68template <> struct CodeTraits<VC5CodeTag> final {
70 static constexpr int MaxCodeLenghtBits = 26;
71 static constexpr int MaxNumCodeValues = 264;
72
74 static constexpr int MaxCodeValueLenghtBits = 19;
75 static constexpr CodeValueTy MaxCodeValue = 524287;
76
77 static constexpr int MaxDiffLengthBits = -1; // unused
78 static constexpr CodeValueTy MaxDiffLength = -1; // unused
79
80 static constexpr bool SupportsFullDecode = false;
81};
82
83template <typename CodeTag> struct CodeTraitsValidator final {
85
86 static_assert(std::is_integral_v<typename Traits::CodeTy>);
87 static_assert(std::is_unsigned_v<typename Traits::CodeTy>);
88 static_assert(std::is_same_v<typename Traits::CodeTy, uint16_t> ||
89 std::is_same_v<typename Traits::CodeTy, uint32_t>);
90
91 static_assert(Traits::MaxCodeLenghtBits > 0 &&
92 Traits::MaxCodeLenghtBits <=
94 static_assert(Traits::MaxCodeLenghtBits == 16 ||
95 Traits::MaxCodeLenghtBits == 26);
96
97 static_assert(Traits::MaxNumCodeValues > 0 &&
98 Traits::MaxNumCodeValues <=
99 ((1ULL << Traits::MaxCodeLenghtBits) - 1ULL));
100 static_assert(Traits::MaxNumCodeValues == 162 ||
101 Traits::MaxNumCodeValues == 264);
102
103 static_assert(std::is_integral_v<typename Traits::CodeValueTy>);
104 static_assert(std::is_unsigned_v<typename Traits::CodeValueTy>);
105 static_assert(std::is_same_v<typename Traits::CodeValueTy, uint8_t> ||
106 std::is_same_v<typename Traits::CodeValueTy, uint32_t>);
107
108 static_assert(Traits::MaxCodeValueLenghtBits > 0 &&
109 Traits::MaxCodeValueLenghtBits <=
111 static_assert(Traits::MaxCodeValueLenghtBits == 8 ||
112 Traits::MaxCodeValueLenghtBits == 19);
113
114 static_assert(Traits::MaxCodeValue > 0 &&
115 Traits::MaxCodeValue <=
116 ((1ULL << Traits::MaxCodeValueLenghtBits) - 1ULL));
117 static_assert(Traits::MaxCodeValue == 255 || Traits::MaxCodeValue == 524287);
118
119 static_assert(
120 std::is_same_v<decltype(Traits::SupportsFullDecode), const bool>);
121
122 static_assert(!Traits::SupportsFullDecode ||
123 (Traits::MaxDiffLengthBits > 0 &&
124 Traits::MaxDiffLengthBits <=
126 static_assert(!Traits::SupportsFullDecode ||
127 (Traits::MaxDiffLengthBits == 5));
128
129 static_assert(!Traits::SupportsFullDecode ||
130 (Traits::MaxDiffLength > 0 &&
131 Traits::MaxDiffLength <=
132 ((1ULL << Traits::MaxDiffLengthBits) - 1ULL)));
133 static_assert(!Traits::SupportsFullDecode || (Traits::MaxDiffLength == 16));
134
135 static constexpr bool validate() { return true; }
136};
137
138template <typename CodeTag> class AbstractPrefixCode {
139public:
141 using CodeValueTy = typename Traits::CodeValueTy;
143
144 struct CodeSymbol final {
145 typename Traits::CodeTy code; // the code (bit pattern)
146 uint8_t code_len; // the code length in bits
147
148 CodeSymbol() = default;
149
150 CodeSymbol(typename Traits::CodeTy code_, uint8_t code_len_)
151 : code(code_), code_len(code_len_) {
152 assert(code_len > 0);
153 assert(code_len <= Traits::MaxCodeLenghtBits);
154 assert(code <= ((1U << code_len) - 1U));
155 }
156
158 getBitsMSB() const {
159 return {{code, code_len - 1}, {code, -1}};
160 }
161
162 static bool HaveCommonPrefix(const CodeSymbol& symbol,
163 const CodeSymbol& partial) {
164 assert(partial.code_len <= symbol.code_len);
165
166 const auto s0 = extractHighBits(symbol.code, partial.code_len,
167 /*effectiveBitwidth=*/symbol.code_len);
168 const auto s1 = partial.code;
169
170 return s0 == s1;
171 }
172
173 bool RAWSPEED_READONLY operator==(const CodeSymbol& other) const {
174 return code == other.code && code_len == other.code_len;
175 }
176 };
177
179
180 explicit AbstractPrefixCode(std::vector<CodeValueTy> codeValues_)
181 : codeValues(std::move(codeValues_)) {
182 if (codeValues.empty())
183 ThrowRDE("Empty code alphabet?");
184 assert(
185 all_of(codeValues.begin(), codeValues.end(),
186 [](const CodeValueTy& v) { return v <= Traits::MaxCodeValue; }));
187 }
188
189 // The target alphabet, the values to which the (prefix) codes map, in order.
190 std::vector<CodeValueTy> codeValues;
191};
192
193} // namespace rawspeed
#define ThrowRDE(...)
assert(dim.area() >=area)
typename Traits::CodeValueTy CodeValueTy
AbstractPrefixCode(std::vector< CodeValueTy > codeValues_)
std::vector< CodeValueTy > codeValues
constexpr unsigned RAWSPEED_READNONE bitwidth(T unused={})
Definition Bit.h:43
constexpr RAWSPEED_READNONE T extractHighBits(T value, unsigned nBits, unsigned effectiveBitwidth=bitwidth< T >())
Definition Bit.h:120
iterator_range< BitMSBIterator< typename Traits::CodeTy > > getBitsMSB() const
static bool HaveCommonPrefix(const CodeSymbol &symbol, const CodeSymbol &partial)
bool RAWSPEED_READONLY operator==(const CodeSymbol &other) const
CodeSymbol(typename Traits::CodeTy code_, uint8_t code_len_)
static constexpr CodeValueTy MaxDiffLength
static constexpr CodeValueTy MaxCodeValue
static constexpr int MaxCodeValueLenghtBits
static constexpr CodeValueTy MaxCodeValue
static constexpr CodeValueTy MaxDiffLength
static constexpr bool validate()