RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
PrefixCode.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2017-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
25#include <algorithm>
26#include <cassert>
27#include <functional>
28#include <vector>
29
30namespace rawspeed {
31
32template <typename CodeTag>
33class PrefixCode final : public AbstractPrefixCode<CodeTag> {
34public:
36 using Traits = typename Base::Traits;
37 using CodeSymbol = typename Base::CodeSymbol;
38 using CodeValueTy = typename Traits::CodeValueTy;
39
40 // 1. The number of codes there are per bit length, this is index 1 based.
41 // (there are always 0 codes of length 0)
42 //
43 // WARNING: just because two PrefixCode's have matching nCodesPerLength,
44 // does not mean their actual code symbols match!
45 std::vector<unsigned> nCodesPerLength;
46
47 // The codes themselves.
48 std::vector<CodeSymbol> symbols;
49
50 PrefixCode(std::vector<CodeSymbol> symbols_,
51 std::vector<CodeValueTy> codeValues_)
52 : Base(std::move(codeValues_)), symbols(std::move(symbols_)) {
53 if (symbols.empty() || Base::codeValues.empty() ||
54 symbols.size() != Base::codeValues.size())
55 ThrowRDE("Malformed code");
56
57 nCodesPerLength.resize(1 + Traits::MaxCodeLenghtBits);
58 for (const CodeSymbol& s : symbols) {
59 assert(s.code_len > 0 && s.code_len <= Traits::MaxCodeLenghtBits);
60 ++nCodesPerLength[s.code_len];
61 }
62 while (nCodesPerLength.back() == 0)
63 nCodesPerLength.pop_back();
64 assert(nCodesPerLength.size() > 1);
65
67 }
68
69private:
71 // We are at the Root node, len is 1, there are two possible child Nodes
72 unsigned maxCodes = 2;
73 for (auto codeLen = 1UL; codeLen < nCodesPerLength.size(); codeLen++) {
74 // we have codeLen bits. make sure that that code count can actually fit
75 // E.g. for len 1 we could have two codes: 0b0 and 0b1
76 // (but in that case there can be no other codes (with higher lengths))
77 const unsigned nCodes = nCodesPerLength[codeLen];
78 if (nCodes > maxCodes)
79 ThrowRDE("Too many codes of of length %lu.", codeLen);
80 // There are nCodes leafs on this level, and those can not be branches
81 maxCodes -= nCodes;
82 // On the next level, rest can be branches, and can have two child Nodes
83 maxCodes *= 2;
84 }
85
86 // The code symbols are ordered so that the code lengths are not decreasing.
87 // NOTE: codes of same lenght are not nessesairly sorted!
88 if (std::adjacent_find(
89 symbols.cbegin(), symbols.cend(),
90 [](const CodeSymbol& lhs, const CodeSymbol& rhs) -> bool {
91 return !std::less_equal<>()(lhs.code_len, rhs.code_len);
92 }) != symbols.cend())
93 ThrowRDE("Code symbols are not globally ordered");
94
95 // No two symbols should have the same prefix (high bits)
96 // Only analyze the lower triangular matrix, excluding diagonal
97 for (auto sId = 0UL; sId < symbols.size(); sId++) {
98 for (auto pId = 0UL; pId < sId; pId++)
99 if (CodeSymbol::HaveCommonPrefix(symbols[sId], symbols[pId]))
100 ThrowRDE("Not prefix codes!");
101 }
102 }
103};
104
105} // namespace rawspeed
#define s
#define ThrowRDE(...)
assert(dim.area() >=area)
std::vector< CodeValueTy > codeValues
PrefixCode(std::vector< CodeSymbol > symbols_, std::vector< CodeValueTy > codeValues_)
Definition PrefixCode.h:50
typename Base::Traits Traits
Definition PrefixCode.h:36
AbstractPrefixCode< CodeTag > Base
Definition PrefixCode.h:35
std::vector< CodeSymbol > symbols
Definition PrefixCode.h:48
typename Traits::CodeValueTy CodeValueTy
Definition PrefixCode.h:38
typename Base::CodeSymbol CodeSymbol
Definition PrefixCode.h:37
std::vector< unsigned > nCodesPerLength
Definition PrefixCode.h:45