codecs: add support for ARIB subtitles
[vlc.git] / modules / codec / arib / substext.h
1 /*****************************************************************************
2  * substext.h : ARIB subtitles subpicture decoder
3  *****************************************************************************
4  * Copyright (C) 2012 Naohiro KORIYAMA
5  *
6  * Authors:  Naohiro KORIYAMA <nkoriyama@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 typedef struct arib_text_region_s
24 {
25     char                      *psz_text;
26     char                      *psz_html;
27
28     char                      *psz_fontname;
29     int                       i_font_color;
30     int                       i_planewidth;
31     int                       i_planeheight;
32     int                       i_fontwidth;
33     int                       i_fontheight;
34     int                       i_verint;
35     int                       i_horint;
36     int                       i_charleft;
37     int                       i_charbottom;
38     int                       i_charleft_adj;
39     int                       i_charbottom_adj;
40
41     struct arib_text_region_s *p_next;
42 } arib_text_region_t;
43
44 struct subpicture_updater_sys_t
45 {
46     arib_text_region_t *p_region;
47 };
48
49 static int SubpictureTextValidate(subpicture_t *subpic,
50                                   bool has_src_changed, const video_format_t *fmt_src,
51                                   bool has_dst_changed, const video_format_t *fmt_dst,
52                                   mtime_t ts)
53 {
54     subpicture_updater_sys_t *sys = subpic->updater.p_sys;
55     VLC_UNUSED(fmt_src); VLC_UNUSED(fmt_dst); VLC_UNUSED(ts);
56     VLC_UNUSED(sys);
57
58     if (!has_src_changed && !has_dst_changed)
59     {
60         return VLC_SUCCESS;
61     }
62     return VLC_EGENERIC;
63 }
64 static void SubpictureTextUpdate(subpicture_t *subpic,
65                                  const video_format_t *fmt_src,
66                                  const video_format_t *fmt_dst,
67                                  mtime_t ts)
68 {
69     subpicture_updater_sys_t *sys = subpic->updater.p_sys;
70     VLC_UNUSED(fmt_src); VLC_UNUSED(ts);
71
72     if (fmt_dst->i_sar_num <= 0 || fmt_dst->i_sar_den <= 0)
73     {
74         return;
75     }
76
77     video_format_t fmt;
78     video_format_Init(&fmt, VLC_CODEC_TEXT);
79     fmt.i_sar_num = 1;
80     fmt.i_sar_den = 1;
81
82     subpicture_region_t *r = NULL;
83     arib_text_region_t *p_region;
84     for( p_region = sys->p_region; p_region; p_region = p_region->p_next )
85     {
86         if( !r )
87         {
88             subpic->p_region = r = subpicture_region_New(&fmt);
89         }
90         else
91         {
92             r->p_next = subpicture_region_New(&fmt);
93             r = r->p_next;
94         }
95         if( r == NULL )
96         {
97             return;
98         }
99
100         r->psz_text = p_region->psz_text ? strdup(p_region->psz_text) : NULL;
101         r->psz_html = p_region->psz_html ? strdup(p_region->psz_html) : NULL;
102         r->i_align  = SUBPICTURE_ALIGN_LEFT | SUBPICTURE_ALIGN_TOP;
103
104         subpic->i_original_picture_width  = p_region->i_planewidth;
105         subpic->i_original_picture_height  = p_region->i_planeheight;
106
107         r->i_x = p_region->i_charleft - (p_region->i_fontwidth + p_region->i_horint / 2) + p_region->i_charleft_adj;
108         r->i_y = p_region->i_charbottom - (p_region->i_fontheight + p_region->i_verint / 2) + p_region->i_charbottom_adj;
109         r->p_style = text_style_New();
110         r->p_style->psz_fontname = p_region->psz_fontname ? strdup( p_region->psz_fontname ) : NULL;
111         r->p_style->i_font_size = p_region->i_fontheight;
112         r->p_style->i_font_color = p_region->i_font_color;
113         r->p_style->i_style_flags = 0;
114         if( p_region->i_fontwidth < p_region->i_fontheight )
115         {
116             r->p_style->i_style_flags |= STYLE_HALFWIDTH;
117         }
118         r->p_style->i_spacing = p_region->i_horint;
119     }
120 }
121 static void SubpictureTextDestroy(subpicture_t *subpic)
122 {
123     subpicture_updater_sys_t *sys = subpic->updater.p_sys;
124
125     arib_text_region_t *p_region, *p_region_next;
126     for( p_region = sys->p_region; p_region; p_region = p_region_next )
127     {
128         free( p_region->psz_text );
129         free( p_region->psz_html );
130         free( p_region->psz_fontname );
131         p_region_next = p_region->p_next;
132         free( p_region );
133     }
134     sys->p_region = NULL;
135     free( sys );
136 }
137
138 static inline subpicture_t *decoder_NewSubpictureText(decoder_t *decoder)
139 {
140     subpicture_updater_sys_t *sys = (subpicture_updater_sys_t*)
141         calloc( 1, sizeof(subpicture_updater_sys_t) );
142     subpicture_updater_t updater = {
143         .pf_validate = SubpictureTextValidate,
144         .pf_update   = SubpictureTextUpdate,
145         .pf_destroy  = SubpictureTextDestroy,
146         .p_sys       = sys,
147     };
148     subpicture_t *subpic = decoder_NewSubpicture(decoder, &updater);
149     if( subpic == NULL )
150     {
151         free( sys );
152     }
153     return subpic;
154 }