dvbsubdec.c 49.5 KB
Newer Older
1
/*
2
 * DVB subtitle decoding
3
 * Copyright (c) 2005 Ian Caulfield
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

22
#include "avcodec.h"
23
#include "get_bits.h"
24
#include "bytestream.h"
25
#include "internal.h"
26
#include "libavutil/colorspace.h"
27
#include "libavutil/imgutils.h"
28
#include "libavutil/opt.h"
29 30 31 32 33

#define DVBSUB_PAGE_SEGMENT     0x10
#define DVBSUB_REGION_SEGMENT   0x11
#define DVBSUB_CLUT_SEGMENT     0x12
#define DVBSUB_OBJECT_SEGMENT   0x13
34
#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
35 36
#define DVBSUB_DISPLAY_SEGMENT  0x80

37
#define cm (ff_crop_tab + MAX_NEG_CROP)
38

39
#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
40 41 42

typedef struct DVBSubCLUT {
    int id;
43
    int version;
44 45 46 47

    uint32_t clut4[4];
    uint32_t clut16[16];
    uint32_t clut256[256];
48

49 50 51 52 53 54 55 56 57 58 59 60
    struct DVBSubCLUT *next;
} DVBSubCLUT;

static DVBSubCLUT default_clut;

typedef struct DVBSubObjectDisplay {
    int object_id;
    int region_id;

    int x_pos;
    int y_pos;

61 62
    int fgcolor;
    int bgcolor;
63

64
    struct DVBSubObjectDisplay *region_list_next;
65
    struct DVBSubObjectDisplay *object_list_next;
66 67 68 69
} DVBSubObjectDisplay;

typedef struct DVBSubObject {
    int id;
70
    int version;
71 72

    int type;
73 74 75

    DVBSubObjectDisplay *display_list;

76 77 78 79 80 81 82 83 84 85 86 87 88 89
    struct DVBSubObject *next;
} DVBSubObject;

typedef struct DVBSubRegionDisplay {
    int region_id;

    int x_pos;
    int y_pos;

    struct DVBSubRegionDisplay *next;
} DVBSubRegionDisplay;

typedef struct DVBSubRegion {
    int id;
90
    int version;
91 92 93 94

    int width;
    int height;
    int depth;
95

96
    int clut;
97
    int bgcolor;
98

99 100 101
    uint8_t computed_clut[4*256];
    int has_computed_clut;

102 103
    uint8_t *pbuf;
    int buf_size;
104
    int dirty;
105 106

    DVBSubObjectDisplay *display_list;
107

108 109 110
    struct DVBSubRegion *next;
} DVBSubRegion;

111 112 113 114 115 116 117 118 119
typedef struct DVBSubDisplayDefinition {
    int version;

    int x;
    int y;
    int width;
    int height;
} DVBSubDisplayDefinition;

120
typedef struct DVBSubContext {
121
    AVClass *class;
122 123 124
    int composition_id;
    int ancillary_id;

125
    int version;
126
    int time_out;
127 128
    int compute_edt; /**< if 1 end display time calculated using pts
                          if 0 (Default) calculated using time out */
129
    int compute_clut;
130
    int clut_count2[257][256];
131
    int substream;
132
    int64_t prev_start;
133 134 135
    DVBSubRegion *region_list;
    DVBSubCLUT   *clut_list;
    DVBSubObject *object_list;
136

137
    DVBSubRegionDisplay *display_list;
138
    DVBSubDisplayDefinition *display_definition;
139 140 141 142 143 144 145
} DVBSubContext;


static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
{
    DVBSubObject *ptr = ctx->object_list;

146
    while (ptr && ptr->id != object_id) {
147 148
        ptr = ptr->next;
    }
149

150 151 152 153 154 155 156
    return ptr;
}

static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
{
    DVBSubCLUT *ptr = ctx->clut_list;

157
    while (ptr && ptr->id != clut_id) {
158 159
        ptr = ptr->next;
    }
160

161 162 163 164 165 166 167
    return ptr;
}

static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
{
    DVBSubRegion *ptr = ctx->region_list;

168
    while (ptr && ptr->id != region_id) {
169 170
        ptr = ptr->next;
    }
171

172 173 174 175 176 177 178 179
    return ptr;
}

static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
{
    DVBSubObject *object, *obj2, **obj2_ptr;
    DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;

180
    while (region->display_list) {
181
        display = region->display_list;
182

183
        object = get_object(ctx, display->object_id);
184

185
        if (object) {
186
            obj_disp_ptr = &object->display_list;
187
            obj_disp = *obj_disp_ptr;
188

189
            while (obj_disp && obj_disp != display) {
190
                obj_disp_ptr = &obj_disp->object_list_next;
191
                obj_disp = *obj_disp_ptr;
192
            }
193

194 195
            if (obj_disp) {
                *obj_disp_ptr = obj_disp->object_list_next;
196

197
                if (!object->display_list) {
198
                    obj2_ptr = &ctx->object_list;
199
                    obj2 = *obj2_ptr;
200

Michael Niedermayer's avatar
Michael Niedermayer committed
201
                    while (obj2 != object) {
202
                        av_assert0(obj2);
203
                        obj2_ptr = &obj2->next;
204
                        obj2 = *obj2_ptr;
205
                    }
206

207
                    *obj2_ptr = obj2->next;
208

209
                    av_freep(&obj2);
210 211 212
                }
            }
        }
213

214
        region->display_list = display->region_list_next;
215

216
        av_freep(&display);
217
    }
218

219 220
}

221
static void delete_cluts(DVBSubContext *ctx)
222
{
223
    while (ctx->clut_list) {
224
        DVBSubCLUT *clut = ctx->clut_list;
225 226 227

        ctx->clut_list = clut->next;

228
        av_freep(&clut);
229
    }
230
}
231

232 233 234
static void delete_objects(DVBSubContext *ctx)
{
    while (ctx->object_list) {
235
        DVBSubObject *object = ctx->object_list;
236 237 238

        ctx->object_list = object->next;

239
        av_freep(&object);
240 241 242 243 244 245
    }
}

static void delete_regions(DVBSubContext *ctx)
{
    while (ctx->region_list) {
246
        DVBSubRegion *region = ctx->region_list;
247 248 249 250 251

        ctx->region_list = region->next;

        delete_region_display_list(ctx, region);

252 253
        av_freep(&region->pbuf);
        av_freep(&region);
254
    }
255 256
}

257
static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
258 259
{
    int i, r, g, b, a = 0;
260
    DVBSubContext *ctx = avctx->priv_data;
261

262 263 264 265
    if (ctx->substream < 0) {
        ctx->composition_id = -1;
        ctx->ancillary_id   = -1;
    } else if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
266
        av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
267 268 269
        ctx->composition_id = -1;
        ctx->ancillary_id   = -1;
    } else {
270 271 272 273 274 275 276
        if (avctx->extradata_size > 5*ctx->substream + 2) {
            ctx->composition_id = AV_RB16(avctx->extradata + 5*ctx->substream);
            ctx->ancillary_id   = AV_RB16(avctx->extradata + 5*ctx->substream + 2);
        } else {
            av_log(avctx, AV_LOG_WARNING, "Selected DVB subtitles sub-stream %d is not available\n", ctx->substream);
            ctx->composition_id = AV_RB16(avctx->extradata);
            ctx->ancillary_id   = AV_RB16(avctx->extradata + 2);
277
        }
278
    }
279

280
    ctx->version = -1;
281
    ctx->prev_start = AV_NOPTS_VALUE;
282

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
    default_clut.id = -1;
    default_clut.next = NULL;

    default_clut.clut4[0] = RGBA(  0,   0,   0,   0);
    default_clut.clut4[1] = RGBA(255, 255, 255, 255);
    default_clut.clut4[2] = RGBA(  0,   0,   0, 255);
    default_clut.clut4[3] = RGBA(127, 127, 127, 255);

    default_clut.clut16[0] = RGBA(  0,   0,   0,   0);
    for (i = 1; i < 16; i++) {
        if (i < 8) {
            r = (i & 1) ? 255 : 0;
            g = (i & 2) ? 255 : 0;
            b = (i & 4) ? 255 : 0;
        } else {
            r = (i & 1) ? 127 : 0;
            g = (i & 2) ? 127 : 0;
            b = (i & 4) ? 127 : 0;
301
        }
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
        default_clut.clut16[i] = RGBA(r, g, b, 255);
    }

    default_clut.clut256[0] = RGBA(  0,   0,   0,   0);
    for (i = 1; i < 256; i++) {
        if (i < 8) {
            r = (i & 1) ? 255 : 0;
            g = (i & 2) ? 255 : 0;
            b = (i & 4) ? 255 : 0;
            a = 63;
        } else {
            switch (i & 0x88) {
            case 0x00:
                r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
                g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
                b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
                a = 255;
                break;
            case 0x08:
                r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
                g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
                b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
                a = 127;
                break;
            case 0x80:
                r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
                g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
                b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
                a = 255;
                break;
            case 0x88:
                r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
                g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
                b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
                a = 255;
                break;
            }
339
        }
340 341 342 343 344 345
        default_clut.clut256[i] = RGBA(r, g, b, a);
    }

    return 0;
}

346
static av_cold int dvbsub_close_decoder(AVCodecContext *avctx)
347
{
348
    DVBSubContext *ctx = avctx->priv_data;
349 350
    DVBSubRegionDisplay *display;

351 352 353 354 355 356 357
    delete_regions(ctx);

    delete_objects(ctx);

    delete_cluts(ctx);

    av_freep(&ctx->display_definition);
358

359
    while (ctx->display_list) {
360 361
        display = ctx->display_list;
        ctx->display_list = display->next;
362

363
        av_freep(&display);
364 365 366 367 368
    }

    return 0;
}

369 370
static int dvbsub_read_2bit_string(AVCodecContext *avctx,
                                   uint8_t *destbuf, int dbuf_len,
Michael Niedermayer's avatar
Michael Niedermayer committed
371
                                   const uint8_t **srcbuf, int buf_size,
372
                                   int non_mod, uint8_t *map_table, int x_pos)
373 374
{
    GetBitContext gb;
375

376 377
    int bits;
    int run_length;
378
    int pixels_read = x_pos;
379

380
    init_get_bits(&gb, *srcbuf, buf_size << 3);
381

382 383
    destbuf += x_pos;

384
    while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
385 386
        bits = get_bits(&gb, 2);

387
        if (bits) {
388
            if (non_mod != 1 || bits != 1) {
389
                if (map_table)
390 391 392 393 394 395
                    *destbuf++ = map_table[bits];
                else
                    *destbuf++ = bits;
            }
            pixels_read++;
        } else {
396
            bits = get_bits1(&gb);
397 398 399
            if (bits == 1) {
                run_length = get_bits(&gb, 3) + 3;
                bits = get_bits(&gb, 2);
400

401 402 403
                if (non_mod == 1 && bits == 1)
                    pixels_read += run_length;
                else {
404
                    if (map_table)
405 406 407 408 409 410 411
                        bits = map_table[bits];
                    while (run_length-- > 0 && pixels_read < dbuf_len) {
                        *destbuf++ = bits;
                        pixels_read++;
                    }
                }
            } else {
412
                bits = get_bits1(&gb);
413 414 415 416 417 418 419 420 421
                if (bits == 0) {
                    bits = get_bits(&gb, 2);
                    if (bits == 2) {
                        run_length = get_bits(&gb, 4) + 12;
                        bits = get_bits(&gb, 2);

                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
422
                            if (map_table)
423 424 425 426 427 428 429 430 431 432 433 434 435
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 3) {
                        run_length = get_bits(&gb, 8) + 29;
                        bits = get_bits(&gb, 2);

                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
436
                            if (map_table)
437 438 439 440 441 442 443
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 1) {
444
                        if (map_table)
445 446 447
                            bits = map_table[0];
                        else
                            bits = 0;
448 449
                        run_length = 2;
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
450
                            *destbuf++ = bits;
451
                            pixels_read++;
452 453 454 455 456 457
                        }
                    } else {
                        (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
                        return pixels_read;
                    }
                } else {
458
                    if (map_table)
459 460 461 462 463 464 465 466 467
                        bits = map_table[0];
                    else
                        bits = 0;
                    *destbuf++ = bits;
                    pixels_read++;
                }
            }
        }
    }
468

469
    if (get_bits(&gb, 6))
470
        av_log(avctx, AV_LOG_ERROR, "line overflow\n");
471 472 473 474 475

    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;

    return pixels_read;
}
476

477
static int dvbsub_read_4bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len,
Michael Niedermayer's avatar
Michael Niedermayer committed
478
                                   const uint8_t **srcbuf, int buf_size,
479
                                   int non_mod, uint8_t *map_table, int x_pos)
480 481
{
    GetBitContext gb;
482

483 484
    int bits;
    int run_length;
485
    int pixels_read = x_pos;
486

487
    init_get_bits(&gb, *srcbuf, buf_size << 3);
488

489 490
    destbuf += x_pos;

491
    while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
492 493
        bits = get_bits(&gb, 4);

494
        if (bits) {
495
            if (non_mod != 1 || bits != 1) {
496
                if (map_table)
497 498 499 500 501 502
                    *destbuf++ = map_table[bits];
                else
                    *destbuf++ = bits;
            }
            pixels_read++;
        } else {
503
            bits = get_bits1(&gb);
504 505
            if (bits == 0) {
                run_length = get_bits(&gb, 3);
506

507 508 509 510
                if (run_length == 0) {
                    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
                    return pixels_read;
                }
511

512
                run_length += 2;
513

514
                if (map_table)
515 516 517
                    bits = map_table[0];
                else
                    bits = 0;
518

519 520 521 522 523
                while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            } else {
524
                bits = get_bits1(&gb);
525 526 527 528 529 530 531
                if (bits == 0) {
                    run_length = get_bits(&gb, 2) + 4;
                    bits = get_bits(&gb, 4);

                    if (non_mod == 1 && bits == 1)
                        pixels_read += run_length;
                    else {
532
                        if (map_table)
533 534 535 536 537 538 539 540 541 542 543
                            bits = map_table[bits];
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
                            *destbuf++ = bits;
                            pixels_read++;
                        }
                    }
                } else {
                    bits = get_bits(&gb, 2);
                    if (bits == 2) {
                        run_length = get_bits(&gb, 4) + 9;
                        bits = get_bits(&gb, 4);
544

545 546 547
                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
548
                            if (map_table)
549 550 551 552 553 554 555 556 557 558 559 560 561
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 3) {
                        run_length = get_bits(&gb, 8) + 25;
                        bits = get_bits(&gb, 4);

                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
562
                            if (map_table)
563 564 565 566 567 568 569
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 1) {
570
                        if (map_table)
571 572 573
                            bits = map_table[0];
                        else
                            bits = 0;
574 575
                        run_length = 2;
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
576
                            *destbuf++ = bits;
577
                            pixels_read++;
578 579
                        }
                    } else {
580
                        if (map_table)
581 582 583 584 585 586 587 588 589 590
                            bits = map_table[0];
                        else
                            bits = 0;
                        *destbuf++ = bits;
                        pixels_read ++;
                    }
                }
            }
        }
    }
591

592
    if (get_bits(&gb, 8))
593
        av_log(avctx, AV_LOG_ERROR, "line overflow\n");
594

595 596 597 598
    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;

    return pixels_read;
}
599

600 601
static int dvbsub_read_8bit_string(AVCodecContext *avctx,
                                   uint8_t *destbuf, int dbuf_len,
Michael Niedermayer's avatar
Michael Niedermayer committed
602
                                    const uint8_t **srcbuf, int buf_size,
603
                                    int non_mod, uint8_t *map_table, int x_pos)
604
{
Michael Niedermayer's avatar
Michael Niedermayer committed
605
    const uint8_t *sbuf_end = (*srcbuf) + buf_size;
606 607
    int bits;
    int run_length;
608 609 610
    int pixels_read = x_pos;

    destbuf += x_pos;
611

612 613
    while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
        bits = *(*srcbuf)++;
614

615
        if (bits) {
616
            if (non_mod != 1 || bits != 1) {
617
                if (map_table)
618 619 620 621 622 623 624 625 626 627 628 629
                    *destbuf++ = map_table[bits];
                else
                    *destbuf++ = bits;
            }
            pixels_read++;
        } else {
            bits = *(*srcbuf)++;
            run_length = bits & 0x7f;
            if ((bits & 0x80) == 0) {
                if (run_length == 0) {
                    return pixels_read;
                }
630

631
                bits = 0;
632 633
            } else {
                bits = *(*srcbuf)++;
634
            }
635 636 637
            if (non_mod == 1 && bits == 1)
                pixels_read += run_length;
            else {
638
                if (map_table)
639
                    bits = map_table[bits];
640 641 642 643 644 645 646
                while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            }
        }
    }
647

648
    if (*(*srcbuf)++)
649
        av_log(avctx, AV_LOG_ERROR, "line overflow\n");
650

651 652
    return pixels_read;
}
653

654
static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRect *rect, int w, int h)
655 656 657 658
{
    uint8_t list[256] = {0};
    uint8_t list_inv[256];
    int counttab[256] = {0};
659
    int (*counttab2)[256] = ctx->clut_count2;
660
    int count, i, x, y;
661
    ptrdiff_t stride = rect->linesize[0];
662 663 664

    memset(ctx->clut_count2, 0 , sizeof(ctx->clut_count2));

665
#define V(x,y) rect->data[0][(x) + (y)*stride]
666 667 668 669 670 671 672 673
    for (y = 0; y<h; y++) {
        for (x = 0; x<w; x++) {
            int v = V(x,y) + 1;
            int vl = x     ? V(x-1,y) + 1 : 0;
            int vr = x+1<w ? V(x+1,y) + 1 : 0;
            int vt = y     ? V(x,y-1) + 1 : 0;
            int vb = y+1<h ? V(x,y+1) + 1 : 0;
            counttab[v-1] += !!((v!=vl) + (v!=vr) + (v!=vt) + (v!=vb));
674 675 676 677
            counttab2[vl][v-1] ++;
            counttab2[vr][v-1] ++;
            counttab2[vt][v-1] ++;
            counttab2[vb][v-1] ++;
678 679
        }
    }
680
#define L(x,y) list[d[(x) + (y)*stride]]
681 682

    for (i = 0; i<256; i++) {
683 684 685
        counttab2[i+1][i] = 0;
    }
    for (i = 0; i<256; i++) {
686 687
        int bestscore = 0;
        int bestv = 0;
688

689
        for (x = 0; x < 256; x++) {
690 691 692 693 694 695 696 697 698 699
            int scorev = 0;
            if (list[x])
                continue;
            scorev += counttab2[0][x];
            for (y = 0; y < 256; y++) {
                scorev += list[y] * counttab2[y+1][x];
            }

            if (scorev) {
                int score = 1024LL*scorev / counttab[x];
700 701
                if (score > bestscore) {
                    bestscore = score;
702
                    bestv = x;
703 704 705 706 707 708 709 710 711
                }
            }
        }
        if (!bestscore)
            break;
        list    [ bestv ] = 1;
        list_inv[     i ] = bestv;
    }

712
    count = FFMAX(i - 1, 1);
713 714
    for (i--; i>=0; i--) {
        int v = i*255/count;
715
        AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v));
716 717 718 719
    }
}


720
static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
721 722 723 724 725 726 727 728
{
    DVBSubContext *ctx = avctx->priv_data;
    DVBSubRegionDisplay *display;
    DVBSubDisplayDefinition *display_def = ctx->display_definition;
    DVBSubRegion *region;
    AVSubtitleRect *rect;
    DVBSubCLUT *clut;
    uint32_t *clut_table;
729
    int i;
730
    int offset_x=0, offset_y=0;
731
    int ret = 0;
732 733 734 735 736 737 738


    if (display_def) {
        offset_x = display_def->x;
        offset_y = display_def->y;
    }

739 740
    /* Not touching AVSubtitles again*/
    if(sub->num_rects) {
741
        avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
742
        return AVERROR_PATCHWELCOME;
743
    }
744 745 746 747 748 749
    for (display = ctx->display_list; display; display = display->next) {
        region = get_region(ctx, display->region_id);
        if (region && region->dirty)
            sub->num_rects++;
    }

750 751 752 753 754 755 756
    if(ctx->compute_edt == 0) {
        sub->end_display_time = ctx->time_out * 1000;
        *got_output = 1;
    } else if (ctx->prev_start != AV_NOPTS_VALUE) {
        sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
        *got_output = 1;
    }
757
    if (sub->num_rects > 0) {
758

759
        sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
760 761 762 763
        if (!sub->rects) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
764

James Almer's avatar
James Almer committed
765
        for (i = 0; i < sub->num_rects; i++) {
766
            sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
James Almer's avatar
James Almer committed
767 768 769 770 771
            if (!sub->rects[i]) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
        }
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790

        i = 0;

        for (display = ctx->display_list; display; display = display->next) {
            region = get_region(ctx, display->region_id);

            if (!region)
                continue;

            if (!region->dirty)
                continue;

            rect = sub->rects[i];
            rect->x = display->x_pos + offset_x;
            rect->y = display->y_pos + offset_y;
            rect->w = region->width;
            rect->h = region->height;
            rect->nb_colors = (1 << region->depth);
            rect->type      = SUBTITLE_BITMAP;
791
            rect->linesize[0] = region->width;
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809

            clut = get_clut(ctx, region->clut);

            if (!clut)
                clut = &default_clut;

            switch (region->depth) {
            case 2:
                clut_table = clut->clut4;
                break;
            case 8:
                clut_table = clut->clut256;
                break;
            case 4:
            default:
                clut_table = clut->clut16;
                break;
            }
810

811 812
            rect->data[1] = av_mallocz(AVPALETTE_SIZE);
            if (!rect->data[1]) {
813 814
                ret = AVERROR(ENOMEM);
                goto fail;
815
            }
816
            memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
817

818 819
            rect->data[0] = av_malloc(region->buf_size);
            if (!rect->data[0]) {
820 821
                ret = AVERROR(ENOMEM);
                goto fail;
822 823
            }

824
            memcpy(rect->data[0], region->pbuf, region->buf_size);
825

826 827
            if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1) {
                if (!region->has_computed_clut) {
828
                    compute_default_clut(ctx, region->computed_clut, rect, rect->w, rect->h);
829 830 831 832 833
                    region->has_computed_clut = 1;
                }

                memcpy(rect->data[1], region->computed_clut, sizeof(region->computed_clut));
            }
834 835 836

#if FF_API_AVPICTURE
FF_DISABLE_DEPRECATION_WARNINGS
837 838
{
            int j;
839 840 841 842
            for (j = 0; j < 4; j++) {
                rect->pict.data[j] = rect->data[j];
                rect->pict.linesize[j] = rect->linesize[j];
            }
843
}
844 845
FF_ENABLE_DEPRECATION_WARNINGS
#endif
846

847 848 849
            i++;
        }
    }
850 851

    return 0;
852 853 854 855 856
fail:
    if (sub->rects) {
        for(i=0; i<sub->num_rects; i++) {
            rect = sub->rects[i];
            if (rect) {
857 858
                av_freep(&rect->data[0]);
                av_freep(&rect->data[1]);
859 860 861 862 863 864 865
            }
            av_freep(&sub->rects[i]);
        }
        av_freep(&sub->rects);
    }
    sub->num_rects = 0;
    return ret;
866
}
867 868

static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
Michael Niedermayer's avatar
Michael Niedermayer committed
869
                                          const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
870
{
871
    DVBSubContext *ctx = avctx->priv_data;
872 873

    DVBSubRegion *region = get_region(ctx, display->region_id);
Michael Niedermayer's avatar
Michael Niedermayer committed
874
    const uint8_t *buf_end = buf + buf_size;
875 876 877
    uint8_t *pbuf;
    int x_pos, y_pos;
    int i;
878

879 880
    uint8_t map2to4[] = { 0x0,  0x7,  0x8,  0xf};
    uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
881
    uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
882 883
                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    uint8_t *map_table;
884

885
#if 0
886
    ff_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
887
            top_bottom ? "bottom" : "top");
888

889
    for (i = 0; i < buf_size; i++) {
890
        if (i % 16 == 0)
891
            ff_dlog(avctx, "0x%8p: ", buf+i);
892

893
        ff_dlog(avctx, "%02x ", buf[i]);
894
        if (i % 16 == 15)
895
            ff_dlog(avctx, "\n");
896
    }
897

898
    if (i % 16)
899
        ff_dlog(avctx, "\n");
900
#endif
901

902
    if (!region)
903
        return;
904

905
    pbuf = region->pbuf;
906
    region->dirty = 1;
907

908 909
    x_pos = display->x_pos;
    y_pos = display->y_pos;
910

911
    y_pos += top_bottom;
912 913

    while (buf < buf_end) {
914
        if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
915
            av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
916 917
            return;
        }
918

919 920 921 922 923 924 925 926
        switch (*buf++) {
        case 0x10:
            if (region->depth == 8)
                map_table = map2to8;
            else if (region->depth == 4)
                map_table = map2to4;
            else
                map_table = NULL;
927

928
            x_pos = dvbsub_read_2bit_string(avctx, pbuf + (y_pos * region->width),
929 930
                                            region->width, &buf, buf_end - buf,
                                            non_mod, map_table, x_pos);
931 932 933 934 935 936
            break;
        case 0x11:
            if (region->depth < 4) {
                av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
                return;
            }
937

938 939 940 941
            if (region->depth == 8)
                map_table = map4to8;
            else
                map_table = NULL;
942

943
            x_pos = dvbsub_read_4bit_string(avctx, pbuf + (y_pos * region->width),
944 945
                                            region->width, &buf, buf_end - buf,
                                            non_mod, map_table, x_pos);
946 947 948 949 950 951
            break;
        case 0x12:
            if (region->depth < 8) {
                av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
                return;
            }
952

953
            x_pos = dvbsub_read_8bit_string(avctx, pbuf + (y_pos * region->width),
954 955
                                            region->width, &buf, buf_end - buf,
                                            non_mod, NULL, x_pos);
956
            break;
957

958 959 960 961 962 963 964 965 966 967 968 969 970 971
        case 0x20:
            map2to4[0] = (*buf) >> 4;
            map2to4[1] = (*buf++) & 0xf;
            map2to4[2] = (*buf) >> 4;
            map2to4[3] = (*buf++) & 0xf;
            break;
        case 0x21:
            for (i = 0; i < 4; i++)
                map2to8[i] = *buf++;
            break;
        case 0x22:
            for (i = 0; i < 16; i++)
                map4to8[i] = *buf++;
            break;
972

973 974 975 976 977 978 979 980
        case 0xf0:
            x_pos = display->x_pos;
            y_pos += 2;
            break;
        default:
            av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
        }
    }
981

982
    region->has_computed_clut = 0;
983 984
}

985 986
static int dvbsub_parse_object_segment(AVCodecContext *avctx,
                                       const uint8_t *buf, int buf_size)
987
{
988
    DVBSubContext *ctx = avctx->priv_data;
989

Michael Niedermayer's avatar
Michael Niedermayer committed
990
    const uint8_t *buf_end = buf + buf_size;
991 992 993 994
    int object_id;
    DVBSubObject *object;
    DVBSubObjectDisplay *display;
    int top_field_len, bottom_field_len;
995

996
    int coding_method, non_modifying_color;
997

998
    object_id = AV_RB16(buf);
999
    buf += 2;
1000

1001 1002
    object = get_object(ctx, object_id);

1003
    if (!object)
1004
        return AVERROR_INVALIDDATA;
1005

1006
    coding_method = ((*buf) >> 2) & 3;
1007
    non_modifying_color = ((*buf++) >> 1) & 1;
1008

1009
    if (coding_method == 0) {
1010
        top_field_len = AV_RB16(buf);
1011
        buf += 2;
1012
        bottom_field_len = AV_RB16(buf);
1013
        buf += 2;
1014

1015
        if (buf + top_field_len + bottom_field_len > buf_end) {
1016
            av_log(avctx, AV_LOG_ERROR, "Field data size %d+%d too large\n", top_field_len, bottom_field_len);
1017
            return AVERROR_INVALIDDATA;
1018 1019
        }

1020
        for (display = object->display_list; display; display = display->object_list_next) {
1021 1022
            const uint8_t *block = buf;
            int bfl = bottom_field_len;
1023 1024

            dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
1025
                                            non_modifying_color);
1026 1027 1028 1029

            if (bottom_field_len > 0)
                block = buf + top_field_len;
            else
1030
                bfl = top_field_len;
1031

1032
            dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
1033
                                            non_modifying_color);
1034
        }
1035

1036
/*  } else if (coding_method == 1) {*/
1037

1038 1039 1040
    } else {
        av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
    }
1041

1042
    return 0;
1043 1044
}

1045
static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
1046
                                     const uint8_t *buf, int buf_size)
1047
{
1048
    DVBSubContext *ctx = avctx->priv_data;
1049

Michael Niedermayer's avatar
Michael Niedermayer committed
1050
    const uint8_t *buf_end = buf + buf_size;
1051
    int i, clut_id;
1052
    int version;
1053 1054 1055 1056 1057
    DVBSubCLUT *clut;
    int entry_id, depth , full_range;
    int y, cr, cb, alpha;
    int r, g, b, r_add, g_add, b_add;

1058
    ff_dlog(avctx, "DVB clut packet:\n");
1059

1060
    for (i=0; i < buf_size; i++) {
1061
        ff_dlog(avctx, "%02x ", buf[i]);
1062
        if (i % 16 == 15)
1063
            ff_dlog(avctx, "\n");
1064
    }
1065

1066
    if (i % 16)
1067
        ff_dlog(avctx, "\n");
1068 1069

    clut_id = *buf++;
1070
    version = ((*buf)>>4)&15;
1071
    buf += 1;
1072

1073
    clut = get_clut(ctx, clut_id);
1074

1075
    if (!clut) {
1076
        clut = av_malloc(sizeof(DVBSubCLUT));
1077 1078
        if (!clut)
            return AVERROR(ENOMEM);
1079

1080 1081 1082
        memcpy(clut, &default_clut, sizeof(DVBSubCLUT));

        clut->id = clut_id;
1083
        clut->version = -1;
1084 1085

        clut->next = ctx->clut_list;
1086 1087
        ctx->clut_list = clut;
    }
1088

1089 1090 1091 1092
    if (clut->version != version) {

    clut->version = version;

1093
    while (buf + 4 < buf_end) {
1094
        entry_id = *buf++;
1095

1096
        depth = (*buf) & 0xe0;
1097

1098 1099 1100
        if (depth == 0) {
            av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
        }
1101

1102
        full_range = (*buf++) & 1;
1103

1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
        if (full_range) {
            y = *buf++;
            cr = *buf++;
            cb = *buf++;
            alpha = *buf++;
        } else {
            y = buf[0] & 0xfc;
            cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
            cb = (buf[1] << 2) & 0xf0;
            alpha = (buf[1] << 6) & 0xc0;
1114

1115 1116
            buf += 2;
        }
1117

1118 1119
        if (y == 0)
            alpha = 0xff;
1120

1121 1122
        YUV_TO_RGB1_CCIR(cb, cr);
        YUV_TO_RGB2_CCIR(r, g, b, y);
1123

1124
        ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1125
        if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
1126
            ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
1127 1128 1129
            if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
                return AVERROR_INVALIDDATA;
        }
1130

1131
        if (depth & 0x80 && entry_id < 4)
1132
            clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
1133
        else if (depth & 0x40 && entry_id < 16)
1134
            clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
1135
        else if (depth & 0x20)
1136 1137
            clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
    }
1138
    }
1139

1140
    return 0;
1141 1142 1143
}


1144
static int dvbsub_parse_region_segment(AVCodecContext *avctx,
1145
                                       const uint8_t *buf, int buf_size)
1146
{
1147
    DVBSubContext *ctx = avctx->priv_data;
1148

Michael Niedermayer's avatar
Michael Niedermayer committed
1149
    const uint8_t *buf_end = buf + buf_size;
1150
    int region_id, object_id;
1151
    int av_unused version;
1152 1153 1154 1155
    DVBSubRegion *region;
    DVBSubObject *object;
    DVBSubObjectDisplay *display;
    int fill;
1156
    int ret;
1157

1158
    if (buf_size < 10)
1159
        return AVERROR_INVALIDDATA;
1160

1161
    region_id = *buf++;
1162

1163
    region = get_region(ctx, region_id);
1164

1165
    if (!region) {
1166
        region = av_mallocz(sizeof(DVBSubRegion));
1167
        if (!region)
1168
            return AVERROR(ENOMEM);
1169

1170
        region->id = region_id;
1171
        region->version = -1;
1172

1173 1174 1175
        region->next = ctx->region_list;
        ctx->region_list = region;
    }
1176

1177
    version = ((*buf)>>4) & 15;
1178
    fill = ((*buf++) >> 3) & 1;
1179

1180
    region->width = AV_RB16(buf);
1181
    buf += 2;
1182
    region->height = AV_RB16(buf);
1183
    buf += 2;
1184

1185
    ret = av_image_check_size2(region->width, region->height, avctx->max_pixels, AV_PIX_FMT_PAL8, 0, avctx);
1186 1187 1188 1189
    if (ret >= 0 && region->width * region->height * 2 > 320 * 1024 * 8) {
        ret = AVERROR_INVALIDDATA;
        av_log(avctx, AV_LOG_ERROR, "Pixel buffer memory constraint violated\n");
    }
1190 1191 1192 1193 1194
    if (ret < 0) {
        region->width= region->height= 0;
        return ret;
    }

1195
    if (region->width * region->height != region->buf_size) {
1196
        av_free(region->pbuf);
1197

1198
        region->buf_size = region->width * region->height;
1199

1200
        region->pbuf = av_malloc(region->buf_size);
1201 1202 1203 1204
        if (!region->pbuf) {
            region->buf_size =
            region->width =
            region->height = 0;
1205
            return AVERROR(ENOMEM);
1206
        }
1207

1208
        fill = 1;
1209
        region->dirty = 0;
1210
    }
1211

1212
    region->depth = 1 << (((*buf++) >> 2) & 7);
1213 1214 1215 1216
    if(region->depth<2 || region->depth>8){
        av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
        region->depth= 4;
    }
1217
    region->clut = *buf++;
1218

1219
    if (region->depth == 8) {
1220
        region->bgcolor = *buf++;
1221 1222
        buf += 1;
    } else {
1223
        buf += 1;
1224

1225
        if (region->depth == 4)
1226
            region->bgcolor = (((*buf++) >> 4) & 15);
1227
        else
1228
            region->bgcolor = (((*buf++) >> 2) & 3);
1229 1230
    }

1231
    ff_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
1232 1233

    if (fill) {
1234
        memset(region->pbuf, region->bgcolor, region->buf_size);
1235
        ff_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
1236 1237 1238 1239 1240
    }

    delete_region_display_list(ctx, region);

    while (buf + 5 < buf_end) {
1241
        object_id = AV_RB16(buf);
1242
        buf += 2;
1243

1244 1245
        object = get_object(ctx, object_id);

1246
        if (!object) {
1247
            object = av_mallocz(sizeof(DVBSubObject));
1248 1249
            if (!object)
                return AVERROR(ENOMEM);
1250

1251 1252 1253 1254
            object->id = object_id;
            object->next = ctx->object_list;
            ctx->object_list = object;
        }
1255

1256
        object->type = (*buf) >> 6;
1257

1258
        display = av_mallocz(sizeof(DVBSubObjectDisplay));
1259 1260
        if (!display)
            return AVERROR(ENOMEM);
1261

1262 1263
        display->object_id = object_id;
        display->region_id = region_id;
1264

1265
        display->x_pos = AV_RB16(buf) & 0xfff;
1266
        buf += 2;
1267
        display->y_pos = AV_RB16(buf) & 0xfff;
1268
        buf += 2;
1269

1270 1271 1272 1273 1274 1275 1276
        if (display->x_pos >= region->width ||
            display->y_pos >= region->height) {
            av_log(avctx, AV_LOG_ERROR, "Object outside region\n");
            av_free(display);
            return AVERROR_INVALIDDATA;
        }

1277
        if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
1278 1279
            display->fgcolor = *buf++;
            display->bgcolor = *buf++;
1280
        }
1281

1282 1283
        display->region_list_next = region->display_list;
        region->display_list = display;
1284

1285 1286 1287
        display->object_list_next = object->display_list;
        object->display_list = display;
    }
1288 1289

    return 0;
1290 1291
}

1292
static int dvbsub_parse_page_segment(AVCodecContext *avctx,
1293
                                     const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
1294
{
1295
    DVBSubContext *ctx = avctx->priv_data;
1296 1297
    DVBSubRegionDisplay *display;
    DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
1298

Michael Niedermayer's avatar
Michael Niedermayer committed
1299
    const uint8_t *buf_end = buf + buf_size;
1300 1301
    int region_id;
    int page_state;
1302 1303
    int timeout;
    int version;
1304

1305
    if (buf_size < 1)
1306
        return AVERROR_INVALIDDATA;
1307

1308 1309
    timeout = *buf++;
    version = ((*buf)>>4) & 15;
1310
    page_state = ((*buf++) >> 2) & 3;
1311

1312
    if (ctx->version == version) {
1313
        return 0;
1314
    }
1315 1316 1317 1318

    ctx->time_out = timeout;
    ctx->version = version;

1319
    ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
1320

1321 1322 1323
    if(ctx->compute_edt == 1)
        save_subtitle_set(avctx, sub, got_output);

1324
    if (page_state == 1 || page_state == 2) {
1325 1326 1327
        delete_regions(ctx);
        delete_objects(ctx);
        delete_cluts(ctx);
1328
    }
1329

1330 1331
    tmp_display_list = ctx->display_list;
    ctx->display_list = NULL;
1332

1333 1334 1335
    while (buf + 5 < buf_end) {
        region_id = *buf++;
        buf += 1;
1336

1337 1338 1339 1340 1341 1342 1343 1344 1345
        display = ctx->display_list;
        while (display && display->region_id != region_id) {
            display = display->next;
        }
        if (display) {
            av_log(avctx, AV_LOG_ERROR, "duplicate region\n");
            break;
        }

1346 1347
        display = tmp_display_list;
        tmp_ptr = &tmp_display_list;
1348

1349
        while (display && display->region_id != region_id) {
1350 1351 1352
            tmp_ptr = &display->next;
            display = display->next;
        }
1353

1354
        if (!display) {
1355
            display = av_mallocz(sizeof(DVBSubRegionDisplay));
1356 1357 1358
            if (!display)
                return AVERROR(ENOMEM);
        }
1359

1360
        display->region_id = region_id;
1361

1362
        display->x_pos = AV_RB16(buf);
1363
        buf += 2;
1364
        display->y_pos = AV_RB16(buf);
1365
        buf += 2;
1366

1367
        *tmp_ptr = display->next;
1368

1369 1370
        display->next = ctx->display_list;
        ctx->display_list = display;
1371

1372
        ff_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
1373
    }
1374

1375
    while (tmp_display_list) {
1376
        display = tmp_display_list;
1377

1378
        tmp_display_list = display->next;
1379

1380
        av_freep(&display);
1381
    }
1382

1383
    return 0;
1384 1385 1386
}


1387
#ifdef DEBUG
1388
static void png_save(DVBSubContext *ctx, const char *filename, uint32_t *bitmap, int w, int h)
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437
{
    int x, y, v;
    FILE *f;
    char fname[40], fname2[40];
    char command[1024];

    snprintf(fname, sizeof(fname), "%s.ppm", filename);

    f = fopen(fname, "w");
    if (!f) {
        perror(fname);
        return;
    }
    fprintf(f, "P6\n"
            "%d %d\n"
            "%d\n",
            w, h, 255);
    for(y = 0; y < h; y++) {
        for(x = 0; x < w; x++) {
            v = bitmap[y * w + x];
            putc((v >> 16) & 0xff, f);
            putc((v >> 8) & 0xff, f);
            putc((v >> 0) & 0xff, f);
        }
    }
    fclose(f);


    snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);

    f = fopen(fname2, "w");
    if (!f) {
        perror(fname2);
        return;
    }
    fprintf(f, "P5\n"
            "%d %d\n"
            "%d\n",
            w, h, 255);
    for(y = 0; y < h; y++) {
        for(x = 0; x < w; x++) {
            v = bitmap[y * w + x];
            putc((v >> 24) & 0xff, f);
        }
    }
    fclose(f);

    snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
    if (system(command) != 0) {
1438
        av_log(ctx, AV_LOG_ERROR, "Error running pnmtopng\n");
1439 1440 1441 1442 1443
        return;
    }

    snprintf(command, sizeof(command), "rm %s %s", fname, fname2);
    if (system(command) != 0) {
1444
        av_log(ctx, AV_LOG_ERROR, "Error removing %s and %s\n", fname, fname2);
1445 1446 1447 1448
        return;
    }
}

1449
static int save_display_set(DVBSubContext *ctx)
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464
{
    DVBSubRegion *region;
    DVBSubRegionDisplay *display;
    DVBSubCLUT *clut;
    uint32_t *clut_table;
    int x_pos, y_pos, width, height;
    int x, y, y_off, x_off;
    uint32_t *pbuf;
    char filename[32];
    static int fileno_index = 0;

    x_pos = -1;
    y_pos = -1;
    width = 0;
    height = 0;
1465

1466
    for (display = ctx->display_list; display; display = display->next) {
1467
        region = get_region(ctx, display->region_id);
1468

1469
        if (!region)
1470
            return -1;
1471

1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
        if (x_pos == -1) {
            x_pos = display->x_pos;
            y_pos = display->y_pos;
            width = region->width;
            height = region->height;
        } else {
            if (display->x_pos < x_pos) {
                width += (x_pos - display->x_pos);
                x_pos = display->x_pos;
            }
1482

1483 1484 1485 1486
            if (display->y_pos < y_pos) {
                height += (y_pos - display->y_pos);
                y_pos = display->y_pos;
            }
1487

1488 1489 1490
            if (display->x_pos + region->width > x_pos + width) {
                width = display->x_pos + region->width - x_pos;
            }
1491

1492 1493 1494 1495 1496
            if (display->y_pos + region->height > y_pos + height) {
                height = display->y_pos + region->height - y_pos;
            }
        }
    }
1497

1498
    if (x_pos >= 0) {
1499

1500
        pbuf = av_malloc(width * height * 4);
1501
        if (!pbuf)
1502
            return -1;
1503

1504
        for (display = ctx->display_list; display; display = display->next) {
1505 1506
            region = get_region(ctx, display->region_id);

1507
            if (!region)
1508
                return -1;
1509

1510 1511 1512 1513 1514
            x_off = display->x_pos - x_pos;
            y_off = display->y_pos - y_pos;

            clut = get_clut(ctx, region->clut);

1515
            if (!clut)
1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
                clut = &default_clut;

            switch (region->depth) {
            case 2:
                clut_table = clut->clut4;
                break;
            case 8:
                clut_table = clut->clut256;
                break;
            case 4:
            default:
                clut_table = clut->clut16;
                break;
            }
1530

1531 1532
            for (y = 0; y < region->height; y++) {
                for (x = 0; x < region->width; x++) {
1533
                    pbuf[((y + y_off) * width) + x_off + x] =
1534 1535 1536 1537
                        clut_table[region->pbuf[y * region->width + x]];
                }
            }

1538
        }
1539

1540
        snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
1541

1542
        png_save(ctx, filename, pbuf, width, height);
1543

1544
        av_freep(&pbuf);
1545
    }
1546

1547
    fileno_index++;
1548
    return 0;
1549
}
1550
#endif /* DEBUG */
1551

1552
static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
1553 1554
                                                   const uint8_t *buf,
                                                   int buf_size)
1555 1556 1557 1558 1559 1560
{
    DVBSubContext *ctx = avctx->priv_data;
    DVBSubDisplayDefinition *display_def = ctx->display_definition;
    int dds_version, info_byte;

    if (buf_size < 5)
1561
        return AVERROR_INVALIDDATA;
1562 1563 1564 1565

    info_byte   = bytestream_get_byte(&buf);
    dds_version = info_byte >> 4;
    if (display_def && display_def->version == dds_version)
1566
        return 0; // already have this display definition version
1567 1568 1569

    if (!display_def) {
        display_def             = av_mallocz(sizeof(*display_def));
1570 1571
        if (!display_def)
            return AVERROR(ENOMEM);
1572 1573 1574 1575 1576 1577 1578 1579
        ctx->display_definition = display_def;
    }

    display_def->version = dds_version;
    display_def->x       = 0;
    display_def->y       = 0;
    display_def->width   = bytestream_get_be16(&buf) + 1;
    display_def->height  = bytestream_get_be16(&buf) + 1;
1580
    if (!avctx->width || !avctx->height) {
1581 1582 1583
        int ret = ff_set_dimensions(avctx, display_def->width, display_def->height);
        if (ret < 0)
            return ret;
1584
    }
1585 1586

    if (info_byte & 1<<3) { // display_window_flag
1587 1588 1589
        if (buf_size < 13)
            return AVERROR_INVALIDDATA;

1590 1591
        display_def->x = bytestream_get_be16(&buf);
        display_def->width  = bytestream_get_be16(&buf) - display_def->x + 1;
1592
        display_def->y = bytestream_get_be16(&buf);
1593 1594
        display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
    }
1595 1596

    return 0;
1597 1598
}

Michael Niedermayer's avatar
Michael Niedermayer committed
1599
static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
1600
                                      int buf_size, AVSubtitle *sub,int *got_output)
1601
{
1602
    DVBSubContext *ctx = avctx->priv_data;
1603

1604 1605
    if(ctx->compute_edt == 0)
        save_subtitle_set(avctx, sub, got_output);
1606
#ifdef DEBUG
1607 1608
    save_display_set(ctx);
#endif
1609
    return 0;
1610 1611 1612 1613
}

static int dvbsub_decode(AVCodecContext *avctx,
                         void *data, int *data_size,
1614
                         AVPacket *avpkt)
1615
{
1616 1617
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
1618 1619
    DVBSubContext *ctx = avctx->priv_data;
    AVSubtitle *sub = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1620
    const uint8_t *p, *p_end;
1621 1622 1623 1624
    int segment_type;
    int page_id;
    int segment_length;
    int i;
1625
    int ret = 0;
1626
    int got_segment = 0;
1627
    int got_dds = 0;
1628

1629
    ff_dlog(avctx, "DVB sub packet:\n");
1630

1631
    for (i=0; i < buf_size; i++) {
1632
        ff_dlog(avctx, "%02x ", buf[i]);
1633
        if (i % 16 == 15)
1634
            ff_dlog(avctx, "\n");
1635
    }
1636

1637
    if (i % 16)
1638
        ff_dlog(avctx, "\n");
1639

1640
    if (buf_size <= 6 || *buf != 0x0f) {
1641
        ff_dlog(avctx, "incomplete or broken packet");
1642
        return AVERROR_INVALIDDATA;
1643
    }
1644

1645 1646
    p = buf;
    p_end = buf + buf_size;
1647

1648
    while (p_end - p >= 6 && *p == 0x0f) {
1649 1650
        p += 1;
        segment_type = *p++;
1651
        page_id = AV_RB16(p);
1652
        p += 2;
1653
        segment_length = AV_RB16(p);
1654
        p += 2;
1655

1656 1657 1658 1659
        if (avctx->debug & FF_DEBUG_STARTCODE) {
            av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
        }

1660
        if (p_end - p < segment_length) {
1661
            ff_dlog(avctx, "incomplete or broken packet");
1662 1663
            ret = -1;
            goto end;
1664 1665
        }

1666 1667
        if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
            ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1668
            int ret = 0;
1669 1670
            switch (segment_type) {
            case DVBSUB_PAGE_SEGMENT:
1671
                ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
1672
                got_segment |= 1;
1673 1674
                break;
            case DVBSUB_REGION_SEGMENT:
1675
                ret = dvbsub_parse_region_segment(avctx, p, segment_length);
1676
                got_segment |= 2;
1677 1678
                break;
            case DVBSUB_CLUT_SEGMENT:
1679
                ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1680
                if (ret < 0) goto end;
1681
                got_segment |= 4;
1682 1683
                break;
            case DVBSUB_OBJECT_SEGMENT:
1684
                ret = dvbsub_parse_object_segment(avctx, p, segment_length);
1685
                got_segment |= 8;
1686
                break;
1687
            case DVBSUB_DISPLAYDEFINITION_SEGMENT:
1688 1689
                ret = dvbsub_parse_display_definition_segment(avctx, p,
                                                              segment_length);
1690
                got_dds = 1;
1691
                break;
1692
            case DVBSUB_DISPLAY_SEGMENT:
1693
                ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
1694 1695 1696 1697 1698
                if (got_segment == 15 && !got_dds && !avctx->width && !avctx->height) {
                    // Default from ETSI EN 300 743 V1.3.1 (7.2.1)
                    avctx->width  = 720;
                    avctx->height = 576;
                }
1699
                got_segment |= 16;
1700 1701
                break;
            default:
1702
                ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
1703 1704 1705
                        segment_type, page_id, segment_length);
                break;
            }
1706
            if (ret < 0)
1707
                goto end;
1708 1709 1710 1711
        }

        p += segment_length;
    }
1712 1713
    // Some streams do not send a display segment but if we have all the other
    // segments then we need no further data.
1714
    if (got_segment == 15) {
1715
        av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726
        dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
    }

end:
    if(ret < 0) {
        *data_size = 0;
        avsubtitle_free(sub);
        return ret;
    } else {
        if(ctx->compute_edt == 1 )
            FFSWAP(int64_t, ctx->prev_start, sub->pts);
1727
    }
1728

1729
    return p - buf;
1730 1731
}

1732
#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
1733
static const AVOption options[] = {
1734 1735
    {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS},
    {"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", offsetof(DVBSubContext, compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS},
1736
    {"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
1737 1738 1739 1740 1741 1742 1743 1744
    {NULL}
};
static const AVClass dvbsubdec_class = {
    .class_name = "DVB Sub Decoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};
1745

1746
AVCodec ff_dvbsub_decoder = {
1747
    .name           = "dvbsub",
1748
    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
1749
    .type           = AVMEDIA_TYPE_SUBTITLE,
1750
    .id             = AV_CODEC_ID_DVB_SUBTITLE,
1751 1752 1753 1754
    .priv_data_size = sizeof(DVBSubContext),
    .init           = dvbsub_init_decoder,
    .close          = dvbsub_close_decoder,
    .decode         = dvbsub_decode,
1755
    .priv_class     = &dvbsubdec_class,
1756
};