1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ULTRAHDR_JPEGR_H 18 #define ULTRAHDR_JPEGR_H 19 20 #include <array> 21 #include <cfloat> 22 23 #include "ultrahdr_api.h" 24 #include "ultrahdr/ultrahdr.h" 25 #include "ultrahdr/ultrahdrcommon.h" 26 #include "ultrahdr/jpegdecoderhelper.h" 27 #include "ultrahdr/jpegencoderhelper.h" 28 29 namespace ultrahdr { 30 31 // Default configurations 32 // gainmap image downscale factor 33 static const int kMapDimensionScaleFactorDefault = 1; 34 static const int kMapDimensionScaleFactorAndroidDefault = 4; 35 36 // JPEG compress quality (0 ~ 100) for base image 37 static const int kBaseCompressQualityDefault = 95; 38 39 // JPEG compress quality (0 ~ 100) for gain map 40 static const int kMapCompressQualityDefault = 95; 41 static const int kMapCompressQualityAndroidDefault = 85; 42 43 // Gain map calculation 44 static const bool kUseMultiChannelGainMapDefault = true; 45 static const bool kUseMultiChannelGainMapAndroidDefault = false; 46 47 // encoding preset 48 static const uhdr_enc_preset_t kEncSpeedPresetDefault = UHDR_USAGE_BEST_QUALITY; 49 static const uhdr_enc_preset_t kEncSpeedPresetAndroidDefault = UHDR_USAGE_REALTIME; 50 51 // Default gamma value for gain map 52 static const float kGainMapGammaDefault = 1.0f; 53 54 // The current JPEGR version that we encode to 55 static const char* const kJpegrVersion = "1.0"; 56 57 /* 58 * Holds information of jpeg image 59 */ 60 struct jpeg_info_struct { 61 std::vector<uint8_t> imgData = std::vector<uint8_t>(0); 62 std::vector<uint8_t> iccData = std::vector<uint8_t>(0); 63 std::vector<uint8_t> exifData = std::vector<uint8_t>(0); 64 std::vector<uint8_t> xmpData = std::vector<uint8_t>(0); 65 std::vector<uint8_t> isoData = std::vector<uint8_t>(0); 66 unsigned int width; 67 unsigned int height; 68 unsigned int numComponents; 69 }; 70 71 /* 72 * Holds information of jpegr image 73 */ 74 struct jpegr_info_struct { 75 unsigned int width; // copy of primary image width (for easier access) 76 unsigned int height; // copy of primary image height (for easier access) 77 jpeg_info_struct* primaryImgInfo = nullptr; 78 jpeg_info_struct* gainmapImgInfo = nullptr; 79 }; 80 81 typedef struct jpeg_info_struct* j_info_ptr; 82 typedef struct jpegr_info_struct* jr_info_ptr; 83 84 class JpegR { 85 public: 86 JpegR(void* uhdrGLESCtxt = nullptr, 87 int mapDimensionScaleFactor = kMapDimensionScaleFactorAndroidDefault, 88 int mapCompressQuality = kMapCompressQualityAndroidDefault, 89 bool useMultiChannelGainMap = kUseMultiChannelGainMapAndroidDefault, 90 float gamma = kGainMapGammaDefault, 91 uhdr_enc_preset_t preset = kEncSpeedPresetAndroidDefault, float minContentBoost = FLT_MIN, 92 float maxContentBoost = FLT_MAX, float targetDispPeakBrightness = -1.0f); 93 94 /*!\brief Encode API-0. 95 * 96 * Create ultrahdr jpeg image from raw hdr intent. 97 * 98 * Experimental only. 99 * 100 * Input hdr image is tonemapped to sdr image. A gainmap coefficient is computed between hdr and 101 * sdr intent. sdr intent and gain map coefficient are compressed using jpeg encoding. compressed 102 * gainmap is appended at the end of compressed sdr image. 103 * 104 * \param[in] hdr_intent hdr intent raw input image descriptor 105 * \param[in, out] dest output image descriptor to store compressed ultrahdr image 106 * \param[in] quality quality factor for sdr intent jpeg compression 107 * \param[in] exif optional exif metadata that needs to be inserted in 108 * compressed output 109 * 110 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 111 */ 112 uhdr_error_info_t encodeJPEGR(uhdr_raw_image_t* hdr_intent, uhdr_compressed_image_t* dest, 113 int quality, uhdr_mem_block_t* exif); 114 115 /*!\brief Encode API-1. 116 * 117 * Create ultrahdr jpeg image from raw hdr intent and raw sdr intent. 118 * 119 * A gainmap coefficient is computed between hdr and sdr intent. sdr intent and gain map 120 * coefficient are compressed using jpeg encoding. compressed gainmap is appended at the end of 121 * compressed sdr image. 122 * NOTE: Color transfer of sdr intent is expected to be sRGB. 123 * 124 * \param[in] hdr_intent hdr intent raw input image descriptor 125 * \param[in] sdr_intent sdr intent raw input image descriptor 126 * \param[in, out] dest output image descriptor to store compressed ultrahdr image 127 * \param[in] quality quality factor for sdr intent jpeg compression 128 * \param[in] exif optional exif metadata that needs to be inserted in 129 * compressed output 130 * 131 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 132 */ 133 uhdr_error_info_t encodeJPEGR(uhdr_raw_image_t* hdr_intent, uhdr_raw_image_t* sdr_intent, 134 uhdr_compressed_image_t* dest, int quality, uhdr_mem_block_t* exif); 135 136 /*!\brief Encode API-2. 137 * 138 * Create ultrahdr jpeg image from raw hdr intent, raw sdr intent and compressed sdr intent. 139 * 140 * A gainmap coefficient is computed between hdr and sdr intent. gain map coefficient is 141 * compressed using jpeg encoding. compressed gainmap is appended at the end of compressed sdr 142 * intent. ICC profile is added if one isn't present in the sdr intent JPEG image. 143 * NOTE: Color transfer of sdr intent is expected to be sRGB. 144 * NOTE: sdr intent raw and compressed inputs are expected to be related via compress/decompress 145 * operations. 146 * 147 * \param[in] hdr_intent hdr intent raw input image descriptor 148 * \param[in] sdr_intent sdr intent raw input image descriptor 149 * \param[in] sdr_intent_compressed sdr intent compressed input image descriptor 150 * \param[in, out] dest output image descriptor to store compressed ultrahdr 151 * image 152 * 153 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 154 */ 155 uhdr_error_info_t encodeJPEGR(uhdr_raw_image_t* hdr_intent, uhdr_raw_image_t* sdr_intent, 156 uhdr_compressed_image_t* sdr_intent_compressed, 157 uhdr_compressed_image_t* dest); 158 159 /*!\brief Encode API-3. 160 * 161 * Create ultrahdr jpeg image from raw hdr intent and compressed sdr intent. 162 * 163 * The sdr intent is decoded and a gainmap coefficient is computed between hdr and sdr intent. 164 * gain map coefficient is compressed using jpeg encoding. compressed gainmap is appended at the 165 * end of compressed sdr image. ICC profile is added if one isn't present in the sdr intent JPEG 166 * image. 167 * NOTE: Color transfer of sdr intent is expected to be sRGB. 168 * 169 * \param[in] hdr_intent hdr intent raw input image descriptor 170 * \param[in] sdr_intent_compressed sdr intent compressed input image descriptor 171 * \param[in, out] dest output image descriptor to store compressed ultrahdr 172 * image 173 * 174 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 175 */ 176 uhdr_error_info_t encodeJPEGR(uhdr_raw_image_t* hdr_intent, 177 uhdr_compressed_image_t* sdr_intent_compressed, 178 uhdr_compressed_image_t* dest); 179 180 /*!\brief Encode API-4. 181 * 182 * Create ultrahdr jpeg image from compressed sdr image and compressed gainmap image 183 * 184 * compressed gainmap image is added at the end of compressed sdr image. ICC profile is added if 185 * one isn't present in the sdr intent compressed image. 186 * 187 * \param[in] base_img_compressed sdr intent compressed input image descriptor 188 * \param[in] gainmap_img_compressed gainmap compressed image descriptor 189 * \param[in] metadata gainmap metadata descriptor 190 * \param[in, out] dest output image descriptor to store compressed ultrahdr 191 * image 192 * 193 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 194 */ 195 uhdr_error_info_t encodeJPEGR(uhdr_compressed_image_t* base_img_compressed, 196 uhdr_compressed_image_t* gainmap_img_compressed, 197 uhdr_gainmap_metadata_ext_t* metadata, 198 uhdr_compressed_image_t* dest); 199 200 /*!\brief Decode API. 201 * 202 * Decompress ultrahdr jpeg image. 203 * 204 * NOTE: This method requires that the ultrahdr input image contains an ICC profile with primaries 205 * that match those of a color gamut that this library is aware of; Bt.709, Display-P3, or 206 * Bt.2100. It also assumes the base image color transfer characteristics are sRGB. 207 * 208 * \param[in] uhdr_compressed_img compressed ultrahdr image descriptor 209 * \param[in, out] dest output image descriptor to store decoded output 210 * \param[in] max_display_boost (optional) the maximum available boost supported by a 211 * display, the value must be greater than or equal 212 * to 1.0 213 * \param[in] output_ct (optional) output color transfer 214 * \param[in] output_format (optional) output pixel format 215 * \param[in, out] gainmap_img (optional) output image descriptor to store decoded 216 * gainmap image 217 * \param[in, out] gainmap_metadata (optional) descriptor to store gainmap metadata 218 * 219 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 220 * 221 * NOTE: This method only supports single gain map metadata values for fields that allow 222 * multi-channel metadata values. 223 * 224 * NOTE: Not all combinations of output color transfer and output pixel format are supported. 225 * Refer below table for supported combinations. 226 * ---------------------------------------------------------------------- 227 * | color transfer | color format | 228 * ---------------------------------------------------------------------- 229 * | SDR | 32bppRGBA8888 | 230 * ---------------------------------------------------------------------- 231 * | HDR_LINEAR | 64bppRGBAHalfFloat | 232 * ---------------------------------------------------------------------- 233 * | HDR_PQ | 32bppRGBA1010102 | 234 * ---------------------------------------------------------------------- 235 * | HDR_HLG | 32bppRGBA1010102 | 236 * ---------------------------------------------------------------------- 237 */ 238 uhdr_error_info_t decodeJPEGR(uhdr_compressed_image_t* uhdr_compressed_img, 239 uhdr_raw_image_t* dest, float max_display_boost = FLT_MAX, 240 uhdr_color_transfer_t output_ct = UHDR_CT_LINEAR, 241 uhdr_img_fmt_t output_format = UHDR_IMG_FMT_64bppRGBAHalfFloat, 242 uhdr_raw_image_t* gainmap_img = nullptr, 243 uhdr_gainmap_metadata_t* gainmap_metadata = nullptr); 244 245 /*!\brief This function parses the bitstream and returns information that is useful for actual 246 * decoding. This does not decode the image. That is handled by decodeJPEGR 247 * 248 * \param[in] uhdr_compressed_img compressed ultrahdr image descriptor 249 * \param[in, out] uhdr_image_info image info descriptor 250 * 251 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 252 */ 253 uhdr_error_info_t getJPEGRInfo(uhdr_compressed_image_t* uhdr_compressed_img, 254 jr_info_ptr uhdr_image_info); 255 256 /*!\brief set gain map dimension scale factor 257 * NOTE: Applicable only in encoding scenario 258 * 259 * \param[in] mapDimensionScaleFactor scale factor 260 * 261 * \return none 262 */ setMapDimensionScaleFactor(int mapDimensionScaleFactor)263 void setMapDimensionScaleFactor(int mapDimensionScaleFactor) { 264 this->mMapDimensionScaleFactor = mapDimensionScaleFactor; 265 } 266 267 /*!\brief get gain map dimension scale factor 268 * NOTE: Applicable only in encoding scenario 269 * 270 * \return mapDimensionScaleFactor 271 */ getMapDimensionScaleFactor()272 int getMapDimensionScaleFactor() { return this->mMapDimensionScaleFactor; } 273 274 /*!\brief set gain map compression quality factor 275 * NOTE: Applicable only in encoding scenario 276 * 277 * \param[in] mapCompressQuality quality factor for gain map image compression 278 * 279 * \return none 280 */ setMapCompressQuality(int mapCompressQuality)281 void setMapCompressQuality(int mapCompressQuality) { 282 this->mMapCompressQuality = mapCompressQuality; 283 } 284 285 /*!\brief get gain map quality factor 286 * NOTE: Applicable only in encoding scenario 287 * 288 * \return quality factor 289 */ getMapCompressQuality()290 int getMapCompressQuality() { return this->mMapCompressQuality; } 291 292 /*!\brief set gain map gamma 293 * NOTE: Applicable only in encoding scenario 294 * 295 * \param[in] gamma gamma parameter that is used for gain map calculation 296 * 297 * \return none 298 */ setGainMapGamma(float gamma)299 void setGainMapGamma(float gamma) { this->mGamma = gamma; } 300 301 /*!\brief get gain map gamma 302 * NOTE: Applicable only in encoding scenario 303 * 304 * \return gamma parameter 305 */ getGainMapGamma()306 float getGainMapGamma() { return this->mGamma; } 307 308 /*!\brief enable / disable multi channel gain map 309 * NOTE: Applicable only in encoding scenario 310 * 311 * \param[in] useMultiChannelGainMap enable / disable multi channel gain map 312 * 313 * \return none 314 */ setUseMultiChannelGainMap(bool useMultiChannelGainMap)315 void setUseMultiChannelGainMap(bool useMultiChannelGainMap) { 316 this->mUseMultiChannelGainMap = useMultiChannelGainMap; 317 } 318 319 /*!\brief check if multi channel gain map is enabled 320 * NOTE: Applicable only in encoding scenario 321 * 322 * \return true if multi channel gain map is enabled, false otherwise 323 */ isUsingMultiChannelGainMap()324 bool isUsingMultiChannelGainMap() { return this->mUseMultiChannelGainMap; } 325 326 /*!\brief set gain map min and max content boost 327 * NOTE: Applicable only in encoding scenario 328 * 329 * \param[in] minBoost gain map min content boost 330 * \param[in] maxBoost gain map max content boost 331 * 332 * \return none 333 */ setGainMapMinMaxContentBoost(float minBoost,float maxBoost)334 void setGainMapMinMaxContentBoost(float minBoost, float maxBoost) { 335 this->mMinContentBoost = minBoost; 336 this->mMaxContentBoost = maxBoost; 337 } 338 339 /*!\brief get gain map min max content boost 340 * NOTE: Applicable only in encoding scenario 341 * 342 * \param[out] minBoost gain map min content boost 343 * \param[out] maxBoost gain map max content boost 344 * 345 * \return none 346 */ getGainMapMinMaxContentBoost(float & minBoost,float & maxBoost)347 void getGainMapMinMaxContentBoost(float& minBoost, float& maxBoost) { 348 minBoost = this->mMinContentBoost; 349 maxBoost = this->mMaxContentBoost; 350 } 351 352 /* \brief Alias of Encode API-0. 353 * 354 * \deprecated This function is deprecated. Use its alias 355 */ 356 status_t encodeJPEGR(jr_uncompressed_ptr p010_image_ptr, ultrahdr_transfer_function hdr_tf, 357 jr_compressed_ptr dest, int quality, jr_exif_ptr exif); 358 359 /* \brief Alias of Encode API-1. 360 * 361 * \deprecated This function is deprecated. Use its actual 362 */ 363 status_t encodeJPEGR(jr_uncompressed_ptr p010_image_ptr, jr_uncompressed_ptr yuv420_image_ptr, 364 ultrahdr_transfer_function hdr_tf, jr_compressed_ptr dest, int quality, 365 jr_exif_ptr exif); 366 367 /* \brief Alias of Encode API-2. 368 * 369 * \deprecated This function is deprecated. Use its actual 370 */ 371 status_t encodeJPEGR(jr_uncompressed_ptr p010_image_ptr, jr_uncompressed_ptr yuv420_image_ptr, 372 jr_compressed_ptr yuv420jpg_image_ptr, ultrahdr_transfer_function hdr_tf, 373 jr_compressed_ptr dest); 374 375 /* \brief Alias of Encode API-3. 376 * 377 * \deprecated This function is deprecated. Use its actual 378 */ 379 status_t encodeJPEGR(jr_uncompressed_ptr p010_image_ptr, jr_compressed_ptr yuv420jpg_image_ptr, 380 ultrahdr_transfer_function hdr_tf, jr_compressed_ptr dest); 381 382 /* \brief Alias of Encode API-4. 383 * 384 * \deprecated This function is deprecated. Use its actual 385 */ 386 status_t encodeJPEGR(jr_compressed_ptr yuv420jpg_image_ptr, 387 jr_compressed_ptr gainmapjpg_image_ptr, ultrahdr_metadata_ptr metadata, 388 jr_compressed_ptr dest); 389 390 /* \brief Alias of Decode API 391 * 392 * \deprecated This function is deprecated. Use its actual 393 */ 394 status_t decodeJPEGR(jr_compressed_ptr jpegr_image_ptr, jr_uncompressed_ptr dest, 395 float max_display_boost = FLT_MAX, jr_exif_ptr exif = nullptr, 396 ultrahdr_output_format output_format = ULTRAHDR_OUTPUT_HDR_LINEAR, 397 jr_uncompressed_ptr gainmap_image_ptr = nullptr, 398 ultrahdr_metadata_ptr metadata = nullptr); 399 400 /* \brief Alias of getJPEGRInfo 401 * 402 * \deprecated This function is deprecated. Use its actual 403 */ 404 status_t getJPEGRInfo(jr_compressed_ptr jpegr_image_ptr, jr_info_ptr jpegr_image_info_ptr); 405 406 /*!\brief This function receives iso block and / or xmp block and parses gainmap metadata and fill 407 * the output descriptor. If both iso block and xmp block are available, then iso block is 408 * preferred over xmp. 409 * 410 * \param[in] iso_data iso memory block 411 * \param[in] iso_size iso block size 412 * \param[in] xmp_data xmp memory block 413 * \param[in] xmp_size xmp block size 414 * \param[in, out] gainmap_metadata gainmap metadata descriptor 415 * 416 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 417 */ 418 uhdr_error_info_t parseGainMapMetadata(uint8_t* iso_data, size_t iso_size, uint8_t* xmp_data, 419 size_t xmp_size, 420 uhdr_gainmap_metadata_ext_t* uhdr_metadata); 421 422 /*!\brief This method is used to tone map a hdr image 423 * 424 * \param[in] hdr_intent hdr image descriptor 425 * \param[in, out] sdr_intent sdr image descriptor 426 * 427 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 428 */ 429 uhdr_error_info_t toneMap(uhdr_raw_image_t* hdr_intent, uhdr_raw_image_t* sdr_intent); 430 431 /*!\brief This method takes hdr intent and sdr intent and computes gainmap coefficient. 432 * 433 * This method is called in the encoding pipeline. It takes uncompressed 8-bit and 10-bit yuv 434 * images as input and calculates gainmap. 435 * 436 * NOTE: The input images must be the same resolution. 437 * NOTE: The SDR input is assumed to use the sRGB transfer function. 438 * 439 * \param[in] sdr_intent sdr intent raw input image descriptor 440 * \param[in] hdr_intent hdr intent raw input image descriptor 441 * \param[in, out] gainmap_metadata gainmap metadata descriptor 442 * \param[in, out] gainmap_img gainmap image descriptor 443 * \param[in] sdr_is_601 (optional) if sdr_is_601 is true, then use BT.601 444 * gamut to represent sdr intent regardless of the value 445 * present in the sdr intent image descriptor 446 * \param[in] use_luminance (optional) used for single channel gainmap. If 447 * use_luminance is true, gainmap calculation is based 448 * on the pixel's luminance which is a weighted 449 * combination of r, g, b channels; otherwise, gainmap 450 * calculation is based of the maximun value of r, g, b 451 * channels. 452 * 453 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 454 */ 455 uhdr_error_info_t generateGainMap(uhdr_raw_image_t* sdr_intent, uhdr_raw_image_t* hdr_intent, 456 uhdr_gainmap_metadata_ext_t* gainmap_metadata, 457 std::unique_ptr<uhdr_raw_image_ext_t>& gainmap_img, 458 bool sdr_is_601 = false, bool use_luminance = true); 459 460 protected: 461 /*!\brief This method takes sdr intent, gainmap image and gainmap metadata and computes hdr 462 * intent. This method is called in the decoding pipeline. The output hdr intent image will have 463 * same color gamut as sdr intent. 464 * 465 * NOTE: The SDR input is assumed to use the sRGB transfer function. 466 * 467 * \param[in] sdr_intent sdr intent raw input image descriptor 468 * \param[in] gainmap_img gainmap image descriptor 469 * \param[in] gainmap_metadata gainmap metadata descriptor 470 * \param[in] output_ct output color transfer 471 * \param[in] output_format output pixel format 472 * \param[in] max_display_boost the maximum available boost supported by a 473 * display, the value must be greater than or equal 474 * to 1.0 475 * \param[in, out] dest output image descriptor to store output 476 * 477 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 478 */ 479 uhdr_error_info_t applyGainMap(uhdr_raw_image_t* sdr_intent, uhdr_raw_image_t* gainmap_img, 480 uhdr_gainmap_metadata_ext_t* gainmap_metadata, 481 uhdr_color_transfer_t output_ct, uhdr_img_fmt_t output_format, 482 float max_display_boost, uhdr_raw_image_t* dest); 483 484 private: 485 /*!\brief compress gainmap image 486 * 487 * \param[in] gainmap_img gainmap image descriptor 488 * \param[in] jpeg_enc_obj jpeg encoder object handle 489 * 490 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 491 */ 492 uhdr_error_info_t compressGainMap(uhdr_raw_image_t* gainmap_img, JpegEncoderHelper* jpeg_enc_obj); 493 494 /*!\brief This method is called to separate base image and gain map image from compressed 495 * ultrahdr image 496 * 497 * \param[in] jpegr_image compressed ultrahdr image descriptor 498 * \param[in, out] primary_image sdr image descriptor 499 * \param[in, out] gainmap_image gainmap image descriptor 500 * 501 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 502 */ 503 uhdr_error_info_t extractPrimaryImageAndGainMap(uhdr_compressed_image_t* jpegr_image, 504 uhdr_compressed_image_t* primary_image, 505 uhdr_compressed_image_t* gainmap_image); 506 507 /*!\brief This function parses the bitstream and returns metadata that is useful for actual 508 * decoding. This does not decode the image. That is handled by decompressImage(). 509 * 510 * \param[in] jpeg_image compressed jpeg image descriptor 511 * \param[in, out] image_info image info descriptor 512 * \param[in, out] img_width (optional) image width 513 * \param[in, out] img_height (optional) image height 514 * 515 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 516 */ 517 uhdr_error_info_t parseJpegInfo(uhdr_compressed_image_t* jpeg_image, j_info_ptr image_info, 518 unsigned int* img_width = nullptr, 519 unsigned int* img_height = nullptr); 520 521 /*!\brief This method takes compressed sdr intent, compressed gainmap coefficient, gainmap 522 * metadata and creates a ultrahdr image. This is done by first generating XMP packet from gainmap 523 * metadata, then appending in the order, 524 * SOI, APP2 (Exif is present), APP2 (XMP), base image, gain map image. 525 * 526 * NOTE: In the final output, EXIF package will appear if ONLY ONE of the following conditions is 527 * fulfilled: 528 * (1) EXIF package is available from outside input. I.e. pExif != nullptr. 529 * (2) Compressed sdr intent has EXIF. 530 * If both conditions are fulfilled, this method will return error indicating that it is unable to 531 * choose which exif to be placed in the bitstream. 532 * 533 * \param[in] sdr_intent_compressed sdr intent image descriptor 534 * \param[in] gainmap_compressed gainmap intent input image descriptor 535 * \param[in] pExif exif block to be placed in the bitstream 536 * \param[in] pIcc pointer to icc segment that needs to be added to the 537 * compressed image 538 * \param[in] icc_size size of icc segment 539 * \param[in] metadata gainmap metadata descriptor 540 * \param[in, out] dest output image descriptor to store compressed ultrahdr 541 * image 542 * 543 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 544 */ 545 uhdr_error_info_t appendGainMap(uhdr_compressed_image_t* sdr_intent_compressed, 546 uhdr_compressed_image_t* gainmap_compressed, 547 uhdr_mem_block_t* pExif, void* pIcc, size_t icc_size, 548 uhdr_gainmap_metadata_ext_t* metadata, 549 uhdr_compressed_image_t* dest); 550 551 /*!\brief This method is used to convert a raw image from one gamut space to another gamut space 552 * in-place. 553 * 554 * \param[in, out] image raw image descriptor 555 * \param[in] src_encoding input gamut space 556 * \param[in] dst_encoding destination gamut space 557 * 558 * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise. 559 */ 560 uhdr_error_info_t convertYuv(uhdr_raw_image_t* image, uhdr_color_gamut_t src_encoding, 561 uhdr_color_gamut_t dst_encoding); 562 563 /* 564 * This method will check the validity of the input arguments. 565 * 566 * @param p010_image_ptr uncompressed HDR image in P010 color format 567 * @param yuv420_image_ptr pointer to uncompressed SDR image struct. HDR image is expected to 568 * be in 420p color format 569 * @param hdr_tf transfer function of the HDR image 570 * @param dest destination of the compressed JPEGR image. Please note that {@code maxLength} 571 * represents the maximum available size of the desitination buffer, and it must be 572 * set before calling this method. If the encoded JPEGR size exceeds 573 * {@code maxLength}, this method will return {@code ERROR_JPEGR_BUFFER_TOO_SMALL}. 574 * @return NO_ERROR if the input args are valid, error code is not valid. 575 */ 576 status_t areInputArgumentsValid(jr_uncompressed_ptr p010_image_ptr, 577 jr_uncompressed_ptr yuv420_image_ptr, 578 ultrahdr_transfer_function hdr_tf, jr_compressed_ptr dest_ptr); 579 580 /* 581 * This method will check the validity of the input arguments. 582 * 583 * @param p010_image_ptr uncompressed HDR image in P010 color format 584 * @param yuv420_image_ptr pointer to uncompressed SDR image struct. HDR image is expected to 585 * be in 420p color format 586 * @param hdr_tf transfer function of the HDR image 587 * @param dest destination of the compressed JPEGR image. Please note that {@code maxLength} 588 * represents the maximum available size of the destination buffer, and it must be 589 * set before calling this method. If the encoded JPEGR size exceeds 590 * {@code maxLength}, this method will return {@code ERROR_JPEGR_BUFFER_TOO_SMALL}. 591 * @param quality target quality of the JPEG encoding, must be in range of 0-100 where 100 is 592 * the highest quality 593 * @return NO_ERROR if the input args are valid, error code is not valid. 594 */ 595 status_t areInputArgumentsValid(jr_uncompressed_ptr p010_image_ptr, 596 jr_uncompressed_ptr yuv420_image_ptr, 597 ultrahdr_transfer_function hdr_tf, jr_compressed_ptr dest, 598 int quality); 599 600 // Configurations 601 void* mUhdrGLESCtxt; // opengl es context 602 int mMapDimensionScaleFactor; // gain map scale factor 603 int mMapCompressQuality; // gain map quality factor 604 bool mUseMultiChannelGainMap; // enable multichannel gain map 605 float mGamma; // gain map gamma parameter 606 uhdr_enc_preset_t mEncPreset; // encoding speed preset 607 float mMinContentBoost; // min content boost recommendation 608 float mMaxContentBoost; // max content boost recommendation 609 float mTargetDispPeakBrightness; // target display max luminance in nits 610 }; 611 612 /* 613 * Holds tonemapping results of a pixel 614 */ 615 struct GlobalTonemapOutputs { 616 std::array<float, 3> rgb_out; 617 float y_hdr; 618 float y_sdr; 619 }; 620 621 /*!\brief Applies a global tone mapping, based on Chrome's HLG/PQ rendering implemented at 622 * https://source.chromium.org/chromium/chromium/src/+/main:ui/gfx/color_transform.cc;l=1197-1252;drc=ac505aff1d29ec3bfcf317cb77d5e196a3664e92 623 * 624 * \param[in] rgb_in hdr intent pixel in array format. 625 * \param[in] headroom ratio between hdr and sdr peak luminances. Must be greater 626 * than 1. If the input is normalized, then this is used to 627 * stretch it linearly from [0.0..1.0] to [0.0..headroom] 628 * \param[in] is_normalized marker to differentiate, if the input is normalized. 629 * 630 * \return tonemapped pixel in the normalized range [0.0..1.0] 631 */ 632 GlobalTonemapOutputs globalTonemap(const std::array<float, 3>& rgb_in, float headroom, 633 bool is_normalized); 634 635 } // namespace ultrahdr 636 637 #endif // ULTRAHDR_JPEGR_H 638