/src/librawspeed/fuzz/librawspeed/decompressors/Cr2Decompressor.cpp
Line | Count | Source |
1 | | /* |
2 | | RawSpeed - RAW file decoder. |
3 | | |
4 | | Copyright (C) 2022 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/Casts.h" |
22 | | #include "adt/Point.h" |
23 | | #include <cstddef> |
24 | | #include <tuple> |
25 | | #include <vector> |
26 | | #ifndef PrefixCodeDecoderImpl |
27 | | #error PrefixCodeDecoderImpl must be defined to one of rawspeeds huffman tables |
28 | | #endif |
29 | | |
30 | | #include "MemorySanitizer.h" |
31 | | #include "codes/DummyPrefixCodeDecoder.h" |
32 | | #include "codes/PrefixCodeDecoder/Common.h" |
33 | | #include "common/RawImage.h" |
34 | | #include "common/RawspeedException.h" |
35 | | #include "decompressors/Cr2Decompressor.h" |
36 | | #include "fuzz/Common.h" |
37 | | #include "io/Buffer.h" |
38 | | #include "io/ByteStream.h" |
39 | | #include "io/Endianness.h" |
40 | | #include <algorithm> |
41 | | #include <cassert> |
42 | | #include <cstdint> |
43 | | #include <iterator> |
44 | | |
45 | | #ifdef WITH_DummyPrefixCodeDecoder |
46 | | #include "decompressors/Cr2DecompressorImpl.h" |
47 | | |
48 | | namespace rawspeed { |
49 | | |
50 | | template class Cr2Decompressor<DummyPrefixCodeDecoder<>>; |
51 | | |
52 | | } // namespace rawspeed |
53 | | |
54 | | #endif // WITH_DummyPrefixCodeDecoder |
55 | | |
56 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size); |
57 | | |
58 | 35.0k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { |
59 | 35.0k | assert(Data); |
60 | | |
61 | 35.0k | try { |
62 | 35.0k | const rawspeed::Buffer b( |
63 | 35.0k | Data, rawspeed::implicit_cast<rawspeed::Buffer::size_type>(Size)); |
64 | 35.0k | const rawspeed::DataBuffer db(b, rawspeed::Endianness::little); |
65 | 35.0k | rawspeed::ByteStream bs(db); |
66 | | |
67 | 35.0k | rawspeed::RawImage mRaw(CreateRawImage(bs)); |
68 | | |
69 | 35.0k | const int N_COMP = bs.getI32(); |
70 | 35.0k | const int X_S_F = bs.getI32(); |
71 | 35.0k | const int Y_S_F = bs.getI32(); |
72 | 35.0k | const std::tuple<int /*N_COMP*/, int /*X_S_F*/, int /*Y_S_F*/> format = { |
73 | 35.0k | N_COMP, X_S_F, Y_S_F}; |
74 | | |
75 | 35.0k | const int frame_w = bs.getI32(); |
76 | 35.0k | const int frame_h = bs.getI32(); |
77 | 35.0k | const rawspeed::iPoint2D frame(frame_w, frame_h); |
78 | | |
79 | 35.0k | using slice_type = uint16_t; |
80 | 35.0k | const auto numSlices = bs.get<slice_type>(); |
81 | 35.0k | const auto sliceWidth = bs.get<slice_type>(); |
82 | 35.0k | const auto lastSliceWidth = bs.get<slice_type>(); |
83 | | |
84 | 35.0k | const rawspeed::Cr2SliceWidths slicing(numSlices, sliceWidth, |
85 | 35.0k | lastSliceWidth); |
86 | | |
87 | 35.0k | const unsigned num_recips = bs.getU32(); |
88 | | |
89 | 35.0k | const unsigned num_unique_hts = bs.getU32(); |
90 | 35.0k | std::vector<rawspeed::PrefixCodeDecoderImpl<>> uniqueHts; |
91 | 373k | std::generate_n(std::back_inserter(uniqueHts), num_unique_hts, [&bs]() { |
92 | 373k | return createPrefixCodeDecoder<rawspeed::PrefixCodeDecoderImpl<>>(bs); |
93 | 373k | }); |
94 | | |
95 | 35.0k | std::vector<const rawspeed::PrefixCodeDecoderImpl<>*> hts; |
96 | 4.26M | std::generate_n(std::back_inserter(hts), num_recips, [&bs, &uniqueHts]() { |
97 | 4.26M | if (unsigned uniq_ht_idx = bs.getU32(); uniq_ht_idx < uniqueHts.size()) |
98 | 4.26M | return &uniqueHts[uniq_ht_idx]; |
99 | 4.26M | ThrowRSE("Unknown unique huffman table"); |
100 | 4.26M | }); |
101 | | |
102 | 35.0k | (void)bs.check(num_recips, sizeof(uint16_t)); |
103 | 35.0k | std::vector<uint16_t> initPred; |
104 | 35.0k | initPred.reserve(num_recips); |
105 | 35.0k | std::generate_n(std::back_inserter(initPred), num_recips, |
106 | 964k | [&bs]() { return bs.get<uint16_t>(); }); |
107 | | |
108 | 35.0k | std::vector<rawspeed::Cr2Decompressor< |
109 | 35.0k | rawspeed::PrefixCodeDecoderImpl<>>::PerComponentRecipe> |
110 | 35.0k | rec; |
111 | 35.0k | rec.reserve(num_recips); |
112 | 35.0k | std::generate_n( |
113 | 35.0k | std::back_inserter(rec), num_recips, |
114 | 35.0k | [&rec, hts, initPred]() |
115 | 35.0k | -> rawspeed::Cr2Decompressor< |
116 | 964k | rawspeed::PrefixCodeDecoderImpl<>>::PerComponentRecipe { |
117 | 964k | const auto i = rawspeed::implicit_cast<int>(rec.size()); |
118 | 964k | return {*hts[i], initPred[i]}; |
119 | 964k | }); |
120 | | |
121 | 35.0k | rawspeed::Cr2Decompressor<rawspeed::PrefixCodeDecoderImpl<>> d( |
122 | 35.0k | mRaw, format, frame, slicing, rec, |
123 | 35.0k | bs.getSubStream(/*offset=*/0).peekRemainingBuffer().getAsArray1DRef()); |
124 | 35.0k | mRaw->createData(); |
125 | 35.0k | (void)d.decompress(); |
126 | | |
127 | 35.0k | rawspeed::MSan::CheckMemIsInitialized( |
128 | 35.0k | mRaw->getByteDataAsUncroppedArray2DRef()); |
129 | 35.0k | } catch (const rawspeed::RawspeedException&) { // NOLINT(bugprone-empty-catch) |
130 | | // Exceptions are good, crashes are bad. |
131 | 30.5k | } |
132 | | |
133 | 35.0k | return 0; |
134 | 35.0k | } |