/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 |