3030#include < initializer_list> // for initializer_list
3131#include < iterator> // for advance, next
3232#include < memory> // for unique_ptr, make_unique
33+ #include < optional> // for optional
3334#include < tuple> // for tie
3435#include < utility> // for pair
3536#include < vector> // for vector, vector<>::co...
3637
3738namespace rawspeed {
3839
3940template <typename CodeTag>
40- class PrefixCodeTreeDecoder final : public AbstractPrefixCodeDecoder<CodeTag> {
41+ class PrefixCodeTreeDecoder : public AbstractPrefixCodeDecoder <CodeTag> {
4142public:
4243 using Tag = CodeTag;
4344 using Base = AbstractPrefixCodeDecoder<CodeTag>;
@@ -48,29 +49,23 @@ class PrefixCodeTreeDecoder final : public AbstractPrefixCodeDecoder<CodeTag> {
4849private:
4950 BinaryPrefixTree<CodeTag> tree;
5051
52+ protected:
5153 template <typename BIT_STREAM>
52- inline std::pair<typename Base::CodeSymbol,
53- typename Traits::CodeValueTy /* codeValue*/ >
54- readSymbol (BIT_STREAM& bs) const {
55- static_assert (
56- BitStreamTraits<typename BIT_STREAM::tag>::canUseWithPrefixCodeDecoder,
57- " This BitStream specialization is not marked as usable here" );
54+ inline std::pair<typename Base::CodeSymbol, int /* codeValue*/ >
55+ finishReadingPartialSymbol (BIT_STREAM& bs,
56+ typename Base::CodeSymbol initialPartial) const {
5857 typename Base::CodeSymbol partial;
58+ partial.code = 0 ;
59+ partial.code_len = 0 ;
5960
6061 const auto * top = &(tree.root ->getAsBranch ());
6162
62- // Read bits until either find the code or detect the incorrect code
63- for (partial.code = 0 , partial.code_len = 1 ;; ++partial.code_len ) {
64- invariant (partial.code_len <= Traits::MaxCodeLenghtBits);
65-
66- // Read one more bit
67- const bool bit = bs.getBitsNoFill (1 );
68-
69- // codechecker_false_positive [core.uninitialized.Assign]
63+ auto walkBinaryTree = [&partial, &top](bool bit)
64+ -> std::optional<
65+ std::pair<typename Base::CodeSymbol, int /* codeValue*/ >> {
7066 partial.code <<= 1 ;
7167 partial.code |= bit;
72-
73- // What is the last bit, which we have just read?
68+ partial.code_len ++;
7469
7570 // NOTE: The order *IS* important! Left to right, zero to one!
7671 const auto & newNode = top->buds [bit];
@@ -84,17 +79,50 @@ class PrefixCodeTreeDecoder final : public AbstractPrefixCodeDecoder<CodeTag> {
8479 if (static_cast <typename decltype (tree)::Node::Type>(*newNode) ==
8580 decltype (tree)::Node::Type::Leaf) {
8681 // Ok, great, hit a Leaf. This is it.
87- return {partial, newNode->getAsLeaf ().value };
82+ return {{ partial, newNode->getAsLeaf ().value } };
8883 }
8984
9085 // Else, this is a branch, continue looking.
9186 top = &(newNode->getAsBranch ());
87+ return std::nullopt ;
88+ };
89+
90+ // First, translate pre-existing code bits.
91+ for (unsigned bit : initialPartial.getBitsMSB ()) {
92+ if (auto sym = walkBinaryTree (bit))
93+ return *sym;
94+ }
95+
96+ // Read bits until either find the code or detect the incorrect code
97+ while (true ) {
98+ invariant (partial.code_len <= Traits::MaxCodeLenghtBits);
99+
100+ // Read one more bit
101+ const bool bit = bs.getBitsNoFill (1 );
102+
103+ if (auto sym = walkBinaryTree (bit))
104+ return *sym;
92105 }
93106
94107 // We have either returned the found symbol, or thrown on incorrect symbol.
95108 __builtin_unreachable ();
96109 }
97110
111+ template <typename BIT_STREAM>
112+ inline std::pair<typename Base::CodeSymbol, int /* codeValue*/ >
113+ readSymbol (BIT_STREAM& bs) const {
114+ static_assert (
115+ BitStreamTraits<typename BIT_STREAM::tag>::canUseWithPrefixCodeDecoder,
116+ " This BitStream specialization is not marked as usable here" );
117+
118+ // Start from completely unknown symbol.
119+ typename Base::CodeSymbol partial;
120+ partial.code_len = 0 ;
121+ partial.code = 0 ;
122+
123+ return finishReadingPartialSymbol (bs, partial);
124+ }
125+
98126public:
99127 void setup (bool fullDecode_, bool fixDNGBug16_) {
100128 AbstractPrefixCodeDecoder<CodeTag>::setup (fullDecode_, fixDNGBug16_);
0 commit comments