aboutsummaryrefslogtreecommitdiff
path: root/lib/src/jpegr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/src/jpegr.cpp')
-rw-r--r--lib/src/jpegr.cpp117
1 files changed, 83 insertions, 34 deletions
diff --git a/lib/src/jpegr.cpp b/lib/src/jpegr.cpp
index ed4fef1..74ef134 100644
--- a/lib/src/jpegr.cpp
+++ b/lib/src/jpegr.cpp
@@ -558,13 +558,13 @@ status_t JpegR::encodeJPEGR(jr_compressed_ptr yuv420jpg_image_ptr,
// We just want to check if ICC is present, so don't do a full decode. Note,
// this doesn't verify that the ICC is valid.
JpegDecoderHelper decoder;
- std::vector<uint8_t> icc;
- decoder.getCompressedImageParameters(yuv420jpg_image_ptr->data, yuv420jpg_image_ptr->length,
- /* pWidth */ nullptr, /* pHeight */ nullptr, &icc,
- /* exifData */ nullptr);
+ if (!decoder.getCompressedImageParameters(yuv420jpg_image_ptr->data,
+ yuv420jpg_image_ptr->length)) {
+ return ERROR_JPEGR_DECODE_ERROR;
+ }
// Add ICC if not already present.
- if (icc.size() > 0) {
+ if (decoder.getICCSize() > 0) {
JPEGR_CHECK(appendGainMap(yuv420jpg_image_ptr, gainmapjpg_image_ptr, /* exif */ nullptr,
/* icc */ nullptr, /* icc size */ 0, metadata, dest));
} else {
@@ -577,12 +577,12 @@ status_t JpegR::encodeJPEGR(jr_compressed_ptr yuv420jpg_image_ptr,
return JPEGR_NO_ERROR;
}
-status_t JpegR::getJPEGRInfo(jr_compressed_ptr jpegr_image_ptr, jr_info_ptr jpeg_image_info_ptr) {
+status_t JpegR::getJPEGRInfo(jr_compressed_ptr jpegr_image_ptr, jr_info_ptr jpegr_image_info_ptr) {
if (jpegr_image_ptr == nullptr || jpegr_image_ptr->data == nullptr) {
ALOGE("received nullptr for compressed jpegr image");
return ERROR_JPEGR_BAD_PTR;
}
- if (jpeg_image_info_ptr == nullptr) {
+ if (jpegr_image_info_ptr == nullptr) {
ALOGE("received nullptr for compressed jpegr info struct");
return ERROR_JPEGR_BAD_PTR;
}
@@ -592,13 +592,16 @@ status_t JpegR::getJPEGRInfo(jr_compressed_ptr jpegr_image_ptr, jr_info_ptr jpeg
if (status != JPEGR_NO_ERROR && status != ERROR_JPEGR_GAIN_MAP_IMAGE_NOT_FOUND) {
return status;
}
-
- JpegDecoderHelper jpeg_dec_obj_hdr;
- if (!jpeg_dec_obj_hdr.getCompressedImageParameters(
- primary_image.data, primary_image.length, &jpeg_image_info_ptr->width,
- &jpeg_image_info_ptr->height, jpeg_image_info_ptr->iccData,
- jpeg_image_info_ptr->exifData)) {
- return ERROR_JPEGR_DECODE_ERROR;
+ status = parseJpegInfo(&primary_image, jpegr_image_info_ptr->primaryImgInfo,
+ &jpegr_image_info_ptr->width, &jpegr_image_info_ptr->height);
+ if (status != JPEGR_NO_ERROR) {
+ return status;
+ }
+ if (jpegr_image_info_ptr->gainmapImgInfo != nullptr) {
+ status = parseJpegInfo(&gainmap_image, jpegr_image_info_ptr->gainmapImgInfo);
+ if (status != JPEGR_NO_ERROR) {
+ return status;
+ }
}
return status;
@@ -641,8 +644,9 @@ status_t JpegR::decodeJPEGR(jr_compressed_ptr jpegr_image_ptr, jr_uncompressed_p
}
JpegDecoderHelper jpeg_dec_obj_yuv420;
- if (!jpeg_dec_obj_yuv420.decompressImage(primary_jpeg_image.data, primary_jpeg_image.length,
- (output_format == ULTRAHDR_OUTPUT_SDR))) {
+ if (!jpeg_dec_obj_yuv420.decompressImage(
+ primary_jpeg_image.data, primary_jpeg_image.length,
+ (output_format == ULTRAHDR_OUTPUT_SDR) ? DECODE_TO_RGBA : DECODE_TO_YCBCR)) {
return ERROR_JPEGR_DECODE_ERROR;
}
@@ -1010,29 +1014,39 @@ status_t JpegR::applyGainMap(jr_uncompressed_ptr yuv420_image_ptr,
return ERROR_JPEGR_BAD_METADATA;
}
- // TODO: remove once map scaling factor is computed based on actual map dims
- size_t image_width = yuv420_image_ptr->width;
- size_t image_height = yuv420_image_ptr->height;
- size_t map_width = image_width / kMapDimensionScaleFactor;
- size_t map_height = image_height / kMapDimensionScaleFactor;
- if (map_width != gainmap_image_ptr->width || map_height != gainmap_image_ptr->height) {
+ if (yuv420_image_ptr->width % gainmap_image_ptr->width != 0 ||
+ yuv420_image_ptr->height % gainmap_image_ptr->height != 0) {
ALOGE(
- "gain map dimensions and primary image dimensions are not to scale, computed gain map "
- "resolution is %zux%zu, received gain map resolution is %zux%zu",
- map_width, map_height, gainmap_image_ptr->width, gainmap_image_ptr->height);
- return ERROR_JPEGR_RESOLUTION_MISMATCH;
+ "gain map dimensions scale factor value is not an integer, primary image resolution is "
+ "%zux%zu, received gain map resolution is %zux%zu",
+ yuv420_image_ptr->width, yuv420_image_ptr->height, gainmap_image_ptr->width,
+ gainmap_image_ptr->height);
+ return ERROR_JPEGR_UNSUPPORTED_MAP_SCALE_FACTOR;
}
+ if (yuv420_image_ptr->width * gainmap_image_ptr->height !=
+ yuv420_image_ptr->height * gainmap_image_ptr->width) {
+ ALOGE(
+ "gain map dimensions scale factor values for height and width are different, \n primary "
+ "image resolution is %zux%zu, received gain map resolution is %zux%zu",
+ yuv420_image_ptr->width, yuv420_image_ptr->height, gainmap_image_ptr->width,
+ gainmap_image_ptr->height);
+ return ERROR_JPEGR_UNSUPPORTED_MAP_SCALE_FACTOR;
+ }
+ // TODO: Currently map_scale_factor is of type size_t, but it could be changed to a float
+ // later.
+ size_t map_scale_factor = yuv420_image_ptr->width / gainmap_image_ptr->width;
+
dest->width = yuv420_image_ptr->width;
dest->height = yuv420_image_ptr->height;
- ShepardsIDW idwTable(kMapDimensionScaleFactor);
+ ShepardsIDW idwTable(map_scale_factor);
float display_boost = (std::min)(max_display_boost, metadata->maxContentBoost);
GainLUT gainLUT(metadata, display_boost);
JobQueue jobQueue;
std::function<void()> applyRecMap = [yuv420_image_ptr, gainmap_image_ptr, dest, &jobQueue,
- &idwTable, output_format, &gainLUT,
- display_boost]() -> void {
+ &idwTable, output_format, &gainLUT, display_boost,
+ map_scale_factor]() -> void {
size_t width = yuv420_image_ptr->width;
size_t rowStart, rowEnd;
@@ -1049,11 +1063,7 @@ status_t JpegR::applyGainMap(jr_uncompressed_ptr yuv420_image_ptr,
Color rgb_sdr = srgbInvOetf(rgb_gamma_sdr);
#endif
float gain;
- // TODO: determine map scaling factor based on actual map dims
- size_t map_scale_factor = kMapDimensionScaleFactor;
// TODO: If map_scale_factor is guaranteed to be an integer, then remove the following.
- // Currently map_scale_factor is of type size_t, but it could be changed to a float
- // later.
if (map_scale_factor != floorf(map_scale_factor)) {
gain = sampleMap(gainmap_image_ptr, map_scale_factor, x, y);
} else {
@@ -1110,7 +1120,7 @@ status_t JpegR::applyGainMap(jr_uncompressed_ptr yuv420_image_ptr,
for (int th = 0; th < threads - 1; th++) {
workers.push_back(std::thread(applyRecMap));
}
- const int rowStep = threads == 1 ? yuv420_image_ptr->height : kJobSzInRows;
+ const int rowStep = threads == 1 ? yuv420_image_ptr->height : map_scale_factor;
for (size_t rowStart = 0; rowStart < yuv420_image_ptr->height;) {
int rowEnd = (std::min)(rowStart + rowStep, yuv420_image_ptr->height);
jobQueue.enqueueJob(rowStart, rowEnd);
@@ -1177,6 +1187,45 @@ status_t JpegR::extractPrimaryImageAndGainMap(jr_compressed_ptr jpegr_image_ptr,
return JPEGR_NO_ERROR;
}
+status_t JpegR::parseJpegInfo(jr_compressed_ptr jpeg_image_ptr, j_info_ptr jpeg_image_info_ptr,
+ size_t* img_width, size_t* img_height) {
+ JpegDecoderHelper jpeg_dec_obj;
+ if (!jpeg_dec_obj.getCompressedImageParameters(jpeg_image_ptr->data, jpeg_image_ptr->length)) {
+ return ERROR_JPEGR_DECODE_ERROR;
+ }
+ size_t imgWidth, imgHeight;
+ imgWidth = jpeg_dec_obj.getDecompressedImageWidth();
+ imgHeight = jpeg_dec_obj.getDecompressedImageHeight();
+
+ if (jpeg_image_info_ptr != nullptr) {
+ jpeg_image_info_ptr->width = imgWidth;
+ jpeg_image_info_ptr->height = imgHeight;
+ jpeg_image_info_ptr->imgData.resize(jpeg_image_ptr->length, 0);
+ memcpy(static_cast<void*>(jpeg_image_info_ptr->imgData.data()), jpeg_image_ptr->data,
+ jpeg_image_ptr->length);
+ if (jpeg_dec_obj.getICCSize() != 0) {
+ jpeg_image_info_ptr->iccData.resize(jpeg_dec_obj.getICCSize(), 0);
+ memcpy(static_cast<void*>(jpeg_image_info_ptr->iccData.data()), jpeg_dec_obj.getICCPtr(),
+ jpeg_dec_obj.getICCSize());
+ }
+ if (jpeg_dec_obj.getEXIFSize() != 0) {
+ jpeg_image_info_ptr->exifData.resize(jpeg_dec_obj.getEXIFSize(), 0);
+ memcpy(static_cast<void*>(jpeg_image_info_ptr->exifData.data()), jpeg_dec_obj.getEXIFPtr(),
+ jpeg_dec_obj.getEXIFSize());
+ }
+ if (jpeg_dec_obj.getXMPSize() != 0) {
+ jpeg_image_info_ptr->xmpData.resize(jpeg_dec_obj.getXMPSize(), 0);
+ memcpy(static_cast<void*>(jpeg_image_info_ptr->xmpData.data()), jpeg_dec_obj.getXMPPtr(),
+ jpeg_dec_obj.getXMPSize());
+ }
+ }
+ if (img_width != nullptr && img_height != nullptr) {
+ *img_width = imgWidth;
+ *img_height = imgHeight;
+ }
+ return JPEGR_NO_ERROR;
+}
+
// JPEG/R structure:
// SOI (ff d8)
//