RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
PrefixCodeVectorEncoder.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2024 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 "adt/Invariant.h"
26
27namespace rawspeed {
28
29template <typename CodeTag>
31public:
32 using Tag = CodeTag;
34 using Traits = typename Base::Traits;
35
36 using Base::Base;
37
38private:
39 template <typename BIT_VACUUMER>
40 void encodeCodeValueImpl(BIT_VACUUMER& bv, int codeIndex) const {
41 static_assert(
43 "This BitVacuumer specialization is not marked as usable here");
44 invariant(codeIndex >= 0);
45 const auto numCodeSymbols = implicit_cast<int>(Base::code.symbols.size());
46 invariant(codeIndex < numCodeSymbols);
47 const typename Base::CodeSymbol& symbol = Base::code.symbols[codeIndex];
48 bv.put(symbol.code, symbol.code_len);
49 }
50
51 [[nodiscard]] int
52 getCodeIndexOfCodeValue(const typename Traits::CodeValueTy value) const {
53 for (int codeIndex = 0;
54 codeIndex != implicit_cast<int>(Base::code.codeValues.size());
55 ++codeIndex) {
56 const auto& codeValue = Base::code.codeValues[codeIndex];
57 if (codeValue == value)
58 return codeIndex;
59 }
60 __builtin_unreachable();
61 }
62
63public:
64 void setup(bool fullDecode_, bool fixDNGBug16_) {
65 AbstractPrefixCodeEncoder<CodeTag>::setup(fullDecode_, fixDNGBug16_);
66 }
67
68 template <typename BIT_VACUUMER>
69 void encodeCodeValue(BIT_VACUUMER& bv,
70 typename Traits::CodeValueTy codeValue) const {
71 static_assert(
73 "This BitVacuumer specialization is not marked as usable here");
75 int codeIndex = getCodeIndexOfCodeValue(codeValue);
76 encodeCodeValueImpl(bv, codeIndex);
77 }
78
79 template <typename BIT_VACUUMER>
80 void encodeDifference(BIT_VACUUMER& bv, int value) const {
81 static_assert(
83 "This BitVacuumer specialization is not marked as usable here");
85 auto [diff, diffLen] = Base::reduce(value);
86 int codeIndex = getCodeIndexOfCodeValue(diffLen);
87 encodeCodeValueImpl(bv, codeIndex);
88 if (diffLen != 16 || Base::handleDNGBug16())
89 bv.put(diff, diffLen);
90 }
91
92 template <typename BIT_VACUUMER, bool FULL_DECODE>
93 void encode(BIT_VACUUMER& bv, int value) const {
94 static_assert(
96 "This BitVacuumer specialization is not marked as usable here");
97 invariant(FULL_DECODE == Base::isFullDecode());
98
99 if constexpr (!FULL_DECODE)
101 else
102 encodeDifference(bv, value);
103 }
104};
105
106} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
AbstractPrefixCodeTranscoder< CodeTag > Base
void setup(bool fullDecode_, bool fixDNGBug16_)
static std::pair< uint32_t, uint8_t > RAWSPEED_READNONE reduce(int32_t extendedDiff)
void setup(bool fullDecode_, bool fixDNGBug16_)
void encodeCodeValue(BIT_VACUUMER &bv, typename Traits::CodeValueTy codeValue) const
int getCodeIndexOfCodeValue(const typename Traits::CodeValueTy value) const
AbstractPrefixCodeEncoder< CodeTag > Base
void encodeDifference(BIT_VACUUMER &bv, int value) const
void encode(BIT_VACUUMER &bv, int value) const
void encodeCodeValueImpl(BIT_VACUUMER &bv, int codeIndex) const
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32