|
|
|
@ -27,6 +27,7 @@ |
|
|
|
|
#include "libavutil/bprint.h" |
|
|
|
|
#include "libavutil/intreadwrite.h" |
|
|
|
|
#include "libavutil/mem.h" |
|
|
|
|
#include "bytestream.h" |
|
|
|
|
|
|
|
|
|
#define STYLE_FLAG_BOLD (1<<0) |
|
|
|
|
#define STYLE_FLAG_ITALIC (1<<1) |
|
|
|
@ -137,7 +138,7 @@ static void mov_text_cleanup_ftab(MovTextContext *m) |
|
|
|
|
|
|
|
|
|
static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
{ |
|
|
|
|
uint8_t *tx3g_ptr = avctx->extradata; |
|
|
|
|
const uint8_t *tx3g_ptr = avctx->extradata; |
|
|
|
|
int i, j = -1, font_length, remaining = avctx->extradata_size - BOX_SIZE_INITIAL; |
|
|
|
|
int8_t v_align, h_align; |
|
|
|
|
unsigned ftab_entries; |
|
|
|
@ -150,8 +151,8 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
// Display Flags
|
|
|
|
|
tx3g_ptr += 4; |
|
|
|
|
// Alignment
|
|
|
|
|
h_align = *tx3g_ptr++; |
|
|
|
|
v_align = *tx3g_ptr++; |
|
|
|
|
h_align = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
v_align = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
if (h_align == 0) { |
|
|
|
|
if (v_align == 0) |
|
|
|
|
m->d.alignment = TOP_LEFT; |
|
|
|
@ -177,29 +178,24 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
m->d.alignment = BOTTOM_RIGHT; |
|
|
|
|
} |
|
|
|
|
// Background Color
|
|
|
|
|
m->d.back_color = AV_RB24(tx3g_ptr); |
|
|
|
|
tx3g_ptr += 3; |
|
|
|
|
m->d.back_alpha = AV_RB8(tx3g_ptr); |
|
|
|
|
tx3g_ptr += 1; |
|
|
|
|
m->d.back_color = bytestream_get_be24(&tx3g_ptr); |
|
|
|
|
m->d.back_alpha = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
// BoxRecord
|
|
|
|
|
tx3g_ptr += 8; |
|
|
|
|
// StyleRecord
|
|
|
|
|
tx3g_ptr += 4; |
|
|
|
|
// fontID
|
|
|
|
|
m->d.fontID = AV_RB16(tx3g_ptr); |
|
|
|
|
tx3g_ptr += 2; |
|
|
|
|
m->d.fontID = bytestream_get_be16(&tx3g_ptr); |
|
|
|
|
// face-style-flags
|
|
|
|
|
s_default.style_flag = *tx3g_ptr++; |
|
|
|
|
s_default.style_flag = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
m->d.bold = !!(s_default.style_flag & STYLE_FLAG_BOLD); |
|
|
|
|
m->d.italic = !!(s_default.style_flag & STYLE_FLAG_ITALIC); |
|
|
|
|
m->d.underline = !!(s_default.style_flag & STYLE_FLAG_UNDERLINE); |
|
|
|
|
// fontsize
|
|
|
|
|
m->d.fontsize = *tx3g_ptr++; |
|
|
|
|
m->d.fontsize = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
// Primary color
|
|
|
|
|
m->d.color = AV_RB24(tx3g_ptr); |
|
|
|
|
tx3g_ptr += 3; |
|
|
|
|
m->d.alpha = AV_RB8(tx3g_ptr); |
|
|
|
|
tx3g_ptr += 1; |
|
|
|
|
m->d.color = bytestream_get_be24(&tx3g_ptr); |
|
|
|
|
m->d.alpha = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
// FontRecord
|
|
|
|
|
// FontRecord Size
|
|
|
|
|
tx3g_ptr += 4; |
|
|
|
@ -209,7 +205,7 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
// In case of broken header, init default font
|
|
|
|
|
m->d.font = ASS_DEFAULT_FONT; |
|
|
|
|
|
|
|
|
|
ftab_entries = AV_RB16(tx3g_ptr); |
|
|
|
|
ftab_entries = bytestream_get_be16(&tx3g_ptr); |
|
|
|
|
if (!ftab_entries) |
|
|
|
|
return 0; |
|
|
|
|
remaining -= 3 * ftab_entries; |
|
|
|
@ -219,14 +215,12 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
if (!m->ftab) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
m->ftab_entries = ftab_entries; |
|
|
|
|
tx3g_ptr += 2; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < m->ftab_entries; i++) { |
|
|
|
|
m->ftab[i].fontID = AV_RB16(tx3g_ptr); |
|
|
|
|
m->ftab[i].fontID = bytestream_get_be16(&tx3g_ptr); |
|
|
|
|
if (m->ftab[i].fontID == m->d.fontID) |
|
|
|
|
j = i; |
|
|
|
|
tx3g_ptr += 2; |
|
|
|
|
font_length = *tx3g_ptr++; |
|
|
|
|
font_length = bytestream_get_byte(&tx3g_ptr); |
|
|
|
|
|
|
|
|
|
remaining -= font_length; |
|
|
|
|
if (remaining < 0) { |
|
|
|
@ -238,9 +232,8 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
mov_text_cleanup_ftab(m); |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
} |
|
|
|
|
memcpy(m->ftab[i].font, tx3g_ptr, font_length); |
|
|
|
|
bytestream_get_buffer(&tx3g_ptr, m->ftab[i].font, font_length); |
|
|
|
|
m->ftab[i].font[font_length] = '\0'; |
|
|
|
|
tx3g_ptr = tx3g_ptr + font_length; |
|
|
|
|
} |
|
|
|
|
if (j >= 0) |
|
|
|
|
m->d.font = m->ftab[j].font; |
|
|
|
@ -250,34 +243,31 @@ static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) |
|
|
|
|
static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
|
m->box_flags |= TWRP_BOX; |
|
|
|
|
m->w.wrap_flag = *tsmb++; |
|
|
|
|
m->w.wrap_flag = bytestream_get_byte(&tsmb); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
|
m->box_flags |= HLIT_BOX; |
|
|
|
|
m->h.hlit_start = AV_RB16(tsmb); |
|
|
|
|
tsmb += 2; |
|
|
|
|
m->h.hlit_end = AV_RB16(tsmb); |
|
|
|
|
tsmb += 2; |
|
|
|
|
m->h.hlit_start = bytestream_get_be16(&tsmb); |
|
|
|
|
m->h.hlit_end = bytestream_get_be16(&tsmb); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
|
m->box_flags |= HCLR_BOX; |
|
|
|
|
memcpy(m->c.hlit_color, tsmb, 4); |
|
|
|
|
tsmb += 4; |
|
|
|
|
bytestream_get_buffer(&tsmb, m->c.hlit_color, 4); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
int style_entries = AV_RB16(tsmb); |
|
|
|
|
int style_entries = bytestream_get_be16(&tsmb); |
|
|
|
|
StyleBox *tmp; |
|
|
|
|
tsmb += 2; |
|
|
|
|
|
|
|
|
|
// A single style record is of length 12 bytes.
|
|
|
|
|
if (m->tracksize + m->size_var + 2 + style_entries * 12 > avpkt->size) |
|
|
|
|
return -1; |
|
|
|
@ -291,17 +281,14 @@ static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) |
|
|
|
|
m->box_flags |= STYL_BOX; |
|
|
|
|
for(i = 0; i < m->style_entries; i++) { |
|
|
|
|
StyleBox *style = &m->s[i]; |
|
|
|
|
style->style_start = AV_RB16(tsmb); |
|
|
|
|
tsmb += 2; |
|
|
|
|
style->style_end = AV_RB16(tsmb); |
|
|
|
|
|
|
|
|
|
style->style_start = bytestream_get_be16(&tsmb); |
|
|
|
|
style->style_end = bytestream_get_be16(&tsmb); |
|
|
|
|
if ( style->style_end < style->style_start |
|
|
|
|
|| (i && style->style_start < m->s[i - 1].style_end)) { |
|
|
|
|
mov_text_cleanup(m); |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tsmb += 2; |
|
|
|
|
if (style->style_start == style->style_end) { |
|
|
|
|
/* Skip this style as it applies to no character */ |
|
|
|
|
tsmb += 8; |
|
|
|
@ -310,19 +297,14 @@ static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
style->style_fontID = AV_RB16(tsmb); |
|
|
|
|
tsmb += 2; |
|
|
|
|
style->style_flag = AV_RB8(tsmb); |
|
|
|
|
style->style_fontID = bytestream_get_be16(&tsmb); |
|
|
|
|
style->style_flag = bytestream_get_byte(&tsmb); |
|
|
|
|
style->bold = !!(style->style_flag & STYLE_FLAG_BOLD); |
|
|
|
|
style->italic = !!(style->style_flag & STYLE_FLAG_ITALIC); |
|
|
|
|
style->underline = !!(style->style_flag & STYLE_FLAG_UNDERLINE); |
|
|
|
|
tsmb++; |
|
|
|
|
style->fontsize = AV_RB8(tsmb); |
|
|
|
|
tsmb++; |
|
|
|
|
style->color = AV_RB24(tsmb); |
|
|
|
|
tsmb += 3; |
|
|
|
|
style->alpha = AV_RB8(tsmb); |
|
|
|
|
tsmb++; |
|
|
|
|
style->fontsize = bytestream_get_byte(&tsmb); |
|
|
|
|
style->color = bytestream_get_be24(&tsmb); |
|
|
|
|
style->alpha = bytestream_get_byte(&tsmb); |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|