comparison dvdsub.c @ 2797:217844bd1fa1 libavcodec

10l (forgot to commit this yesterday) DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
author michael
date Sun, 17 Jul 2005 09:22:51 +0000
parents d8874c8749ec
children 1f117208d20f
comparison
equal deleted inserted replaced
2796:95c35706acbb 2797:217844bd1fa1
130 const uint8_t *buf, int buf_size) 130 const uint8_t *buf, int buf_size)
131 { 131 {
132 int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; 132 int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;
133 uint8_t palette[4], alpha[4]; 133 uint8_t palette[4], alpha[4];
134 int date; 134 int date;
135 int i;
135 136
136 if (buf_size < 4) 137 if (buf_size < 4)
137 return -1; 138 return -1;
138 sub_header->bitmap = NULL; 139 sub_header->rects = NULL;
139 sub_header->rgba_palette = NULL; 140 sub_header->num_rects = 0;
140 sub_header->start_display_time = 0; 141 sub_header->start_display_time = 0;
141 sub_header->end_display_time = 0; 142 sub_header->end_display_time = 0;
142 143
143 cmd_pos = getbe16(buf + 2); 144 cmd_pos = getbe16(buf + 2);
144 while ((cmd_pos + 4) < buf_size) { 145 while ((cmd_pos + 4) < buf_size) {
228 w = 0; 229 w = 0;
229 h = y2 - y1; 230 h = y2 - y1;
230 if (h < 0) 231 if (h < 0)
231 h = 0; 232 h = 0;
232 if (w > 0 && h > 0) { 233 if (w > 0 && h > 0) {
233 av_freep(&sub_header->bitmap); 234 if (sub_header->rects != NULL) {
234 av_freep(&sub_header->rgba_palette); 235 for (i = 0; i < sub_header->num_rects; i++) {
236 av_free(sub_header->rects[i].bitmap);
237 av_free(sub_header->rects[i].rgba_palette);
238 }
239 av_freep(&sub_header->rects);
240 sub_header->num_rects = 0;
241 }
242
235 bitmap = av_malloc(w * h); 243 bitmap = av_malloc(w * h);
236 sub_header->rgba_palette = av_malloc(4 * 4); 244 sub_header->rects = av_mallocz(sizeof(AVSubtitleRect));
245 sub_header->num_rects = 1;
246 sub_header->rects[0].rgba_palette = av_malloc(4 * 4);
237 decode_rle(bitmap, w * 2, w, h / 2, 247 decode_rle(bitmap, w * 2, w, h / 2,
238 buf, offset1 * 2, buf_size); 248 buf, offset1 * 2, buf_size);
239 decode_rle(bitmap + w, w * 2, w, h / 2, 249 decode_rle(bitmap + w, w * 2, w, h / 2,
240 buf, offset2 * 2, buf_size); 250 buf, offset2 * 2, buf_size);
241 guess_palette(sub_header->rgba_palette, 251 guess_palette(sub_header->rects[0].rgba_palette,
242 palette, alpha, 0xffff00); 252 palette, alpha, 0xffff00);
243 sub_header->x = x1; 253 sub_header->rects[0].x = x1;
244 sub_header->y = y1; 254 sub_header->rects[0].y = y1;
245 sub_header->w = w; 255 sub_header->rects[0].w = w;
246 sub_header->h = h; 256 sub_header->rects[0].h = h;
247 sub_header->nb_colors = 4; 257 sub_header->rects[0].nb_colors = 4;
248 sub_header->linesize = w; 258 sub_header->rects[0].linesize = w;
249 sub_header->bitmap = bitmap; 259 sub_header->rects[0].bitmap = bitmap;
250 } 260 }
251 } 261 }
252 if (next_cmd_pos == cmd_pos) 262 if (next_cmd_pos == cmd_pos)
253 break; 263 break;
254 cmd_pos = next_cmd_pos; 264 cmd_pos = next_cmd_pos;
255 } 265 }
256 if (sub_header->bitmap) 266 if (sub_header->num_rects > 0)
257 return 0; 267 return 0;
258 fail: 268 fail:
259 return -1; 269 return -1;
260 } 270 }
261 271
276 { 286 {
277 uint8_t transp_color[256]; 287 uint8_t transp_color[256];
278 int y1, y2, x1, x2, y, w, h, i; 288 int y1, y2, x1, x2, y, w, h, i;
279 uint8_t *bitmap; 289 uint8_t *bitmap;
280 290
281 if (s->w <= 0 || s->h <= 0) 291 if (s->num_rects == 0 || s->rects == NULL || s->rects[0].w <= 0 || s->rects[0].h <= 0)
282 return 0; 292 return 0;
283 293
284 memset(transp_color, 0, 256); 294 memset(transp_color, 0, 256);
285 for(i = 0; i < s->nb_colors; i++) { 295 for(i = 0; i < s->rects[0].nb_colors; i++) {
286 if ((s->rgba_palette[i] >> 24) == 0) 296 if ((s->rects[0].rgba_palette[i] >> 24) == 0)
287 transp_color[i] = 1; 297 transp_color[i] = 1;
288 } 298 }
289 y1 = 0; 299 y1 = 0;
290 while (y1 < s->h && is_transp(s->bitmap + y1 * s->linesize, 1, s->w, 300 while (y1 < s->rects[0].h && is_transp(s->rects[0].bitmap + y1 * s->rects[0].linesize,
291 transp_color)) 301 1, s->rects[0].w, transp_color))
292 y1++; 302 y1++;
293 if (y1 == s->h) { 303 if (y1 == s->rects[0].h) {
294 av_freep(&s->bitmap); 304 av_freep(&s->rects[0].bitmap);
295 s->w = s->h = 0; 305 s->rects[0].w = s->rects[0].h = 0;
296 return 0; 306 return 0;
297 } 307 }
298 308
299 y2 = s->h - 1; 309 y2 = s->rects[0].h - 1;
300 while (y2 > 0 && is_transp(s->bitmap + y2 * s->linesize, 1, s->w, 310 while (y2 > 0 && is_transp(s->rects[0].bitmap + y2 * s->rects[0].linesize, 1,
301 transp_color)) 311 s->rects[0].w, transp_color))
302 y2--; 312 y2--;
303 x1 = 0; 313 x1 = 0;
304 while (x1 < (s->w - 1) && is_transp(s->bitmap + x1, s->linesize, s->h, 314 while (x1 < (s->rects[0].w - 1) && is_transp(s->rects[0].bitmap + x1, s->rects[0].linesize,
305 transp_color)) 315 s->rects[0].h, transp_color))
306 x1++; 316 x1++;
307 x2 = s->w - 1; 317 x2 = s->rects[0].w - 1;
308 while (x2 > 0 && is_transp(s->bitmap + x2, s->linesize, s->h, 318 while (x2 > 0 && is_transp(s->rects[0].bitmap + x2, s->rects[0].linesize, s->rects[0].h,
309 transp_color)) 319 transp_color))
310 x2--; 320 x2--;
311 w = x2 - x1 + 1; 321 w = x2 - x1 + 1;
312 h = y2 - y1 + 1; 322 h = y2 - y1 + 1;
313 bitmap = av_malloc(w * h); 323 bitmap = av_malloc(w * h);
314 if (!bitmap) 324 if (!bitmap)
315 return 1; 325 return 1;
316 for(y = 0; y < h; y++) { 326 for(y = 0; y < h; y++) {
317 memcpy(bitmap + w * y, s->bitmap + x1 + (y1 + y) * s->linesize, w); 327 memcpy(bitmap + w * y, s->rects[0].bitmap + x1 + (y1 + y) * s->rects[0].linesize, w);
318 } 328 }
319 av_freep(&s->bitmap); 329 av_freep(&s->rects[0].bitmap);
320 s->bitmap = bitmap; 330 s->rects[0].bitmap = bitmap;
321 s->linesize = w; 331 s->rects[0].linesize = w;
322 s->w = w; 332 s->rects[0].w = w;
323 s->h = h; 333 s->rects[0].h = h;
324 s->x += x1; 334 s->rects[0].x += x1;
325 s->y += y1; 335 s->rects[0].y += y1;
326 return 1; 336 return 1;
327 } 337 }
328 338
329 static int dvdsub_close_decoder(AVCodecContext *avctx) 339 static int dvdsub_close_decoder(AVCodecContext *avctx)
330 { 340 {
377 387
378 #if defined(DEBUG) 388 #if defined(DEBUG)
379 av_log(NULL, AV_LOG_INFO, "start=%d ms end =%d ms\n", 389 av_log(NULL, AV_LOG_INFO, "start=%d ms end =%d ms\n",
380 sub->start_display_time, 390 sub->start_display_time,
381 sub->end_display_time); 391 sub->end_display_time);
382 ppm_save("/tmp/a.ppm", sub->bitmap, 392 ppm_save("/tmp/a.ppm", sub->rects[0].bitmap,
383 sub->w, sub->h, sub->rgba_palette); 393 sub->rects[0].w, sub->rects[0].h, sub->rects[0].rgba_palette);
384 #endif 394 #endif
385 395
386 *data_size = 1; 396 *data_size = 1;
387 return buf_size; 397 return buf_size;
388 } 398 }