diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c index 89615e63f0..35e6a56a5a 100644 --- a/libavcodec/dvbsub.c +++ b/libavcodec/dvbsub.c @@ -194,6 +194,61 @@ static void dvb_encode_rle4(uint8_t **pq, *pq = q; } +static void dvb_encode_rle8(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q; + int x, y, len, x1, f, color; + + q = *pq; + + for (y = 0; y < h; y++) { + *q++ = 0x12; + + x = 0; + f = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (len == 1 && color) { + // 00000001 to 11111111 1 pixel in colour x + *q++ = color; + } else { + if (color == 0x00) { + // 00000000 0LLLLLLL L pixels (1-127) in colour 0 (L > 0) + len = FFMIN(len, 127); + *q++ = 0x00; + *q++ = len; + } else if (len > 2) { + // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2) + len = FFMIN(len, 127); + *q++ = 0x00; + *q++ = 0x80+len; + *q++ = color; + } + else if (len == 2) { + *q++ = color; + *q++ = color; + } else { + *q++ = color; + len = 1; + } + } + x += len; + } + /* end of line */ + // 00000000 00000000 end of 8-bit/pixel_code_string + *q++ = 0x00; + *q++ = 0x00; + bitmap += linesize; + } + *pq = q; +} + static int encode_dvb_subtitles(DVBSubtitleContext *s, uint8_t *outbuf, AVSubtitle *h) { @@ -245,6 +300,9 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, } else if (h->rects[clut_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ bpp_index = 1; + } else if (h->rects[clut_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + bpp_index = 2; } else { return -1; } @@ -332,6 +390,9 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, } else if (h->rects[object_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ dvb_encode_rle = dvb_encode_rle4; + } else if (h->rects[object_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + dvb_encode_rle = dvb_encode_rle8; } else { return -1; }