Mercurial > libavcodec.hg
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 */ |