RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
BitVacuumerJPEGTest.cpp
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
22#include "adt/Array1DRef.h"
23#include "adt/Casts.h"
26#include <cstdint>
27#include <iterator>
28#include <utility>
29#include <vector>
30#include <gmock/gmock.h>
31#include <gtest/gtest.h>
32
33#pragma GCC diagnostic push
34#pragma GCC diagnostic ignored "-Wpragmas"
35#pragma GCC diagnostic ignored "-Wunknown-warning-option"
36#pragma GCC diagnostic ignored "-Wunknown-pragmas"
37#pragma GCC diagnostic ignored "-Wframe-larger-than="
38#pragma GCC diagnostic ignored "-Wstack-usage="
39
40namespace rawspeed {
41
42namespace {
43
44using RecepieEntryType = std::pair<uint32_t, uint8_t>;
45using RecepieType = std::vector<RecepieEntryType>;
46using ResultType = std::vector<uint8_t>;
47
48using valueType = std::pair<RecepieType, ResultType>;
49class BitVacuumerJPEGTest : public ::testing::TestWithParam<valueType> {
50protected:
52 virtual void SetUp() {
53 recepie = std::get<0>(GetParam());
54 expectedOutput = std::get<1>(GetParam());
55 }
56
59};
60const std::vector<valueType> values = {{
61 // clang-format off
62 {RecepieType({{std::make_pair(0x00, 0)}}), ResultType()},
63 {RecepieType({{std::make_pair(0x00, 1)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
64 {RecepieType({{std::make_pair(0x00, 2)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
65 {RecepieType({{std::make_pair(0x00, 3)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
66 {RecepieType({{std::make_pair(0x00, 4)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
67 {RecepieType({{std::make_pair(0x00, 5)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
68 {RecepieType({{std::make_pair(0x00, 6)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
69 {RecepieType({{std::make_pair(0x00, 7)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
70 {RecepieType({{std::make_pair(0x00, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
71 {RecepieType({{std::make_pair(0x00, 9)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
72 {RecepieType({{std::make_pair(0x00, 10)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
73 {RecepieType({{std::make_pair(0x00, 11)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
74 {RecepieType({{std::make_pair(0x00, 12)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
75 {RecepieType({{std::make_pair(0x00, 13)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
76 {RecepieType({{std::make_pair(0x00, 14)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
77 {RecepieType({{std::make_pair(0x00, 15)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
78 {RecepieType({{std::make_pair(0x00, 16)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
79 {RecepieType({{std::make_pair(0x00, 17)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
80 {RecepieType({{std::make_pair(0x00, 18)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
81 {RecepieType({{std::make_pair(0x00, 19)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
82 {RecepieType({{std::make_pair(0x00, 20)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
83 {RecepieType({{std::make_pair(0x00, 21)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
84 {RecepieType({{std::make_pair(0x00, 22)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
85 {RecepieType({{std::make_pair(0x00, 23)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
86 {RecepieType({{std::make_pair(0x00, 24)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
87 {RecepieType({{std::make_pair(0x00, 25)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
88 {RecepieType({{std::make_pair(0x00, 26)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
89 {RecepieType({{std::make_pair(0x00, 27)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
90 {RecepieType({{std::make_pair(0x00, 28)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
91 {RecepieType({{std::make_pair(0x00, 29)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
92 {RecepieType({{std::make_pair(0x00, 30)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
93 {RecepieType({{std::make_pair(0x00, 31)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
94 {RecepieType({{std::make_pair(0x00, 32)}}), ResultType({{0x00, 0x00, 0x00, 0x00}})},
95
96 {RecepieType({{std::make_pair(0xFF, 8)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
97
98 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 0)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
99 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 1)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
100 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 2)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
101 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 3)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
102 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 4)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
103 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 5)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
104 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 6)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
105 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 7)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
106 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 8)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
107 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 9)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
108 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 10)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
109 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 11)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
110 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 12)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
111 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 13)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
112 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 14)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
113 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 15)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
114 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 16)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
115 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 17)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
116 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 18)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
117 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 19)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
118 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 20)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
119 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 21)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
120 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 22)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
121 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 23)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
122 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 24)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
123 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 25)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
124 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 26)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
125 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 27)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
126 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 28)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
127 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 29)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
128 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 30)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
129 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 31)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
130 {RecepieType({{std::make_pair(0xFF, 8), std::make_pair(0x00, 32)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}})},
131
132 {RecepieType({{std::make_pair(0x00, 0), std::make_pair(0xFF, 8)}}), ResultType({{0xFF, 0x00, 0x00, 0x00, 0x00}})},
133 {RecepieType({{std::make_pair(0x00, 1), std::make_pair(0xFF, 8)}}), ResultType({{0x7F, 0x80, 0x00, 0x00}})},
134 {RecepieType({{std::make_pair(0x00, 2), std::make_pair(0xFF, 8)}}), ResultType({{0x3F, 0xC0, 0x00, 0x00}})},
135 {RecepieType({{std::make_pair(0x00, 3), std::make_pair(0xFF, 8)}}), ResultType({{0x1F, 0xE0, 0x00, 0x00}})},
136 {RecepieType({{std::make_pair(0x00, 4), std::make_pair(0xFF, 8)}}), ResultType({{0x0F, 0xF0, 0x00, 0x00}})},
137 {RecepieType({{std::make_pair(0x00, 5), std::make_pair(0xFF, 8)}}), ResultType({{0x07, 0xF8, 0x00, 0x00}})},
138 {RecepieType({{std::make_pair(0x00, 6), std::make_pair(0xFF, 8)}}), ResultType({{0x03, 0xFC, 0x00, 0x00}})},
139 {RecepieType({{std::make_pair(0x00, 7), std::make_pair(0xFF, 8)}}), ResultType({{0x01, 0xFE, 0x00, 0x00}})},
140 {RecepieType({{std::make_pair(0x00, 8), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0xFF, 0x00, 0x00, 0x00}})},
141 {RecepieType({{std::make_pair(0x00, 9), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x7F, 0x80, 0x00}})},
142 {RecepieType({{std::make_pair(0x00, 10), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x3F, 0xC0, 0x00}})},
143 {RecepieType({{std::make_pair(0x00, 11), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x1F, 0xE0, 0x00}})},
144 {RecepieType({{std::make_pair(0x00, 12), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x0F, 0xF0, 0x00}})},
145 {RecepieType({{std::make_pair(0x00, 13), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x07, 0xF8, 0x00}})},
146 {RecepieType({{std::make_pair(0x00, 14), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x03, 0xFC, 0x00}})},
147 {RecepieType({{std::make_pair(0x00, 15), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x01, 0xFE, 0x00}})},
148 {RecepieType({{std::make_pair(0x00, 16), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0xFF, 0x00, 0x00}})},
149 {RecepieType({{std::make_pair(0x00, 17), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x7F, 0x80}})},
150 {RecepieType({{std::make_pair(0x00, 18), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x3F, 0xC0}})},
151 {RecepieType({{std::make_pair(0x00, 19), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x1F, 0xE0}})},
152 {RecepieType({{std::make_pair(0x00, 20), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x0F, 0xF0}})},
153 {RecepieType({{std::make_pair(0x00, 21), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x07, 0xF8}})},
154 {RecepieType({{std::make_pair(0x00, 22), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x03, 0xFC}})},
155 {RecepieType({{std::make_pair(0x00, 23), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x01, 0xFE}})},
156 {RecepieType({{std::make_pair(0x00, 24), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0xFF, 0x00}})},
157 {RecepieType({{std::make_pair(0x00, 25), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00}})},
158 {RecepieType({{std::make_pair(0x00, 26), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00}})},
159 {RecepieType({{std::make_pair(0x00, 27), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x00}})},
160 {RecepieType({{std::make_pair(0x00, 28), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00}})},
161 {RecepieType({{std::make_pair(0x00, 29), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00}})},
162 {RecepieType({{std::make_pair(0x00, 30), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00}})},
163 {RecepieType({{std::make_pair(0x00, 31), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00}})},
164 {RecepieType({{std::make_pair(0x00, 32), std::make_pair(0xFF, 8)}}), ResultType({{0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00}})},
165 // clang-format on
166}};
167
169 ::testing::ValuesIn(values));
170
172 ResultType bitstream;
173
174 {
175 auto bsInserter = PartitioningOutputIterator(std::back_inserter(bitstream));
176 using BitVacuumer = BitVacuumerJPEG<decltype(bsInserter)>;
177 auto bv = BitVacuumer(bsInserter);
178
179 for (const auto& e : recepie)
180 bv.put(e.first, e.second);
181 }
182
183 return bitstream;
184}
185
187 const ResultType bitstream = synthesizeBitstream(recepie);
188 ASSERT_THAT(bitstream, testing::ContainerEq(expectedOutput));
189}
190
192 if (expectedOutput.empty())
193 return;
194
195 if (constexpr int MinSize =
197 expectedOutput.size() < MinSize)
198 expectedOutput.resize(MinSize, uint8_t(0));
199
200 auto bs = BitStreamerJPEG(Array1DRef(
201 expectedOutput.data(), implicit_cast<int>(expectedOutput.size())));
202 for (int i = 0; i != implicit_cast<int>(recepie.size()); ++i) {
203 const auto [expectedVal, len] = recepie[i];
204 bs.fill(32);
205 const auto actualVal = len != 0 ? bs.getBitsNoFill(len) : 0;
206 ASSERT_THAT(actualVal, expectedVal);
207 }
208}
209
210} // namespace
211
212} // namespace rawspeed
213
214// NOTE: no `#pragma GCC diagnostic pop` wanted!
INSTANTIATE_TEST_SUITE_P(MD5Test, MD5Test, ::testing::ValuesIn(testCases))
TEST_P(MD5Test, CheckTestCaseSet)
Definition MD5Test.cpp:388
void put(uint32_t bits, int count)
ResultType synthesizeBitstream(const RecepieType &recepie)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
Array1DRef(T *data_, int numElts_) -> Array1DRef< T >
PartitioningOutputIterator(T) -> PartitioningOutputIterator< T >