[FFmpeg-devel] [PATCH] movtextdec.c: Add support for font names

Philip Langdale philipl at overt.org
Wed Aug 5 03:16:07 CEST 2015


On Tue, 4 Aug 2015 20:15:58 +0530
Niklesh Lalwani <niklesh.lalwani at iitb.ac.in> wrote:

> From f901f48320140b8f011ec089e6d950e25c90beec Mon Sep 17 00:00:00 2001
> From: Niklesh <niklesh.lalwani at iitb.ac.in>
> Date: Tue, 4 Aug 2015 20:10:28 +0530
> Subject: [PATCH] movtextdec.c: Add support for font names
> 
> Signed-off-by: Niklesh <niklesh.lalwani at iitb.ac.in>
> ---
>  libavcodec/movtextdec.c | 94
> +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91
> insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
> index 869358c..3bea93e 100644
> --- a/libavcodec/movtextdec.c
> +++ b/libavcodec/movtextdec.c
> @@ -36,10 +36,17 @@
>  #define HCLR_BOX   (1<<2)
>  
>  typedef struct {
> +    uint16_t fontID;
> +    uint8_t font_name_length;
> +    uint8_t font[20];
> +} FontRecord;
> +
> +typedef struct {
>      uint16_t style_start;
>      uint16_t style_end;
>      uint8_t style_flag;
>      uint8_t fontsize;
> +    uint16_t style_fontID;
>  } StyleBox;
>  
>  typedef struct {
> @@ -56,11 +63,13 @@ typedef struct {
>      StyleBox *s_temp;
>      HighlightBox h;
>      HilightcolorBox c;
> +    FontRecord **ftab;
> +    FontRecord *ftab_temp;
>      uint8_t box_flags;
> -    uint16_t style_entries;
> +    uint16_t style_entries, ftab_entries;
>      uint64_t tracksize;
>      int size_var;
> -    int count_s;
> +    int count_s, count_f;
>  } MovTextContext;
>  
>  typedef struct {
> @@ -80,6 +89,63 @@ static void mov_text_cleanup(MovTextContext *m)
>      }
>  }
>  
> +static void mov_text_cleanup_ftab(MovTextContext *m)
> +{
> +    int i;
> +    for(i = 0; i < m->count_f; i++) {
> +        av_freep(&m->ftab[i]);
> +    }
> +    av_freep(&m->ftab);
> +}
> +
> +static int mov_text_t3xg(AVCodecContext *avctx, MovTextContext *m)
> +{
> +    char *t3xg_ptr = avctx->extradata;
> +    int i;
> +    // Display Flags
> +    t3xg_ptr += 4;
> +    // Alignment
> +    t3xg_ptr += 2;
> +    // Background Color
> +    t3xg_ptr += 4;
> +    // BoxRecord
> +    t3xg_ptr += 8;
> +    // StyleRecord
> +    t3xg_ptr += 12;
> +    // FontRecord
> +    // FontRecord Size
> +    t3xg_ptr += 4;
> +    // ftab
> +    t3xg_ptr += 4;
> +    m->ftab_entries = AV_RB16(t3xg_ptr);
> +    if (!ftab_entries) {
> +        return -1;
> +    }

I didn't mean this - it's ok for the value to be 0, but it's
not ok for it to be some huge number that will cause you to
read beyond the end of the buffer. So like you did for the other
variable length fields, you need to sanity check this against the total
packet size.

> +    t3xg_ptr += 2;
> +    for (i = 0; i < m->ftab_entries; i++) {
> +        m->ftab_temp = av_malloc(sizeof(*m->ftab_temp));
> +        if (!m->ftab_temp) {
> +            mov_text_cleanup_ftab(m);
> +            return AVERROR(ENOMEM);
> +        }
> +        m->ftab_temp->fontID = AV_RB16(t3xg_ptr);
> +        t3xg_ptr += 2;
> +        m->ftab_temp->font_name_length = *t3xg_ptr++;
> +        if (!m->ftab_temp->font_name_length) {
> +            m->ftab_entries = 0;
> +            return -1;
> +        }

Similarly here. The fontname length could be too long. We know it is
not allowed to be more than 20, but you also need to verify against
total packet size.

> +        memcpy(m->ftab_temp->font, t3xg_ptr,
> m->ftab_temp->font_name_length);
> +        av_dynarray_add(&m->ftab, &m->count_f, m->ftab_temp);
> +        if (!m->ftab) {
> +            mov_text_cleanup_ftab(m);
> +            return AVERROR(ENOMEM);
> +        }
> +        t3xg_ptr += 10;
> +    }
> +    return 0;
> +}
> +
>  static int decode_hlit(const uint8_t *tsmb, MovTextContext *m,
> AVPacket *avpkt) {
>      m->box_flags |= HLIT_BOX;
> @@ -118,7 +184,7 @@ static int decode_styl(const uint8_t *tsmb,
> MovTextContext *m, AVPacket *avpkt) tsmb += 2;
>          m->s_temp->style_end = AV_RB16(tsmb);
>          tsmb += 2;
> -        // fontID = AV_RB16(tsmb);
> +        m->s_temp->style_fontID = AV_RB16(tsmb);
>          tsmb += 2;
>          m->s_temp->style_flag = AV_RB8(tsmb);
>          tsmb++;
> @@ -147,6 +213,8 @@ static int text_to_ass(AVBPrint *buf, const char
> *text, const char *text_end, MovTextContext *m)
>  {
>      int i = 0;
> +    int j = 0;
> +    int k = 0;
>      int text_pos = 0;
>      while (text < text_end) {
>          if (m->box_flags & STYL_BOX) {
> @@ -164,6 +232,14 @@ static int text_to_ass(AVBPrint *buf, const char
> *text, const char *text_end, if (m->s[i]->style_flag &
> STYLE_FLAG_UNDERLINE) av_bprintf(buf, "{\\u1}");
>                      av_bprintf(buf, "{\\fs%d}", m->s[i]->fontsize);
> +                    av_bprintf(buf, "{\\fn");
> +                    for (j = 0; j < m->ftab_entries; j++) {
> +                        if (m->s[i]->style_fontID ==
> m->ftab[j]->fontID) {
> +                            av_bprint_append_data(buf,
> m->ftab[j]->font,
> +
> m->ftab[j]->font_name_length);
> +                        }
> +                    }
> +                    av_bprintf(buf, "}");
>                  }
>              }
>          }
> @@ -215,6 +291,8 @@ static int mov_text_init(AVCodecContext *avctx) {
>       * it's very common to find files where the default style is
> broken
>       * and respecting it results in a worse experience than ignoring
> it. */
> +    MovTextContext *m = avctx->priv_data;
> +    mov_text_t3xg(avctx, m);
>      return ff_ass_subtitle_header_default(avctx);
>  }
>  
> @@ -265,6 +343,8 @@ static int mov_text_decode_frame(AVCodecContext
> *avctx, m->style_entries = 0;
>      m->box_flags = 0;
>      m->count_s = 0;
> +    m->count_f = 0;
> +    m->ftab_entries = 0;
>      // Note that the spec recommends lines be no longer than 2048
> characters. av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
>      if (text_length + 2 != avpkt->size) {
> @@ -313,6 +393,13 @@ static int mov_text_decode_frame(AVCodecContext
> *avctx, return avpkt->size;
>  }
>  
> +static int mov_text_decode_close(AVCodecContext *avctx)
> +{
> +    MovTextContext *m = avctx->priv_data;
> +    mov_text_cleanup_ftab(m);
> +    return 0;
> +}
> +
>  AVCodec ff_movtext_decoder = {
>      .name         = "mov_text",
>      .long_name    = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
> @@ -321,4 +408,5 @@ AVCodec ff_movtext_decoder = {
>      .priv_data_size = sizeof(MovTextContext),
>      .init         = mov_text_init,
>      .decode       = mov_text_decode_frame,
> +    .close        = mov_text_decode_close,
>  };




--phil


More information about the ffmpeg-devel mailing list