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