RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
Cr2Decompressor.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2017 Axel Waggershauser
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/Invariant.h"
26#include "adt/Point.h"
27#include "adt/iterator_range.h"
29#include "common/RawImage.h"
31#include "io/ByteStream.h"
32#include <array>
33#include <cstddef>
34#include <cstdint>
35#include <functional>
36#include <iterator>
37#include <tuple>
38#include <utility>
39#include <vector>
40
41namespace rawspeed {
42
43class ByteStream;
44class RawImage;
46struct Cr2SliceIterator;
49
50class Cr2SliceWidths final {
51 int numSlices = 0;
52 int sliceWidth = 0;
54
55 friend class Cr2LJpegDecoder;
56 friend struct Cr2SliceWidthIterator;
57
58 template <typename PrefixCodeDecoder> friend class Cr2Decompressor;
59
60public:
61 Cr2SliceWidths() = default;
62
63 Cr2SliceWidths(uint16_t numSlices_, uint16_t sliceWidth_,
64 uint16_t lastSliceWidth_)
65 : numSlices(numSlices_), sliceWidth(sliceWidth_),
66 lastSliceWidth(lastSliceWidth_) {
67 if (numSlices < 1)
68 ThrowRDE("Bad slice count: %d", numSlices);
69 }
70
71 [[nodiscard]] bool empty() const {
72 return 0 == numSlices && 0 == sliceWidth && 0 == lastSliceWidth;
73 }
74
75 [[nodiscard]] int widthOfSlice(int sliceId) const {
76 invariant(sliceId >= 0 && sliceId < numSlices);
77 if ((sliceId + 1) == numSlices)
78 return lastSliceWidth;
79 return sliceWidth;
80 }
81
82 [[nodiscard]] Cr2SliceWidthIterator begin() const;
83 [[nodiscard]] Cr2SliceWidthIterator end() const;
84};
85
88
90
91 using iterator_category = std::input_iterator_tag;
92 using difference_type = std::ptrdiff_t;
93 using value_type = int;
94 using pointer = const value_type*; // Unusable, but must be here.
95 using reference = const value_type&; // Unusable, but must be here.
96
97 Cr2SliceWidthIterator(const Cr2SliceWidths& slicing_, int sliceId_)
98 : slicing(slicing_), sliceId(sliceId_) {
99 invariant(sliceId >= 0 && sliceId <= slicing.numSlices &&
100 "Iterator overflow");
101 }
102
104 invariant(sliceId >= 0 && sliceId < slicing.numSlices &&
105 "Iterator overflow");
106 return slicing.widthOfSlice(sliceId);
107 }
109 ++sliceId;
110 return *this;
111 }
112 friend bool operator==(const Cr2SliceWidthIterator& a,
113 const Cr2SliceWidthIterator& b) {
114 invariant(&a.slicing == &b.slicing && "Comparing unrelated iterators.");
115 return a.sliceId == b.sliceId;
116 }
117};
118
120 return {*this, 0};
121}
123 return {*this, numSlices};
124}
125
126template <typename PrefixCodeDecoder> class Cr2Decompressor final {
127public:
132
133private:
135 const std::tuple<int /*N_COMP*/, int /*X_S_F*/, int /*Y_S_F*/> format;
139
140 const std::vector<PerComponentRecipe> rec;
141
143
144 template <int N_COMP, size_t... I>
145 [[nodiscard]] std::array<std::reference_wrapper<const PrefixCodeDecoder>,
146 N_COMP>
147 getPrefixCodeDecodersImpl(std::index_sequence<I...> /*unused*/) const;
148
149 template <int N_COMP>
150 [[nodiscard]] std::array<std::reference_wrapper<const PrefixCodeDecoder>,
151 N_COMP>
152 getPrefixCodeDecoders() const;
153
154 template <int N_COMP>
155 [[nodiscard]] std::array<uint16_t, N_COMP> getInitialPreds() const;
156
157 template <int N_COMP, int X_S_F, int Y_S_F>
158 [[nodiscard]] __attribute__((noinline)) ByteStream::size_type
159 decompressN_X_Y() const;
160
166
167public:
170 std::tuple<int /*N_COMP*/, int /*X_S_F*/, int /*Y_S_F*/> format,
172 std::vector<PerComponentRecipe> rec, Array1DRef<const uint8_t> input);
173
174 [[nodiscard]] ByteStream::size_type decompress() const;
175};
176
177extern template class Cr2Decompressor<PrefixCodeDecoder<>>;
178
179} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
#define ThrowRDE(...)
uint32_t size_type
Definition Buffer.h:49
const std::tuple< int, int, int > format
iterator_range< Cr2VerticalOutputStripIterator > getVerticalOutputStrips() const
std::array< std::reference_wrapper< const PrefixCodeDecoder >, N_COMP > getPrefixCodeDecoders() const
ByteStream::size_type decompress() const
const std::vector< PerComponentRecipe > rec
const Array1DRef< const uint8_t > input
Cr2Decompressor(RawImage mRaw, std::tuple< int, int, int > format, iPoint2D frame, Cr2SliceWidths slicing, std::vector< PerComponentRecipe > rec, Array1DRef< const uint8_t > input)
std::array< uint16_t, N_COMP > getInitialPreds() const
iterator_range< Cr2OutputTileIterator > getOutputTiles() const
std::array< std::reference_wrapper< const PrefixCodeDecoder >, N_COMP > getPrefixCodeDecodersImpl(std::index_sequence< I... >) const
iterator_range< Cr2OutputTileIterator > getAllOutputTiles() const
__attribute__((noinline)) ByteStream iterator_range< Cr2SliceIterator > getSlices() const
Cr2SliceWidths(uint16_t numSlices_, uint16_t sliceWidth_, uint16_t lastSliceWidth_)
int widthOfSlice(int sliceId) const
friend struct Cr2SliceWidthIterator
Cr2SliceWidthIterator end() const
Cr2SliceWidthIterator begin() const
PrefixCodeLUTDecoder< CodeTag, PrefixCodeLookupDecoder< CodeTag > > PrefixCodeDecoder
__attribute__((noinline)) __attribute__((visibility("default"))) JPEGStuffedByteStreamGenerator
friend bool operator==(const Cr2SliceWidthIterator &a, const Cr2SliceWidthIterator &b)
Cr2SliceWidthIterator & operator++()
std::input_iterator_tag iterator_category
const Cr2SliceWidths & slicing
Cr2SliceWidthIterator(const Cr2SliceWidths &slicing_, int sliceId_)