comparison dvbsub.c @ 2796:95c35706acbb libavcodec

DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
author michael
date Sun, 17 Jul 2005 00:28:12 +0000
parents d8874c8749ec
children ac94d509884e
comparison
equal deleted inserted replaced
2795:de03cac6f7c2 2796:95c35706acbb
223 223
224 224
225 q = outbuf; 225 q = outbuf;
226 226
227 page_id = 1; 227 page_id = 1;
228 region_id = 0; 228
229 clut_id = 0; 229 if (h->num_rects == 0 || h->rects == NULL)
230 object_id = 0;
231 if (h->nb_colors <= 4) {
232 /* 2 bpp, some decoders do not support it correctly */
233 bpp_index = 0;
234 } else if (h->nb_colors <= 16) {
235 /* 4 bpp, standard encoding */
236 bpp_index = 1;
237 } else {
238 return -1; 230 return -1;
239 }
240 231
241 *q++ = 0x00; /* subtitle_stream_id */ 232 *q++ = 0x00; /* subtitle_stream_id */
242 233
243 /* page composition segment */ 234 /* page composition segment */
244 235
252 page_state = 0; /* normal case */ 243 page_state = 0; /* normal case */
253 else 244 else
254 page_state = 2; /* mode change */ 245 page_state = 2; /* mode change */
255 /* page_version = 0 + page_state */ 246 /* page_version = 0 + page_state */
256 *q++ = s->object_version | (page_state << 2) | 3; 247 *q++ = s->object_version | (page_state << 2) | 3;
257 *q++ = region_id; 248
258 *q++ = 0xff; /* reserved */ 249 for (region_id = 0; region_id < h->num_rects; region_id++) {
259 putbe16(&q, 0); /* left pos */ 250 *q++ = region_id;
260 putbe16(&q, 0); /* top pos */ 251 *q++ = 0xff; /* reserved */
252 putbe16(&q, h->rects[region_id].x); /* left pos */
253 putbe16(&q, h->rects[region_id].y); /* top pos */
254 }
261 255
262 putbe16(&pseg_len, q - pseg_len - 2); 256 putbe16(&pseg_len, q - pseg_len - 2);
263 257
264 if (!s->hide_state) { 258 if (!s->hide_state) {
265 /* CLUT segment */ 259 for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
260
261 /* CLUT segment */
262
263 if (h->rects[clut_id].nb_colors <= 4) {
264 /* 2 bpp, some decoders do not support it correctly */
265 bpp_index = 0;
266 } else if (h->rects[clut_id].nb_colors <= 16) {
267 /* 4 bpp, standard encoding */
268 bpp_index = 1;
269 } else {
270 return -1;
271 }
272
273 *q++ = 0x0f; /* sync byte */
274 *q++ = 0x12; /* CLUT definition segment */
275 putbe16(&q, page_id);
276 pseg_len = q;
277 q += 2; /* segment length */
278 *q++ = clut_id;
279 *q++ = (0 << 4) | 0xf; /* version = 0 */
280
281 for(i = 0; i < h->rects[clut_id].nb_colors; i++) {
282 *q++ = i; /* clut_entry_id */
283 *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
284 {
285 int a, r, g, b;
286 a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff;
287 r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff;
288 g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff;
289 b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff;
290
291 *q++ = RGB_TO_Y_CCIR(r, g, b);
292 *q++ = RGB_TO_V_CCIR(r, g, b, 0);
293 *q++ = RGB_TO_U_CCIR(r, g, b, 0);
294 *q++ = 255 - a;
295 }
296 }
297
298 putbe16(&pseg_len, q - pseg_len - 2);
299 }
300 }
301
302 for (region_id = 0; region_id < h->num_rects; region_id++) {
303
304 /* region composition segment */
266 305
267 *q++ = 0x0f; /* sync byte */ 306 if (h->rects[region_id].nb_colors <= 4) {
268 *q++ = 0x12; /* CLUT definition segment */ 307 /* 2 bpp, some decoders do not support it correctly */
308 bpp_index = 0;
309 } else if (h->rects[region_id].nb_colors <= 16) {
310 /* 4 bpp, standard encoding */
311 bpp_index = 1;
312 } else {
313 return -1;
314 }
315
316 *q++ = 0x0f; /* sync_byte */
317 *q++ = 0x11; /* segment_type */
269 putbe16(&q, page_id); 318 putbe16(&q, page_id);
270 pseg_len = q; 319 pseg_len = q;
271 q += 2; /* segment length */ 320 q += 2; /* segment length */
272 *q++ = clut_id; 321 *q++ = region_id;
273 *q++ = (0 << 4) | 0xf; /* version = 0 */ 322 *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
274 323 putbe16(&q, h->rects[region_id].w); /* region width */
275 for(i = 0; i < h->nb_colors; i++) { 324 putbe16(&q, h->rects[region_id].h); /* region height */
276 *q++ = i; /* clut_entry_id */ 325 *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
277 *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ 326 *q++ = region_id; /* clut_id == region_id */
278 { 327 *q++ = 0; /* 8 bit fill colors */
279 int a, r, g, b; 328 *q++ = 0x03; /* 4 bit and 2 bit fill colors */
280 a = (h->rgba_palette[i] >> 24) & 0xff; 329
281 r = (h->rgba_palette[i] >> 16) & 0xff; 330 if (!s->hide_state) {
282 g = (h->rgba_palette[i] >> 8) & 0xff; 331 putbe16(&q, region_id); /* object_id == region_id */
283 b = (h->rgba_palette[i] >> 0) & 0xff; 332 *q++ = (0 << 6) | (0 << 4);
284 333 *q++ = 0;
285 *q++ = RGB_TO_Y_CCIR(r, g, b); 334 *q++ = 0xf0;
286 *q++ = RGB_TO_V_CCIR(r, g, b, 0); 335 *q++ = 0;
287 *q++ = RGB_TO_U_CCIR(r, g, b, 0);
288 *q++ = 255 - a;
289 }
290 } 336 }
291 337
292 putbe16(&pseg_len, q - pseg_len - 2); 338 putbe16(&pseg_len, q - pseg_len - 2);
293 } 339 }
294 /* region composition segment */
295
296 *q++ = 0x0f; /* sync_byte */
297 *q++ = 0x11; /* segment_type */
298 putbe16(&q, page_id);
299 pseg_len = q;
300 q += 2; /* segment length */
301 *q++ = region_id;
302 *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
303 putbe16(&q, 720); /* region width */
304 putbe16(&q, 576); /* region height */
305 *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
306 *q++ = clut_id;
307 *q++ = 0; /* 8 bit fill colors */
308 *q++ = 0x03; /* 4 bit and 2 bit fill colors */
309
310 if (!s->hide_state) {
311 putbe16(&q, object_id);
312 *q++ = (0 << 6) | (0 << 4) | ((h->x >> 8) & 0xf);
313 *q++ = h->x;
314 *q++ = 0xf0 | ((h->y >> 8) & 0xf);
315 *q++ = h->y;
316 }
317
318 putbe16(&pseg_len, q - pseg_len - 2);
319 340
320 if (!s->hide_state) { 341 if (!s->hide_state) {
321 342
322 /* Object Data segment */ 343 for (object_id = 0; object_id < h->num_rects; object_id++) {
323 344 /* Object Data segment */
324 *q++ = 0x0f; /* sync byte */ 345
325 *q++ = 0x13; 346 if (h->rects[region_id].nb_colors <= 4) {
326 putbe16(&q, page_id); 347 /* 2 bpp, some decoders do not support it correctly */
327 pseg_len = q; 348 bpp_index = 0;
328 q += 2; /* segment length */ 349 } else if (h->rects[region_id].nb_colors <= 16) {
329 350 /* 4 bpp, standard encoding */
330 putbe16(&q, object_id); 351 bpp_index = 1;
331 *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, 352 } else {
332 onject_coding_method, 353 return -1;
333 non_modifying_color_flag */ 354 }
334 { 355
335 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; 356 *q++ = 0x0f; /* sync byte */
336 void (*dvb_encode_rle)(uint8_t **pq, 357 *q++ = 0x13;
337 const uint8_t *bitmap, int linesize, 358 putbe16(&q, page_id);
338 int w, int h); 359 pseg_len = q;
339 ptop_field_len = q; 360 q += 2; /* segment length */
340 q += 2; 361
341 pbottom_field_len = q; 362 putbe16(&q, object_id);
342 q += 2; 363 *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
343 364 onject_coding_method,
344 if (bpp_index == 0) 365 non_modifying_color_flag */
345 dvb_encode_rle = dvb_encode_rle2; 366 {
346 else 367 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
347 dvb_encode_rle = dvb_encode_rle4; 368 void (*dvb_encode_rle)(uint8_t **pq,
348 369 const uint8_t *bitmap, int linesize,
349 top_ptr = q; 370 int w, int h);
350 dvb_encode_rle(&q, h->bitmap, h->w * 2, h->w, h->h >> 1); 371 ptop_field_len = q;
351 bottom_ptr = q; 372 q += 2;
352 dvb_encode_rle(&q, h->bitmap + h->w, h->w * 2, h->w, h->h >> 1); 373 pbottom_field_len = q;
353 374 q += 2;
354 putbe16(&ptop_field_len, bottom_ptr - top_ptr); 375
355 putbe16(&pbottom_field_len, q - bottom_ptr); 376 if (bpp_index == 0)
356 } 377 dvb_encode_rle = dvb_encode_rle2;
357 378 else
358 putbe16(&pseg_len, q - pseg_len - 2); 379 dvb_encode_rle = dvb_encode_rle4;
380
381 top_ptr = q;
382 dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2,
383 h->rects[object_id].w, h->rects[object_id].h >> 1);
384 bottom_ptr = q;
385 dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w,
386 h->rects[object_id].w * 2, h->rects[object_id].w,
387 h->rects[object_id].h >> 1);
388
389 putbe16(&ptop_field_len, bottom_ptr - top_ptr);
390 putbe16(&pbottom_field_len, q - bottom_ptr);
391 }
392
393 putbe16(&pseg_len, q - pseg_len - 2);
394 }
359 } 395 }
360 396
361 /* end of display set segment */ 397 /* end of display set segment */
362 398
363 *q++ = 0x0f; /* sync_byte */ 399 *q++ = 0x0f; /* sync_byte */