Coverage Report

Created: 2025-12-05 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libultrahdr/lib/include/ultrahdr/jpegr.h
Line
Count
Source
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
   */
263
0
  void setMapDimensionScaleFactor(int mapDimensionScaleFactor) {
264
0
    this->mMapDimensionScaleFactor = mapDimensionScaleFactor;
265
0
  }
266
267
  /*!\brief get gain map dimension scale factor
268
   * NOTE: Applicable only in encoding scenario
269
   *
270
   * \return mapDimensionScaleFactor
271
   */
272
0
  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
   */
281
0
  void setMapCompressQuality(int mapCompressQuality) {
282
0
    this->mMapCompressQuality = mapCompressQuality;
283
0
  }
284
285
  /*!\brief get gain map quality factor
286
   * NOTE: Applicable only in encoding scenario
287
   *
288
   * \return quality factor
289
   */
290
0
  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
   */
299
0
  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
   */
306
0
  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
   */
315
0
  void setUseMultiChannelGainMap(bool useMultiChannelGainMap) {
316
0
    this->mUseMultiChannelGainMap = useMultiChannelGainMap;
317
0
  }
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
   */
324
0
  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
   */
334
0
  void setGainMapMinMaxContentBoost(float minBoost, float maxBoost) {
335
0
    this->mMinContentBoost = minBoost;
336
0
    this->mMaxContentBoost = maxBoost;
337
0
  }
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
   */
347
0
  void getGainMapMinMaxContentBoost(float& minBoost, float& maxBoost) {
348
0
    minBoost = this->mMinContentBoost;
349
0
    maxBoost = this->mMaxContentBoost;
350
0
  }
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