Coverage Report

Created: 2026-08-13 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libultrahdr/lib/include/ultrahdr/ultrahdrcommon.h
Line
Count
Source
1
/*
2
 * Copyright 2023 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7
 * option. This file may not be copied, modified, or distributed
8
 * except according to those terms.
9
 */
10
11
#ifndef ULTRAHDR_ULTRAHDRCOMMON_H
12
#define ULTRAHDR_ULTRAHDRCOMMON_H
13
14
//#define LOG_NDEBUG 0
15
16
#ifdef UHDR_ENABLE_GLES
17
#include <EGL/egl.h>
18
#include <GLES3/gl3.h>
19
#endif
20
21
#include <array>
22
#include <cfloat>
23
#include <cstdint>
24
#include <deque>
25
#include <map>
26
#include <memory>
27
#include <string>
28
#include <vector>
29
30
#include "ultrahdr_api.h"
31
32
// ===============================================================================================
33
// Function Macros
34
// ===============================================================================================
35
36
#ifdef __ANDROID__
37
38
#ifdef LOG_NDEBUG
39
#include "android/log.h"
40
41
#ifndef LOG_TAG
42
#define LOG_TAG "UHDR"
43
#endif
44
45
#ifndef ALOGD
46
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
47
#endif
48
49
#ifndef ALOGE
50
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
51
#endif
52
53
#ifndef ALOGI
54
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
55
#endif
56
57
#ifndef ALOGV
58
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
59
#endif
60
61
#ifndef ALOGW
62
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
63
#endif
64
65
#else
66
67
#define ALOGD(...) ((void)0)
68
#define ALOGE(...) ((void)0)
69
#define ALOGI(...) ((void)0)
70
#define ALOGV(...) ((void)0)
71
#define ALOGW(...) ((void)0)
72
73
#endif
74
75
#else
76
77
#ifdef LOG_NDEBUG
78
#include <cstdio>
79
80
#define ALOGD(...)                \
81
  do {                            \
82
    fprintf(stderr, __VA_ARGS__); \
83
    fprintf(stderr, "\n");        \
84
  } while (0)
85
86
#define ALOGE(...)                \
87
  do {                            \
88
    fprintf(stderr, __VA_ARGS__); \
89
    fprintf(stderr, "\n");        \
90
  } while (0)
91
92
#define ALOGI(...)                \
93
  do {                            \
94
    fprintf(stdout, __VA_ARGS__); \
95
    fprintf(stdout, "\n");        \
96
  } while (0)
97
98
#define ALOGV(...)                \
99
  do {                            \
100
    fprintf(stdout, __VA_ARGS__); \
101
    fprintf(stdout, "\n");        \
102
  } while (0)
103
104
#define ALOGW(...)                \
105
  do {                            \
106
    fprintf(stderr, __VA_ARGS__); \
107
    fprintf(stderr, "\n");        \
108
  } while (0)
109
110
#else
111
112
924
#define ALOGD(...) ((void)0)
113
37.5k
#define ALOGE(...) ((void)0)
114
#define ALOGI(...) ((void)0)
115
84.5k
#define ALOGV(...) ((void)0)
116
811
#define ALOGW(...) ((void)0)
117
118
#endif
119
120
#endif
121
122
43.7k
#define ALIGNM(x, m) ((((x) + ((m)-1)) / (m)) * (m))
123
124
#define UHDR_ERR_CHECK(x)                     \
125
319k
  {                                           \
126
319k
    uhdr_error_info_t status = (x);           \
127
319k
    if (status.error_code != UHDR_CODEC_OK) { \
128
18.6k
      return status;                          \
129
18.6k
    }                                         \
130
319k
  }
131
132
#if defined(_MSC_VER)
133
#define FORCE_INLINE __forceinline
134
#define INLINE __inline
135
#else
136
#define FORCE_INLINE __inline__ __attribute__((always_inline))
137
#define INLINE inline
138
#endif
139
140
// '__has_attribute' macro was introduced by clang. later picked up by gcc.
141
// If not supported by the current toolchain, define it to zero.
142
#ifndef __has_attribute
143
#define __has_attribute(x) 0
144
#endif
145
146
// Disables undefined behavior analysis for a function.
147
// GCC 4.9+ uses __attribute__((no_sanitize_undefined))
148
// clang uses __attribute__((no_sanitize("undefined")))
149
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
150
#define UHDR_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined))
151
#elif __has_attribute(no_sanitize)
152
#define UHDR_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
153
#else
154
#define UHDR_NO_SANITIZE_UNDEFINED
155
#endif
156
157
static const uhdr_error_info_t g_no_error = {UHDR_CODEC_OK, 0, ""};
158
159
namespace ultrahdr {
160
161
// ===============================================================================================
162
// Globals
163
// ===============================================================================================
164
extern const int kMinWidth, kMinHeight;
165
extern const int kMaxWidth, kMaxHeight;
166
167
// ===============================================================================================
168
// Structure Definitions
169
// ===============================================================================================
170
171
/**\brief uhdr memory block */
172
typedef struct uhdr_memory_block {
173
  uhdr_memory_block(size_t capacity);
174
175
  std::unique_ptr<uint8_t[]> m_buffer; /**< data */
176
  size_t m_capacity;                   /**< capacity */
177
} uhdr_memory_block_t;                 /**< alias for struct uhdr_memory_block */
178
179
/**\brief extended raw image descriptor */
180
typedef struct uhdr_raw_image_ext : uhdr_raw_image_t {
181
  uhdr_raw_image_ext(uhdr_img_fmt_t fmt, uhdr_color_gamut_t cg, uhdr_color_transfer_t ct,
182
                     uhdr_color_range_t range, unsigned w, unsigned h, unsigned align_stride_to);
183
184
 private:
185
  std::unique_ptr<ultrahdr::uhdr_memory_block> m_block;
186
} uhdr_raw_image_ext_t; /**< alias for struct uhdr_raw_image_ext */
187
188
/**\brief extended compressed image descriptor */
189
typedef struct uhdr_compressed_image_ext : uhdr_compressed_image_t {
190
  uhdr_compressed_image_ext(uhdr_color_gamut_t cg, uhdr_color_transfer_t ct,
191
                            uhdr_color_range_t range, size_t sz);
192
193
 private:
194
  std::unique_ptr<ultrahdr::uhdr_memory_block> m_block;
195
} uhdr_compressed_image_ext_t; /**< alias for struct uhdr_compressed_image_ext */
196
197
/*!\brief forward declaration for image effect descriptor */
198
typedef struct uhdr_effect_desc uhdr_effect_desc_t;
199
200
/**\brief Gain map metadata. */
201
typedef struct uhdr_gainmap_metadata_ext : uhdr_gainmap_metadata {
202
18.2k
  uhdr_gainmap_metadata_ext() {}
203
204
439
  uhdr_gainmap_metadata_ext(std::string ver) : version(ver) {}
205
206
  uhdr_gainmap_metadata_ext(uhdr_gainmap_metadata& metadata, std::string ver)
207
0
      : uhdr_gainmap_metadata_ext(ver) {
208
0
    std::copy(metadata.max_content_boost, metadata.max_content_boost + 3, max_content_boost);
209
0
    std::copy(metadata.min_content_boost, metadata.min_content_boost + 3, min_content_boost);
210
0
    std::copy(metadata.gamma, metadata.gamma + 3, gamma);
211
0
    std::copy(metadata.offset_sdr, metadata.offset_sdr + 3, offset_sdr);
212
0
    std::copy(metadata.offset_hdr, metadata.offset_hdr + 3, offset_hdr);
213
0
    hdr_capacity_min = metadata.hdr_capacity_min;
214
0
    hdr_capacity_max = metadata.hdr_capacity_max;
215
0
    use_base_cg = metadata.use_base_cg;
216
0
  }
217
218
1.11k
  bool are_all_channels_identical() const {
219
1.11k
    return max_content_boost[0] == max_content_boost[1] &&
220
1.11k
           max_content_boost[0] == max_content_boost[2] &&
221
1.11k
           min_content_boost[0] == min_content_boost[1] &&
222
1.11k
           min_content_boost[0] == min_content_boost[2] && gamma[0] == gamma[1] &&
223
1.11k
           gamma[0] == gamma[2] && offset_sdr[0] == offset_sdr[1] &&
224
1.10k
           offset_sdr[0] == offset_sdr[2] && offset_hdr[0] == offset_hdr[1] &&
225
1.10k
           offset_hdr[0] == offset_hdr[2];
226
1.11k
  }
227
228
  std::string version;         /**< Ultra HDR format version */
229
} uhdr_gainmap_metadata_ext_t; /**< alias for struct uhdr_gainmap_metadata */
230
231
#ifdef UHDR_ENABLE_GLES
232
233
typedef enum uhdr_effect_shader {
234
  UHDR_MIR_HORZ,
235
  UHDR_MIR_VERT,
236
  UHDR_ROT_90,
237
  UHDR_ROT_180,
238
  UHDR_ROT_270,
239
  UHDR_CROP,
240
  UHDR_RESIZE,
241
} uhdr_effect_shader_t;
242
243
/**\brief OpenGL context */
244
typedef struct uhdr_opengl_ctxt {
245
  // EGL Context
246
  EGLDisplay mEGLDisplay; /**< EGL display connection */
247
  EGLContext mEGLContext; /**< EGL rendering context */
248
  EGLSurface mEGLSurface; /**< EGL surface for rendering */
249
  EGLConfig mEGLConfig;   /**< EGL frame buffer configuration */
250
251
  // GLES Context
252
  GLuint mQuadVAO, mQuadVBO, mQuadEBO;           /**< GL objects */
253
  GLuint mShaderProgram[UHDR_RESIZE + 1];        /**< Shader programs */
254
  GLuint mDecodedImgTexture, mGainmapImgTexture; /**< GL Textures */
255
  uhdr_error_info_t mErrorStatus;                /**< Context status */
256
257
  uhdr_opengl_ctxt();
258
  ~uhdr_opengl_ctxt();
259
260
  /*!\brief Initializes the OpenGL context. Mainly it prepares EGL. We want a GLES3.0 context and a
261
   * surface that supports pbuffer. Once this is done and surface is made current, the gl state is
262
   * initialized
263
   *
264
   * \return none
265
   */
266
  void init_opengl_ctxt();
267
268
  /*!\brief This method is used to compile a shader
269
   *
270
   * \param[in]   type    shader type
271
   * \param[in]   source  shader source code
272
   *
273
   * \return GLuint #shader_id if operation succeeds, 0 otherwise.
274
   */
275
  GLuint compile_shader(GLenum type, const char* source);
276
277
  /*!\brief This method is used to create a shader program
278
   *
279
   * \param[in]   vertex_source      vertex shader source code
280
   * \param[in]   fragment_source    fragment shader source code
281
   *
282
   * \return GLuint #shader_program_id if operation succeeds, 0 otherwise.
283
   */
284
  GLuint create_shader_program(const char* vertex_source, const char* fragment_source);
285
286
  /*!\brief This method is used to create a 2D texture for a raw image
287
   * NOTE: For multichannel planar image, this method assumes the channel data to be contiguous
288
   * NOTE: For any channel, this method assumes width and stride to be identical
289
   *
290
   * \param[in]   fmt       image format
291
   * \param[in]   w         image width
292
   * \param[in]   h         image height
293
   * \param[in]   data      image data
294
   *
295
   * \return GLuint #texture_id if operation succeeds, 0 otherwise.
296
   */
297
  GLuint create_texture(uhdr_img_fmt_t fmt, int w, int h, void* data);
298
299
  /*!\breif This method is used to read data from texture into a raw image
300
   * NOTE: For any channel, this method assumes width and stride to be identical
301
   *
302
   * \param[in]   texture    texture_id
303
   * \param[in]   fmt        image format
304
   * \param[in]   w          image width
305
   * \param[in]   h          image height
306
   * \param[in]   data       image data
307
   *
308
   * \return none
309
   */
310
  void read_texture(GLuint* texture, uhdr_img_fmt_t fmt, int w, int h, void* data);
311
312
  /*!\brief This method is used to set up quad buffers and arrays
313
   *
314
   * \return none
315
   */
316
  void setup_quad();
317
318
  /*!\brief This method is used to set up frame buffer for a 2D texture
319
   *
320
   * \param[in]   texture         texture id
321
   *
322
   * \return GLuint #framebuffer_id if operation succeeds, 0 otherwise.
323
   */
324
  GLuint setup_framebuffer(GLuint& texture);
325
326
  /*!\brief Checks for gl errors. On error, internal error state is updated with details
327
   *
328
   * \param[in]   msg     useful description for logging
329
   *
330
   * \return none
331
   */
332
  void check_gl_errors(const char* msg);
333
334
  /*!\brief Reset the current context to default state for reuse
335
   *
336
   * \return none
337
   */
338
  void reset_opengl_ctxt();
339
340
  /*!\brief Deletes the current context
341
   *
342
   * \return none
343
   */
344
  void delete_opengl_ctxt();
345
346
} uhdr_opengl_ctxt_t; /**< alias for struct uhdr_opengl_ctxt */
347
348
bool isBufferDataContiguous(uhdr_raw_image_t* img);
349
350
#endif
351
352
uhdr_error_info_t uhdr_validate_gainmap_metadata_descriptor(uhdr_gainmap_metadata_t* metadata);
353
354
}  // namespace ultrahdr
355
356
// ===============================================================================================
357
// Extensions of ultrahdr api definitions, so outside ultrahdr namespace
358
// ===============================================================================================
359
360
struct uhdr_codec_private {
361
  std::deque<ultrahdr::uhdr_effect_desc_t*> m_effects;
362
#ifdef UHDR_ENABLE_GLES
363
  ultrahdr::uhdr_opengl_ctxt_t m_uhdr_gl_ctxt;
364
  bool m_enable_gles;
365
#endif
366
  bool m_sailed;
367
368
  virtual ~uhdr_codec_private();
369
};
370
371
struct uhdr_encoder_private : uhdr_codec_private {
372
  // config data
373
  std::map<uhdr_img_label, std::unique_ptr<ultrahdr::uhdr_raw_image_ext_t>> m_raw_images;
374
  std::map<uhdr_img_label, std::unique_ptr<ultrahdr::uhdr_compressed_image_ext_t>>
375
      m_compressed_images;
376
  std::map<uhdr_img_label, int> m_quality;
377
  std::vector<uint8_t> m_exif;
378
  uhdr_gainmap_metadata_t m_metadata;
379
  uhdr_codec_t m_output_format;
380
  int m_gainmap_scale_factor;
381
  bool m_use_multi_channel_gainmap;
382
  float m_gamma;
383
  uhdr_enc_preset_t m_enc_preset;
384
  float m_min_content_boost;
385
  float m_max_content_boost;
386
  float m_target_disp_max_brightness;
387
388
  // internal data
389
  std::unique_ptr<ultrahdr::uhdr_compressed_image_ext_t> m_compressed_output_buffer;
390
  uhdr_error_info_t m_encode_call_status;
391
};
392
393
struct uhdr_decoder_private : uhdr_codec_private {
394
  // config data
395
  std::unique_ptr<ultrahdr::uhdr_compressed_image_ext_t> m_uhdr_compressed_img;
396
  uhdr_img_fmt_t m_output_fmt;
397
  uhdr_color_transfer_t m_output_ct;
398
  float m_output_max_disp_boost;
399
400
  // internal data
401
  bool m_probed;
402
  bool m_is_jpeg;
403
  std::unique_ptr<ultrahdr::uhdr_raw_image_ext_t> m_decoded_img_buffer;
404
  std::unique_ptr<ultrahdr::uhdr_raw_image_ext_t> m_gainmap_img_buffer;
405
  int m_img_wd, m_img_ht;
406
  int m_gainmap_wd, m_gainmap_ht, m_gainmap_num_comp;
407
  std::vector<uint8_t> m_exif;
408
  uhdr_mem_block_t m_exif_block;
409
  std::vector<uint8_t> m_icc;
410
  uhdr_mem_block_t m_icc_block;
411
  std::vector<uint8_t> m_base_img;
412
  uhdr_mem_block_t m_base_img_block;
413
  std::vector<uint8_t> m_gainmap_img;
414
  uhdr_mem_block_t m_gainmap_img_block;
415
  uhdr_gainmap_metadata_t m_metadata;
416
  uhdr_error_info_t m_probe_call_status;
417
  uhdr_error_info_t m_decode_call_status;
418
};
419
420
namespace ultrahdr {
421
422
// Default configurations
423
// gainmap image downscale factor
424
static const int kMapDimensionScaleFactorDefault = 1;
425
static const int kMapDimensionScaleFactorAndroidDefault = 4;
426
427
// JPEG compress quality (0 ~ 100) for base image
428
static const int kBaseCompressQualityDefault = 95;
429
430
// JPEG compress quality (0 ~ 100) for gain map
431
static const int kMapCompressQualityDefault = 95;
432
static const int kMapCompressQualityAndroidDefault = 85;
433
434
// Gain map calculation
435
static const bool kUseMultiChannelGainMapDefault = true;
436
static const bool kUseMultiChannelGainMapAndroidDefault = false;
437
438
// encoding preset
439
static const uhdr_enc_preset_t kEncSpeedPresetDefault = UHDR_USAGE_BEST_QUALITY;
440
static const uhdr_enc_preset_t kEncSpeedPresetAndroidDefault = UHDR_USAGE_REALTIME;
441
442
// Default gamma value for gain map
443
static const float kGainMapGammaDefault = 1.0f;
444
445
// The current JPEGR version that we encode to
446
static const char* const kJpegrVersion = "1.0";
447
448
class UltraHdr {
449
 public:
450
  UltraHdr(void* uhdrGLESCtxt = nullptr,
451
           int mapDimensionScaleFactor = kMapDimensionScaleFactorAndroidDefault,
452
           int mapCompressQuality = kMapCompressQualityAndroidDefault,
453
           bool useMultiChannelGainMap = kUseMultiChannelGainMapAndroidDefault,
454
           float gamma = kGainMapGammaDefault,
455
           uhdr_enc_preset_t preset = kEncSpeedPresetAndroidDefault,
456
           float minContentBoost = FLT_MIN, float maxContentBoost = FLT_MAX,
457
           float targetDispPeakBrightness = -1.0f);
458
459
  /*!\brief This function receives iso block and / or xmp block and parses gainmap metadata and fill
460
   * the output descriptor. If both iso block and xmp block are available, then iso block is
461
   * preferred over xmp.
462
   *
463
   * \param[in]       iso_data                  iso memory block
464
   * \param[in]       iso_size                  iso block size
465
   * \param[in]       xmp_data                  xmp memory block
466
   * \param[in]       xmp_size                  xmp block size
467
   * \param[in, out]  gainmap_metadata          gainmap metadata descriptor
468
   *
469
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
470
   */
471
  uhdr_error_info_t parseGainMapMetadata(uint8_t* iso_data, size_t iso_size, uint8_t* xmp_data,
472
                                         size_t xmp_size, uint8_t* exif_data, int exif_size,
473
                                         uhdr_gainmap_metadata_ext_t* uhdr_metadata);
474
475
  /*!\brief This method is used to tone map a hdr image
476
   *
477
   * \param[in]            hdr_intent      hdr image descriptor
478
   * \param[in, out]       sdr_intent      sdr image descriptor
479
   *
480
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
481
   */
482
  uhdr_error_info_t toneMap(uhdr_raw_image_t* hdr_intent, uhdr_raw_image_t* sdr_intent);
483
484
  /*!\brief This method takes hdr intent and sdr intent and computes gainmap coefficient.
485
   *
486
   * This method is called in the encoding pipeline. It takes uncompressed 8-bit and 10-bit yuv
487
   * images as input and calculates gainmap.
488
   *
489
   * NOTE: The input images must be the same resolution.
490
   * NOTE: The SDR input is assumed to use the sRGB transfer function.
491
   *
492
   * \param[in]       sdr_intent               sdr intent raw input image descriptor
493
   * \param[in]       hdr_intent               hdr intent raw input image descriptor
494
   * \param[in, out]  gainmap_metadata         gainmap metadata descriptor
495
   * \param[in, out]  gainmap_img              gainmap image descriptor
496
   * \param[in]       sdr_is_601               (optional) if sdr_is_601 is true, then use BT.601
497
   *                                           gamut to represent sdr intent regardless of the value
498
   *                                           present in the sdr intent image descriptor
499
   * \param[in]       use_luminance            (optional) used for single channel gainmap. If
500
   *                                           use_luminance is true, gainmap calculation is based
501
   *                                           on the pixel's luminance which is a weighted
502
   *                                           combination of r, g, b channels; otherwise, gainmap
503
   *                                           calculation is based of the maximun value of r, g, b
504
   *                                           channels.
505
   *
506
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
507
   */
508
  uhdr_error_info_t generateGainMap(uhdr_raw_image_t* sdr_intent, uhdr_raw_image_t* hdr_intent,
509
                                    uhdr_gainmap_metadata_ext_t* gainmap_metadata,
510
                                    std::unique_ptr<uhdr_raw_image_ext_t>& gainmap_img,
511
                                    bool sdr_is_601 = false, bool use_luminance = true);
512
513
  /*!\brief This method takes sdr intent, gainmap image and gainmap metadata and computes hdr
514
   * intent. This method is called in the decoding pipeline. The output hdr intent image will have
515
   * same color gamut as sdr intent.
516
   *
517
   * NOTE: The SDR input is assumed to use the sRGB transfer function.
518
   *
519
   * \param[in]       sdr_intent               sdr intent raw input image descriptor
520
   * \param[in]       gainmap_img              gainmap image descriptor
521
   * \param[in]       gainmap_metadata         gainmap metadata descriptor
522
   * \param[in]       output_ct                output color transfer
523
   * \param[in]       output_format            output pixel format
524
   * \param[in]       max_display_boost        the maximum available boost supported by a
525
   *                                           display, the value must be greater than or equal
526
   *                                           to 1.0
527
   * \param[in, out]  dest                     output image descriptor to store output
528
   *
529
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
530
   */
531
  uhdr_error_info_t applyGainMap(uhdr_raw_image_t* sdr_intent, uhdr_raw_image_t* gainmap_img,
532
                                 uhdr_gainmap_metadata_ext_t* gainmap_metadata,
533
                                 uhdr_color_transfer_t output_ct, uhdr_img_fmt_t output_format,
534
                                 float max_display_boost, uhdr_raw_image_t* dest);
535
536
  /*!\brief This method is used to convert a raw image from one gamut space to another gamut space
537
   * in-place.
538
   *
539
   * \param[in, out]  image              raw image descriptor
540
   * \param[in]       src_encoding       input gamut space
541
   * \param[in]       dst_encoding       destination gamut space
542
   *
543
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
544
   */
545
  uhdr_error_info_t convertYuv(uhdr_raw_image_t* image, uhdr_color_gamut_t src_encoding,
546
                               uhdr_color_gamut_t dst_encoding);
547
548
 protected:
549
  /*!\brief set gain map dimension scale factor
550
   * NOTE: Applicable only in encoding scenario
551
   *
552
   * \param[in]       mapDimensionScaleFactor      scale factor
553
   *
554
   * \return none
555
   */
556
0
  void setMapDimensionScaleFactor(int mapDimensionScaleFactor) {
557
0
    this->mMapDimensionScaleFactor = mapDimensionScaleFactor;
558
0
  }
559
560
  /*!\brief get gain map dimension scale factor
561
   * NOTE: Applicable only in encoding scenario
562
   *
563
   * \return mapDimensionScaleFactor
564
   */
565
0
  int getMapDimensionScaleFactor() { return this->mMapDimensionScaleFactor; }
566
567
  /*!\brief set gain map compression quality factor
568
   * NOTE: Applicable only in encoding scenario
569
   *
570
   * \param[in]       mapCompressQuality      quality factor for gain map image compression
571
   *
572
   * \return none
573
   */
574
0
  void setMapCompressQuality(int mapCompressQuality) {
575
0
    this->mMapCompressQuality = mapCompressQuality;
576
0
  }
577
578
  /*!\brief get gain map quality factor
579
   * NOTE: Applicable only in encoding scenario
580
   *
581
   * \return quality factor
582
   */
583
0
  int getMapCompressQuality() { return this->mMapCompressQuality; }
584
585
  /*!\brief set gain map gamma
586
   * NOTE: Applicable only in encoding scenario
587
   *
588
   * \param[in]       gamma      gamma parameter that is used for gain map calculation
589
   *
590
   * \return none
591
   */
592
0
  void setGainMapGamma(float gamma) { this->mGamma = gamma; }
593
594
  /*!\brief get gain map gamma
595
   * NOTE: Applicable only in encoding scenario
596
   *
597
   * \return gamma parameter
598
   */
599
0
  float getGainMapGamma() { return this->mGamma; }
600
601
  /*!\brief enable / disable multi channel gain map
602
   * NOTE: Applicable only in encoding scenario
603
   *
604
   * \param[in]       useMultiChannelGainMap      enable / disable multi channel gain map
605
   *
606
   * \return none
607
   */
608
0
  void setUseMultiChannelGainMap(bool useMultiChannelGainMap) {
609
0
    this->mUseMultiChannelGainMap = useMultiChannelGainMap;
610
0
  }
611
612
  /*!\brief check if multi channel gain map is enabled
613
   * NOTE: Applicable only in encoding scenario
614
   *
615
   * \return true if multi channel gain map is enabled, false otherwise
616
   */
617
0
  bool isUsingMultiChannelGainMap() { return this->mUseMultiChannelGainMap; }
618
619
  /*!\brief set gain map min and max content boost
620
   * NOTE: Applicable only in encoding scenario
621
   *
622
   * \param[in]       minBoost      gain map min content boost
623
   * \param[in]       maxBoost      gain map max content boost
624
   *
625
   * \return none
626
   */
627
0
  void setGainMapMinMaxContentBoost(float minBoost, float maxBoost) {
628
0
    this->mMinContentBoost = minBoost;
629
0
    this->mMaxContentBoost = maxBoost;
630
0
  }
631
632
  /*!\brief get gain map min max content boost
633
   * NOTE: Applicable only in encoding scenario
634
   *
635
   * \param[out]       minBoost      gain map min content boost
636
   * \param[out]       maxBoost      gain map max content boost
637
   *
638
   * \return none
639
   */
640
0
  void getGainMapMinMaxContentBoost(float& minBoost, float& maxBoost) {
641
0
    minBoost = this->mMinContentBoost;
642
0
    maxBoost = this->mMaxContentBoost;
643
0
  }
644
645
  // Configurations
646
  void* mUhdrGLESCtxt;              // opengl es context
647
  int mMapDimensionScaleFactor;     // gain map scale factor
648
  int mMapCompressQuality;          // gain map quality factor
649
  bool mUseMultiChannelGainMap;     // enable multichannel gain map
650
  float mGamma;                     // gain map gamma parameter
651
  uhdr_enc_preset_t mEncPreset;     // encoding speed preset
652
  float mMinContentBoost;           // min content boost recommendation
653
  float mMaxContentBoost;           // max content boost recommendation
654
  float mTargetDispPeakBrightness;  // target display max luminance in nits
655
};
656
657
/*
658
 * Holds tonemapping results of a pixel
659
 */
660
struct GlobalTonemapOutputs {
661
  std::array<float, 3> rgb_out;
662
  float y_hdr;
663
  float y_sdr;
664
};
665
666
/*!\brief Applies a global tone mapping, based on Chrome's HLG/PQ rendering implemented at
667
 *  https://source.chromium.org/chromium/chromium/src/+/main:ui/gfx/color_transform.cc;l=1197-1252;drc=ac505aff1d29ec3bfcf317cb77d5e196a3664e92
668
 *
669
 * \param[in]       rgb_in              hdr intent pixel in array format.
670
 * \param[in]       headroom            ratio between hdr and sdr peak luminances. Must be greater
671
 *                                      than 1. If the input is normalized, then this is used to
672
 *                                      stretch it linearly from [0.0..1.0] to [0.0..headroom]
673
 * \param[in]       is_normalized       marker to differentiate, if the input is normalized.
674
 *
675
 * \return tonemapped pixel in the normalized range [0.0..1.0]
676
 */
677
GlobalTonemapOutputs globalTonemap(const std::array<float, 3>& rgb_in, float headroom,
678
                                   bool is_normalized);
679
}  // namespace ultrahdr
680
681
#endif  // ULTRAHDR_ULTRAHDRCOMMON_H