summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRam Mohan <ram.mohan@ittiam.com>2023-05-26 00:09:50 +0530
committerDichen Zhang <dichenzhang@google.com>2023-05-26 22:45:12 +0000
commit9b3d6859c8a19dcf478d66ff60436c423a77b8a8 (patch)
tree9b5e97ba86b347939f64029cd346b2ba548a3590
parent6bd58d4d045fab777551175e0d16fb9c5f22c0cb (diff)
downloadnative-9b3d6859c8a19dcf478d66ff60436c423a77b8a8.tar.gz
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
-rw-r--r--libs/ultrahdr/include/ultrahdr/ultrahdr.h4
-rw-r--r--libs/ultrahdr/jpegr.cpp33
2 files changed, 28 insertions, 9 deletions
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<size_t>(
+ 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);