From 9b3d6859c8a19dcf478d66ff60436c423a77b8a8 Mon Sep 17 00:00:00 2001 From: Ram Mohan Date: Fri, 26 May 2023 00:09:50 +0530 Subject: ultrahdr: update error checks in encode/decode path 1. library assumes the gain map resolution is 1/kMapDimensionScaleFactor of primary image resolution. If it is not the case the output hdr image computations are not according to the scale factor. Signal error if map scale factor is not kMapDimensionScaleFactor. 2. library expects primary image to be 420 and gain map image to be 400. Validate the same. 3. disallow srgb transfer function way early as this is not handled. 4. avoid nullptr access in metadata. Bug: 284120011 Test: ./ultrahdr_enc_fuzzer Change-Id: Ie2cd12ac95306958cbb18679039681fc4eb3d9cc --- libs/ultrahdr/include/ultrahdr/ultrahdr.h | 4 ++-- libs/ultrahdr/jpegr.cpp | 33 ++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'libs') diff --git a/libs/ultrahdr/include/ultrahdr/ultrahdr.h b/libs/ultrahdr/include/ultrahdr/ultrahdr.h index d6153e9890..21751b4634 100644 --- a/libs/ultrahdr/include/ultrahdr/ultrahdr.h +++ b/libs/ultrahdr/include/ultrahdr/ultrahdr.h @@ -20,7 +20,7 @@ namespace android::ultrahdr { // Color gamuts for image data typedef enum { - ULTRAHDR_COLORGAMUT_UNSPECIFIED, + ULTRAHDR_COLORGAMUT_UNSPECIFIED = -1, ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_P3, ULTRAHDR_COLORGAMUT_BT2100, @@ -52,7 +52,7 @@ typedef enum { */ struct ultrahdr_metadata_struct { // Ultra HDR library version - const char* version; + std::string version; // Max Content Boost for the map float maxContentBoost; // Min Content Boost for the map diff --git a/libs/ultrahdr/jpegr.cpp b/libs/ultrahdr/jpegr.cpp index c250aa02fd..366706ac53 100644 --- a/libs/ultrahdr/jpegr.cpp +++ b/libs/ultrahdr/jpegr.cpp @@ -145,7 +145,8 @@ status_t JpegR::areInputArgumentsValid(jr_uncompressed_ptr uncompressed_p010_ima return ERROR_JPEGR_INVALID_NULL_PTR; } - if (hdr_tf <= ULTRAHDR_TF_UNSPECIFIED || hdr_tf > ULTRAHDR_TF_MAX) { + if (hdr_tf <= ULTRAHDR_TF_UNSPECIFIED || hdr_tf > ULTRAHDR_TF_MAX + || hdr_tf == ULTRAHDR_TF_SRGB) { ALOGE("Invalid hdr transfer function %d", hdr_tf); return ERROR_JPEGR_INVALID_INPUT_TYPE; } @@ -509,11 +510,6 @@ status_t JpegR::decodeJPEGR(jr_compressed_ptr compressed_jpegr_image, return ERROR_JPEGR_INVALID_INPUT_TYPE; } - if (gain_map != nullptr && gain_map->data == nullptr) { - ALOGE("received nullptr address for gain map data"); - return ERROR_JPEGR_INVALID_INPUT_TYPE; - } - if (output_format == ULTRAHDR_OUTPUT_SDR) { JpegDecoderHelper jpeg_decoder; if (!jpeg_decoder.decompressImage(compressed_jpegr_image->data, compressed_jpegr_image->length, @@ -555,6 +551,11 @@ status_t JpegR::decodeJPEGR(jr_compressed_ptr compressed_jpegr_image, if (!gain_map_decoder.decompressImage(compressed_map.data, compressed_map.length)) { return ERROR_JPEGR_DECODE_ERROR; } + if ((gain_map_decoder.getDecompressedImageWidth() * + gain_map_decoder.getDecompressedImageHeight()) > + gain_map_decoder.getDecompressedImageSize()) { + return ERROR_JPEGR_CALCULATION_ERROR; + } if (gain_map != nullptr) { gain_map->width = gain_map_decoder.getDecompressedImageWidth(); @@ -584,6 +585,11 @@ status_t JpegR::decodeJPEGR(jr_compressed_ptr compressed_jpegr_image, if (!jpeg_decoder.decompressImage(compressed_jpegr_image->data, compressed_jpegr_image->length)) { return ERROR_JPEGR_DECODE_ERROR; } + if ((jpeg_decoder.getDecompressedImageWidth() * + jpeg_decoder.getDecompressedImageHeight() * 3 / 2) > + jpeg_decoder.getDecompressedImageSize()) { + return ERROR_JPEGR_CALCULATION_ERROR; + } if (exif != nullptr) { if (exif->data == nullptr) { @@ -605,7 +611,6 @@ status_t JpegR::decodeJPEGR(jr_compressed_ptr compressed_jpegr_image, uncompressed_yuv_420_image.data = jpeg_decoder.getDecompressedImagePtr(); uncompressed_yuv_420_image.width = jpeg_decoder.getDecompressedImageWidth(); uncompressed_yuv_420_image.height = jpeg_decoder.getDecompressedImageHeight(); - JPEGR_CHECK(applyGainMap(&uncompressed_yuv_420_image, &map, &uhdr_metadata, output_format, max_display_boost, dest)); return NO_ERROR; @@ -848,6 +853,20 @@ status_t JpegR::applyGainMap(jr_uncompressed_ptr uncompressed_yuv_420_image, return ERROR_JPEGR_INVALID_NULL_PTR; } + // TODO: remove once map scaling factor is computed based on actual map dims + size_t image_width = uncompressed_yuv_420_image->width; + size_t image_height = uncompressed_yuv_420_image->height; + size_t map_width = image_width / kMapDimensionScaleFactor; + size_t map_height = image_height / kMapDimensionScaleFactor; + map_width = static_cast( + floor((map_width + kJpegBlock - 1) / kJpegBlock)) * kJpegBlock; + map_height = ((map_height + 1) >> 1) << 1; + if (map_width != uncompressed_gain_map->width + || map_height != uncompressed_gain_map->height) { + ALOGE("gain map dimensions and primary image dimensions are not to scale"); + return ERROR_JPEGR_INVALID_INPUT_TYPE; + } + dest->width = uncompressed_yuv_420_image->width; dest->height = uncompressed_yuv_420_image->height; ShepardsIDW idwTable(kMapDimensionScaleFactor); -- cgit v1.2.3-59-g8ed1b