blob: dba543b95d4591d51de8305752c2a62993b2dc17 [file] [log] [blame]
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fuzzer/FuzzedDataProvider.h>
#include "ultrahdr_api.h"
#include "ultrahdr/ultrahdrcommon.h"
using namespace ultrahdr;
// Transfer functions for image data, sync with ultrahdr.h
constexpr int kTfMin = UHDR_CT_UNSPECIFIED;
constexpr int kTfMax = UHDR_CT_SRGB;
class UltraHdrDecFuzzer {
public:
UltraHdrDecFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {};
void process();
private:
FuzzedDataProvider mFdp;
};
void UltraHdrDecFuzzer::process() {
auto output_ct =
static_cast<uhdr_color_transfer>(mFdp.ConsumeIntegralInRange<int8_t>(kTfMin, kTfMax));
auto displayBoost = mFdp.ConsumeFloatingPointInRange<float>(-10.0f, 100.0f);
auto enableGpu = mFdp.ConsumeBool();
// editing effects
auto applyMirror = mFdp.ConsumeBool();
uhdr_mirror_direction_t direction =
mFdp.ConsumeBool() ? UHDR_MIRROR_VERTICAL : UHDR_MIRROR_HORIZONTAL;
auto applyRotate = mFdp.ConsumeBool();
int degrees = degrees = mFdp.PickValueInArray({-90, 0, 90, 180, 270});
auto applyCrop = mFdp.ConsumeBool();
int left = mFdp.ConsumeIntegral<int16_t>();
int right = mFdp.ConsumeIntegral<int16_t>();
int top = mFdp.ConsumeIntegral<int16_t>();
int bottom = mFdp.ConsumeIntegral<int16_t>();
auto applyResize = mFdp.ConsumeBool();
int resizeWidth = mFdp.ConsumeIntegralInRange<int32_t>(-32, kMaxWidth + 128);
int resizeHeight = mFdp.ConsumeIntegralInRange<int32_t>(-32, kMaxHeight + 128);
auto buffer = mFdp.ConsumeRemainingBytes<uint8_t>();
uhdr_compressed_image_t jpegImgR{
buffer.data(), (unsigned int)buffer.size(), (unsigned int)buffer.size(),
UHDR_CG_UNSPECIFIED, UHDR_CT_UNSPECIFIED, UHDR_CR_UNSPECIFIED};
#define ON_ERR(x) \
{ \
uhdr_error_info_t status_ = (x); \
if (status_.error_code != UHDR_CODEC_OK) { \
if (status_.has_detail) { \
ALOGE("%s", status_.detail); \
} \
} \
}
(void)is_uhdr_image(buffer.data(), buffer.size());
uhdr_codec_private_t* dec_handle = uhdr_create_decoder();
if (dec_handle) {
ON_ERR(uhdr_dec_set_image(dec_handle, &jpegImgR))
ON_ERR(uhdr_dec_set_out_color_transfer(dec_handle, output_ct))
if (output_ct == UHDR_CT_LINEAR)
ON_ERR(uhdr_dec_set_out_img_format(dec_handle, UHDR_IMG_FMT_64bppRGBAHalfFloat))
else if (output_ct == UHDR_CT_SRGB)
ON_ERR(uhdr_dec_set_out_img_format(dec_handle, UHDR_IMG_FMT_32bppRGBA8888))
else
ON_ERR(uhdr_dec_set_out_img_format(dec_handle, UHDR_IMG_FMT_32bppRGBA1010102))
ON_ERR(uhdr_dec_set_out_max_display_boost(dec_handle, displayBoost))
ON_ERR(uhdr_enable_gpu_acceleration(dec_handle, enableGpu))
if (applyMirror) ON_ERR(uhdr_add_effect_mirror(dec_handle, direction))
if (applyRotate) ON_ERR(uhdr_add_effect_rotate(dec_handle, degrees))
if (applyCrop) ON_ERR(uhdr_add_effect_crop(dec_handle, left, right, top, bottom))
if (applyResize) ON_ERR(uhdr_add_effect_resize(dec_handle, resizeWidth, resizeHeight))
uhdr_dec_probe(dec_handle);
auto width = uhdr_dec_get_image_width(dec_handle);
auto height = uhdr_dec_get_image_height(dec_handle);
auto gainmap_width = uhdr_dec_get_gainmap_width(dec_handle);
auto gainmap_height = uhdr_dec_get_gainmap_height(dec_handle);
ALOGV("image dimensions %d x %d ", (int)width, (int)height);
ALOGV("gainmap image dimensions %d x %d ", (int)gainmap_width, (int)gainmap_height);
ALOGV("output color transfer %d ", (int)output_ct);
ALOGV("max display boost %f ", (float)displayBoost);
ALOGV("enable gpu %d ", (int)enableGpu);
if (applyMirror) ALOGV("added mirror effect, direction %d", (int)direction);
if (applyRotate) ALOGV("added rotate effect, degrees %d", (int)degrees);
if (applyCrop)
ALOGV("added crop effect, crop-left %d, crop-right %d, crop-top %d, crop-bottom %d", left,
right, top, bottom);
if (applyResize)
ALOGV("added resize effect, resize wd %d, resize ht %d", resizeWidth, resizeHeight);
uhdr_dec_get_exif(dec_handle);
uhdr_dec_get_icc(dec_handle);
uhdr_dec_get_base_image(dec_handle);
uhdr_dec_get_gainmap_image(dec_handle);
uhdr_dec_get_gainmap_metadata(dec_handle);
uhdr_decode(dec_handle);
uhdr_get_decoded_image(dec_handle);
uhdr_get_decoded_gainmap_image(dec_handle);
uhdr_reset_decoder(dec_handle);
uhdr_release_decoder(dec_handle);
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
UltraHdrDecFuzzer fuzzHandle(data, size);
fuzzHandle.process();
return 0;
}