1 /*
2  *
3  * Copyright 2019 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*
19  * @file    VendorVideoAPI.cpp
20  * @author  ByungGwan Kang (bk0917.kang@samsung.com)
21  * @version 1.0
22  * @history
23  *   2019.08.08 : Create
24  */
25 
26 //#define LOG_NDEBUG 0
27 #define LOG_TAG "VendorVideoAPI"
28 
29 /* Check data boundary before read it */
30 #define CHECK_BOUNDARY(bit_offset, size) {                      \
31     if ((bit_offset) > (size) * 8) {                            \
32         ALOGE("[%s][%d] read bit offset(%d) > total bits(%d)",  \
33               __func__, __LINE__, (bit_offset), (size) * 8);    \
34         return -1;                                              \
35     }                                                           \
36 }
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <log/log.h>
42 
43 #include <VendorVideoAPI.h>
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
Exynos_parsing_user_data_registered_itu_t_t35(ExynosHdrDynamicInfo * dest,void * src,int size)49 int Exynos_parsing_user_data_registered_itu_t_t35 (
50     ExynosHdrDynamicInfo *dest,
51     void                 *src,
52     int                  size)
53 
54 {
55     int   bit_offset = 0;
56     int   data       = 0;
57     ExynosHdrDynamicInfo *pHdr10PlusInfo;
58 
59     int windows = 0;
60     int targeted_system_display_actual_peak_luminance_flag     = 0;
61     int num_rows_targeted_system_display_actual_peak_luminance = 0;
62     int num_cols_targeted_system_display_actual_peak_luminance = 0;
63     int mastering_display_actual_peak_luminance_flag           = 0;
64     int num_rows_mastering_display_actual_peak_luminance       = 0;
65     int color_saturation_mapping_flag                          = 0;
66     int num_cols_mastering_display_actual_peak_luminance       = 0;
67 
68     int extraBit, extraByte = 0;
69 
70     int i, j, k, l;
71 
72     if ((dest == NULL) || (src == NULL)) {
73         ALOGE("[%s] invalid parameters", __FUNCTION__);
74         return -1;
75     }
76 
77     pHdr10PlusInfo = dest;
78 
79     CHECK_BOUNDARY(bit_offset + 8, size);
80     /* country_code : 8bit */
81     for (i = 0; i < 1; i++) {
82         for (j = 0; j < 8; j++) {
83             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << j));
84         }
85     }
86     bit_offset += 8;
87     pHdr10PlusInfo->data.country_code = data;
88     data = 0;
89 
90     CHECK_BOUNDARY(bit_offset + 16, size);
91     /* terminal_provider_code : 16bit */
92     for (i = 0; i < 2; i++) {
93         for (j = 0; j < 8; j++) {
94             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << j));
95         }
96     }
97     bit_offset += 16;
98     pHdr10PlusInfo->data.provider_code = data;
99     data = 0;
100 
101     CHECK_BOUNDARY(bit_offset + 16, size);
102     /* terminal_provider_oriented_code : 16bit */
103     for (i = 0; i < 2; i++) {
104         for (j = 0; j < 8; j++) {
105             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << j));
106         }
107     }
108     bit_offset += 16;
109     pHdr10PlusInfo->data.provider_oriented_code = data;
110     data = 0;
111 
112     CHECK_BOUNDARY(bit_offset + 8, size);
113     /* application_identifier : 8bit*/
114     for (i = 0; i < 1; i++) {
115         for (j = 0; j < 8; j++) {
116             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << j));
117         }
118     }
119     bit_offset += 8;
120     pHdr10PlusInfo->data.application_identifier = data;
121     data = 0;
122 
123     CHECK_BOUNDARY(bit_offset + 8, size);
124     /* application_version : 8bit*/
125     for (i = 0; i < 1; i++) {
126         for (j = 0; j < 8; j++) {
127             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << j));
128         }
129     }
130     bit_offset += 8;
131     pHdr10PlusInfo->data.application_version = data;
132     data = 0;
133 
134     CHECK_BOUNDARY(bit_offset + 2, size);
135     /* num_windows : 2bit*/
136     for (i = 0; i < 1; i++) {
137         for (j = 0; j < 2; j++) {
138             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j)));
139         }
140     }
141     bit_offset += 2;
142     extraBit   = (bit_offset % 8);
143     data       = data >> (8 - extraBit);
144     pHdr10PlusInfo->data.num_windows = data;
145     data = 0;
146 
147     for (i = 1; i < pHdr10PlusInfo->data.num_windows; i++) {
148         CHECK_BOUNDARY(bit_offset + 16, size);
149         /* window_upper_left_corner_x : 16bit */
150         if (extraBit > 0)
151             extraByte = 1;
152 
153         for (j = 0; j < 2 + extraByte; j++) {
154             for (k = extraBit; k < 8; k++) {
155                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
156             }
157 
158             if (j < 2 + extraByte - 1)
159                 data = data << 8;
160 
161             extraBit += (k - extraBit);
162             extraBit %= 8;
163         }
164         bit_offset += 16;
165         extraByte   = 0;
166         extraBit    = bit_offset % 8;
167         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
168         pHdr10PlusInfo->data.window_upper_left_corner_x[i - 1] = data;
169         data = 0;
170 
171         CHECK_BOUNDARY(bit_offset + 16, size);
172         /* window_upper_left_corner_y : 16bit */
173         if (extraBit > 0)
174             extraByte = 1;
175 
176         for (j = 0; j < 2 + extraByte; j++) {
177             for (k = extraBit; k < 8; k++) {
178                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
179             }
180 
181             if (j < 2 + extraByte - 1)
182                 data = data << 8;
183 
184             extraBit += (k - extraBit);
185             extraBit %= 8;
186         }
187         bit_offset += 16;
188         extraByte   = 0;
189         extraBit    = bit_offset % 8;
190         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
191         pHdr10PlusInfo->data.window_upper_left_corner_y[i - 1] = data;
192         data = 0;
193 
194         CHECK_BOUNDARY(bit_offset + 16, size);
195         /* window_lower_right_corner_x : 16bit */
196         if (extraBit > 0)
197             extraByte = 1;
198 
199         for (j = 0; j < 2 + extraByte; j++) {
200             for (k = extraBit; k < 8; k++) {
201                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
202             }
203 
204             if (j < 2 + extraByte - 1)
205                 data = data << 8;
206 
207             extraBit += (k - extraBit);
208             extraBit %= 8;
209         }
210         bit_offset += 16;
211         extraByte   = 0;
212         extraBit    = bit_offset % 8;
213         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
214         pHdr10PlusInfo->data.window_lower_right_corner_x[i - 1] = data;
215         data = 0;
216 
217         CHECK_BOUNDARY(bit_offset + 16, size);
218         /* window_lower_right_corner_y : 16bit */
219         if (extraBit > 0)
220             extraByte = 1;
221 
222         for (j = 0; j < 2 + extraByte; j++) {
223             for (k = extraBit; k < 8; k++) {
224                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
225             }
226 
227             if (j < 2 + extraByte - 1)
228                 data = data << 8;
229 
230             extraBit += (k - extraBit);
231             extraBit %= 8;
232         }
233         bit_offset += 16;
234         extraByte   = 0;
235         extraBit    = bit_offset % 8;
236         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
237         pHdr10PlusInfo->data.window_lower_right_corner_y[i - 1] = data;
238         data = 0;
239 
240         CHECK_BOUNDARY(bit_offset + 16, size);
241         /* center_of_ellipse_x : 16bit */
242         if (extraBit > 0)
243             extraByte = 1;
244 
245         for (j = 0; j < 2 + extraByte; j++) {
246             for (k = extraBit; k < 8; k++) {
247                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
248             }
249 
250             if (j < 2 + extraByte - 1)
251                 data = data << 8;
252 
253             extraBit += (k - extraBit);
254             extraBit %= 8;
255         }
256         bit_offset += 16;
257         extraByte   = 0;
258         extraBit    = bit_offset % 8;
259         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
260         pHdr10PlusInfo->data.center_of_ellipse_x[i - 1] = data;
261         data = 0;
262 
263         CHECK_BOUNDARY(bit_offset + 16, size);
264         /* center_of_ellipse_y : 16bit */
265         if (extraBit > 0)
266             extraByte = 1;
267 
268         for (j = 0; j < 2 + extraByte; j++) {
269             for (k = extraBit; k < 8; k++) {
270                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
271             }
272 
273             if (j < 2 + extraByte - 1)
274                 data = data << 8;
275 
276             extraBit += (k - extraBit);
277             extraBit %= 8;
278         }
279         bit_offset += 16;
280         extraByte   = 0;
281         extraBit    = bit_offset % 8;
282         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
283         pHdr10PlusInfo->data.center_of_ellipse_y[i - 1] = data;
284         data = 0;
285 
286         CHECK_BOUNDARY(bit_offset + 8, size);
287         /* rotation_angle : 8bit */
288         if (extraBit > 0)
289             extraByte = 1;
290 
291         for (j = 0; j < 1 + extraByte; j++) {
292             for (k = extraBit; k < 8; k++) {
293                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
294             }
295 
296             if (j < 1 + extraByte - 1)
297                 data = data << 8;
298 
299             extraBit += (k - extraBit);
300             extraBit %= 8;
301         }
302         bit_offset += 8;
303         extraByte   = 0;
304         extraBit    = bit_offset % 8;
305         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
306         pHdr10PlusInfo->data.rotation_angle[i - 1] = data;
307         data = 0;
308 
309         CHECK_BOUNDARY(bit_offset + 16, size);
310         /* semimajor_axis_internal_ellipse : 16bit */
311         if (extraBit > 0)
312             extraByte = 1;
313 
314         for (j = 0; j < 2 + extraByte; j++) {
315             for (k = extraBit; k < 8; k++) {
316                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
317             }
318 
319             if (j < 2 + extraByte - 1)
320                 data = data << 8;
321 
322             extraBit += (k - extraBit);
323             extraBit %= 8;
324         }
325         bit_offset += 16;
326         extraByte   = 0;
327         extraBit    = bit_offset % 8;
328         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
329         pHdr10PlusInfo->data.semimajor_axis_internal_ellipse[i - 1] = data;
330         data = 0;
331 
332         CHECK_BOUNDARY(bit_offset + 16, size);
333         /* semimajor_axis_external_ellipse : 16bit */
334         if (extraBit > 0)
335             extraByte = 1;
336 
337         for (j = 0; j < 2 + extraByte; j++) {
338             for (k = extraBit; k < 8; k++) {
339                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
340             }
341 
342             if (j < 2 + extraByte - 1)
343                 data = data << 8;
344 
345             extraBit += (k - extraBit);
346             extraBit %= 8;
347         }
348         bit_offset += 16;
349         extraByte   = 0;
350         extraBit    = bit_offset % 8;
351         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
352         pHdr10PlusInfo->data.semimajor_axis_external_ellipse[i - 1] = data;
353         data = 0;
354 
355         CHECK_BOUNDARY(bit_offset + 16, size);
356         /* semiminor_axis_external_ellipse : 16bit */
357         if (extraBit > 0)
358             extraByte = 1;
359 
360         for (j = 0; j < 2 + extraByte; j++) {
361             for (k = extraBit; k < 8; k++) {
362                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
363             }
364 
365             if (j < 2 + extraByte - 1)
366                 data = data << 8;
367 
368             extraBit += (k - extraBit);
369             extraBit %= 8;
370         }
371         bit_offset += 16;
372         extraByte   = 0;
373         extraBit    = bit_offset % 8;
374         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
375         pHdr10PlusInfo->data.semiminor_axis_external_ellipse[i - 1] = data;
376         data = 0;
377 
378         CHECK_BOUNDARY(bit_offset + 1, size);
379         /* overlap_process_option : 1bit */
380         data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit)));
381 
382         bit_offset  += 1;
383         extraByte    = 0;
384         extraBit     = bit_offset % 8;
385         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
386         pHdr10PlusInfo->data.overlap_process_option[i - 1] = data;
387         data = 0;
388     }
389 
390     CHECK_BOUNDARY(bit_offset + 27, size);
391     /* targeted_system_display_maximum_luminance : 27bit */
392     if (extraBit > 5)
393         extraByte = 2;
394     else if (extraBit <= 5)
395         extraByte = 1;
396 
397     for (i = 0; i < 3 + extraByte; i++) {
398         for (j = extraBit; j < 8; j++) {
399             data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j)));
400         }
401 
402         if (i < 3 + extraByte - 1)
403             data = data << 8;
404 
405         extraBit += (j - extraBit);
406         extraBit %= 8;
407     }
408     bit_offset += 27;
409     extraByte   = 0;
410     extraBit    = bit_offset % 8;
411     data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
412     pHdr10PlusInfo->data.targeted_system_display_maximum_luminance = data;
413     data = 0;
414 
415     CHECK_BOUNDARY(bit_offset + 1, size);
416     /* targeted_system_display_actual_peak_luminance_flag : 1bit */
417     data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit)));
418 
419     bit_offset  += 1;
420     extraBit     = bit_offset % 8;
421     data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
422     pHdr10PlusInfo->data.targeted_system_display_actual_peak_luminance_flag = data;
423     targeted_system_display_actual_peak_luminance_flag = data;
424     data = 0;
425 
426     if (targeted_system_display_actual_peak_luminance_flag) {
427         CHECK_BOUNDARY(bit_offset + 5, size);
428         /* num_rows_targeted_system_display_actual_peak_luminance : 5bit */
429         if (extraBit > 3)
430             extraByte = 1;
431 
432         for (i = 0; i < 1 + extraByte; i++) {
433             for (j = extraBit; j < 8; j++) {
434                 data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j)));
435             }
436 
437             if (i < 1 + extraByte - 1)
438                 data = data << 8;
439 
440             extraBit += (j - extraBit);
441             extraBit %= 8;
442         }
443         bit_offset += 5;
444         extraByte   = 0;
445         extraBit    = bit_offset % 8;
446         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
447         pHdr10PlusInfo->data.num_rows_targeted_system_display_actual_peak_luminance = data;
448         num_rows_targeted_system_display_actual_peak_luminance = data;
449         data = 0;
450 
451         CHECK_BOUNDARY(bit_offset + 5, size);
452         /* num_cols_targeted_system_display_actual_peak_luminance : 5bit */
453         if (extraBit > 3)
454             extraByte = 1;
455 
456         for (i = 0; i < 1 + extraByte; i++) {
457             for (j = extraBit; j < 8; j++) {
458                 data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j)));
459             }
460 
461             if (i < 1 + extraByte - 1)
462                 data = data << 8;
463 
464             extraBit += (j - extraBit);
465             extraBit %= 8;
466         }
467         bit_offset += 5;
468         extraByte   = 0;
469         extraBit    = bit_offset % 8;
470         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
471         pHdr10PlusInfo->data.num_cols_targeted_system_display_actual_peak_luminance = data;
472         num_cols_targeted_system_display_actual_peak_luminance = data;
473         data = 0;
474 
475         for (i = 0; i < num_rows_targeted_system_display_actual_peak_luminance; i++) {
476             for (j = 0; j < num_cols_targeted_system_display_actual_peak_luminance; j++) {
477                 CHECK_BOUNDARY(bit_offset + 4, size);
478                 /* targeted_system_display_actual_peak_luminance : 4bit */
479                 if (extraBit > 4)
480                     extraByte = 1;
481 
482                 for (k = 0; k < 1 + extraByte; k++) {
483                     for (l = extraBit; l < 8; l++) {
484                         data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l)));
485                     }
486 
487                     if (k < 1 + extraByte - 1)
488                         data = data << 8;
489 
490                     extraBit += (l - extraBit);
491                     extraBit %= 8;
492                 }
493                 bit_offset += 4;
494                 extraByte   = 0;
495                 extraBit    = bit_offset % 8;
496                 data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
497                 pHdr10PlusInfo->data.targeted_system_display_actual_peak_luminance[i][j] = data;
498                 data = 0;
499             }
500         }
501     }
502 
503     for (i = 0; i < pHdr10PlusInfo->data.num_windows; i++) {
504         for (j = 0; j < 3; j++) {
505             CHECK_BOUNDARY(bit_offset + 17, size);
506             /* maxscl : 17bit */
507             for (k = 0; k < 3; k++) {
508                 for (l = extraBit; l < 8; l++) {
509                     data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l)));
510                 }
511 
512                 if (k < 2)
513                     data = data << 8;
514 
515                 extraBit += (l - extraBit);
516                 extraBit %= 8;
517             }
518             bit_offset += 17;
519             extraBit    = bit_offset % 8;
520 
521             if (extraBit != 0)
522                 data = data >> (8 - extraBit);
523 
524             pHdr10PlusInfo->data.maxscl[i][j] = data;
525             data = 0;
526         }
527 
528         CHECK_BOUNDARY(bit_offset + 17, size);
529         /* average_maxrgb : 17bit */
530         for (j = 0; j < 3; j++) {
531             for (k = extraBit; k < 8; k++) {
532                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
533             }
534 
535             if (j < 2)
536                 data = data << 8;
537 
538             extraBit += (k - extraBit);
539             extraBit %= 8;
540         }
541         bit_offset += 17;
542         extraBit    = bit_offset % 8;
543         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
544         pHdr10PlusInfo->data.average_maxrgb[i] = data;
545         data = 0;
546 
547         CHECK_BOUNDARY(bit_offset + 4, size);
548         /* num_distribution_maxrgb_percentiles : 4bit */
549         if (extraBit > 4)
550             extraByte = 1;
551 
552         for (j = 0; j < 1 + extraByte; j++) {
553             for (k = extraBit; k < 8; k++) {
554                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
555             }
556 
557             if (j < 1 + extraByte - 1)
558                 data = data << 8;
559 
560             extraBit += (k - extraBit);
561             extraBit %= 8;
562         }
563         bit_offset += 4;
564         extraByte   = 0;
565         extraBit    = bit_offset % 8;
566         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
567         pHdr10PlusInfo->data.num_maxrgb_percentiles[i] = data;
568         data = 0;
569 
570         for (j = 0; j < pHdr10PlusInfo->data.num_maxrgb_percentiles[i]; j++) {
571             CHECK_BOUNDARY(bit_offset + 7, size);
572             /* distribution_maxrgb_percentages : 7bit */
573             if (extraBit > 1)
574                 extraByte = 1;
575 
576             for (k = 0; k < 1 + extraByte; k++) {
577                 for (l = extraBit; l < 8; l++) {
578                     data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l)));
579                 }
580 
581                 if (k < 1 + extraByte - 1)
582                     data = data << 8;
583 
584                 extraBit += (l - extraBit);
585                 extraBit %= 8;
586             }
587             bit_offset += 7;
588             extraByte   = 0;
589             extraBit    = bit_offset % 8;
590             data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
591             pHdr10PlusInfo->data.maxrgb_percentages[i][j] = data;
592             data = 0;
593 
594             CHECK_BOUNDARY(bit_offset + 17, size);
595             /* distribution_maxrgb_percentiles : 17bit */
596             if (extraBit >= 0)
597                 extraByte = 1;
598 
599             for (k = 0; k < 2 + extraByte; k++) {
600                 for (l = extraBit; l < 8; l++) {
601                     data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l)));
602                 }
603 
604                 if (k < 2 + extraByte - 1)
605                     data = data << 8;
606 
607                 extraBit += (l - extraBit);
608                 extraBit %= 8;
609             }
610             bit_offset += 17;
611             extraByte   = 0;
612             extraBit    = bit_offset % 8;
613             data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
614             pHdr10PlusInfo->data.maxrgb_percentiles[i][j] = data;
615             data = 0;
616         }
617 
618         CHECK_BOUNDARY(bit_offset + 10, size);
619         /* fraction_bright_pixels : 10bit*/
620         if (extraBit > 6)
621             extraByte = 2;
622         else if (extraBit <= 6)
623             extraByte = 1;
624 
625         for (j = 0; j < 1 + extraByte; j++) {
626             for (k = extraBit; k < 8; k++) {
627                 data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
628             }
629 
630             if (j < 1 + extraByte - 1)
631                 data = data << 8;
632 
633             extraBit += (k - extraBit);
634             extraBit %= 8;
635         }
636         bit_offset += 10;
637         extraByte   = 0;
638         extraBit    = bit_offset % 8;
639         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
640         pHdr10PlusInfo->data.fraction_bright_pixels[i] = data;
641         data = 0;
642     }
643 
644     CHECK_BOUNDARY(bit_offset + 1, size);
645     /* mastering_display_actual_peak_luminance_flag : 1bit */
646     data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit)));
647 
648     bit_offset  += 1;
649     extraBit     = bit_offset % 8;
650     data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
651     pHdr10PlusInfo->data.mastering_display_actual_peak_luminance_flag = data;
652     mastering_display_actual_peak_luminance_flag = data;
653     data = 0;
654 
655     if (mastering_display_actual_peak_luminance_flag) {
656         CHECK_BOUNDARY(bit_offset + 5, size);
657         /* num_rows_mastering_display_actual_peak_luminance : 5bit */
658         if (extraBit > 3)
659             extraByte = 1;
660 
661         for (i = 0; i < 1 + extraByte; i++) {
662             for (j = extraBit; j < 8; j++) {
663                 data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j)));
664             }
665 
666             if (i < 1 + extraByte - 1)
667                 data = data << 8;
668 
669             extraBit += (j - extraBit);
670             extraBit %= 8;
671         }
672         bit_offset += 5;
673         extraByte   = 0;
674         extraBit    = bit_offset % 8;
675         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
676         pHdr10PlusInfo->data.num_rows_mastering_display_actual_peak_luminance = data;
677         num_rows_mastering_display_actual_peak_luminance = data;
678         data = 0;
679 
680         CHECK_BOUNDARY(bit_offset + 5, size);
681         /* num_cols_mastering_display_actual_peak_luminance : 5bit */
682         if (extraBit > 3)
683             extraByte = 1;
684 
685         for (i = 0; i < 1 + extraByte; i++) {
686             for (j = extraBit; j < 8; j++) {
687                 data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j)));
688             }
689 
690             if (i < 1 + extraByte - 1)
691                 data = data << 8;
692 
693             extraBit += (j - extraBit);
694             extraBit %= 8;
695         }
696         bit_offset += 5;
697         extraByte   = 0;
698         extraBit    = bit_offset % 8;
699         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
700         pHdr10PlusInfo->data.num_cols_mastering_display_actual_peak_luminance = data;
701         num_cols_mastering_display_actual_peak_luminance = data;
702         data = 0;
703 
704         for (i = 0; i < num_rows_mastering_display_actual_peak_luminance; i++) {
705             for (j = 0; j < num_cols_mastering_display_actual_peak_luminance; j++) {
706                 CHECK_BOUNDARY(bit_offset + 4, size);
707                 /* mastering_display_actual_peak_luminance : 4bit */
708                 if (extraBit > 4)
709                     extraByte = 1;
710 
711                 for (k = 0; k < 1 + extraByte; k++) {
712                     for (l = extraBit; l < 8; l++) {
713                         data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l)));
714                     }
715 
716                     if (k < 1 + extraByte - 1)
717                         data = data << 8;
718 
719                     extraBit += (l - extraBit);
720                     extraBit %= 8;
721                 }
722                 bit_offset += 4;
723                 extraByte   = 0;
724                 extraBit    = bit_offset % 8;
725                 data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
726                 pHdr10PlusInfo->data.mastering_display_actual_peak_luminance[i][j] = data;
727                 data = 0;
728             }
729         }
730     }
731 
732     for (i = 0; i < pHdr10PlusInfo->data.num_windows; i++) {
733         CHECK_BOUNDARY(bit_offset + 1, size);
734         /* tone_mapping_flag : 1bit */
735         data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit)));
736 
737         bit_offset  += 1;
738         extraBit     = bit_offset % 8;
739         data         = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
740         pHdr10PlusInfo->data.tone_mapping.tone_mapping_flag[i] = data;
741         data = 0;
742 
743         if (pHdr10PlusInfo->data.tone_mapping.tone_mapping_flag[i]) {
744             CHECK_BOUNDARY(bit_offset + 12, size);
745             /* knee_point_x : 12bit */
746             if (extraBit > 4)
747                 extraByte = 2;
748             else if (extraBit <= 4)
749                 extraByte = 1;
750 
751             for (j = 0; j < 1 + extraByte; j++) {
752                 for (k = extraBit; k < 8; k++) {
753                     data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
754                 }
755 
756                 if (j < 1 + extraByte - 1)
757                     data = data << 8;
758 
759                 extraBit += (k - extraBit);
760                 extraBit %= 8;
761             }
762             bit_offset += 12;
763             extraByte   = 0;
764             extraBit    = bit_offset % 8;
765             data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
766             pHdr10PlusInfo->data.tone_mapping.knee_point_x[i] = data;
767             data = 0;
768 
769             CHECK_BOUNDARY(bit_offset + 12, size);
770             /* knee_point_y : 12bit */
771             if (extraBit > 4)
772                 extraByte = 2;
773             else if (extraBit <= 4)
774                 extraByte = 1;
775 
776             for (j = 0; j < 1 + extraByte; j++) {
777                 for (k = extraBit; k < 8; k++) {
778                     data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
779                 }
780 
781                 if (j < 1 + extraByte - 1)
782                     data = data << 8;
783 
784                 extraBit += (k - extraBit);
785                 extraBit %= 8;
786             }
787             bit_offset += 12;
788             extraByte   = 0;
789             extraBit    = bit_offset % 8;
790             data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
791             pHdr10PlusInfo->data.tone_mapping.knee_point_y[i] = data;
792             data = 0;
793 
794             CHECK_BOUNDARY(bit_offset + 4, size);
795             /* num_bezier_curve_anchors : 4bit */
796             if (extraBit > 4)
797                 extraByte = 1;
798 
799             for (j = 0; j < 1 + extraByte; j++) {
800                 for (k = extraBit; k < 8; k++) {
801                     data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
802                 }
803 
804                 if (j < 1 + extraByte - 1)
805                     data = data << 8;
806 
807                 extraBit += (k - extraBit);
808                 extraBit %= 8;
809             }
810             bit_offset += 4;
811             extraByte   = 0;
812             extraBit    = bit_offset % 8;
813             data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
814             pHdr10PlusInfo->data.tone_mapping.num_bezier_curve_anchors[i] = data;
815             data = 0;
816 
817             for (j = 0; j < pHdr10PlusInfo->data.tone_mapping.num_bezier_curve_anchors[i]; j++) {
818                 CHECK_BOUNDARY(bit_offset + 10, size);
819                 /* bezier_curve_anchors : 10bit */
820                 if (extraBit > 6)
821                     extraByte = 2;
822                 else if (extraBit <= 6)
823                     extraByte = 1;
824 
825                 for (k = 0; k < 1 + extraByte; k++) {
826                     for (l = extraBit; l < 8; l++) {
827                         data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l)));
828                     }
829 
830                     if (k < 1 + extraByte - 1)
831                         data = data << 8;
832 
833                     extraBit += (l - extraBit);
834                     extraBit %= 8;
835                 }
836                 bit_offset += 10;
837                 extraByte   = 0;
838                 extraBit    = bit_offset % 8;
839                 data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
840                 pHdr10PlusInfo->data.tone_mapping.bezier_curve_anchors[i][j] = data;
841                 data = 0;
842             }
843         }
844 
845         CHECK_BOUNDARY(bit_offset + 1, size);
846         /* color_saturation_mapping_flag : 1bit */
847         data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit)));
848 
849         bit_offset  += 1;
850         extraByte    = 0;
851         extraBit     = bit_offset % 8;
852         data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
853         pHdr10PlusInfo->data.color_saturation_mapping_flag[i] = data;
854         data = 0;
855 
856         if (pHdr10PlusInfo->data.color_saturation_mapping_flag[i]) {
857             CHECK_BOUNDARY(bit_offset + 6, size);
858             /* color_saturation_weight : 6bit */
859             if (extraBit > 2)
860                 extraByte = 1;
861 
862             for (j = 0; j < 1 + extraByte; j++) {
863                 for (k = extraBit; k < 8; k++) {
864                     data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k)));
865                 }
866 
867                 if (j < 1 + extraByte - 1)
868                     data = data << 8;
869 
870                 extraBit += (k - extraBit);
871                 extraBit %= 8;
872             }
873             bit_offset += 6;
874             extraByte   = 0;
875             extraBit    = bit_offset % 8;
876             data        = (extraBit != 0) ? (data >> (8 - extraBit)) : data;
877             pHdr10PlusInfo->data.color_saturation_weight[i] = data;
878             data = 0;
879         }
880     }
881 
882     return 0;
883 }
884 
Exynos_dynamic_meta_to_itu_t_t35(ExynosHdrDynamicInfo * src,char * dst)885 int Exynos_dynamic_meta_to_itu_t_t35 (
886     ExynosHdrDynamicInfo *src,
887     char                 *dst)
888 {
889     ExynosHdrDynamicInfo *pHDRDynamicInfo = NULL;
890     char                 *pBlob           = NULL;
891 
892     int size         = 0;
893     int bit_offset   = 0;
894     int extraBit     = 0;
895     int extraByte    = 0;
896     int offset_limit = 0;
897 
898     int buffer     = 0;
899     int tempBuffer = 0;
900 
901     int i, j, k, l;
902 
903     if ((src == NULL) || (dst == NULL)) {
904         ALOGE("[%s] invalid parameters", __FUNCTION__);
905         return -1;
906     }
907 
908     pHDRDynamicInfo = src;
909     pBlob           = dst;
910 
911     /* country_code: 8bit */
912     offset_limit = bit_offset + 8;
913 
914     for (i = 0; i < 8; i++) {
915         *((char *)pBlob + (bit_offset / 8)) |=
916             (*((char *)&pHDRDynamicInfo->data.country_code) & (1 << (7 - i)));
917         bit_offset++;
918 
919         if (bit_offset == offset_limit)
920             break;
921     }
922     extraBit = (bit_offset % 8);
923 
924     /* terminal_provider_code: 16bit */
925     offset_limit = bit_offset + 16;
926 
927     for (i = 0; i < 2; i++) {
928         for (j = 0; j < 8; j++) {
929             *((char *)pBlob + (bit_offset / 8)) |=
930                 (*((char *)&pHDRDynamicInfo->data.provider_code + 1 - i) & (1 << (7 - j)));
931             bit_offset++;
932 
933             if (bit_offset == offset_limit)
934                 break;
935         }
936     }
937     extraBit = (bit_offset % 8);
938 
939     /* terminal_provider_oriented_code: 16bit */
940     offset_limit = bit_offset + 16;
941 
942     for (i = 0; i < 2; i++) {
943         for (j = 0; j < 8; j++) {
944             *((char *)pBlob + (bit_offset / 8)) |=
945                 (*((char *)&pHDRDynamicInfo->data.provider_oriented_code + 1 - i) & (1 << (7 - j)));
946             bit_offset++;
947 
948             if (bit_offset == offset_limit)
949                 break;
950         }
951     }
952     extraBit = (bit_offset % 8);
953 
954     /* application_identifier: 8bit */
955     offset_limit = bit_offset + 8;
956 
957     for (i = 0; i < 8; i++) {
958         *((char *)pBlob + (bit_offset / 8)) |=
959             (*((char *)&pHDRDynamicInfo->data.application_identifier) & (1 << (7 - i)));
960         bit_offset++;
961 
962         if (bit_offset == offset_limit)
963             break;
964     }
965     extraBit = (bit_offset % 8);
966 
967     /* application_version: 8bit */
968     offset_limit = bit_offset + 8;
969 
970     for (i = 0; i < 8; i++) {
971         *((char *)pBlob + (bit_offset / 8)) |=
972             (*((char *)&pHDRDynamicInfo->data.application_version) & (1 << (7 - i)));
973         bit_offset++;
974 
975         if (bit_offset == offset_limit)
976             break;
977     }
978     extraBit = (bit_offset % 8);
979 
980     /* num_windows: 2bit */
981     offset_limit = bit_offset + 2;
982 
983     tempBuffer = pHDRDynamicInfo->data.num_windows << (6 - extraBit);
984     for (i = 0; i < 2; i++) {
985         /* num_windows is always 1 now */
986         *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&tempBuffer) & (1 << (7 - i)));
987         bit_offset++;
988 
989         if (bit_offset == offset_limit)
990             break;
991     }
992     extraBit = (bit_offset % 8);
993     tempBuffer = 0;
994 
995     for (i = 1; i < pHDRDynamicInfo->data.num_windows; i++) {
996         /* window_upper_left_corner_x: 16bit */
997         offset_limit = bit_offset + 16;
998 
999         if (extraBit > 0)
1000             extraByte = 1;
1001 
1002         tempBuffer = pHDRDynamicInfo->data.window_upper_left_corner_x[i - 1];
1003         tempBuffer = tempBuffer << (16 - extraBit);
1004         for (j = 0; j < 4; j++) {
1005             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1006         }
1007 
1008         for (j = 0; j < (2 + extraByte); j++) {
1009             for (k = extraBit; k < 8; k++) {
1010                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1011                 bit_offset++;
1012 
1013                 if (bit_offset == offset_limit) {
1014                     break;
1015                 }
1016             }
1017             extraBit = (bit_offset % 8);
1018         }
1019         buffer     = 0;
1020         tempBuffer = 0;
1021         extraByte  = 0;
1022 
1023         /* window_upper_left_corner_y: 16bit */
1024         offset_limit = bit_offset + 16;
1025 
1026         if (extraBit > 0)
1027             extraByte = 1;
1028 
1029         tempBuffer = pHDRDynamicInfo->data.window_upper_left_corner_y[i - 1];
1030         tempBuffer = tempBuffer << (16 - extraBit);
1031         for (j = 0; j < 4; j++) {
1032             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1033         }
1034 
1035         for (j = 0; j < (2 + extraByte); j++) {
1036             for (k = extraBit; k < 8; k++) {
1037                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1038                 bit_offset++;
1039 
1040                 if (bit_offset == offset_limit) {
1041                     break;
1042                 }
1043             }
1044             extraBit = (bit_offset % 8);
1045         }
1046         buffer     = 0;
1047         tempBuffer = 0;
1048         extraByte  = 0;
1049 
1050         /* window_lower_right_corner_x: 16bit */
1051         offset_limit = bit_offset + 16;
1052 
1053         if (extraBit > 0)
1054             extraByte = 1;
1055 
1056         tempBuffer = pHDRDynamicInfo->data.window_lower_right_corner_x[i - 1];
1057         tempBuffer = tempBuffer << (16 - extraBit);
1058         for (j = 0; j < 4; j++) {
1059             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1060         }
1061 
1062         for (j = 0; j < (2 + extraByte); j++) {
1063             for (k = extraBit; k < 8; k++) {
1064                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1065                 bit_offset++;
1066 
1067                 if (bit_offset == offset_limit) {
1068                     break;
1069                 }
1070             }
1071             extraBit = (bit_offset % 8);
1072         }
1073         buffer     = 0;
1074         tempBuffer = 0;
1075         extraByte  = 0;
1076 
1077         /* window_lower_right_corner_y: 16bit */
1078         offset_limit = bit_offset + 16;
1079 
1080         if (extraBit > 0)
1081             extraByte = 1;
1082 
1083         tempBuffer = pHDRDynamicInfo->data.window_lower_right_corner_y[i - 1];
1084         tempBuffer = tempBuffer << (16 - extraBit);
1085         for (j = 0; j < 4; j++) {
1086             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1087         }
1088 
1089         for (j = 0; j < (2 + extraByte); j++) {
1090             for (k = extraBit; k < 8; k++) {
1091                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1092                 bit_offset++;
1093 
1094                 if (bit_offset == offset_limit) {
1095                     break;
1096                 }
1097             }
1098             extraBit = (bit_offset % 8);
1099         }
1100         buffer     = 0;
1101         tempBuffer = 0;
1102         extraByte  = 0;
1103 
1104         /* center_of_ellipse_x: 16bit */
1105         offset_limit = bit_offset + 16;
1106 
1107         if (extraBit > 0)
1108             extraByte = 1;
1109 
1110         tempBuffer = pHDRDynamicInfo->data.center_of_ellipse_x[i - 1];
1111         tempBuffer = tempBuffer << (16 - extraBit);
1112         for (j = 0; j < 4; j++) {
1113             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1114         }
1115 
1116         for (j = 0; j < (2 + extraByte); j++) {
1117             for (k = extraBit; k < 8; k++) {
1118                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1119                 bit_offset++;
1120 
1121                 if (bit_offset == offset_limit) {
1122                     break;
1123                 }
1124             }
1125             extraBit = (bit_offset % 8);
1126         }
1127         buffer     = 0;
1128         tempBuffer = 0;
1129         extraByte  = 0;
1130 
1131         /* center_of_ellipse_y: 16bit */
1132         offset_limit = bit_offset + 16;
1133 
1134         if (extraBit > 0)
1135             extraByte = 1;
1136 
1137         tempBuffer = pHDRDynamicInfo->data.center_of_ellipse_y[i - 1];
1138         tempBuffer = tempBuffer << (16 - extraBit);
1139         for (j = 0; j < 4; j++) {
1140             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1141         }
1142 
1143         for (j = 0; j < (2 + extraByte); j++) {
1144             for (k = extraBit; k < 8; k++) {
1145                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1146                 bit_offset++;
1147 
1148                 if (bit_offset == offset_limit) {
1149                     break;
1150                 }
1151             }
1152             extraBit = (bit_offset % 8);
1153         }
1154         buffer     = 0;
1155         tempBuffer = 0;
1156         extraByte  = 0;
1157 
1158         /* rotation_angle: 8bit */
1159         offset_limit = bit_offset + 8;
1160 
1161         if (extraBit > 0)
1162             extraByte = 1;
1163 
1164         tempBuffer = pHDRDynamicInfo->data.rotation_angle[i - 1];
1165         tempBuffer = tempBuffer << (24 - extraBit);
1166         for (j = 0; j < 4; j++) {
1167             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1168         }
1169 
1170         for (j = 0; j < (1 + extraByte); j++) {
1171             for (k = extraBit; k < 8; k++) {
1172                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1173                 bit_offset++;
1174 
1175                 if (bit_offset == offset_limit) {
1176                     break;
1177                 }
1178             }
1179             extraBit = (bit_offset % 8);
1180         }
1181         buffer     = 0;
1182         tempBuffer = 0;
1183         extraByte  = 0;
1184 
1185         /* semimajor_axis_internal_ellipse: 16bit */
1186         offset_limit = bit_offset + 16;
1187 
1188         if (extraBit > 0)
1189             extraByte = 1;
1190 
1191         tempBuffer = pHDRDynamicInfo->data.semimajor_axis_internal_ellipse[i - 1];
1192         tempBuffer = tempBuffer << (16 - extraBit);
1193         for (j = 0; j < 4; j++) {
1194             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1195         }
1196 
1197         for (j = 0; j < (2 + extraByte); j++) {
1198             for (k = extraBit; k < 8; k++) {
1199                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1200                 bit_offset++;
1201 
1202                 if (bit_offset == offset_limit) {
1203                     break;
1204                 }
1205             }
1206             extraBit = (bit_offset % 8);
1207         }
1208         buffer     = 0;
1209         tempBuffer = 0;
1210         extraByte  = 0;
1211 
1212         /* semimajor_axis_external_ellipse: 16bit */
1213         offset_limit = bit_offset + 16;
1214 
1215         if (extraBit > 0)
1216             extraByte = 1;
1217 
1218         tempBuffer = pHDRDynamicInfo->data.semimajor_axis_external_ellipse[i - 1];
1219         tempBuffer = tempBuffer << (16 - extraBit);
1220         for (j = 0; j < 4; j++) {
1221             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1222         }
1223 
1224         for (j = 0; j < (2 + extraByte); j++) {
1225             for (k = extraBit; k < 8; k++) {
1226                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1227                 bit_offset++;
1228 
1229                 if (bit_offset == offset_limit) {
1230                     break;
1231                 }
1232             }
1233             extraBit = (bit_offset % 8);
1234         }
1235         buffer     = 0;
1236         tempBuffer = 0;
1237         extraByte  = 0;
1238 
1239         /* semiminor_axis_external_ellipse: 16bit */
1240         offset_limit = bit_offset + 16;
1241 
1242         if (extraBit > 0)
1243             extraByte = 1;
1244 
1245         tempBuffer = pHDRDynamicInfo->data.semiminor_axis_external_ellipse[i - 1];
1246         tempBuffer = tempBuffer << (16 - extraBit);
1247         for (j = 0; j < 4; j++) {
1248             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1249         }
1250 
1251         for (j = 0; j < (2 + extraByte); j++) {
1252             for (k = extraBit; k < 8; k++) {
1253                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1254                 bit_offset++;
1255 
1256                 if (bit_offset == offset_limit) {
1257                     break;
1258                 }
1259             }
1260             extraBit = (bit_offset % 8);
1261         }
1262         buffer     = 0;
1263         tempBuffer = 0;
1264         extraByte  = 0;
1265 
1266         /* overlap_process_option: 1bit */
1267         if (pHDRDynamicInfo->data.overlap_process_option[i - 1]) {
1268             *((char *)pBlob + (bit_offset / 8)) |= (1 << (7 - extraBit));
1269         }
1270 
1271         bit_offset += 1;
1272         extraBit = (bit_offset % 8);
1273     }
1274 
1275     /* targeted_system_display_maximum_luminance: 27bit */
1276     offset_limit = bit_offset + 27;
1277 
1278     tempBuffer = pHDRDynamicInfo->data.targeted_system_display_maximum_luminance;
1279     tempBuffer = tempBuffer << (5 - extraBit);
1280     for (i = 0; i < 4; i++) {
1281         memcpy((char *)&buffer + i, (char *)&tempBuffer + (3 - i), sizeof(char));
1282     }
1283 
1284     for (i = 0; i < 4; i++) {
1285         for (j = extraBit; j < 8; j++) {
1286             *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + i) & (1 << (7 - j)));
1287             bit_offset++;
1288 
1289             if (bit_offset == offset_limit)
1290                 break;
1291         }
1292         extraBit = (bit_offset % 8);
1293     }
1294     buffer     = 0;
1295     tempBuffer = 0;
1296 
1297     /* targeted_system_display_actual_peak_luminance_flag: 1bit */
1298     if (pHDRDynamicInfo->data.targeted_system_display_actual_peak_luminance_flag) {
1299         *((char *)pBlob + (bit_offset / 8)) |= (1 << (7 - extraBit));
1300     }
1301     bit_offset += 1;
1302     extraBit = (bit_offset % 8);
1303 
1304     if (pHDRDynamicInfo->data.targeted_system_display_actual_peak_luminance_flag) {
1305         /* num_rows_targeted_system_display_actual_peak_luminance: 5bit */
1306         offset_limit = bit_offset + 5;
1307 
1308         if (extraBit > 3)
1309             extraByte = 1;
1310 
1311         tempBuffer = pHDRDynamicInfo->data.num_rows_targeted_system_display_actual_peak_luminance;
1312         tempBuffer = tempBuffer << (27 - extraBit);
1313         for (i = 0; i < 4; i++) {
1314             memcpy((char *)&buffer + i, (char *)&tempBuffer + (3 - i), sizeof(char));
1315         }
1316 
1317         for (i = 0; i < (1 + extraByte); i++) {
1318             for (j = extraBit; j < 8; j++) {
1319                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + i) & (1 << (7 - j)));
1320                 bit_offset++;
1321 
1322                 if (bit_offset == offset_limit) {
1323                     break;
1324                 }
1325             }
1326             extraBit = (bit_offset % 8);
1327         }
1328         buffer     = 0;
1329         tempBuffer = 0;
1330         extraByte  = 0;
1331 
1332         /* num_cols_targeted_system_display_actual_peak_luminance: 5bit */
1333         offset_limit = bit_offset + 5;
1334 
1335         if (extraBit > 3)
1336             extraByte = 1;
1337 
1338         tempBuffer = pHDRDynamicInfo->data.num_cols_targeted_system_display_actual_peak_luminance;
1339         tempBuffer = tempBuffer << (27 - extraBit);
1340         for (i = 0; i < 4; i++) {
1341             memcpy((char *)&buffer + i, (char *)&tempBuffer + (3 - i), sizeof(char));
1342         }
1343 
1344         for (i = 0; i < (1 + extraByte); i++) {
1345             for (j = extraBit; j < 8; j++) {
1346                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + i) & (1 << (7 - j)));
1347                 bit_offset++;
1348 
1349                 if (bit_offset == offset_limit) {
1350                     break;
1351                 }
1352             }
1353             extraBit = (bit_offset % 8);
1354         }
1355         buffer     = 0;
1356         tempBuffer = 0;
1357         extraByte  = 0;
1358 
1359         /* targeted_system_display_actual_peak_luminance[row][col]: 4bit */
1360         for (i = 0; i < pHDRDynamicInfo->data.num_rows_targeted_system_display_actual_peak_luminance; i++) {
1361             for (j = 0; j < pHDRDynamicInfo->data.num_cols_targeted_system_display_actual_peak_luminance; j++) {
1362                 offset_limit = bit_offset + 4;
1363 
1364                 if (extraBit > 4)
1365                     extraByte = 1;
1366 
1367                 tempBuffer = pHDRDynamicInfo->data.targeted_system_display_actual_peak_luminance[i][j];
1368                 tempBuffer = tempBuffer << (28 - extraBit);
1369                 for (k = 0; k < 4; k++) {
1370                     memcpy((char *)&buffer + k, (char *)&tempBuffer + (3 - k), sizeof(char));
1371                 }
1372 
1373                 for (k = 0; k < (1 + extraByte); k++) {
1374                     for (l = extraBit; l < 8; l++) {
1375                         *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + k) & (1 << (7 - l)));
1376                         bit_offset++;
1377 
1378                         if (bit_offset == offset_limit) {
1379                             break;
1380                         }
1381                     }
1382                     extraBit = (bit_offset % 8);
1383                 }
1384                 buffer     = 0;
1385                 tempBuffer = 0;
1386                 extraByte  = 0;
1387             }
1388         }
1389     }
1390 
1391     for (i = 0; i < pHDRDynamicInfo->data.num_windows; i++) {
1392         /* maxscl: 17bit */
1393         for (j = 0; j < 3; j++) {
1394             offset_limit = bit_offset + 17;
1395 
1396             tempBuffer = pHDRDynamicInfo->data.maxscl[i][j] << (15 - extraBit);
1397             for (k = 0; k < 4; k++) {
1398                 memcpy((char *)&buffer + k, (char *)&tempBuffer + (3 - k), sizeof(char));
1399             }
1400 
1401             for (k = 0; k < 3; k++) {
1402                 for (l = extraBit; l < 8; l++) {
1403                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + k) & (1 << (7 - l)));
1404                     bit_offset++;
1405 
1406                     if (bit_offset == offset_limit)
1407                         break;
1408                 }
1409                 extraBit = (bit_offset % 8);
1410             }
1411             buffer     = 0;
1412             tempBuffer = 0;
1413         }
1414 
1415         /* average_maxrgb: 17bit */
1416         offset_limit = bit_offset + 17;
1417 
1418         tempBuffer = pHDRDynamicInfo->data.average_maxrgb[i] << (15 - extraBit);
1419         for (j = 0; j < 4; j++) {
1420             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1421         }
1422 
1423         for (j = 0; j < 3; j++) {
1424             for (k = extraBit; k < 8; k++) {
1425                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1426                 bit_offset++;
1427 
1428                 if (bit_offset == offset_limit)
1429                     break;
1430             }
1431             extraBit = (bit_offset % 8);
1432         }
1433         buffer     = 0;
1434         tempBuffer = 0;
1435 
1436         /* num_distribution_maxrgb_percentiles: 4bit */
1437         offset_limit = bit_offset + 4;
1438 
1439         if (extraBit > 4)
1440             extraByte = 1;
1441 
1442         tempBuffer = pHDRDynamicInfo->data.num_maxrgb_percentiles[i] << (28 - extraBit);
1443         for (j = 0; j < 4; j++) {
1444             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1445         }
1446 
1447         for (j = 0; j < (1 + extraByte); j++) {
1448             for (k = extraBit; k < 8; k++) {
1449                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1450                 bit_offset++;
1451 
1452                 if (bit_offset == offset_limit)
1453                     break;
1454             }
1455             extraBit = (bit_offset % 8);
1456         }
1457         buffer     = 0;
1458         tempBuffer = 0;
1459         extraByte  = 0;
1460 
1461         for (j = 0; j < pHDRDynamicInfo->data.num_maxrgb_percentiles[i]; j++) {
1462             /* distribution_maxrgb_percentaged: 7bit */
1463             offset_limit = bit_offset + 7;
1464 
1465             if (extraBit > 1)
1466                 extraByte = 1;
1467 
1468             tempBuffer = pHDRDynamicInfo->data.maxrgb_percentages[i][j];
1469             tempBuffer = tempBuffer << (25 - extraBit);
1470             for (k = 0; k < 4; k++) {
1471                 memcpy((char *)&buffer + k, (char *)&tempBuffer + (3 - k), sizeof(char));
1472             }
1473 
1474             for (k = 0; k < (1 + extraByte); k++) {
1475                 for (l = extraBit; l < 8; l++) {
1476                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + k) & (1 << (7 - l)));
1477                     bit_offset++;
1478 
1479                     if (bit_offset == offset_limit) {
1480                         break;
1481                     }
1482                 }
1483                 extraBit = (bit_offset % 8);
1484             }
1485             buffer     = 0;
1486             tempBuffer = 0;
1487             extraByte  = 0;
1488 
1489             /* distribution_maxrgb_percentiles: 17bit */
1490             offset_limit = bit_offset + 17;
1491 
1492             tempBuffer = pHDRDynamicInfo->data.maxrgb_percentiles[i][j] << (15 - extraBit);
1493             for (k = 0; k < 4; k++) {
1494                 memcpy((char *)&buffer + k, (char *)&tempBuffer + (3 - k), sizeof(char));
1495             }
1496 
1497             for (k = 0; k < 3; k++) {
1498                 for (l = extraBit; l < 8; l++) {
1499                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + k) & (1 << (7 - l)));
1500                     bit_offset++;
1501 
1502                     if (bit_offset == offset_limit) {
1503                         break;
1504                     }
1505                 }
1506                 extraBit = (bit_offset % 8);
1507             }
1508             buffer     = 0;
1509             tempBuffer = 0;
1510         }
1511 
1512         /* fraction_bright_pixels: 10bit */
1513         if (extraBit > 6)
1514             extraByte = 1;
1515 
1516         offset_limit = bit_offset + 10;
1517 
1518         tempBuffer = pHDRDynamicInfo->data.fraction_bright_pixels[i];
1519         tempBuffer = tempBuffer << (22 - extraBit);
1520         for (j = 0; j < 4; j++) {
1521             memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1522         }
1523 
1524         for (j = 0; j < (2 + extraByte); j++) {
1525             for (k = extraBit; k < 8; k++) {
1526                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1527                 bit_offset++;
1528 
1529                 if (bit_offset == offset_limit) {
1530                     break;
1531                 }
1532             }
1533             extraBit = (bit_offset % 8);
1534         }
1535         buffer     = 0;
1536         tempBuffer = 0;
1537         extraByte  = 0;
1538     }
1539 
1540     /* mastering_display_actual_peak_luminance_flag: 1bit */
1541     if (pHDRDynamicInfo->data.mastering_display_actual_peak_luminance_flag) {
1542         *((char *)pBlob + (bit_offset / 8)) |= (1 << (7 - extraBit));
1543     }
1544     bit_offset += 1;
1545     extraBit = (bit_offset % 8);
1546 
1547     if (pHDRDynamicInfo->data.mastering_display_actual_peak_luminance_flag) {
1548         /* num_rows_mastering_display_actual_peak_luminance: 5bit */
1549         offset_limit = bit_offset + 5;
1550 
1551         if (extraBit > 3)
1552             extraByte = 1;
1553 
1554         tempBuffer = pHDRDynamicInfo->data.num_rows_mastering_display_actual_peak_luminance;
1555         tempBuffer = tempBuffer << (27 - extraBit);
1556         for (i = 0; i < 4; i++) {
1557             memcpy((char *)&buffer + i, (char *)&tempBuffer + (3 - i), sizeof(char));
1558         }
1559 
1560         for (i = 0; i < (1 + extraByte); i++) {
1561             for (j = extraBit; j < 8; j++) {
1562                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + i) & (1 << (7 - j)));
1563                 bit_offset++;
1564 
1565                 if (bit_offset == offset_limit) {
1566                     break;
1567                 }
1568             }
1569             extraBit = (bit_offset % 8);
1570         }
1571         buffer     = 0;
1572         tempBuffer = 0;
1573         extraByte  = 0;
1574 
1575         /* num_cols_mastering_display_actual_peak_luminance: 5bit */
1576         offset_limit = bit_offset + 5;
1577 
1578         if (extraBit > 3)
1579             extraByte = 1;
1580 
1581         tempBuffer = pHDRDynamicInfo->data.num_cols_mastering_display_actual_peak_luminance;
1582         tempBuffer = tempBuffer << (27 - extraBit);
1583         for (i = 0; i < 4; i++) {
1584             memcpy((char *)&buffer + i, (char *)&tempBuffer + (3 - i), sizeof(char));
1585         }
1586 
1587         for (i = 0; i < (1 + extraByte); i++) {
1588             for (j = extraBit; j < 8; j++) {
1589                 *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + i) & (1 << (7 - j)));
1590                 bit_offset++;
1591 
1592                 if (bit_offset == offset_limit) {
1593                     break;
1594                 }
1595             }
1596             extraBit = (bit_offset % 8);
1597         }
1598         buffer     = 0;
1599         tempBuffer = 0;
1600         extraByte  = 0;
1601 
1602         /* mastering_display_actual_peak_luminance[row][col]: 4bit */
1603         for (i = 0; i < pHDRDynamicInfo->data.num_rows_mastering_display_actual_peak_luminance; i++) {
1604             for (j = 0; j < pHDRDynamicInfo->data.num_cols_mastering_display_actual_peak_luminance; j++) {
1605                 offset_limit = bit_offset + 4;
1606 
1607                 if (extraBit > 4)
1608                     extraByte = 1;
1609 
1610                 tempBuffer = pHDRDynamicInfo->data.mastering_display_actual_peak_luminance[i][j];
1611                 tempBuffer = tempBuffer << (28 - extraBit);
1612                 for (k = 0; k < 4; k++) {
1613                     memcpy((char *)&buffer + k, (char *)&tempBuffer + (3 - k), sizeof(char));
1614                 }
1615 
1616                 for (k = 0; k < (1 + extraByte); k++) {
1617                     for (l = extraBit; l < 8; l++) {
1618                         *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + k) & (1 << (7 - l)));
1619                         bit_offset++;
1620 
1621                         if (bit_offset == offset_limit) {
1622                             break;
1623                         }
1624                     }
1625                     extraBit = (bit_offset % 8);
1626                 }
1627                 buffer     = 0;
1628                 tempBuffer = 0;
1629                 extraByte  = 0;
1630             }
1631         }
1632     }
1633 
1634     for (i = 0; i < pHDRDynamicInfo->data.num_windows; i++) {
1635         /* tone_mapping_flag: 1bit */
1636         if (pHDRDynamicInfo->data.tone_mapping.tone_mapping_flag[i]) {
1637             *((char *)pBlob + (bit_offset / 8)) |= (1 << (7 - extraBit));
1638         }
1639         bit_offset += 1;
1640         extraBit = (bit_offset % 8);
1641 
1642         if (pHDRDynamicInfo->data.tone_mapping.tone_mapping_flag[i]) {
1643             /* knee_point_x: 12bit */
1644             if (extraBit > 4)
1645                 extraByte = 1;
1646 
1647             offset_limit = bit_offset + 12;
1648 
1649             tempBuffer = pHDRDynamicInfo->data.tone_mapping.knee_point_x[i];
1650             tempBuffer = tempBuffer << (20 - extraBit);
1651             for (j = 0; j < 4; j++) {
1652                 memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1653             }
1654 
1655             for (j = 0; j < (2 + extraByte); j++) {
1656                 for (k = extraBit; k < 8; k++) {
1657                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1658                     bit_offset++;
1659 
1660                     if (bit_offset == offset_limit) {
1661                         break;
1662                     }
1663                 }
1664                 extraBit = (bit_offset % 8);
1665             }
1666             buffer     = 0;
1667             tempBuffer = 0;
1668             extraByte  = 0;
1669 
1670             /* knee_point_y: 12bit */
1671             if (extraBit > 4)
1672                 extraByte = 1;
1673 
1674             offset_limit = bit_offset + 12;
1675 
1676             tempBuffer = pHDRDynamicInfo->data.tone_mapping.knee_point_y[i];
1677             tempBuffer = tempBuffer << (20 - extraBit);
1678             for (j = 0; j < 4; j++) {
1679                 memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1680             }
1681 
1682             for (j = 0; j < (2 + extraByte); j++) {
1683                 for (k = extraBit; k < 8; k++) {
1684                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1685                     bit_offset++;
1686 
1687                     if (bit_offset == offset_limit) {
1688                         break;
1689                     }
1690                 }
1691                 extraBit = (bit_offset % 8);
1692             }
1693             buffer     = 0;
1694             tempBuffer = 0;
1695             extraByte  = 0;
1696 
1697             /* num_bezier_curve_anchors: 4bit */
1698             if (extraBit > 4)
1699                 extraByte = 1;
1700 
1701             offset_limit = bit_offset + 4;
1702 
1703             tempBuffer = pHDRDynamicInfo->data.tone_mapping.num_bezier_curve_anchors[i];
1704             tempBuffer = tempBuffer << (28 - extraBit);
1705             for (j = 0; j < 4; j++) {
1706                 memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1707             }
1708 
1709             for (j = 0; j < (1 + extraByte); j++) {
1710                 for (k = extraBit; k < 8; k++) {
1711                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1712                     bit_offset++;
1713 
1714                     if (bit_offset == offset_limit) {
1715                         break;
1716                     }
1717                 }
1718                 extraBit = (bit_offset % 8);
1719             }
1720             buffer     = 0;
1721             tempBuffer = 0;
1722             extraByte  = 0;
1723 
1724             for (j = 0; j < pHDRDynamicInfo->data.tone_mapping.num_bezier_curve_anchors[i]; j++) {
1725                 /* bezier_curve_anchors: 10bit */
1726                 if (extraBit > 6)
1727                     extraByte = 1;
1728 
1729                 offset_limit = bit_offset + 10;
1730 
1731                 tempBuffer = pHDRDynamicInfo->data.tone_mapping.bezier_curve_anchors[i][j];
1732                 tempBuffer = tempBuffer << (22 - extraBit);
1733                 for (k = 0; k < 4; k++) {
1734                     memcpy((char *)&buffer + k, (char *)&tempBuffer + (3 - k), sizeof(char));
1735                 }
1736 
1737                 for (k = 0; k < (2 + extraByte); k++) {
1738                     for (l = extraBit; l < 8; l++) {
1739                         *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + k) & (1 << (7 - l)));
1740                         bit_offset++;
1741 
1742                         if (bit_offset == offset_limit) {
1743                             break;
1744                         }
1745                     }
1746                     extraBit = (bit_offset % 8);
1747                 }
1748                 buffer     = 0;
1749                 tempBuffer = 0;
1750                 extraByte  = 0;
1751             }
1752         }
1753 
1754         /* color_saturation_mapping_flag: 1bit */
1755         if (pHDRDynamicInfo->data.color_saturation_mapping_flag[i]) {
1756             *((char *)pBlob + (bit_offset / 8)) |= (1 << (7 - extraBit));
1757         }
1758         bit_offset += 1;
1759         extraBit = (bit_offset % 8);
1760 
1761         if (pHDRDynamicInfo->data.color_saturation_mapping_flag[i]) {
1762             /* color_saturation_weight: 6bit */
1763             if (extraBit > 2)
1764                 extraByte = 1;
1765 
1766             offset_limit = bit_offset + 6;
1767 
1768             tempBuffer = pHDRDynamicInfo->data.color_saturation_weight[i];
1769             tempBuffer = tempBuffer << (26 - extraBit);
1770             for (j = 0; j < 4; j++) {
1771                 memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char));
1772             }
1773 
1774             for (j = 0; j < (1 + extraByte); j++) {
1775                 for (k = extraBit; k < 8; k++) {
1776                     *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k)));
1777                     bit_offset++;
1778 
1779                     if (bit_offset == offset_limit) {
1780                         break;
1781                     }
1782                 }
1783                 extraBit = (bit_offset % 8);
1784             }
1785             buffer     = 0;
1786             tempBuffer = 0;
1787             extraByte  = 0;
1788         }
1789     }
1790 
1791     if(extraBit > 0) {
1792         size = (bit_offset / 8) + 1;
1793     } else {
1794         size = (bit_offset / 8);
1795     }
1796 
1797     return size;
1798 }
1799 
1800 #ifdef __cplusplus
1801 }
1802 #endif
1803