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