1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <fuzzer/FuzzedDataProvider.h>
18
19 #include "ultrahdr_api.h"
20 #include "ultrahdr/ultrahdrcommon.h"
21
22 using namespace ultrahdr;
23
24 // Transfer functions for image data, sync with ultrahdr.h
25 constexpr int kTfMin = UHDR_CT_UNSPECIFIED;
26 constexpr int kTfMax = UHDR_CT_SRGB;
27
28 class UltraHdrDecFuzzer {
29 public:
UltraHdrDecFuzzer(const uint8_t * data,size_t size)30 UltraHdrDecFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {};
31 void process();
32
33 private:
34 FuzzedDataProvider mFdp;
35 };
36
process()37 void UltraHdrDecFuzzer::process() {
38 auto output_ct =
39 static_cast<uhdr_color_transfer>(mFdp.ConsumeIntegralInRange<int8_t>(kTfMin, kTfMax));
40 auto displayBoost = mFdp.ConsumeFloatingPointInRange<float>(-10.0f, 100.0f);
41 auto enableGpu = mFdp.ConsumeBool();
42
43 // editing effects
44 auto applyMirror = mFdp.ConsumeBool();
45 uhdr_mirror_direction_t direction =
46 mFdp.ConsumeBool() ? UHDR_MIRROR_VERTICAL : UHDR_MIRROR_HORIZONTAL;
47
48 auto applyRotate = mFdp.ConsumeBool();
49 int degrees = degrees = mFdp.PickValueInArray({-90, 0, 90, 180, 270});
50
51 auto applyCrop = mFdp.ConsumeBool();
52 int left = mFdp.ConsumeIntegral<int16_t>();
53 int right = mFdp.ConsumeIntegral<int16_t>();
54 int top = mFdp.ConsumeIntegral<int16_t>();
55 int bottom = mFdp.ConsumeIntegral<int16_t>();
56
57 auto applyResize = mFdp.ConsumeBool();
58 int resizeWidth = mFdp.ConsumeIntegralInRange<int32_t>(-32, kMaxWidth + 128);
59 int resizeHeight = mFdp.ConsumeIntegralInRange<int32_t>(-32, kMaxHeight + 128);
60
61 auto buffer = mFdp.ConsumeRemainingBytes<uint8_t>();
62
63 uhdr_compressed_image_t jpegImgR{
64 buffer.data(), (unsigned int)buffer.size(), (unsigned int)buffer.size(),
65 UHDR_CG_UNSPECIFIED, UHDR_CT_UNSPECIFIED, UHDR_CR_UNSPECIFIED};
66 #define ON_ERR(x) \
67 { \
68 uhdr_error_info_t status_ = (x); \
69 if (status_.error_code != UHDR_CODEC_OK) { \
70 if (status_.has_detail) { \
71 ALOGE("%s", status_.detail); \
72 } \
73 } \
74 }
75
76 (void)is_uhdr_image(buffer.data(), buffer.size());
77
78 uhdr_codec_private_t* dec_handle = uhdr_create_decoder();
79 if (dec_handle) {
80 ON_ERR(uhdr_dec_set_image(dec_handle, &jpegImgR))
81 ON_ERR(uhdr_dec_set_out_color_transfer(dec_handle, output_ct))
82 if (output_ct == UHDR_CT_LINEAR)
83 ON_ERR(uhdr_dec_set_out_img_format(dec_handle, UHDR_IMG_FMT_64bppRGBAHalfFloat))
84 else if (output_ct == UHDR_CT_SRGB)
85 ON_ERR(uhdr_dec_set_out_img_format(dec_handle, UHDR_IMG_FMT_32bppRGBA8888))
86 else
87 ON_ERR(uhdr_dec_set_out_img_format(dec_handle, UHDR_IMG_FMT_32bppRGBA1010102))
88 ON_ERR(uhdr_dec_set_out_max_display_boost(dec_handle, displayBoost))
89 ON_ERR(uhdr_enable_gpu_acceleration(dec_handle, enableGpu))
90 if (applyMirror) ON_ERR(uhdr_add_effect_mirror(dec_handle, direction))
91 if (applyRotate) ON_ERR(uhdr_add_effect_rotate(dec_handle, degrees))
92 if (applyCrop) ON_ERR(uhdr_add_effect_crop(dec_handle, left, right, top, bottom))
93 if (applyResize) ON_ERR(uhdr_add_effect_resize(dec_handle, resizeWidth, resizeHeight))
94 uhdr_dec_probe(dec_handle);
95 auto width = uhdr_dec_get_image_width(dec_handle);
96 auto height = uhdr_dec_get_image_height(dec_handle);
97 auto gainmap_width = uhdr_dec_get_gainmap_width(dec_handle);
98 auto gainmap_height = uhdr_dec_get_gainmap_height(dec_handle);
99
100 ALOGV("image dimensions %d x %d ", (int)width, (int)height);
101 ALOGV("gainmap image dimensions %d x %d ", (int)gainmap_width, (int)gainmap_height);
102 ALOGV("output color transfer %d ", (int)output_ct);
103 ALOGV("max display boost %f ", (float)displayBoost);
104 ALOGV("enable gpu %d ", (int)enableGpu);
105 if (applyMirror) ALOGV("added mirror effect, direction %d", (int)direction);
106 if (applyRotate) ALOGV("added rotate effect, degrees %d", (int)degrees);
107 if (applyCrop)
108 ALOGV("added crop effect, crop-left %d, crop-right %d, crop-top %d, crop-bottom %d", left,
109 right, top, bottom);
110 if (applyResize)
111 ALOGV("added resize effect, resize wd %d, resize ht %d", resizeWidth, resizeHeight);
112
113 uhdr_dec_get_exif(dec_handle);
114 uhdr_dec_get_icc(dec_handle);
115 uhdr_dec_get_base_image(dec_handle);
116 uhdr_dec_get_gainmap_image(dec_handle);
117 uhdr_dec_get_gainmap_metadata(dec_handle);
118 uhdr_decode(dec_handle);
119 uhdr_get_decoded_image(dec_handle);
120 uhdr_get_decoded_gainmap_image(dec_handle);
121 uhdr_reset_decoder(dec_handle);
122 uhdr_release_decoder(dec_handle);
123 }
124 }
125
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)126 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
127 UltraHdrDecFuzzer fuzzHandle(data, size);
128 fuzzHandle.process();
129 return 0;
130 }
131