RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
BitStreamerTest.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2018 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#include "adt/Array1DRef.h"
22#include "io/Buffer.h"
23#include "io/ByteStream.h"
24#include "io/Endianness.h"
25#include <array>
26#include <cassert>
27#include <cstdint>
28#include <gtest/gtest.h>
29
34
35namespace rawspeed_test {
36
37// NOLINTNEXTLINE(google-build-namespaces)
38namespace {
39
40template <typename T, typename Tag> struct BitStreamerPatternTest final {};
41
42struct TestGetBitsTag;
43
44template <typename T> struct BitStreamerPatternTest<T, TestGetBitsTag> {
45 using PumpT = typename T::PumpT;
46 using PatternT = typename T::PatternT;
47
48 template <typename L> static void Test(PumpT& pump, L gen) {
49 for (int len = 1; len <= 7; len++)
50 ASSERT_EQ(pump.getBits(len), gen(len)) << " Where len: " << len;
51 }
52};
53
54struct TestGetBitsNoFillTag;
55
56template <typename T> struct BitStreamerPatternTest<T, TestGetBitsNoFillTag> {
57 using PumpT = typename T::PumpT;
58 using PatternT = typename T::PatternT;
59
60 template <typename L> static void Test(PumpT& pump, L gen) {
61 pump.fill(32); // Actually fills 32 bits
62 for (int len = 1; len <= 7; len++)
63 ASSERT_EQ(pump.getBitsNoFill(len), gen(len)) << " Where len: " << len;
64 }
65};
66
67struct TestPeekBitsTag;
68
69template <typename T> struct BitStreamerPatternTest<T, TestPeekBitsTag> {
70 using PumpT = typename T::PumpT;
71 using PatternT = typename T::PatternT;
72
73 template <typename L> static void Test(PumpT& pump, L gen) {
74 for (int len = 1; len <= 7; len++) {
75 ASSERT_EQ(pump.peekBits(len), gen(len)) << " Where len: " << len;
76 pump.skipBitsNoFill(len);
77 }
78 }
79};
80
81struct TestPeekBitsNoFillTag;
82
83template <typename T> struct BitStreamerPatternTest<T, TestPeekBitsNoFillTag> {
84 using PumpT = typename T::PumpT;
85 using PatternT = typename T::PatternT;
86
87 template <typename L> static void Test(PumpT& pump, L gen) {
88 pump.fill(32); // Actually fills 32 bits
89 for (int len = 1; len <= 7; len++) {
90 ASSERT_EQ(pump.peekBitsNoFill(len), gen(len))
91 << " Where len: " << len;
92 pump.skipBitsNoFill(len);
93 }
94 }
95};
96
97struct TestIncreasingPeekLengthTag;
98
99template <typename T>
100struct BitStreamerPatternTest<T, TestIncreasingPeekLengthTag> {
101 using PumpT = typename T::PumpT;
102 using PatternT = typename T::PatternT;
103
104 template <typename L> static void Test(PumpT& pump, L data) {
105 static const auto MaxLen = 28;
106 for (int len = 1; len <= MaxLen; len++)
107 ASSERT_EQ(pump.peekBits(len), data(len)) << " Where len: " << len;
108 }
109};
110
111struct TestIncreasingPeekLengthNoFillTag;
112
113template <typename T>
114struct BitStreamerPatternTest<T, TestIncreasingPeekLengthNoFillTag> {
115 using PumpT = typename T::PumpT;
116 using PatternT = typename T::PatternT;
117
118 template <typename L> static void Test(PumpT& pump, L data) {
119 static const auto MaxLen = 28;
120 pump.fill(MaxLen); // Actually fills 32 bits
121 for (int len = 1; len <= MaxLen; len++)
122 ASSERT_EQ(pump.peekBitsNoFill(len), data(len))
123 << " Where len: " << len;
124 }
125};
126
127template <typename T> class BitStreamerTest : public ::testing::Test {
128public:
129 using PumpT = typename T::PumpT;
130 using PatternT = typename T::PatternT;
131
132protected:
133 template <typename Tag, typename TestDataType, typename L>
134 void runTest(const TestDataType& data, L gen) {
136 data.data(), rawspeed::implicit_cast<int>(data.size()));
137
138 PumpT pump(input);
140 }
141};
142
144
146 this->template runTest<TestGetBitsTag>(TypeParam::PatternT::Data,
147 TypeParam::PatternT::element);
148}
150 this->template runTest<TestGetBitsNoFillTag>(TypeParam::PatternT::Data,
151 TypeParam::PatternT::element);
152}
154 this->template runTest<TestPeekBitsTag>(TypeParam::PatternT::Data,
155 TypeParam::PatternT::element);
156}
158 this->template runTest<TestPeekBitsNoFillTag>(TypeParam::PatternT::Data,
159 TypeParam::PatternT::element);
160}
161TYPED_TEST_P(BitStreamerTest, IncreasingPeekLengthTest) {
162 this->template runTest<TestIncreasingPeekLengthTag>(
163 TypeParam::PatternT::Data, TypeParam::PatternT::data);
164}
165TYPED_TEST_P(BitStreamerTest, IncreasingPeekLengthNoFillTest) {
166 this->template runTest<TestIncreasingPeekLengthNoFillTag>(
167 TypeParam::PatternT::Data, TypeParam::PatternT::data);
168}
169
170REGISTER_TYPED_TEST_SUITE_P(BitStreamerTest, GetTest, GetNoFillTest, PeekTest,
171 PeekNoFillTest, IncreasingPeekLengthTest,
172 IncreasingPeekLengthNoFillTest);
173
174template <typename Pump, typename PatternTag> struct Pattern final {};
175
176struct ZerosTag;
177
178template <typename Pump> struct Pattern<Pump, ZerosTag> {
179 static const std::array<uint8_t, 8> Data;
180 static uint32_t element(int index) { return 0U; }
181 static uint32_t data(int len) { return 0U; }
182};
183template <typename Pump>
184const std::array<uint8_t, 8> Pattern<Pump, ZerosTag>::Data{{/* zero-init */}};
185
186struct OnesTag;
187
188template <typename Pump> struct Pattern<Pump, OnesTag> {
189 static const std::array<uint8_t, 8> Data;
190 static uint32_t element(int index) { return 1U; }
191 static uint32_t data(int len);
192};
193
194struct InvOnesTag;
195
196template <typename Pump> struct Pattern<Pump, InvOnesTag> {
197 static const std::array<uint8_t, 8> Data;
198 static uint32_t element(int index) { return 1U << (index - 1U); }
199 static uint32_t data(int len);
200};
201
202struct SaturatedTag;
203
204template <typename Pump> struct Pattern<Pump, SaturatedTag> {
205 static const std::array<uint8_t, 8> Data;
206 static uint32_t element(int index) { return (1U << index) - 1U; }
207 static uint32_t data(int len) { return (1U << len) - 1U; }
208};
209template <typename Pump>
210const std::array<uint8_t, 8> Pattern<Pump, SaturatedTag>::Data{
211 {uint8_t(~0U), uint8_t(~0U), uint8_t(~0U), uint8_t(~0U)}};
212
213auto GenOnesLE = [](int zerosToOutput,
214 int zerosOutputted) -> std::array<uint32_t, 29> {
215 std::array<uint32_t, 29> v;
216 uint32_t bits = 0;
217 int currBit = -1;
218 for (auto& value : v) {
219 if (zerosToOutput == zerosOutputted) {
220 assert(currBit < 32);
221 bits |= 0b1 << currBit;
222 zerosToOutput++;
223 zerosOutputted = 0;
224 }
225 value = bits;
226 zerosOutputted++;
227 currBit++;
228 }
229 return v;
230};
231auto GenOnesBE = [](int zerosToOutput,
232 int zerosOutputted) -> std::array<uint32_t, 29> {
233 std::array<uint32_t, 29> v;
234 uint32_t bits = 0;
235 for (auto& value : v) {
236 if (zerosToOutput == zerosOutputted) {
237 bits |= 0b1;
238 zerosToOutput++;
239 zerosOutputted = 0;
240 }
241 value = bits;
242 zerosOutputted++;
243 bits <<= 1;
244 }
245 return v;
246};
247
248template <typename Pump, typename Pattern> struct PumpAndPattern final {
249 using PumpT = Pump;
251};
252
253template <typename Pump>
254using Patterns =
255 ::testing::Types<PumpAndPattern<Pump, Pattern<Pump, ZerosTag>>,
259
260} // namespace
261
262} // namespace rawspeed_test
assert(dim.area() >=area)
::testing::Types< PumpAndPattern< Pump, Pattern< Pump, ZerosTag > >, PumpAndPattern< Pump, Pattern< Pump, OnesTag > >, PumpAndPattern< Pump, Pattern< Pump, InvOnesTag > >, PumpAndPattern< Pump, Pattern< Pump, SaturatedTag > > > Patterns
REGISTER_TYPED_TEST_SUITE_P(BitStreamerTest, GetTest, GetNoFillTest, PeekTest, PeekNoFillTest, IncreasingPeekLengthTest, IncreasingPeekLengthNoFillTest)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32