RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
VC5Decompressor.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2018 Stefan Löffler
5 Copyright (C) 2018 Roman Lebedev
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#pragma once
23
24#include "adt/Array1DRef.h"
25#include "adt/Array2DRef.h"
27#include "adt/Optional.h"
32#include "common/BayerPhase.h"
33#include "common/RawImage.h"
34#include "common/SimpleLUT.h"
36#include "io/ByteStream.h"
37#include <array>
38#include <cstdint>
39#include <memory>
40#include <type_traits>
41#include <utility>
42#include <vector>
43
44namespace rawspeed {
45class ErrorLog;
46
47const int MAX_NUM_PRESCALE = 8;
48
49// Decompresses VC-5 as used by GoPro
50
51enum class VC5Tag : int16_t {
52 NoTag = 0x0, // synthetic, not an actual tag
53
54 ChannelCount = 0x000c,
55 ImageWidth = 0x0014,
56 ImageHeight = 0x0015,
58 SubbandCount = 0x000E,
59 SubbandNumber = 0x0030,
60 Quantization = 0x0035,
61 ChannelNumber = 0x003e,
62 ImageFormat = 0x0054,
64 PatternWidth = 0x006a,
65 PatternHeight = 0x006b,
67 PrescaleShift = 0x006d,
68
69 LARGE_CHUNK = 0x2000,
70 SMALL_CHUNK = 0x4000,
73
74 Optional = int16_t(0x8000U), // only signbit set
75};
76inline VC5Tag operator&(VC5Tag LHS, VC5Tag RHS) {
77 using value_type = std::underlying_type_t<VC5Tag>;
78 return static_cast<VC5Tag>(static_cast<value_type>(LHS) &
79 static_cast<value_type>(RHS));
80}
81inline bool matches(VC5Tag LHS, VC5Tag RHS) {
82 // Are there any common bit set?
83 return (LHS & RHS) != VC5Tag::NoTag;
84}
85inline bool is(VC5Tag LHS, VC5Tag RHS) {
86 // Does LHS have all the RHS bits set?
87 return (LHS & RHS) == RHS;
88}
89inline VC5Tag operator-(VC5Tag tag) {
90 using value_type = std::underlying_type_t<VC5Tag>;
91 // Negate
92 return static_cast<VC5Tag>(-static_cast<value_type>(tag));
93}
94
98
100
101 static constexpr auto VC5_LOG_TABLE_BITWIDTH = 12;
104
107
109
111
112 void initVC5LogTable();
113
114 static constexpr int numWaveletLevels = 3;
115 static constexpr int numHighPassBands = 3;
116 static constexpr int numLowPassBands = 1;
117 static constexpr int numSubbands =
119
120 struct {
121 uint16_t iChannel = 0; // 0'th channel is the default
125
129 const uint16_t cps = 1;
131
132 struct BandData final {
133 std::vector<int16_t, DefaultInitAllocatorAdaptor<int16_t>> storage;
135
136 BandData(int width, int height)
137 : description(Array2DRef<int16_t>::create(storage, width, height)) {}
138 };
139
140 class Wavelet final {
141 public:
142 int width;
145
149 virtual void anchor() const;
150 explicit AbstractBand(Wavelet& wavelet_) : wavelet(wavelet_) {}
151 virtual ~AbstractBand() = default;
152 virtual void createDecodingTasks(ErrorLog& errLog,
153 bool& exceptionThrown) noexcept = 0;
154 };
158 struct {
162 explicit ReconstructableBand(Wavelet& wavelet_, bool clampUint_ = false,
163 bool finalWavelet_ = false)
164 : AbstractBand(wavelet_), clampUint(clampUint_),
165 finalWavelet(finalWavelet_) {}
166 void
167 createLowpassReconstructionTask(const bool& exceptionThrown) noexcept;
168 void
169 createHighpassReconstructionTask(const bool& exceptionThrown) noexcept;
170 void createLowHighPassCombiningTask(const bool& exceptionThrown) noexcept;
171 void createDecodingTasks(ErrorLog& errLog,
172 bool& exceptionThrown) noexcept override;
173 };
176 explicit AbstractDecodeableBand(Wavelet& wavelet_,
178 : AbstractBand(wavelet_), input(input_) {}
179 [[nodiscard]] virtual BandData decode() const = 0;
180 void createDecodingTasks(ErrorLog& errLog,
181 bool& exceptionThrown) noexcept final;
182 };
185 LowPassBand(Wavelet& wavelet_, ByteStream bs, uint16_t lowpassPrecision_);
186 [[nodiscard]] BandData decode() const noexcept override;
187 };
192 const Optional<PrefixCodeDecoder>& decoder_, int16_t quant_)
193 : AbstractDecodeableBand(wavelet_, input_), decoder(decoder_),
194 quant(quant_) {}
195 [[nodiscard]] BandData decode() const override;
196 };
197
199 std::vector<std::unique_ptr<AbstractBand>> bands;
200
201 void setBandValid(int band);
202 [[nodiscard]] bool isBandValid(int band) const;
203 [[nodiscard]] uint32_t getValidBandMask() const { return mDecodedBandMask; }
204 [[nodiscard]] bool allBandsValid() const;
205
207 Array2DRef<const int16_t> low) noexcept;
208
211 int descaleShift,
212 bool clampUint /*= false*/,
213 bool finalWavelet /*= false*/) noexcept;
214
216 };
217
218 struct Channel final {
219 std::array<Wavelet, numWaveletLevels + 1> wavelets;
220 };
221
222 static constexpr int numChannels = 4;
223 static constexpr int numSubbandsTotal = numSubbands * numChannels;
225 std::array<Channel, numChannels> channels;
226
227 static inline std::pair<int16_t /*value*/, unsigned int /*count*/>
228 getRLV(const PrefixCodeDecoder& decoder, BitStreamerMSB& bits);
229
231
232 template <BayerPhase p> void combineFinalLowpassBandsImpl() const noexcept;
233
234 void combineFinalLowpassBands() const noexcept;
235
236 void createWaveletBandDecodingTasks(bool& exceptionThrown) const noexcept;
237
238 void decodeThread(bool& exceptionThrown) const noexcept;
239
240 void parseVC5();
241
242public:
243 VC5Decompressor(ByteStream bs, const RawImage& img);
244
245 void decode(unsigned int offsetX, unsigned int offsetY, unsigned int width,
246 unsigned int height);
247};
248
249} // namespace rawspeed
std::vector< std::unique_ptr< AbstractBand > > bands
static BandData combineLowHighPass(Array2DRef< const int16_t > low, Array2DRef< const int16_t > high, int descaleShift, bool clampUint, bool finalWavelet) noexcept
static constexpr uint16_t maxBands
static BandData reconstructPass(Array2DRef< const int16_t > high, Array2DRef< const int16_t > low) noexcept
std::array< Channel, numChannels > channels
void combineFinalLowpassBandsImpl() const noexcept
static constexpr int numHighPassBands
SimpleLUT< unsigned, VC5_LOG_TABLE_BITWIDTH > mVC5LogTable
static constexpr int numLowPassBandsTotal
static constexpr auto VC5_LOG_TABLE_BITWIDTH
Optional< uint16_t > iSubband
static constexpr int numSubbandsTotal
static std::pair< int16_t, unsigned int > getRLV(const PrefixCodeDecoder &decoder, BitStreamerMSB &bits)
PrefixCodeLUTDecoder< VC5CodeTag, PrefixCodeVectorDecoder< VC5CodeTag > > PrefixCodeDecoder
void decodeThread(bool &exceptionThrown) const noexcept
static constexpr int numChannels
static constexpr int numLowPassBands
Optional< PrefixCodeDecoder > codeDecoder
Optional< int16_t > quantization
void parseLargeCodeblock(ByteStream bs)
struct rawspeed::VC5Decompressor::@172102134063262333165153326146073302307047041007 mVC5
void createWaveletBandDecodingTasks(bool &exceptionThrown) const noexcept
Optional< uint16_t > lowpassPrecision
static constexpr int numWaveletLevels
void decode(unsigned int offsetX, unsigned int offsetY, unsigned int width, unsigned int height)
VC5Decompressor(ByteStream bs, const RawImage &img)
void combineFinalLowpassBands() const noexcept
static constexpr int numSubbands
bool matches(VC5Tag LHS, VC5Tag RHS)
VC5Tag operator&(VC5Tag LHS, VC5Tag RHS)
bool is(VC5Tag LHS, VC5Tag RHS)
const int MAX_NUM_PRESCALE
VC5Tag operator-(VC5Tag tag)
std::vector< int16_t, DefaultInitAllocatorAdaptor< int16_t > > storage
std::array< Wavelet, numWaveletLevels+1 > wavelets
virtual void createDecodingTasks(ErrorLog &errLog, bool &exceptionThrown) noexcept=0
AbstractDecodeableBand(Wavelet &wavelet_, Array1DRef< const uint8_t > input_)
void createDecodingTasks(ErrorLog &errLog, bool &exceptionThrown) noexcept final
HighPassBand(Wavelet &wavelet_, Array1DRef< const uint8_t > input_, const Optional< PrefixCodeDecoder > &decoder_, int16_t quant_)
const Optional< PrefixCodeDecoder > & decoder
BandData decode() const noexcept override
LowPassBand(Wavelet &wavelet_, ByteStream bs, uint16_t lowpassPrecision_)
void createHighpassReconstructionTask(const bool &exceptionThrown) noexcept
void createLowHighPassCombiningTask(const bool &exceptionThrown) noexcept
struct rawspeed::VC5Decompressor::Wavelet::ReconstructableBand::@202240301251226100165006340307035260152240136207 intermediates
void createDecodingTasks(ErrorLog &errLog, bool &exceptionThrown) noexcept override
void createLowpassReconstructionTask(const bool &exceptionThrown) noexcept
ReconstructableBand(Wavelet &wavelet_, bool clampUint_=false, bool finalWavelet_=false)