jpegr: encode ICC
bug: b/264715926, b/263609305
test: recoverymap_test.cpp, check the ICC package in the encoded jpeg/r
image in a hex editor
Change-Id: I099eb9201c26fce046b7ca8ea4b5e7e8443adcb3
diff --git a/libs/jpegrecoverymap/recoverymap.cpp b/libs/jpegrecoverymap/recoverymap.cpp
index 30aa846..7ca6094 100644
--- a/libs/jpegrecoverymap/recoverymap.cpp
+++ b/libs/jpegrecoverymap/recoverymap.cpp
@@ -26,7 +26,10 @@
#include <image_io/jpeg/jpeg_info_builder.h>
#include <image_io/base/data_segment_data_source.h>
#include <utils/Log.h>
+#include "SkColorSpace.h"
+#include "SkICC.h"
+#include <map>
#include <memory>
#include <sstream>
#include <string>
@@ -93,6 +96,20 @@
return cpuCoreCount;
}
+static const map<recoverymap::jpegr_color_gamut, skcms_Matrix3x3> jrGamut_to_skGamut {
+ {JPEGR_COLORGAMUT_BT709, SkNamedGamut::kSRGB},
+ {JPEGR_COLORGAMUT_P3, SkNamedGamut::kDisplayP3},
+ {JPEGR_COLORGAMUT_BT2100, SkNamedGamut::kRec2020},
+};
+
+static const map<
+ recoverymap::jpegr_transfer_function, skcms_TransferFunction> jrTransFunc_to_skTransFunc {
+ {JPEGR_TF_SRGB, SkNamedTransferFn::kSRGB},
+ {JPEGR_TF_LINEAR, SkNamedTransferFn::kLinear},
+ {JPEGR_TF_HLG, SkNamedTransferFn::kHLG},
+ {JPEGR_TF_PQ, SkNamedTransferFn::kPQ},
+};
+
/*
* Helper function copies the JPEG image from without EXIF.
*
@@ -164,11 +181,15 @@
compressed_map.data = compressed_map_data.get();
JPEGR_CHECK(compressRecoveryMap(&map, &compressed_map));
+ sk_sp<SkData> icc = SkWriteICCProfile(
+ jrTransFunc_to_skTransFunc.at(JPEGR_TF_SRGB),
+ jrGamut_to_skGamut.at(uncompressed_yuv_420_image.colorGamut));
+
JpegEncoder jpeg_encoder;
- // TODO: determine ICC data based on color gamut information
if (!jpeg_encoder.compressImage(uncompressed_yuv_420_image.data,
uncompressed_yuv_420_image.width,
- uncompressed_yuv_420_image.height, quality, nullptr, 0)) {
+ uncompressed_yuv_420_image.height, quality,
+ icc.get()->data(), icc.get()->size())) {
return ERROR_JPEGR_ENCODE_ERROR;
}
jpegr_compressed_struct jpeg;
@@ -228,11 +249,15 @@
compressed_map.data = compressed_map_data.get();
JPEGR_CHECK(compressRecoveryMap(&map, &compressed_map));
+ sk_sp<SkData> icc = SkWriteICCProfile(
+ jrTransFunc_to_skTransFunc.at(JPEGR_TF_SRGB),
+ jrGamut_to_skGamut.at(uncompressed_yuv_420_image->colorGamut));
+
JpegEncoder jpeg_encoder;
- // TODO: determine ICC data based on color gamut information
if (!jpeg_encoder.compressImage(uncompressed_yuv_420_image->data,
uncompressed_yuv_420_image->width,
- uncompressed_yuv_420_image->height, quality, nullptr, 0)) {
+ uncompressed_yuv_420_image->height, quality,
+ icc.get()->data(), icc.get()->size())) {
return ERROR_JPEGR_ENCODE_ERROR;
}
jpegr_compressed_struct jpeg;
@@ -574,7 +599,7 @@
#endif
hdr_white_nits = kPqMaxNits;
break;
- case JPEGR_TF_UNSPECIFIED:
+ default:
// Should be impossible to hit after input validation.
return ERROR_JPEGR_INVALID_TRANS_FUNC;
}
@@ -750,7 +775,7 @@
hdrOetf = pqOetf;
#endif
break;
- case JPEGR_TF_UNSPECIFIED:
+ default:
// Should be impossible to hit after input validation.
hdrOetf = identityConversion;
}