/src/vlc/modules/demux/mpeg/ts_arib.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * ts_arib.c : TS demux ARIB specific handling |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2017 - VideoLAN Authors |
5 | | * |
6 | | * This program is free software; you can redistribute it and/or modify it |
7 | | * under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation; either version 2.1 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | | *****************************************************************************/ |
19 | | #ifdef HAVE_CONFIG_H |
20 | | # include "config.h" |
21 | | #endif |
22 | | |
23 | | #include <vlc_common.h> |
24 | | #include <vlc_demux.h> |
25 | | |
26 | | #include "timestamps.h" |
27 | | #include "ts_pid.h" |
28 | | #include "ts.h" |
29 | | |
30 | | #include "ts_arib.h" |
31 | | |
32 | | /* |
33 | | * ARIB TR-B21 |
34 | | * Logo PNG is 8 bit indexed dans the palette is missing, |
35 | | * provided as a CLUT. We need to reinject the CLUT as a |
36 | | * split palette + transparency (as PNG only allows split alpha table) |
37 | | */ |
38 | | |
39 | | /* ARIB TR-B14-1 Appendix 1 */ |
40 | | static const unsigned char CLUT_to_chunks[] = { |
41 | | /* size + PLTE */ |
42 | | 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, 0x45, |
43 | | /* DATA ARIB TR-B14-1 Appendix 1 */ |
44 | | 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, /* 0-7 */ |
45 | | 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, |
46 | | |
47 | | 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, /* 8-15 */ |
48 | | 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, |
49 | | |
50 | | 0x00, 0x00, 0x55, 0x00, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x55, 0xaa, /* 16-23 */ |
51 | | 0x00, 0x55, 0xff, 0x00, 0xaa, 0x55, 0x00, 0xaa, 0xff, 0x00, 0xff, 0x55, |
52 | | |
53 | | 0x00, 0xff, 0xaa, 0x55, 0x00, 0x00, 0x55, 0x00, 0x55, 0x55, 0x00, 0xaa, /* 24-31 */ |
54 | | 0x55, 0x00, 0xff, 0x55, 0x55, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, |
55 | | |
56 | | 0x55, 0x55, 0xff, 0x55, 0xaa, 0x00, 0x55, 0xaa, 0x00, 0x55, 0xaa, 0x55, /* 32-39 */ |
57 | | 0x55, 0xaa, 0xaa, 0x55, 0xaa, 0xff, 0x55, 0xff, 0x00, 0x55, 0xff, 0x55, |
58 | | |
59 | | 0x55, 0xff, 0xff, 0xaa, 0x00, 0x55, 0xaa, 0x00, 0xff, 0xaa, 0x55, 0x00, /* 40-47 */ |
60 | | 0xaa, 0x55, 0x55, 0xaa, 0x55, 0xaa, 0xaa, 0x55, 0xff, 0xaa, 0xaa, 0x55, |
61 | | |
62 | | 0xaa, 0xaa, 0xff, 0xaa, 0xff, 0x00, 0xaa, 0xff, 0x55, 0xaa, 0xff, 0xaa, /* 48-55 */ |
63 | | 0xaa, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0x00, 0xaa, 0xff, 0x55, 0x00, |
64 | | |
65 | | 0xff, 0x55, 0x55, 0xff, 0x55, 0xaa, 0xff, 0x55, 0xff, 0xff, 0xaa, 0x00, /* 56-63 */ |
66 | | 0xff, 0xaa, 0x55, 0xff, 0xaa, 0xaa, 0xff, 0xaa, 0xff, 0xff, 0xff, 0x55, |
67 | | |
68 | | 0xff, 0xff, 0xaa, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, /* 64-71 */ |
69 | | 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, |
70 | | |
71 | | 0xff, 0xff, 0xff, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0x00, 0xaa, 0xaa, 0x00, /* 72-79 */ |
72 | | 0x00, 0x00, 0xaa, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, |
73 | | |
74 | | 0x00, 0x00, 0x55, 0x00, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x55, 0xaa, /* 80-87 */ |
75 | | 0x00, 0x55, 0xff, 0x00, 0xaa, 0x55, 0x00, 0xaa, 0xff, 0x00, 0xff, 0x55, |
76 | | |
77 | | 0x00, 0xff, 0xaa, 0x55, 0x00, 0x00, 0x55, 0x00, 0x55, 0x55, 0x00, 0xaa, /* 88-95 */ |
78 | | 0x55, 0x00, 0xff, 0x55, 0x55, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, |
79 | | |
80 | | 0x55, 0x55, 0xff, 0x55, 0xaa, 0x00, 0x55, 0xaa, 0x55, 0x55, 0xaa, 0xaa, /* 96-103 */ |
81 | | 0x55, 0xaa, 0xff, 0x55, 0xff, 0x00, 0x55, 0xff, 0x55, 0x55, 0xff, 0xaa, |
82 | | |
83 | | 0x55, 0xff, 0xff, 0xaa, 0x00, 0x55, 0xaa, 0x00, 0xff, 0xaa, 0x55, 0x00, /* 104-111 */ |
84 | | 0xaa, 0x55, 0x55, 0xaa, 0x55, 0xaa, 0xaa, 0x55, 0xff, 0xaa, 0xaa, 0x55, |
85 | | |
86 | | 0xaa, 0xaa, 0xff, 0xaa, 0xff, 0x00, 0xaa, 0xff, 0x55, 0xaa, 0xff, 0xaa, /* 112-119 */ |
87 | | 0xaa, 0xff, 0xff, 0xff, 0x00, 0x55, 0xff, 0x00, 0xaa, 0xff, 0x55, 0x00, |
88 | | |
89 | | 0xff, 0x55, 0x55, 0xff, 0x55, 0xaa, 0xff, 0x55, 0xff, 0xff, 0xaa, 0x00, /* 120-127 */ |
90 | | 0xff, 0xaa, 0x55, 0xff, 0xaa, 0xaa, 0xff, 0xaa, 0xff, 0xff, 0xff, 0x55, |
91 | | |
92 | | /* CRC32 (all data including type, without length and crc) . pngcheck output being the lazy way */ |
93 | | 0x4f, 0xed, 0xfc, 0x8d, |
94 | | |
95 | | /* Second Chunk */ |
96 | | |
97 | | /* size + tRNS */ |
98 | | 0x00, 0x00, 0x00, 0x80, 0x74, 0x52, 0x4e, 0x53, |
99 | | |
100 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0-63 */ |
101 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
102 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
103 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
104 | | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
105 | | 0xff, 0xff, 0xff, 0xff, |
106 | | |
107 | | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 64-127 */ |
108 | | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
109 | | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
110 | | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
111 | | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, |
112 | | 0x80, 0x80, 0x80, 0x80, |
113 | | |
114 | | /* CRC32 */ |
115 | | 0xfa, 0xe9, 0x51, 0x40, |
116 | | }; |
117 | | static const unsigned int CLUT_to_chunks_len = sizeof(CLUT_to_chunks); |
118 | | |
119 | | bool ts_arib_inject_png_palette( const uint8_t *p_in, size_t i_in, uint8_t **pp_out, size_t *pi_out ) |
120 | 0 | { |
121 | 0 | const uint8_t *p_data = p_in; |
122 | 0 | const uint8_t *p_idat = NULL; |
123 | 0 | size_t i_data = i_in - 8; |
124 | 0 | p_data += 8; |
125 | 0 | i_data -= 8; |
126 | |
|
127 | 0 | while( i_data > 11 ) |
128 | 0 | { |
129 | 0 | uint32_t i_len = GetDWBE( p_data ); |
130 | 0 | if( i_len > 0x7FFFFFFFU || i_len > i_data - 12 ) |
131 | 0 | break; |
132 | | |
133 | 0 | uint32_t i_chunk = VLC_FOURCC(p_data[4], p_data[5], p_data[6], p_data[7]); |
134 | 0 | if( i_chunk == VLC_FOURCC('I', 'D', 'A', 'T') ) |
135 | 0 | { |
136 | 0 | p_idat = p_data; |
137 | 0 | break; |
138 | 0 | } |
139 | | |
140 | 0 | p_data += i_len + 12; |
141 | 0 | i_data -= i_len + 12; |
142 | 0 | } |
143 | |
|
144 | 0 | if( !p_idat ) |
145 | 0 | return false; |
146 | | |
147 | 0 | { |
148 | 0 | uint8_t *p_out = *pp_out = malloc( i_in + CLUT_to_chunks_len ); |
149 | 0 | if( !p_out ) |
150 | 0 | return false; |
151 | 0 | *pi_out = i_in + CLUT_to_chunks_len; |
152 | |
|
153 | 0 | const size_t i_head = p_data - p_in; |
154 | 0 | memcpy( p_out, p_in, i_head ); |
155 | 0 | memcpy( &p_out[i_head], CLUT_to_chunks, CLUT_to_chunks_len ); |
156 | 0 | memcpy( &p_out[i_head + CLUT_to_chunks_len], p_data, i_in - i_head ); |
157 | 0 | } |
158 | | |
159 | 0 | return true; |
160 | 0 | } |
161 | | |
162 | | |
163 | | void ts_arib_logo_dr_Delete( ts_arib_logo_dr_t *p_dr ) |
164 | 0 | { |
165 | 0 | free( p_dr->p_logo_char ); |
166 | 0 | free( p_dr ); |
167 | 0 | } |
168 | | |
169 | | ts_arib_logo_dr_t * ts_arib_logo_dr_Decode( const uint8_t *p_data, size_t i_data ) |
170 | 0 | { |
171 | 0 | if( i_data < 2 ) |
172 | 0 | return NULL; |
173 | | |
174 | 0 | ts_arib_logo_dr_t *p_dr = calloc( 1, sizeof(*p_dr) ); |
175 | 0 | if( unlikely( p_dr == NULL ) ) |
176 | 0 | return NULL; |
177 | | |
178 | 0 | p_dr->i_logo_version = p_data[0]; |
179 | 0 | switch( p_data[0] ) |
180 | 0 | { |
181 | 0 | case 1: |
182 | 0 | if( i_data != 7 ) |
183 | 0 | break; |
184 | 0 | p_dr->i_logo_id = ((p_data[1] & 0x01) << 8) | p_data[2]; |
185 | 0 | p_dr->i_logo_version = ((p_data[3] & 0x0F) << 8) | p_data[4]; |
186 | 0 | p_dr->i_download_data_id = (p_data[5] << 8) | p_data[6]; |
187 | 0 | return p_dr; |
188 | 0 | case 2: |
189 | 0 | if( i_data != 3 ) |
190 | 0 | break; |
191 | 0 | p_dr->i_logo_id = ((p_data[1] & 0x01) << 8) | p_data[2]; |
192 | 0 | return p_dr; |
193 | 0 | case 3: |
194 | 0 | if( i_data <= 2 ) |
195 | 0 | break; |
196 | | |
197 | 0 | p_dr->p_logo_char = malloc( i_data - 1 ); |
198 | 0 | if( unlikely( p_dr->p_logo_char == NULL ) ) |
199 | 0 | break; |
200 | | |
201 | 0 | p_dr->i_logo_char = i_data - 1; |
202 | 0 | memcpy( p_dr->p_logo_char, &p_data[1], p_dr->i_logo_char ); |
203 | 0 | return p_dr; |
204 | 0 | default: |
205 | 0 | break; |
206 | 0 | } |
207 | | |
208 | 0 | ts_arib_logo_dr_Delete( p_dr ); |
209 | | return NULL; |
210 | 0 | } |