1 /*
2 * This file is part of libbluray
3 * Copyright (C) 2010 Petri Hintukainen <phintuka@users.sourceforge.net>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see
17 * <http://www.gnu.org/licenses/>.
18 */
19
20 #if HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "pg_decode.h"
25
26 #include "util/refcnt.h"
27 #include "util/macro.h"
28 #include "util/logging.h"
29 #include "util/bits.h"
30
31 #include <string.h>
32 #include <stdlib.h>
33
34 /*
35 *
36 */
37
pg_decode_video_descriptor(BITBUFFER * bb,BD_PG_VIDEO_DESCRIPTOR * p)38 void pg_decode_video_descriptor(BITBUFFER *bb, BD_PG_VIDEO_DESCRIPTOR *p)
39 {
40 p->video_width = bb_read(bb, 16);
41 p->video_height = bb_read(bb, 16);
42 p->frame_rate = bb_read(bb, 4);
43 bb_skip(bb, 4);
44 }
45
pg_decode_composition_descriptor(BITBUFFER * bb,BD_PG_COMPOSITION_DESCRIPTOR * p)46 void pg_decode_composition_descriptor(BITBUFFER *bb, BD_PG_COMPOSITION_DESCRIPTOR *p)
47 {
48 p->number = bb_read(bb, 16);
49 p->state = bb_read(bb, 2);
50 bb_skip(bb, 6);
51 }
52
pg_decode_sequence_descriptor(BITBUFFER * bb,BD_PG_SEQUENCE_DESCRIPTOR * p)53 void pg_decode_sequence_descriptor(BITBUFFER *bb, BD_PG_SEQUENCE_DESCRIPTOR *p)
54 {
55 p->first_in_seq = bb_read(bb, 1);
56 p->last_in_seq = bb_read(bb, 1);
57 bb_skip(bb, 6);
58 }
59
pg_decode_window(BITBUFFER * bb,BD_PG_WINDOW * p)60 void pg_decode_window(BITBUFFER *bb, BD_PG_WINDOW *p)
61 {
62 p->id = bb_read(bb, 8);
63 p->x = bb_read(bb, 16);
64 p->y = bb_read(bb, 16);
65 p->width = bb_read(bb, 16);
66 p->height = bb_read(bb, 16);
67 }
68
pg_decode_composition_object(BITBUFFER * bb,BD_PG_COMPOSITION_OBJECT * p)69 void pg_decode_composition_object(BITBUFFER *bb, BD_PG_COMPOSITION_OBJECT *p)
70 {
71 p->object_id_ref = bb_read(bb, 16);
72 p->window_id_ref = bb_read(bb, 8);
73
74 p->crop_flag = bb_read(bb, 1);
75 p->forced_on_flag = bb_read(bb, 1);
76 bb_skip(bb, 6);
77
78 p->x = bb_read(bb, 16);
79 p->y = bb_read(bb, 16);
80
81 if (p->crop_flag) {
82 p->crop_x = bb_read(bb, 16);
83 p->crop_y = bb_read(bb, 16);
84 p->crop_w = bb_read(bb, 16);
85 p->crop_h = bb_read(bb, 16);
86 }
87 }
88
pg_decode_palette_entry(BITBUFFER * bb,BD_PG_PALETTE_ENTRY * entry)89 void pg_decode_palette_entry(BITBUFFER *bb, BD_PG_PALETTE_ENTRY *entry)
90 {
91 uint8_t entry_id = bb_read(bb, 8);
92
93 entry[entry_id].Y = bb_read(bb, 8);
94 entry[entry_id].Cr = bb_read(bb, 8);
95 entry[entry_id].Cb = bb_read(bb, 8);
96 entry[entry_id].T = bb_read(bb, 8);
97 }
98
99 /*
100 * segments
101 */
102
pg_decode_palette_update(BITBUFFER * bb,BD_PG_PALETTE * p)103 int pg_decode_palette_update(BITBUFFER *bb, BD_PG_PALETTE *p)
104 {
105 p->id = bb_read(bb, 8);
106 p->version = bb_read(bb, 8);
107
108 while (!bb_eof(bb)) {
109 pg_decode_palette_entry(bb, p->entry);
110 }
111
112 return 1;
113 }
114
pg_decode_palette(BITBUFFER * bb,BD_PG_PALETTE * p)115 int pg_decode_palette(BITBUFFER *bb, BD_PG_PALETTE *p)
116 {
117 memset(p->entry, 0, sizeof(p->entry));
118
119 return pg_decode_palette_update(bb, p);
120 }
121
_decode_rle(BITBUFFER * bb,BD_PG_OBJECT * p)122 static int _decode_rle(BITBUFFER *bb, BD_PG_OBJECT *p)
123 {
124 BD_PG_RLE_ELEM *tmp;
125 int pixels_left = p->width * p->height;
126 int num_rle = 0;
127 int rle_size = p->width * p->height / 4;
128
129 if (rle_size < 1)
130 rle_size = 1;
131
132 tmp = refcnt_realloc(p->img, rle_size * sizeof(BD_PG_RLE_ELEM), NULL);
133 if (!tmp) {
134 BD_DEBUG(DBG_DECODE | DBG_CRIT, "pg_decode_object(): realloc failed\n");
135 return 0;
136 }
137 p->img = tmp;
138
139 while (!bb_eof(bb)) {
140 uint32_t len = 1;
141 uint8_t color = 0;
142
143 if (!(color = bb_read(bb, 8))) {
144 if (!bb_read(bb, 1)) {
145 if (!bb_read(bb, 1)) {
146 len = bb_read(bb, 6);
147 } else {
148 len = bb_read(bb, 14);
149 }
150 } else {
151 if (!bb_read(bb, 1)) {
152 len = bb_read(bb, 6);
153 } else {
154 len = bb_read(bb, 14);
155 }
156 color = bb_read(bb, 8);
157 }
158 }
159
160 p->img[num_rle].len = len;
161 p->img[num_rle].color = color;
162
163 pixels_left -= len;
164
165 if (pixels_left < 0) {
166 BD_DEBUG(DBG_DECODE, "pg_decode_object(): too many pixels (%d)\n", -pixels_left);
167 return 0;
168 }
169
170 num_rle++;
171 if (num_rle >= rle_size) {
172 rle_size *= 2;
173 tmp = refcnt_realloc(p->img, rle_size * sizeof(BD_PG_RLE_ELEM), NULL);
174 if (!tmp) {
175 BD_DEBUG(DBG_DECODE | DBG_CRIT, "pg_decode_object(): realloc failed\n");
176 return 0;
177 }
178 p->img = tmp;
179 }
180 }
181
182 if (pixels_left > 0) {
183 BD_DEBUG(DBG_DECODE, "pg_decode_object(): missing %d pixels\n", pixels_left);
184 return 0;
185 }
186
187 return 1;
188 }
189
pg_decode_object(BITBUFFER * bb,BD_PG_OBJECT * p)190 int pg_decode_object(BITBUFFER *bb, BD_PG_OBJECT *p)
191 {
192 BD_PG_SEQUENCE_DESCRIPTOR sd;
193
194 p->id = bb_read(bb, 16);
195 p->version = bb_read(bb, 8);
196
197 pg_decode_sequence_descriptor(bb, &sd);
198
199 /* splitted segments should be already joined */
200 if (!sd.first_in_seq) {
201 BD_DEBUG(DBG_DECODE, "pg_decode_object(): not first in sequence\n");
202 return 0;
203 }
204 if (!sd.last_in_seq) {
205 BD_DEBUG(DBG_DECODE, "pg_decode_object(): not last in sequence\n");
206 return 0;
207 }
208
209 if (!bb_is_align(bb, 0x07)) {
210 BD_DEBUG(DBG_DECODE, "pg_decode_object(): alignment error\n");
211 return 0;
212 }
213
214 uint32_t data_len = bb_read(bb, 24);
215 uint32_t buf_len = bb->p_end - bb->p;
216 if (data_len != buf_len) {
217 BD_DEBUG(DBG_DECODE, "pg_decode_object(): buffer size mismatch (expected %d, have %d)\n", data_len, buf_len);
218 return 0;
219 }
220
221 p->width = bb_read(bb, 16);
222 p->height = bb_read(bb, 16);
223
224 return _decode_rle(bb, p);
225 }
226
pg_decode_composition(BITBUFFER * bb,BD_PG_COMPOSITION * p)227 int pg_decode_composition(BITBUFFER *bb, BD_PG_COMPOSITION *p)
228 {
229 unsigned ii;
230
231 pg_decode_video_descriptor(bb, &p->video_descriptor);
232 pg_decode_composition_descriptor(bb, &p->composition_descriptor);
233
234 p->palette_update_flag = bb_read(bb, 1);
235 bb_skip(bb, 7);
236
237 p->palette_id_ref = bb_read(bb, 8);
238
239 p->num_composition_objects = bb_read(bb, 8);
240 p->composition_object = calloc(p->num_composition_objects, sizeof(BD_PG_COMPOSITION_OBJECT));
241 if (!p->composition_object) {
242 BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n");
243 return 0;
244 }
245
246 for (ii = 0; ii < p->num_composition_objects; ii++) {
247 pg_decode_composition_object(bb, &p->composition_object[ii]);
248 }
249
250 return 1;
251 }
252
pg_decode_windows(BITBUFFER * bb,BD_PG_WINDOWS * p)253 int pg_decode_windows(BITBUFFER *bb, BD_PG_WINDOWS *p)
254 {
255 unsigned ii;
256
257 p->num_windows = bb_read(bb, 8);
258 p->window = calloc(p->num_windows, sizeof(BD_PG_WINDOW));
259 if (!p->window) {
260 BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n");
261 return 0;
262 }
263
264 for (ii = 0; ii < p->num_windows; ii++) {
265 pg_decode_window(bb, &p->window[ii]);
266 }
267
268 return 1;
269 }
270
271 /*
272 * cleanup
273 */
274
pg_clean_object(BD_PG_OBJECT * p)275 void pg_clean_object(BD_PG_OBJECT *p)
276 {
277 if (p) {
278 bd_refcnt_dec(p->img);
279 p->img = NULL;
280 }
281 }
282
pg_clean_windows(BD_PG_WINDOWS * p)283 void pg_clean_windows(BD_PG_WINDOWS *p)
284 {
285 if (p) {
286 X_FREE(p->window);
287 }
288 }
289
pg_clean_composition(BD_PG_COMPOSITION * p)290 static void pg_clean_composition(BD_PG_COMPOSITION *p)
291 {
292 if (p) {
293 X_FREE(p->composition_object);
294 }
295 }
296
pg_free_composition(BD_PG_COMPOSITION ** p)297 void pg_free_composition(BD_PG_COMPOSITION **p)
298 {
299 if (p && *p) {
300 pg_clean_composition(*p);
301 X_FREE(*p);
302 }
303 }
304