RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
Dual.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2017-2023 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 "adt/Casts.h"
23#ifndef IMPL0
24#error IMPL0 must be defined to one of rawspeeds huffman table implementations
25#endif
26#ifndef IMPL1
27#error IMPL1 must be defined to one of rawspeeds huffman table implementations
28#endif
29
33#include "codes/PrefixCodeDecoder.h" // IWYU pragma: keep
35#include "codes/PrefixCodeLUTDecoder.h" // IWYU pragma: keep
36#include "codes/PrefixCodeLookupDecoder.h" // IWYU pragma: keep
37#include "codes/PrefixCodeTreeDecoder.h" // IWYU pragma: keep
38#include "codes/PrefixCodeVectorDecoder.h" // IWYU pragma: keep
39#include "io/Buffer.h"
40#include "io/ByteStream.h"
41#include "io/Endianness.h"
42#include "io/IOException.h"
43#include <cassert>
44#include <cstdint>
45#include <cstdio>
46
47namespace rawspeed {
48struct BaselineCodeTag;
49struct VC5CodeTag;
50} // namespace rawspeed
51
52namespace {
53
54template <typename Pump, bool IsFullDecode, typename HT0, typename HT1>
56 const HT1& ht1) {
57 Pump bits0(input);
58 Pump bits1(input);
59
60 while (true) {
61 int decoded0;
62 int decoded1;
63
64 bool failure0 = false;
65 bool failure1 = false;
66
67 try {
68 decoded1 = ht1.template decode<decltype(bits1), IsFullDecode>(bits1);
69 } catch (const rawspeed::IOException&) {
70 // For now, let's ignore stream depleteon issues.
71 throw;
72 } catch (const rawspeed::RawspeedException&) {
73 failure1 = true;
74 }
75
76 try {
77 decoded0 = ht0.template decode<decltype(bits0), IsFullDecode>(bits0);
78 } catch (const rawspeed::IOException&) {
79 // For now, let's ignore stream depleteon issues.
80 throw;
81 } catch (const rawspeed::RawspeedException&) {
82 failure0 = true;
83 }
84
85 // They both should either fail or succeed, else there is a bug.
86 assert(failure0 == failure1);
87
88 // If any failed, we can't continue.
89 if (failure0 || failure1)
90 ThrowRSE("Failure detected");
91
92 (void)decoded0;
93 (void)decoded1;
94
95 // They both should have decoded the same value.
96 assert(decoded0 == decoded1);
97 }
98}
99
100template <typename Pump, typename HT0, typename HT1>
102 const HT1& ht1) {
103 assert(ht0.isFullDecode() == ht1.isFullDecode());
104 if (ht0.isFullDecode())
105 workloop<Pump, /*IsFullDecode=*/true>(input, ht0, ht1);
106 else
107 workloop<Pump, /*IsFullDecode=*/false>(input, ht0, ht1);
108}
109
110template <typename CodeTag> void checkFlavour(rawspeed::ByteStream bs) {
111 rawspeed::ByteStream bs0 = bs;
112 rawspeed::ByteStream bs1 = bs;
113
114#ifndef BACKIMPL0
116#else
117 const auto ht0 = createPrefixCodeDecoder<
118 rawspeed::IMPL0<CodeTag, rawspeed::BACKIMPL0<CodeTag>>>(bs0);
119#endif
120
121#ifndef BACKIMPL1
123#else
124 const auto ht1 = createPrefixCodeDecoder<
125 rawspeed::IMPL1<CodeTag, rawspeed::BACKIMPL1<CodeTag>>>(bs1);
126#endif
127
128 // Which bit pump should we use?
129 const int format0 = bs0.getByte();
130 const int format1 = bs1.getByte();
131
132 // should have consumed 16 bytes for n-codes-per-length, at *least* 1 byte
133 // as code value, and a byte per 'fixDNGBug16'/'fullDecode' booleans
134 assert(bs0.getPosition() == bs1.getPosition());
135
136 assert(format0 == format1);
137 (void)format1;
138
139 const auto input = bs0.peekRemainingBuffer().getAsArray1DRef();
140
141 assert(format0 == format1);
142 switch (format0) {
143 case 0:
145 break;
146 case 1:
148 break;
149 case 2:
151 break;
152 default:
153 ThrowRSE("Unknown bit pump");
154 }
155}
156
157} // namespace
158
159extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
160
161extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
162 assert(Data);
163
164 try {
165 const rawspeed::Buffer b(
169
170 // Which flavor?
171 switch (bs.getByte()) {
172 case 0:
174 break;
175 case 1:
177 break;
178 default:
179 ThrowRSE("Unknown flavor");
180 }
181 } catch (const rawspeed::RawspeedException&) {
182 return 0;
183 }
184
185 __builtin_unreachable();
186}
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
Definition Dual.cpp:161
#define ThrowRSE(...)
assert(dim.area() >=area)
Array1DRef< const uint8_t > getAsArray1DRef() const
Definition Buffer.h:70
size_type getPosition() const
Definition ByteStream.h:78
Buffer peekRemainingBuffer() const
Definition ByteStream.h:108
static T createPrefixCodeDecoder(rawspeed::ByteStream &bs)
Definition Common.h:147
void checkPump(rawspeed::Array1DRef< const uint8_t > input, const HT0 &ht0, const HT1 &ht1)
Definition Dual.cpp:101
void checkFlavour(rawspeed::ByteStream bs)
Definition Dual.cpp:110
void workloop(rawspeed::Array1DRef< const uint8_t > input, const HT0 &ht0, const HT1 &ht1)
Definition Dual.cpp:55
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32