]> git.sesse.net Git - vlc/blob - modules/codec/dvbsub.c
* Add support for HD DVBsub closes #896
[vlc] / modules / codec / dvbsub.c
1 /*****************************************************************************
2  * dvbsub.c : DVB subtitles decoder
3  *            DVB subtitles encoder (developed for Anevia, www.anevia.com)
4  *****************************************************************************
5  * Copyright (C) 2003 ANEVIA
6  * Copyright (C) 2003-2005 the VideoLAN team
7  * $Id$
8  *
9  * Authors: Gildas Bazin <gbazin@videolan.org>
10  *          Damien LUCAS <damien.lucas@anevia.com>
11  *          Laurent Aimar <fenrir@via.ecp.fr>
12  *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
13  *          Derk-Jan Hartman <hartman #at# videolan dot org>
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
28  *****************************************************************************/
29 /*****************************************************************************
30  * Preamble
31  *
32  * FIXME:
33  * DVB subtitles coded as strings of characters are not handled correctly.
34  * The character codes in the string should actually be indexes referring to a
35  * character table identified in the subtitle descriptor. 
36  *
37  * The spec is quite vague in this area, but what is meant is perhaps that it
38  * refers to the character index in the codepage belonging to the language specified
39  * in the subtitle descriptor. Potentially it's designed for widechar
40  * (but not for UTF-*) codepages.
41  *****************************************************************************/
42 #include <vlc/vlc.h>
43 #include <vlc_vout.h>
44 #include <vlc_codec.h>
45 #include <vlc_sout.h>
46
47 #include "vlc_bits.h"
48
49 /* #define DEBUG_DVBSUB 1 */
50
51 #define POSX_TEXT N_("Decoding X coordinate")
52 #define POSX_LONGTEXT N_("X coordinate of the rendered subtitle")
53
54 #define POSY_TEXT N_("Decoding Y coordinate")
55 #define POSY_LONGTEXT N_("Y coordinate of the rendered subtitle") 
56
57 #define POS_TEXT N_("Subpicture position")
58 #define POS_LONGTEXT N_( \
59   "You can enforce the subpicture position on the video " \
60   "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
61   "also use combinations of these values, e.g. 6=top-right).")
62
63 #define ENC_POSX_TEXT N_("Encoding X coordinate")
64 #define ENC_POSX_LONGTEXT N_("X coordinate of the encoded subtitle" )
65 #define ENC_POSY_TEXT N_("Encoding Y coordinate")
66 #define ENC_POSY_LONGTEXT N_("Y coordinate of the encoded subtitle" )
67
68 static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
69 static const char *ppsz_pos_descriptions[] =
70 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
71   N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
72
73 /*****************************************************************************
74  * Module descriptor.
75  *****************************************************************************/
76 static int  Open ( vlc_object_t * );
77 static void Close( vlc_object_t * );
78 static subpicture_t *Decode( decoder_t *, block_t ** );
79
80 static int OpenEncoder  ( vlc_object_t * );
81 static void CloseEncoder( vlc_object_t * );
82 static block_t *Encode  ( encoder_t *, subpicture_t * );
83
84 vlc_module_begin();
85 #   define DVBSUB_CFG_PREFIX "dvbsub-"
86     set_description( _("DVB subtitles decoder") );
87     set_capability( "decoder", 50 );
88     set_category( CAT_INPUT );
89     set_subcategory( SUBCAT_INPUT_SCODEC );
90     set_callbacks( Open, Close );
91
92     add_integer( DVBSUB_CFG_PREFIX "position", 8, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
93         change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
94     add_integer( DVBSUB_CFG_PREFIX "x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, VLC_FALSE );
95     add_integer( DVBSUB_CFG_PREFIX "y", -1, NULL, POSY_TEXT, POSY_LONGTEXT, VLC_FALSE );
96
97 #   define ENC_CFG_PREFIX "sout-dvbsub-"
98     add_submodule();
99     set_description( _("DVB subtitles encoder") );
100     set_capability( "encoder", 100 );
101     set_callbacks( OpenEncoder, CloseEncoder );
102
103     add_integer( ENC_CFG_PREFIX "x", -1, NULL, ENC_POSX_TEXT, ENC_POSX_LONGTEXT, VLC_FALSE );
104     add_integer( ENC_CFG_PREFIX "y", -1, NULL, ENC_POSY_TEXT, ENC_POSY_LONGTEXT, VLC_FALSE );
105     add_suppressed_integer( ENC_CFG_PREFIX "timeout" ); /* Suppressed since 0.8.5 */
106 vlc_module_end();
107
108 static const char *ppsz_enc_options[] = { "x", "y", NULL };
109
110 /****************************************************************************
111  * Local structures
112  ****************************************************************************
113  * Those structures refer closely to the ETSI 300 743 Object model
114  ****************************************************************************/
115
116 /* The object definition gives the position of the object in a region [7.2.5] */
117 typedef struct dvbsub_objectdef_s
118 {
119     int i_id;
120     int i_type;
121     int i_x;
122     int i_y;
123     int i_fg_pc;
124     int i_bg_pc;
125     char *psz_text; /* for string of characters objects */
126
127 } dvbsub_objectdef_t;
128
129 /* The entry in the palette CLUT */
130 typedef struct
131 {
132     uint8_t                 Y;
133     uint8_t                 Cr;
134     uint8_t                 Cb;
135     uint8_t                 T;
136
137 } dvbsub_color_t;
138
139 /* The displays dimensions [7.2.1] */
140 typedef struct dvbsub_display_s
141 {
142     uint8_t                 i_id;
143     uint8_t                 i_version;
144
145     int                     i_width;
146     int                     i_height;
147
148     vlc_bool_t              b_windowed;
149     int                     i_x;
150     int                     i_y;
151     int                     i_max_x;
152     int                     i_max_y;
153
154 } dvbsub_display_t;
155
156 /* [7.2.4] */
157 typedef struct dvbsub_clut_s
158 {
159     uint8_t                 i_id;
160     uint8_t                 i_version;
161     dvbsub_color_t          c_2b[4];
162     dvbsub_color_t          c_4b[16];
163     dvbsub_color_t          c_8b[256];
164
165     struct dvbsub_clut_s    *p_next;
166
167 } dvbsub_clut_t;
168
169 /* The Region is an aera on the image [7.2.3]
170  * with a list of the object definitions associated and a CLUT */
171 typedef struct dvbsub_region_s
172 {
173     int i_id;
174     int i_version;
175     int i_x;
176     int i_y;
177     int i_width;
178     int i_height;
179     int i_level_comp;
180     int i_depth;
181     int i_clut;
182
183     uint8_t *p_pixbuf;
184
185     int                    i_object_defs;
186     dvbsub_objectdef_t     *p_object_defs;
187
188     struct dvbsub_region_s *p_next;
189
190 } dvbsub_region_t;
191
192 /* The object definition gives the position of the object in a region */
193 typedef struct dvbsub_regiondef_s
194 {
195     int i_id;
196     int i_x;
197     int i_y;
198
199 } dvbsub_regiondef_t;
200
201 /* The page defines the list of regions [7.2.2] */
202 typedef struct
203 {
204     int i_id;
205     int i_timeout; /* in seconds */
206     int i_state;
207     int i_version;
208
209     int                i_region_defs;
210     dvbsub_regiondef_t *p_region_defs;
211
212 } dvbsub_page_t;
213
214 struct decoder_sys_t
215 {
216     bs_t            bs;
217
218     /* Decoder internal data */
219     int             i_id;
220     int             i_ancillary_id;
221     mtime_t         i_pts;
222
223     vlc_bool_t      b_absolute;
224     int             i_spu_position;
225     int             i_spu_x;
226     int             i_spu_y;
227
228     vlc_bool_t      b_page;
229     dvbsub_page_t   *p_page;
230     dvbsub_region_t *p_regions;
231     dvbsub_clut_t   *p_cluts;
232     dvbsub_display_t *p_display;
233     dvbsub_clut_t    default_clut;
234 };
235
236
237 /* List of different SEGMENT TYPES */
238 /* According to EN 300-743, table 2 */
239 #define DVBSUB_ST_PAGE_COMPOSITION      0x10
240 #define DVBSUB_ST_REGION_COMPOSITION    0x11
241 #define DVBSUB_ST_CLUT_DEFINITION       0x12
242 #define DVBSUB_ST_OBJECT_DATA           0x13
243 #define DVBSUB_ST_DISPLAY_DEFINITION    0x14
244 #define DVBSUB_ST_ENDOFDISPLAY          0x80
245 #define DVBSUB_ST_STUFFING              0xff
246 /* List of different OBJECT TYPES */
247 /* According to EN 300-743, table 6 */
248 #define DVBSUB_OT_BASIC_BITMAP          0x00
249 #define DVBSUB_OT_BASIC_CHAR            0x01
250 #define DVBSUB_OT_COMPOSITE_STRING      0x02
251 /* Pixel DATA TYPES */
252 /* According to EN 300-743, table 9 */ 
253 #define DVBSUB_DT_2BP_CODE_STRING       0x10
254 #define DVBSUB_DT_4BP_CODE_STRING       0x11
255 #define DVBSUB_DT_8BP_CODE_STRING       0x12
256 #define DVBSUB_DT_24_TABLE_DATA         0x20
257 #define DVBSUB_DT_28_TABLE_DATA         0x21
258 #define DVBSUB_DT_48_TABLE_DATA         0x22
259 #define DVBSUB_DT_END_LINE              0xf0
260 /* List of different Page Composition Segment state */
261 /* According to EN 300-743, 7.2.1 table 3 */
262 #define DVBSUB_PCS_STATE_ACQUISITION    0x01
263 #define DVBSUB_PCS_STATE_CHANGE         0x02
264
265 /*****************************************************************************
266  * Local prototypes
267  *****************************************************************************/
268 static void decode_segment( decoder_t *, bs_t * );
269 static void decode_page_composition( decoder_t *, bs_t * );
270 static void decode_region_composition( decoder_t *, bs_t * );
271 static void decode_object( decoder_t *, bs_t * );
272 static void decode_display_definition( decoder_t *, bs_t * );
273 static void decode_clut( decoder_t *, bs_t * );
274 static void free_all( decoder_t * );
275
276 static void default_clut_init( decoder_t * );
277
278 static subpicture_t *render( decoder_t * );
279
280 /*****************************************************************************
281  * Open: probe the decoder and return score
282  *****************************************************************************
283  * Tries to launch a decoder and return score so that the interface is able
284  * to chose.
285  *****************************************************************************/
286 static int Open( vlc_object_t *p_this )
287 {
288     decoder_t     *p_dec = (decoder_t *) p_this;
289     decoder_sys_t *p_sys;
290     vlc_value_t    val;
291     int i_posx, i_posy;
292
293     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
294     {
295         return VLC_EGENERIC;
296     }
297
298     p_dec->pf_decode_sub = Decode;
299     p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );
300     memset( p_sys, 0, sizeof(decoder_sys_t) );
301
302     p_sys->i_pts          = (mtime_t) 0;    
303     p_sys->i_id           = p_dec->fmt_in.subs.dvb.i_id & 0xFFFF;
304     p_sys->i_ancillary_id = p_dec->fmt_in.subs.dvb.i_id >> 16;
305
306     p_sys->p_regions      = NULL;
307     p_sys->p_cluts        = NULL;
308     p_sys->p_page         = NULL;
309     p_sys->p_display      = NULL;
310
311     var_Create( p_this, DVBSUB_CFG_PREFIX "position",
312                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
313     var_Get( p_this, DVBSUB_CFG_PREFIX "position", &val );
314     p_sys->i_spu_position = val.i_int;
315     var_Create( p_this, DVBSUB_CFG_PREFIX "x",
316                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
317     var_Get( p_this, DVBSUB_CFG_PREFIX "x", &val );
318     i_posx = val.i_int;
319     var_Create( p_this, DVBSUB_CFG_PREFIX "y",
320                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
321     var_Get( p_this, DVBSUB_CFG_PREFIX "y", &val );
322     i_posy = val.i_int;
323
324     /* Check if subpicture position was overridden */
325     p_sys->b_absolute = VLC_TRUE;
326     p_sys->i_spu_x = p_sys->i_spu_y = 0;
327
328     if( i_posx >= 0 && i_posy >= 0 )
329     {
330         p_sys->b_absolute = VLC_FALSE;
331         p_sys->i_spu_x = i_posx;
332         p_sys->i_spu_y = i_posy;
333     }
334
335     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );
336
337     default_clut_init( p_dec );
338
339     return VLC_SUCCESS;
340 }
341
342 /*****************************************************************************
343  * Close:
344  *****************************************************************************/
345 static void Close( vlc_object_t *p_this )
346 {
347     decoder_t     *p_dec = (decoder_t*) p_this;
348     decoder_sys_t *p_sys = p_dec->p_sys;
349
350     var_Destroy( p_this, DVBSUB_CFG_PREFIX "x" );
351     var_Destroy( p_this, DVBSUB_CFG_PREFIX "y" );
352     var_Destroy( p_this, DVBSUB_CFG_PREFIX "position" );
353
354     free_all( p_dec );
355     free( p_sys );
356 }
357
358 /*****************************************************************************
359  * Decode:
360  *****************************************************************************/
361 static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
362 {
363     decoder_sys_t *p_sys = p_dec->p_sys;
364     block_t       *p_block;
365     subpicture_t  *p_spu = NULL;
366
367     if( pp_block == NULL || *pp_block == NULL ) return NULL;
368     p_block = *pp_block;
369     *pp_block = NULL;
370
371     p_sys->i_pts = p_block->i_pts;
372     if( p_sys->i_pts <= 0 )
373     {
374 #ifdef DEBUG_DVBSUB
375         /* Some DVB channels send stuffing segments in non-dated packets so
376          * don't complain too loudly. */
377         msg_Warn( p_dec, "non dated subtitle" );
378 #endif
379         block_Release( p_block );
380         return NULL;
381     }
382
383     bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );
384
385     if( bs_read( &p_sys->bs, 8 ) != 0x20 ) /* Data identifier */
386     {
387         msg_Dbg( p_dec, "invalid data identifier" );
388         block_Release( p_block );
389         return NULL;
390     }
391
392     if( bs_read( &p_sys->bs, 8 ) ) /* Subtitle stream id */
393     {
394         msg_Dbg( p_dec, "invalid subtitle stream id" );
395         block_Release( p_block );
396         return NULL;
397     }
398
399 #ifdef DEBUG_DVBSUB
400     msg_Dbg( p_dec, "subtitle packet received: "I64Fd, p_sys->i_pts );
401 #endif
402
403     p_sys->b_page = VLC_FALSE;
404     while( bs_show( &p_sys->bs, 8 ) == 0x0f ) /* Sync byte */
405     {
406         decode_segment( p_dec, &p_sys->bs );
407     }
408
409     if( bs_read( &p_sys->bs, 8 ) != 0xff ) /* End marker */
410     {
411         msg_Warn( p_dec, "end marker not found (corrupted subtitle ?)" );
412         block_Release( p_block );
413         return NULL;
414     }
415
416     /* Check if the page is to be displayed */
417     if( p_sys->p_page && p_sys->b_page ) p_spu = render( p_dec );
418
419     block_Release( p_block );
420
421     return p_spu;
422 }
423
424 /* following functions are local */
425
426 /*****************************************************************************
427  * default_clut_init: default clut as defined in EN 300-743 section 10
428  *****************************************************************************/
429 static void default_clut_init( decoder_t *p_dec )
430 {
431     decoder_sys_t *p_sys = p_dec->p_sys;
432     uint8_t i;
433
434 #define RGB_TO_Y(r, g, b) ((int16_t) 77 * r + 150 * g + 29 * b) / 256;
435 #define RGB_TO_U(r, g, b) ((int16_t) -44 * r - 87 * g + 131 * b) / 256;
436 #define RGB_TO_V(r, g, b) ((int16_t) 131 * r - 110 * g - 21 * b) / 256;
437
438     /* 4 entries CLUT */
439     for( i = 0; i < 4; i++ )
440     {
441         uint8_t R = 0, G = 0, B = 0, T = 0;
442
443         if( !(i & 0x2) && !(i & 0x1) ) T = 0xFF;
444         else if( !(i & 0x2) && (i & 0x1) ) R = G = B = 0xFF;
445         else if( (i & 0x2) && !(i & 0x1) ) R = G = B = 0;
446         else R = G = B = 0x7F;
447
448         p_sys->default_clut.c_2b[i].Y = RGB_TO_Y(R,G,B);
449         p_sys->default_clut.c_2b[i].Cb = RGB_TO_V(R,G,B);
450         p_sys->default_clut.c_2b[i].Cr = RGB_TO_U(R,G,B);
451         p_sys->default_clut.c_2b[i].T = T;
452     }
453
454     /* 16 entries CLUT */
455     for( i = 0; i < 16; i++ )
456     {
457         uint8_t R = 0, G = 0, B = 0, T = 0;
458
459         if( !(i & 0x8) )
460         {
461             if( !(i & 0x4) && !(i & 0x2) && !(i & 0x1) )
462             {
463                 T = 0xFF;
464             }
465             else
466             {
467                 R = (i & 0x1) ? 0xFF : 0;
468                 G = (i & 0x2) ? 0xFF : 0;
469                 B = (i & 0x4) ? 0xFF : 0;
470             }
471         }
472         else
473         {
474             R = (i & 0x1) ? 0x7F : 0;
475             G = (i & 0x2) ? 0x7F : 0;
476             B = (i & 0x4) ? 0x7F : 0;
477         }
478
479         p_sys->default_clut.c_4b[i].Y = RGB_TO_Y(R,G,B);
480         p_sys->default_clut.c_4b[i].Cr = RGB_TO_V(R,G,B);
481         p_sys->default_clut.c_4b[i].Cb = RGB_TO_U(R,G,B);
482         p_sys->default_clut.c_4b[i].T = T;
483     }
484
485     /* 256 entries CLUT */
486     memset( p_sys->default_clut.c_8b, 0xFF, 256 * sizeof(dvbsub_color_t) );
487 }
488
489 static void decode_segment( decoder_t *p_dec, bs_t *s )
490 {
491     decoder_sys_t *p_sys = p_dec->p_sys;
492     int i_type;
493     int i_page_id;
494     int i_size;
495
496     /* sync_byte (already checked) */
497     bs_skip( s, 8 );
498
499     /* segment type */
500     i_type = bs_read( s, 8 );
501
502     /* page id */
503     i_page_id = bs_read( s, 16 );
504
505     /* segment size */
506     i_size = bs_show( s, 16 );
507
508     if( i_page_id != p_sys->i_id && i_page_id != p_sys->i_ancillary_id )
509     {
510 #ifdef DEBUG_DVBSUB
511         msg_Dbg( p_dec, "subtitle skipped (page id: %i, %i)",
512                  i_page_id, p_sys->i_id );
513 #endif
514         bs_skip( s,  8 * ( 2 + i_size ) );
515         return;
516     }
517
518     if( p_sys->i_ancillary_id != p_sys->i_id &&
519         i_type == DVBSUB_ST_PAGE_COMPOSITION &&
520         i_page_id == p_sys->i_ancillary_id )
521     {
522 #ifdef DEBUG_DVBSUB
523         msg_Dbg( p_dec, "skipped invalid ancillary subtitle packet" );
524 #endif
525         bs_skip( s,  8 * ( 2 + i_size ) );
526         return;
527     }
528
529 #ifdef DEBUG_DVBSUB
530     if( i_page_id == p_sys->i_id )
531         msg_Dbg( p_dec, "segment (id: %i)", i_page_id );
532     else
533         msg_Dbg( p_dec, "ancillary segment (id: %i)", i_page_id );
534 #endif
535
536     switch( i_type )
537     {
538     case DVBSUB_ST_PAGE_COMPOSITION:
539 #ifdef DEBUG_DVBSUB
540         msg_Dbg( p_dec, "decode_page_composition" );
541 #endif
542         decode_page_composition( p_dec, s );
543         break;
544
545     case DVBSUB_ST_REGION_COMPOSITION:
546 #ifdef DEBUG_DVBSUB
547         msg_Dbg( p_dec, "decode_region_composition" );
548 #endif
549         decode_region_composition( p_dec, s );
550         break;
551
552     case DVBSUB_ST_CLUT_DEFINITION:
553 #ifdef DEBUG_DVBSUB
554         msg_Dbg( p_dec, "decode_clut" );
555 #endif
556         decode_clut( p_dec, s );
557         break;
558
559     case DVBSUB_ST_OBJECT_DATA:
560 #ifdef DEBUG_DVBSUB
561         msg_Dbg( p_dec, "decode_object" );
562 #endif
563         decode_object( p_dec, s );
564         break;
565
566     case DVBSUB_ST_DISPLAY_DEFINITION:
567 #ifdef DEBUG_DVBSUB
568         msg_Dbg( p_dec, "decode_display_definition" );
569 #endif
570         decode_display_definition( p_dec, s );
571         break;
572
573     case DVBSUB_ST_ENDOFDISPLAY:
574 #ifdef DEBUG_DVBSUB
575         msg_Dbg( p_dec, "end of display" );
576 #endif
577         bs_skip( s,  8 * ( 2 + i_size ) );
578         break;
579
580     case DVBSUB_ST_STUFFING:
581 #ifdef DEBUG_DVBSUB
582         msg_Dbg( p_dec, "skip stuffing" );
583 #endif
584         bs_skip( s,  8 * ( 2 + i_size ) );
585         break;
586
587     default:
588         msg_Warn( p_dec, "unsupported segment type: (%04x)", i_type );
589         bs_skip( s,  8 * ( 2 + i_size ) );
590         break;
591     }
592 }
593
594 static void decode_clut( decoder_t *p_dec, bs_t *s )
595 {
596     decoder_sys_t *p_sys = p_dec->p_sys;
597     uint16_t      i_segment_length;
598     uint16_t      i_processed_length;
599     dvbsub_clut_t *p_clut, *p_next;
600     int           i_id, i_version;
601
602     i_segment_length = bs_read( s, 16 );
603     i_id             = bs_read( s, 8 );
604     i_version        = bs_read( s, 4 );
605
606     /* Check if we already have this clut */
607     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
608     {
609         if( p_clut->i_id == i_id ) break;
610     }
611
612     /* Check version number */
613     if( p_clut && p_clut->i_version == i_version )
614     {
615         /* Nothing to do */
616         bs_skip( s, 8 * i_segment_length - 12 );
617         return;
618     }
619
620     if( !p_clut )
621     {
622 #ifdef DEBUG_DVBSUB
623         msg_Dbg( p_dec, "new clut: %i", i_id );
624 #endif
625         p_clut = malloc( sizeof(dvbsub_clut_t) );
626         p_clut->p_next = p_sys->p_cluts;
627         p_sys->p_cluts = p_clut;
628     }
629
630     /* Initialize to default clut */
631     p_next = p_clut->p_next;
632     *p_clut = p_sys->default_clut;
633     p_clut->p_next = p_next;
634
635     /* We don't have this version of the CLUT: Parse it */
636     p_clut->i_version = i_version;
637     p_clut->i_id = i_id;
638     bs_skip( s, 4 ); /* Reserved bits */
639     i_processed_length = 2;
640     while( i_processed_length < i_segment_length )
641     {
642         uint8_t y, cb, cr, t;
643         uint8_t i_id;
644         uint8_t i_type;
645
646         i_id = bs_read( s, 8 );
647         i_type = bs_read( s, 3 );
648
649         bs_skip( s, 4 );
650
651         if( bs_read( s, 1 ) )
652         {
653             y  = bs_read( s, 8 );
654             cr = bs_read( s, 8 );
655             cb = bs_read( s, 8 );
656             t  = bs_read( s, 8 );
657             i_processed_length += 6;
658         }
659         else
660         {
661             y  = bs_read( s, 6 ) << 2;
662             cr = bs_read( s, 4 ) << 4;
663             cb = bs_read( s, 4 ) << 4;
664             t  = bs_read( s, 2 ) << 6;
665             i_processed_length += 4;
666         }
667
668         /* We are not entirely compliant here as full transparency is indicated
669          * with a luma value of zero, not a transparency value of 0xff
670          * (full transparency would actually be 0xff + 1). */
671         if( y == 0 )
672         {
673             cr = cb = 0;
674             t  = 0xff;
675         }
676
677         /* According to EN 300-743 section 7.2.3 note 1, type should
678          * not have more than 1 bit set to one, but some streams don't
679          * respect this note. */
680         if( i_type & 0x04 && i_id < 4 )
681         {
682             p_clut->c_2b[i_id].Y = y;
683             p_clut->c_2b[i_id].Cr = cr;
684             p_clut->c_2b[i_id].Cb = cb;
685             p_clut->c_2b[i_id].T = t;
686         }
687         if( i_type & 0x02 && i_id < 16 )
688         {
689             p_clut->c_4b[i_id].Y = y;
690             p_clut->c_4b[i_id].Cr = cr;
691             p_clut->c_4b[i_id].Cb = cb;
692             p_clut->c_4b[i_id].T = t;
693         }
694         if( i_type & 0x01 )
695         {
696             p_clut->c_8b[i_id].Y = y;
697             p_clut->c_8b[i_id].Cr = cr;
698             p_clut->c_8b[i_id].Cb = cb;
699             p_clut->c_8b[i_id].T = t;
700         }
701     }
702 }
703
704 static void decode_page_composition( decoder_t *p_dec, bs_t *s )
705 {
706     decoder_sys_t *p_sys = p_dec->p_sys;
707     int i_version, i_state, i_segment_length, i_timeout, i;
708
709     /* A page is composed by 0 or more region */
710     i_segment_length = bs_read( s, 16 );
711     i_timeout = bs_read( s, 8 );
712     i_version = bs_read( s, 4 );
713     i_state = bs_read( s, 2 );
714     bs_skip( s, 2 ); /* Reserved */
715
716     if( i_state == DVBSUB_PCS_STATE_CHANGE )
717     {
718         /* End of an epoch, reset decoder buffer */
719 #ifdef DEBUG_DVBSUB
720         msg_Dbg( p_dec, "page composition mode change" );
721 #endif
722         free_all( p_dec );
723     }
724     else if( !p_sys->p_page && i_state != DVBSUB_PCS_STATE_ACQUISITION &&
725              i_state != DVBSUB_PCS_STATE_CHANGE )
726     {
727         /* Not a full PCS, we need to wait for one */
728         msg_Dbg( p_dec, "didn't receive an acquisition page yet" );
729
730 #if 0
731         /* Try to start decoding even without an acquisition page */
732         bs_skip( s,  8 * (i_segment_length - 2) );
733         return;
734 #endif
735     }
736
737 #ifdef DEBUG_DVBSUB
738     if( i_state == DVBSUB_PCS_STATE_ACQUISITION )
739         msg_Dbg( p_dec, "acquisition page composition" );
740 #endif
741
742     /* Check version number */
743     if( p_sys->p_page && p_sys->p_page->i_version == i_version )
744     {
745         bs_skip( s,  8 * (i_segment_length - 2) );
746         return;
747     }
748     else if( p_sys->p_page )
749     {
750         if( p_sys->p_page->i_region_defs )
751             free( p_sys->p_page->p_region_defs );
752         p_sys->p_page->i_region_defs = 0;
753     }
754
755     if( !p_sys->p_page )
756     {
757 #ifdef DEBUG_DVBSUB
758         msg_Dbg( p_dec, "new page" );
759 #endif
760         /* Allocate a new page */
761         p_sys->p_page = malloc( sizeof(dvbsub_page_t) );
762     }
763
764     p_sys->p_page->i_version = i_version;
765     p_sys->p_page->i_timeout = i_timeout;
766     p_sys->b_page = VLC_TRUE;
767
768     /* Number of regions */
769     p_sys->p_page->i_region_defs = (i_segment_length - 2) / 6;
770
771     if( p_sys->p_page->i_region_defs == 0 ) return;
772
773     p_sys->p_page->p_region_defs =
774         malloc( p_sys->p_page->i_region_defs * sizeof(dvbsub_region_t) );
775     for( i = 0; i < p_sys->p_page->i_region_defs; i++ )
776     {
777         p_sys->p_page->p_region_defs[i].i_id = bs_read( s, 8 );
778         bs_skip( s, 8 ); /* Reserved */
779         p_sys->p_page->p_region_defs[i].i_x = bs_read( s, 16 );
780         p_sys->p_page->p_region_defs[i].i_y = bs_read( s, 16 );
781
782 #ifdef DEBUG_DVBSUB
783         msg_Dbg( p_dec, "page_composition, region %i (%i,%i)",
784                  i, p_sys->p_page->p_region_defs[i].i_x,
785                  p_sys->p_page->p_region_defs[i].i_y );
786 #endif
787     }
788 }
789
790 static void decode_region_composition( decoder_t *p_dec, bs_t *s )
791 {
792     decoder_sys_t *p_sys = p_dec->p_sys;
793     dvbsub_region_t *p_region, **pp_region = &p_sys->p_regions;
794     int i_segment_length, i_processed_length, i_id, i_version;
795     int i_width, i_height, i_level_comp, i_depth, i_clut;
796     int i_8_bg, i_4_bg, i_2_bg;
797     vlc_bool_t b_fill;
798
799     i_segment_length = bs_read( s, 16 );
800     i_id = bs_read( s, 8 );
801     i_version = bs_read( s, 4 );
802
803     /* Check if we already have this region */
804     for( p_region = p_sys->p_regions; p_region != NULL;
805          p_region = p_region->p_next )
806     {
807         pp_region = &p_region->p_next;
808         if( p_region->i_id == i_id ) break;
809     }
810
811     /* Check version number */
812     if( p_region && p_region->i_version == i_version )
813     {
814         bs_skip( s, 8 * (i_segment_length - 1) - 4 );
815         return;
816     }
817
818     if( !p_region )
819     {
820 #ifdef DEBUG_DVBSUB
821         msg_Dbg( p_dec, "new region: %i", i_id );
822 #endif
823         p_region = *pp_region = malloc( sizeof(dvbsub_region_t) );
824         memset( p_region, 0, sizeof(dvbsub_region_t) );
825         p_region->p_object_defs = NULL;
826         p_region->p_pixbuf = NULL;
827         p_region->p_next = NULL;
828     }
829
830     /* Region attributes */
831     p_region->i_id = i_id;
832     p_region->i_version = i_version;
833     b_fill = bs_read( s, 1 );
834     bs_skip( s, 3 ); /* Reserved */
835
836     i_width = bs_read( s, 16 );
837     i_height = bs_read( s, 16 );
838 #ifdef DEBUG_DVBSUB
839     msg_Dbg( p_dec, " width=%d height=%d", i_width, i_height );
840 #endif
841     i_level_comp = bs_read( s, 3 );
842     i_depth = bs_read( s, 3 );
843     bs_skip( s, 2 ); /* Reserved */
844     i_clut = bs_read( s, 8 );
845
846     i_8_bg = bs_read( s, 8 );
847     i_4_bg = bs_read( s, 4 );
848     i_2_bg = bs_read( s, 2 );
849     bs_skip( s, 2 ); /* Reserved */
850
851     /* Free old object defs */
852     while( p_region->i_object_defs )
853     {
854         int i = p_region->i_object_defs - 1;
855         if( p_region->p_object_defs[i].psz_text )
856             free( p_region->p_object_defs[i].psz_text );
857         if( !i ) free( p_region->p_object_defs );
858
859         p_region->i_object_defs--;
860     }
861     p_region->p_object_defs = NULL;
862
863     /* Extra sanity checks */
864     if( p_region->i_width != i_width || p_region->i_height != i_height )
865     {
866         if( p_region->p_pixbuf )
867         {
868             msg_Dbg( p_dec, "region size changed (%dx%d->%dx%d)",
869                      p_region->i_width, p_region->i_height, i_width, i_height );
870             free( p_region->p_pixbuf );
871         }
872
873         p_region->p_pixbuf = malloc( i_height * i_width );
874         p_region->i_depth = 0;
875         b_fill = VLC_TRUE;
876     }
877     if( p_region->i_depth && (p_region->i_depth != i_depth ||
878         p_region->i_level_comp != i_level_comp || p_region->i_clut != i_clut) )
879     {
880         msg_Dbg( p_dec, "region parameters changed (not allowed)" );
881     }
882
883     /* Erase background of region */
884     if( b_fill )
885     {
886         int i_background = (p_region->i_depth == 1) ? i_2_bg :
887             (p_region->i_depth == 2) ? i_4_bg : i_8_bg;
888         memset( p_region->p_pixbuf, i_background, i_width * i_height );
889     }
890
891     p_region->i_width = i_width;
892     p_region->i_height = i_height;
893     p_region->i_level_comp = i_level_comp;
894     p_region->i_depth = i_depth;
895     p_region->i_clut = i_clut;
896
897     /* List of objects in the region */
898     i_processed_length = 10;
899     while( i_processed_length < i_segment_length )
900     {
901         dvbsub_objectdef_t *p_obj;
902
903         /* We create a new object */
904         p_region->i_object_defs++;
905         p_region->p_object_defs =
906             realloc( p_region->p_object_defs,
907                      sizeof(dvbsub_objectdef_t) * p_region->i_object_defs );
908
909         /* We parse object properties */
910         p_obj = &p_region->p_object_defs[p_region->i_object_defs - 1];
911         p_obj->i_id         = bs_read( s, 16 );
912         p_obj->i_type       = bs_read( s, 2 );
913         bs_skip( s, 2 ); /* Provider */
914         p_obj->i_x          = bs_read( s, 12 );
915         bs_skip( s, 4 ); /* Reserved */
916         p_obj->i_y          = bs_read( s, 12 );
917         p_obj->psz_text     = 0;
918
919         i_processed_length += 6;
920
921         if( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ||
922             p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
923         {
924             p_obj->i_fg_pc =  bs_read( s, 8 );
925             p_obj->i_bg_pc =  bs_read( s, 8 );
926             i_processed_length += 2;
927         }
928     }
929 }
930
931 /* ETSI 300 743 [7.2.1] */
932 static void decode_display_definition( decoder_t *p_dec, bs_t *s )
933 {
934     decoder_sys_t *p_sys = p_dec->p_sys;
935     uint16_t      i_segment_length;
936     uint16_t      i_processed_length = 40;
937     dvbsub_display_t *p_display;
938     dvbsub_display_t *p_old = p_sys->p_display;
939     int           i_version;
940
941     i_segment_length = bs_read( s, 16 );
942     i_version        = bs_read( s, 4 );
943
944     /* Check version number */
945     if( p_old && p_old->i_version == i_version )
946     {
947         /* The definition did not change */
948         bs_skip( s, 8*i_segment_length - 4 );
949         return;
950     }
951
952 #ifdef DEBUG_DVBSUB
953     msg_Dbg( p_dec, "new display definition: %i", i_version );
954 #endif
955     p_display = malloc( sizeof(dvbsub_display_t) );
956
957     /* We don't have this version of the display definition: Parse it */
958     p_display->i_version = i_version;
959     p_display->b_windowed = bs_read( s, 1 );
960     bs_skip( s, 3 ); /* Reserved bits */
961     p_display->i_width = bs_read( s, 16 )+1;
962     p_display->i_height = bs_read( s, 16 )+1;
963
964     if( p_display->b_windowed )
965     {
966 #ifdef DEBUG_DVBSUB
967         msg_Dbg( p_dec, "display definition with offsets (windowed)" );
968 #endif
969         /* Coordinates are measured from the top left corner */
970         p_display->i_x     = bs_read( s, 16 );
971         p_display->i_max_x = bs_read( s, 16 );
972         p_display->i_y     = bs_read( s, 16 );
973         p_display->i_max_y = bs_read( s, 16 );
974         i_processed_length += 64;  
975     }
976
977     p_sys->p_display = p_display;
978     if( p_old ) free( p_old );
979
980     if( i_processed_length != i_segment_length*8 )
981     {
982         msg_Err( p_dec, "processed length %d != segment length %d", i_processed_length, i_segment_length );
983     }
984
985 #ifdef DEBUG_DVBSUB
986     msg_Dbg( p_dec, "version: %d, width: %d, height: %d", p_display->i_version, p_display->i_width, p_display->i_height );
987     if( p_display->b_windowed )
988         msg_Dbg( p_dec, "xmin: %d, xmax: %d, ymin: %d, ymax: %d", p_display->i_x, p_display->i_max_x, p_display->i_y, p_display->i_max_y );
989 #endif
990 }
991
992 static void dvbsub_render_pdata( decoder_t *, dvbsub_region_t *, int, int,
993                                  uint8_t *, int );
994 static void dvbsub_pdata2bpp( bs_t *, uint8_t *, int, int * );
995 static void dvbsub_pdata4bpp( bs_t *, uint8_t *, int, int * );
996 static void dvbsub_pdata8bpp( bs_t *, uint8_t *, int, int * );
997
998 static void decode_object( decoder_t *p_dec, bs_t *s )
999 {
1000     decoder_sys_t *p_sys = p_dec->p_sys;
1001     dvbsub_region_t *p_region;
1002     int i_segment_length, i_coding_method, i_version, i_id, i;
1003     vlc_bool_t b_non_modify_color;
1004
1005     /* ETSI 300-743 paragraph 7.2.4
1006      * sync_byte, segment_type and page_id have already been processed.
1007      */
1008     i_segment_length = bs_read( s, 16 );
1009     i_id             = bs_read( s, 16 );
1010     i_version        = bs_read( s, 4 );
1011     i_coding_method  = bs_read( s, 2 );
1012
1013     if( i_coding_method > 1 )
1014     {
1015         msg_Dbg( p_dec, "unknown DVB subtitling coding %d is not handled!", i_coding_method );
1016         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
1017         return;
1018     }
1019
1020     /* Check if the object needs to be rendered in at least one
1021      * of the regions */
1022     for( p_region = p_sys->p_regions; p_region != NULL;
1023          p_region = p_region->p_next )
1024     {
1025         for( i = 0; i < p_region->i_object_defs; i++ )
1026             if( p_region->p_object_defs[i].i_id == i_id ) break;
1027
1028         if( i != p_region->i_object_defs ) break;
1029     }
1030     if( !p_region )
1031     {
1032         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
1033         return;
1034     }
1035
1036 #ifdef DEBUG_DVBSUB
1037     msg_Dbg( p_dec, "new object: %i", i_id );
1038 #endif
1039
1040     b_non_modify_color = bs_read( s, 1 );
1041     bs_skip( s, 1 ); /* Reserved */
1042
1043     if( i_coding_method == 0x00 )
1044     {
1045         int i_topfield, i_bottomfield;
1046         uint8_t *p_topfield, *p_bottomfield;
1047
1048         i_topfield    = bs_read( s, 16 );
1049         i_bottomfield = bs_read( s, 16 );
1050         p_topfield    = s->p_start + bs_pos( s ) / 8;
1051         p_bottomfield = p_topfield + i_topfield;
1052
1053         bs_skip( s, 8 * (i_segment_length - 7) );
1054
1055         /* Sanity check */
1056         if( i_segment_length < i_topfield + i_bottomfield + 7 ||
1057             p_topfield + i_topfield + i_bottomfield > s->p_end )
1058         {
1059             msg_Dbg( p_dec, "corrupted object data" );
1060             return;
1061         }
1062
1063         for( p_region = p_sys->p_regions; p_region != NULL;
1064              p_region = p_region->p_next )
1065         {
1066             for( i = 0; i < p_region->i_object_defs; i++ )
1067             {
1068                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
1069
1070                 dvbsub_render_pdata( p_dec, p_region,
1071                                      p_region->p_object_defs[i].i_x,
1072                                      p_region->p_object_defs[i].i_y,
1073                                      p_topfield, i_topfield );
1074
1075                 if( i_bottomfield )
1076                 {
1077                     dvbsub_render_pdata( p_dec, p_region,
1078                                          p_region->p_object_defs[i].i_x,
1079                                          p_region->p_object_defs[i].i_y + 1,
1080                                          p_bottomfield, i_bottomfield );
1081                 }
1082                 else
1083                 {
1084                     /* Duplicate the top field */
1085                     dvbsub_render_pdata( p_dec, p_region,
1086                                          p_region->p_object_defs[i].i_x,
1087                                          p_region->p_object_defs[i].i_y + 1,
1088                                          p_topfield, i_topfield );
1089                 }
1090             }
1091         }
1092     }
1093     else
1094     {
1095         /* DVB subtitling as characters */
1096         int i_number_of_codes = bs_read( s, 8 );
1097         uint8_t* p_start = s->p_start + bs_pos( s ) / 8;
1098
1099         /* Sanity check */
1100         if( i_segment_length <  i_number_of_codes*2 + 4 ||
1101             p_start + i_number_of_codes*2 > s->p_end )
1102         {
1103             msg_Dbg( p_dec, "corrupted object data" );
1104             return;
1105         }
1106
1107         for( p_region = p_sys->p_regions; p_region != NULL;
1108              p_region = p_region->p_next )
1109         {
1110             for( i = 0; i < p_region->i_object_defs; i++ )
1111             {
1112                 int j;
1113
1114                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
1115
1116                 p_region->p_object_defs[i].psz_text =
1117                     realloc( p_region->p_object_defs[i].psz_text,
1118                              i_number_of_codes + 1 );
1119
1120                 /* FIXME 16bits -> char ??? See Preamble */
1121                 for( j = 0; j < i_number_of_codes; j++ )
1122                 {
1123                     p_region->p_object_defs[i].psz_text[j] = (char)(bs_read( s, 16 ) & 0xFF);
1124                 }
1125                 p_region->p_object_defs[i].psz_text[j] = 0;
1126             }
1127         }
1128     }
1129
1130 #ifdef DEBUG_DVBSUB
1131     msg_Dbg( p_dec, "end object: %i", i_id );
1132 #endif
1133 }
1134
1135 static void dvbsub_render_pdata( decoder_t *p_dec, dvbsub_region_t *p_region,
1136                                  int i_x, int i_y,
1137                                  uint8_t *p_field, int i_field )
1138 {
1139     uint8_t *p_pixbuf;
1140     int i_offset = 0;
1141     bs_t bs;
1142
1143     /* Sanity check */
1144     if( !p_region->p_pixbuf )
1145     {
1146         msg_Err( p_dec, "region %i has no pixel buffer!", p_region->i_id );
1147         return;
1148     }
1149     if( i_y < 0 || i_x < 0 || i_y >= p_region->i_height ||
1150         i_x >= p_region->i_width )
1151     {
1152         msg_Dbg( p_dec, "invalid offset (%i,%i)", i_x, i_y );
1153         return;
1154     }
1155
1156     p_pixbuf = p_region->p_pixbuf + i_y * p_region->i_width;
1157     bs_init( &bs, p_field, i_field );
1158
1159     while( !bs_eof( &bs ) )
1160     {
1161         /* Sanity check */
1162         if( i_y >= p_region->i_height ) return;
1163
1164         switch( bs_read( &bs, 8 ) )
1165         {
1166         case 0x10:
1167             dvbsub_pdata2bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1168                               &i_offset );
1169             break;
1170
1171         case 0x11:
1172             dvbsub_pdata4bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1173                               &i_offset );
1174             break;
1175
1176         case 0x12:
1177             dvbsub_pdata8bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1178                               &i_offset );
1179             break;
1180
1181         case 0x20:
1182         case 0x21:
1183         case 0x22:
1184             /* We don't use map tables */
1185             break;
1186
1187         case 0xf0: /* End of line code */
1188             p_pixbuf += 2*p_region->i_width;
1189             i_offset = 0; i_y += 2;
1190             break;
1191         }
1192     }
1193 }
1194
1195 static void dvbsub_pdata2bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1196 {
1197     vlc_bool_t b_stop = 0;
1198
1199     while( !b_stop && !bs_eof( s ) )
1200     {
1201         int i_count = 0, i_color = 0;
1202
1203         if( (i_color = bs_read( s, 2 )) != 0x00 )
1204         {
1205             i_count = 1;
1206         }
1207         else
1208         {
1209             if( bs_read( s, 1 ) == 0x01 )         // Switch1
1210             {
1211                 i_count = 3 + bs_read( s, 3 );
1212                 i_color = bs_read( s, 2 );
1213             }
1214             else
1215             {
1216                 if( bs_read( s, 1 ) == 0x00 )     //Switch2
1217                 {
1218                     switch( bs_read( s, 2 ) )     //Switch3
1219                     {
1220                     case 0x00:
1221                         b_stop = 1;
1222                         break;
1223                     case 0x01:
1224                         i_count = 2;
1225                         break;
1226                     case 0x02:
1227                         i_count =  12 + bs_read( s, 4 );
1228                         i_color = bs_read( s, 2 );
1229                         break;
1230                     case 0x03:
1231                         i_count =  29 + bs_read( s, 8 );
1232                         i_color = bs_read( s, 2 );
1233                         break;
1234                     default:
1235                         break;
1236                     }
1237                 }
1238                 else
1239                 {
1240                     /* 1 pixel color 0 */
1241                     i_count = 1;
1242                 }
1243             }
1244         }
1245
1246         if( !i_count ) continue;
1247
1248         /* Sanity check */
1249         if( i_count + *pi_off > i_width ) break;
1250
1251         if( i_count == 1 ) p[*pi_off] = i_color;
1252         else memset( p + *pi_off, i_color, i_count );
1253
1254         (*pi_off) += i_count;
1255     }
1256
1257     bs_align( s );
1258 }
1259
1260 static void dvbsub_pdata4bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1261 {
1262     vlc_bool_t b_stop = 0;
1263
1264     while( !b_stop && !bs_eof( s ) )
1265     {
1266         int i_count = 0, i_color = 0;
1267
1268         if( (i_color = bs_read( s, 4 )) != 0x00 )
1269         {
1270             /* Add 1 pixel */
1271             i_count = 1;
1272         }
1273         else
1274         {
1275             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1276             {
1277                 if( bs_show( s, 3 ) != 0x00 )
1278                 {
1279                     i_count = 2 + bs_read( s, 3 );
1280                 }
1281                 else
1282                 {
1283                     bs_skip( s, 3 );
1284                     b_stop = 1;
1285                 }
1286             }
1287             else
1288             {
1289                 if( bs_read( s, 1 ) == 0x00)        //Switch2
1290                 {
1291                     i_count =  4 + bs_read( s, 2 );
1292                     i_color = bs_read( s, 4 );
1293                 }
1294                 else
1295                 {
1296                     switch ( bs_read( s, 2 ) )     //Switch3
1297                     {
1298                     case 0x0:
1299                         i_count = 1;
1300                         break;
1301                     case 0x1:
1302                         i_count = 2;
1303                         break;
1304                     case 0x2:
1305                         i_count = 9 + bs_read( s, 4 );
1306                         i_color = bs_read( s, 4 );
1307                         break;
1308                     case 0x3:
1309                         i_count= 25 + bs_read( s, 8 );
1310                         i_color = bs_read( s, 4 );
1311                         break;
1312                     }
1313                 }
1314             }
1315         }
1316
1317         if( !i_count ) continue;
1318
1319         /* Sanity check */
1320         if( i_count + *pi_off > i_width ) break;
1321
1322         if( i_count == 1 ) p[*pi_off] = i_color;
1323         else memset( p + *pi_off, i_color, i_count );
1324
1325         (*pi_off) += i_count;
1326     }
1327
1328     bs_align( s );
1329 }
1330
1331 static void dvbsub_pdata8bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1332 {
1333     vlc_bool_t b_stop = 0;
1334
1335     while( !b_stop && !bs_eof( s ) )
1336     {
1337         int i_count = 0, i_color = 0;
1338
1339         if( (i_color = bs_read( s, 8 )) != 0x00 )
1340         {
1341             /* Add 1 pixel */
1342             i_count = 1;
1343         }
1344         else
1345         {
1346             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1347             {
1348                 if( bs_show( s, 7 ) != 0x00 )
1349                 {
1350                     i_count = bs_read( s, 7 );
1351                 }
1352                 else
1353                 {
1354                     bs_skip( s, 7 );
1355                     b_stop = 1;
1356                 }
1357             }
1358             else
1359             {
1360                 i_count = bs_read( s, 7 );
1361                 i_color = bs_read( s, 8 );
1362             }
1363         }
1364
1365         if( !i_count ) continue;
1366
1367         /* Sanity check */
1368         if( i_count + *pi_off > i_width ) break;
1369
1370         if( i_count == 1 ) p[*pi_off] = i_color;
1371         else memset( p + *pi_off, i_color, i_count );
1372
1373         (*pi_off) += i_count;
1374     }
1375
1376     bs_align( s );
1377 }
1378
1379 static void free_all( decoder_t *p_dec )
1380 {
1381     decoder_sys_t *p_sys = p_dec->p_sys;
1382     dvbsub_region_t *p_reg, *p_reg_next;
1383     dvbsub_clut_t *p_clut, *p_clut_next;
1384
1385     if( p_sys->p_display ) free( p_sys->p_display );
1386
1387     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut_next )
1388     {
1389         p_clut_next = p_clut->p_next;
1390         free( p_clut );
1391     }
1392     p_sys->p_cluts = NULL;
1393
1394     for( p_reg = p_sys->p_regions; p_reg != NULL; p_reg = p_reg_next )
1395     {
1396         int i;
1397
1398         p_reg_next = p_reg->p_next;
1399         for( i = 0; i < p_reg->i_object_defs; i++ )
1400             if( p_reg->p_object_defs[i].psz_text )
1401                 free( p_reg->p_object_defs[i].psz_text );
1402         if( p_reg->i_object_defs ) free( p_reg->p_object_defs );
1403         if( p_reg->p_pixbuf ) free( p_reg->p_pixbuf );
1404         free( p_reg );
1405     }
1406     p_sys->p_regions = NULL;
1407
1408     if( p_sys->p_page )
1409     {
1410         if( p_sys->p_page->i_region_defs )
1411             free( p_sys->p_page->p_region_defs );
1412         free( p_sys->p_page );
1413     }
1414     p_sys->p_page = NULL;
1415 }
1416
1417 static subpicture_t *render( decoder_t *p_dec )
1418 {
1419     decoder_sys_t *p_sys = p_dec->p_sys;
1420     subpicture_t *p_spu;
1421     subpicture_region_t **pp_spu_region;
1422     int i, j, i_timeout = 0;
1423
1424     /* Allocate the subpicture internal data. */
1425     p_spu = p_dec->pf_spu_buffer_new( p_dec );
1426     if( !p_spu ) return NULL;
1427
1428     pp_spu_region = &p_spu->p_region;
1429
1430     /* Loop on region definitions */
1431 #ifdef DEBUG_DVBSUB
1432     if( p_sys->p_page )
1433         msg_Dbg( p_dec, "rendering %i regions", p_sys->p_page->i_region_defs );
1434 #endif
1435
1436     for( i = 0; p_sys->p_page && i < p_sys->p_page->i_region_defs; i++ )
1437     {
1438         dvbsub_region_t     *p_region;
1439         dvbsub_regiondef_t  *p_regiondef;
1440         dvbsub_clut_t       *p_clut;
1441         dvbsub_color_t      *p_color;
1442         subpicture_region_t *p_spu_region;
1443         uint8_t *p_src, *p_dst;
1444         video_format_t fmt;
1445         int i_pitch;
1446
1447         i_timeout = p_sys->p_page->i_timeout;
1448
1449         p_regiondef = &p_sys->p_page->p_region_defs[i];
1450
1451 #ifdef DEBUG_DVBSUB
1452         msg_Dbg( p_dec, "rendering region %i (%i,%i)", i,
1453                  p_regiondef->i_x, p_regiondef->i_y );
1454 #endif
1455
1456         /* Find associated region */
1457         for( p_region = p_sys->p_regions; p_region != NULL;
1458              p_region = p_region->p_next )
1459         {
1460             if( p_regiondef->i_id == p_region->i_id ) break;
1461         }
1462
1463         if( !p_region )
1464         {
1465             msg_Dbg( p_dec, "region %i not found", p_regiondef->i_id );
1466             continue;
1467         }
1468
1469         /* Find associated CLUT */
1470         for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
1471         {
1472             if( p_region->i_clut == p_clut->i_id ) break;
1473         }
1474         if( !p_clut )
1475         {
1476             msg_Dbg( p_dec, "clut %i not found", p_region->i_clut );
1477             continue;
1478         }
1479
1480         /* Create new SPU region */
1481         memset( &fmt, 0, sizeof(video_format_t) );
1482         fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
1483         fmt.i_aspect = 0; /* 0 means use aspect ratio of background video */
1484         fmt.i_width = fmt.i_visible_width = p_region->i_width;
1485         fmt.i_height = fmt.i_visible_height = p_region->i_height;
1486         fmt.i_x_offset = fmt.i_y_offset = 0;
1487         p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
1488         if( !p_spu_region )
1489         {
1490             msg_Err( p_dec, "cannot allocate SPU region" );
1491             continue;
1492         }
1493         p_spu_region->i_x = p_regiondef->i_x;
1494         p_spu_region->i_y = p_regiondef->i_y;
1495         *pp_spu_region = p_spu_region;
1496         pp_spu_region = &p_spu_region->p_next;
1497
1498         /* Build palette */
1499         fmt.p_palette->i_entries = p_region->i_depth == 1 ? 4 :
1500             p_region->i_depth == 2 ? 16 : 256;
1501         p_color = (p_region->i_depth == 1) ? p_clut->c_2b :
1502             (p_region->i_depth == 2) ? p_clut->c_4b : p_clut->c_8b;
1503         for( j = 0; j < fmt.p_palette->i_entries; j++ )
1504         {
1505             fmt.p_palette->palette[j][0] = p_color[j].Y;
1506             fmt.p_palette->palette[j][1] = p_color[j].Cb; /* U == Cb */
1507             fmt.p_palette->palette[j][2] = p_color[j].Cr; /* V == Cr */
1508             fmt.p_palette->palette[j][3] = 0xff - p_color[j].T;
1509         }
1510
1511         p_src = p_region->p_pixbuf;
1512         p_dst = p_spu_region->picture.Y_PIXELS;
1513         i_pitch = p_spu_region->picture.Y_PITCH;
1514
1515         /* Copy pixel buffer */
1516         for( j = 0; j < p_region->i_height; j++ )
1517         {
1518             memcpy( p_dst, p_src, p_region->i_width );
1519             p_src += p_region->i_width;
1520             p_dst += i_pitch;
1521         }
1522
1523         /* Check subtitles encoded as strings of characters
1524          * (since there are not rendered in the pixbuffer) */
1525         for( j = 0; j < p_region->i_object_defs; j++ )
1526         {
1527             dvbsub_objectdef_t *p_object_def = &p_region->p_object_defs[j];
1528
1529             if( p_object_def->i_type != 1 || !p_object_def->psz_text )
1530                 continue;
1531
1532             /* Create new SPU region */
1533             memset( &fmt, 0, sizeof(video_format_t) );
1534             fmt.i_chroma = VLC_FOURCC('T','E','X','T');
1535             fmt.i_aspect = VOUT_ASPECT_FACTOR;
1536             fmt.i_width = fmt.i_visible_width = p_region->i_width;
1537             fmt.i_height = fmt.i_visible_height = p_region->i_height;
1538             fmt.i_x_offset = fmt.i_y_offset = 0;
1539             p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
1540             if( !p_region )
1541             {
1542                 msg_Err( p_dec, "cannot allocate SPU region" );
1543                 continue;
1544             }
1545
1546             p_spu_region->psz_text = strdup( p_object_def->psz_text );
1547             p_spu_region->i_x = p_regiondef->i_x + p_object_def->i_x;
1548             p_spu_region->i_y = p_regiondef->i_y + p_object_def->i_y;
1549             *pp_spu_region = p_spu_region;
1550             pp_spu_region = &p_spu_region->p_next;
1551         }
1552     }
1553
1554     /* Set the pf_render callback */
1555     p_spu->i_start = p_sys->i_pts;
1556     p_spu->b_ephemer = VLC_TRUE;
1557     p_spu->b_pausable = VLC_TRUE;
1558     //p_spu->b_fade = VLC_TRUE;
1559     //p_spu->i_stop = p_spu->i_start + (mtime_t) (i_timeout * 1000000);
1560
1561     /* Correct positioning of SPU */
1562     p_spu->b_absolute = p_sys->b_absolute;
1563     p_spu->i_flags = p_sys->i_spu_position;
1564     p_spu->i_x = p_sys->i_spu_x;
1565     p_spu->i_y = p_sys->i_spu_y;
1566     p_spu->i_original_picture_width = 720;
1567     p_spu->i_original_picture_height = 576;
1568
1569     if( p_sys->p_display )
1570     {
1571         p_spu->i_original_picture_width = p_sys->p_display->i_width;
1572         p_spu->i_original_picture_height = p_sys->p_display->i_height;
1573
1574         if( p_sys->p_display->b_windowed )
1575         {
1576             /* TODO: check that this actually works */
1577             p_spu->i_original_picture_width = p_sys->p_display->i_max_x - p_sys->p_display->i_x;
1578             p_spu->i_original_picture_height = p_sys->p_display->i_max_y - p_sys->p_display->i_y;
1579             p_spu->i_x += p_sys->p_display->i_x;
1580             p_spu->i_y += p_sys->p_display->i_y;
1581         }
1582     }
1583
1584     return p_spu;
1585 }
1586
1587 /*****************************************************************************
1588  * encoder_sys_t : encoder descriptor
1589  *****************************************************************************/
1590 typedef struct encoder_region_t
1591 {
1592     int i_width;
1593     int i_height;
1594
1595 } encoder_region_t;
1596
1597 struct encoder_sys_t
1598 {
1599     unsigned int i_page_ver;
1600     unsigned int i_region_ver;
1601     unsigned int i_clut_ver;
1602
1603     int i_regions;
1604     encoder_region_t *p_regions;
1605
1606     mtime_t i_pts;
1607
1608     /* subpicture positioning */
1609     int i_offset_x;
1610     int i_offset_y;
1611 };
1612
1613 static void encode_page_composition( encoder_t *, bs_t *, subpicture_t * );
1614 static void encode_clut( encoder_t *, bs_t *, subpicture_t * );
1615 static void encode_region_composition( encoder_t *, bs_t *, subpicture_t * );
1616 static void encode_object( encoder_t *, bs_t *, subpicture_t * );
1617
1618 /*****************************************************************************
1619  * OpenEncoder: probe the encoder and return score
1620  *****************************************************************************/
1621 static int OpenEncoder( vlc_object_t *p_this )
1622 {
1623     encoder_t *p_enc = (encoder_t *)p_this;
1624     encoder_sys_t *p_sys;
1625     vlc_value_t val;
1626
1627     if( p_enc->fmt_out.i_codec != VLC_FOURCC('d','v','b','s') &&
1628         !p_enc->b_force )
1629     {
1630         return VLC_EGENERIC;
1631     }
1632
1633     /* Allocate the memory needed to store the decoder's structure */
1634     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
1635     {
1636         msg_Err( p_enc, "out of memory" );
1637         return VLC_ENOMEM;
1638     }
1639     p_enc->p_sys = p_sys;
1640
1641     p_enc->pf_encode_sub = Encode;
1642     p_enc->fmt_out.i_codec = VLC_FOURCC('d','v','b','s');
1643     p_enc->fmt_out.subs.dvb.i_id  = 1 << 16 | 1;
1644
1645     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
1646
1647     p_sys->i_page_ver = 0;
1648     p_sys->i_region_ver = 0;
1649     p_sys->i_clut_ver = 0;
1650     p_sys->i_regions = 0;
1651     p_sys->p_regions = 0;
1652
1653     var_Create( p_this, ENC_CFG_PREFIX "x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
1654     var_Get( p_this, ENC_CFG_PREFIX "x", &val );
1655     p_sys->i_offset_x = val.i_int;
1656     var_Create( p_this, ENC_CFG_PREFIX "y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
1657     var_Get( p_this, ENC_CFG_PREFIX "y", &val );
1658     p_sys->i_offset_y = val.i_int;
1659
1660     return VLC_SUCCESS;
1661 }
1662
1663 /* FIXME: this routine is a hack to convert VLC_FOURCC('Y','U','V','A') 
1664  *        into VLC_FOURCC('Y','U','V','P')
1665  */
1666 static subpicture_t *YuvaYuvp( encoder_t *p_enc, subpicture_t *p_subpic )
1667 {
1668     subpicture_region_t *p_region = NULL;
1669
1670     if( !p_subpic ) return NULL;
1671
1672     for( p_region = p_subpic->p_region; p_region; p_region = p_region->p_next )
1673     {
1674         video_format_t *p_fmt = &p_region->fmt;
1675         int i = 0, j = 0, n = 0, p = 0;
1676         int i_max_entries = 256;
1677
1678 #ifdef RANDOM_DITHERING
1679         int i_seed = 0xdeadbeef; /* random seed */
1680 #else
1681         int *pi_delta;
1682 #endif
1683         int i_pixels = p_region->picture.p[0].i_visible_lines
1684                         * p_region->picture.p[0].i_pitch;
1685         int i_iterator = p_region->picture.p[0].i_visible_lines * 3 / 4
1686                             * p_region->picture.p[0].i_pitch
1687                         + p_region->picture.p[0].i_pitch * 1 / 3;
1688         int i_tolerance = 0;
1689
1690 #ifdef DEBUG_DVBSUB
1691         msg_Dbg( p_enc, "YuvaYuvp: i_pixels=%d, i_iterator=%d", i_pixels, i_iterator );
1692 #endif
1693         p_fmt->i_chroma = VLC_FOURCC('Y','U','V','P');
1694         p_fmt->p_palette = (video_palette_t *) malloc( sizeof( video_palette_t ) );
1695         if( !p_fmt->p_palette ) break;
1696         p_fmt->p_palette->i_entries = 0;
1697
1698         /* Find best iterator using Euclide’s algorithm */
1699         for( ; i_iterator > 1 ; i_iterator-- )
1700         {
1701             int a = i_pixels;
1702             int b = i_iterator;
1703             int c;
1704
1705             while( b )
1706             {
1707                 c = a % b;
1708                 a = b;
1709                 b = c;
1710             }
1711
1712             if( a == 1 )
1713             {
1714                 break;
1715             }
1716         }
1717
1718         /* Count colors, build best palette */
1719         for( i_tolerance = 0; i_tolerance < 128; i_tolerance++ )
1720         {
1721             vlc_bool_t b_success = VLC_TRUE;
1722             p_fmt->p_palette->i_entries = 0;
1723
1724             for( i = 0; i < i_pixels ; )
1725             {
1726                 uint8_t y, u, v, a;
1727                 y = p_region->picture.p[0].p_pixels[i];
1728                 u = p_region->picture.p[1].p_pixels[i];
1729                 v = p_region->picture.p[2].p_pixels[i];
1730                 a = p_region->picture.p[3].p_pixels[i];
1731                 for( j = 0; j < p_fmt->p_palette->i_entries; j++ )
1732                 {
1733                     if( abs((int)p_fmt->p_palette->palette[j][0] - (int)y) <= i_tolerance &&
1734                         abs((int)p_fmt->p_palette->palette[j][1] - (int)u) <= i_tolerance &&
1735                         abs((int)p_fmt->p_palette->palette[j][2] - (int)v) <= i_tolerance &&
1736                         abs((int)p_fmt->p_palette->palette[j][3] - (int)a) <= i_tolerance / 2 )
1737                     {
1738                         break;
1739                     }
1740                 }
1741                 if( j == p_fmt->p_palette->i_entries )
1742                 {
1743                     p_fmt->p_palette->palette[j][0] = y;
1744                     p_fmt->p_palette->palette[j][1] = u;
1745                     p_fmt->p_palette->palette[j][2] = v;
1746                     p_fmt->p_palette->palette[j][3] = a;
1747                     p_fmt->p_palette->i_entries++;
1748                 }
1749                 if( p_fmt->p_palette->i_entries >= i_max_entries )
1750                 {
1751                     b_success = VLC_FALSE;
1752                     break;
1753                 }
1754                 i += i_iterator;
1755                 if( i > i_pixels )
1756                 {
1757                     i -= i_pixels;
1758                 }
1759             }
1760
1761             if( b_success )
1762             {
1763                 break;
1764             }
1765         }
1766
1767 #ifdef DEBUG_DVBSUB
1768         msg_Dbg( p_enc, "best palette has %d colors", p_fmt->p_palette->i_entries );
1769 #endif
1770
1771 #ifndef RANDOM_DITHERING
1772         pi_delta = malloc( ( p_region->picture.p[0].i_pitch + 1 )
1773                             * sizeof(int) * 4  );
1774         for( i = 0; i < (p_region->picture.p[0].i_pitch + 1) * 4 ; i++ )
1775         {
1776             pi_delta[ i ] = 0;
1777         }
1778 #endif
1779
1780         /* Fill image with our new colours */
1781         for( p = 0; p < p_region->picture.p[0].i_visible_lines ; p++ )
1782         {
1783             int i_ydelta = 0, i_udelta = 0, i_vdelta = 0, i_adelta = 0;
1784
1785             for( n = 0; n < p_region->picture.p[0].i_pitch ; n++ )
1786             {
1787                 int i_offset = p * p_region->picture.p[0].i_pitch + n;
1788                 int y, u, v, a;
1789                 int i_mindist, i_best;
1790
1791                 y = (int)p_region->picture.p[0].p_pixels[i_offset];
1792                 u = (int)p_region->picture.p[1].p_pixels[i_offset];
1793                 v = (int)p_region->picture.p[2].p_pixels[i_offset];
1794                 a = (int)p_region->picture.p[3].p_pixels[i_offset];
1795
1796                 /* Add dithering compensation */
1797 #ifdef RANDOM_DITHERING
1798                 y += ((i_seed & 0xff) - 0x80) * i_tolerance / 0x80;
1799                 u += (((i_seed >> 8) & 0xff) - 0x80) * i_tolerance / 0x80;
1800                 v += (((i_seed >> 16) & 0xff) - 0x80) * i_tolerance / 0x80;
1801                 a += (((i_seed >> 24) & 0xff) - 0x80) * i_tolerance / 0x80;
1802 #else
1803                 y += i_ydelta + pi_delta[ n * 4 ];
1804                 u += i_udelta + pi_delta[ n * 4 + 1 ];
1805                 v += i_vdelta + pi_delta[ n * 4 + 2 ];
1806                 a += i_adelta + pi_delta[ n * 4 + 3 ];
1807 #endif
1808
1809                 /* Find best colour in palette */
1810                 for( i_mindist = 99999999, i_best = 0, j = 0; j < p_fmt->p_palette->i_entries; j++ )
1811                 {
1812                     int i_dist = 0;
1813
1814                     i_dist += abs((int)p_fmt->p_palette->palette[j][0] - y);
1815                     i_dist += abs((int)p_fmt->p_palette->palette[j][1] - u);
1816                     i_dist += abs((int)p_fmt->p_palette->palette[j][2] - v);
1817                     i_dist += 2 * abs((int)p_fmt->p_palette->palette[j][3] - a);
1818
1819                     if( i_dist < i_mindist )
1820                     {
1821                         i_mindist = i_dist;
1822                         i_best = j;
1823                     }
1824                 }
1825
1826                 /* Set pixel to best color */
1827                 p_region->picture.p[0].p_pixels[i_offset] = i_best;
1828
1829                 /* Update dithering state */
1830 #ifdef RANDOM_DITHERING
1831                 i_seed = (i_seed * 0x1283837) ^ 0x789479 ^ (i_seed >> 13);
1832 #else
1833                 i_ydelta = y - (int)p_fmt->p_palette->palette[i_best][0];
1834                 i_udelta = u - (int)p_fmt->p_palette->palette[i_best][1];
1835                 i_vdelta = v - (int)p_fmt->p_palette->palette[i_best][2];
1836                 i_adelta = a - (int)p_fmt->p_palette->palette[i_best][3];
1837                 pi_delta[ n * 4 ] = i_ydelta * 3 / 8;
1838                 pi_delta[ n * 4 + 1 ] = i_udelta * 3 / 8;
1839                 pi_delta[ n * 4 + 2 ] = i_vdelta * 3 / 8;
1840                 pi_delta[ n * 4 + 3 ] = i_adelta * 3 / 8;
1841                 i_ydelta = i_ydelta * 5 / 8;
1842                 i_udelta = i_udelta * 5 / 8;
1843                 i_vdelta = i_vdelta * 5 / 8;
1844                 i_adelta = i_adelta * 5 / 8;
1845 #endif
1846             }
1847         }
1848 #ifndef RANDOM_DITHERING
1849         free( pi_delta );
1850 #endif
1851
1852         /* pad palette */
1853         for( i = p_fmt->p_palette->i_entries; i < i_max_entries; i++ )
1854         {
1855             p_fmt->p_palette->palette[i][0] = 0;
1856             p_fmt->p_palette->palette[i][1] = 0;
1857             p_fmt->p_palette->palette[i][2] = 0;
1858             p_fmt->p_palette->palette[i][3] = 0;
1859         }
1860         p_fmt->p_palette->i_entries = i_max_entries;
1861 #ifdef DEBUG_DVBSUB
1862         msg_Dbg( p_enc, "best palette has %d colors", p_fmt->p_palette->i_entries );
1863 #endif
1864     }
1865     return p_subpic;
1866 } /* End of hack */
1867
1868 /****************************************************************************
1869  * Encode: the whole thing
1870  ****************************************************************************/
1871 static block_t *Encode( encoder_t *p_enc, subpicture_t *p_subpic )
1872 {
1873     subpicture_t *p_temp = NULL;
1874     subpicture_region_t *p_region = NULL;
1875     bs_t bits, *s = &bits;
1876     block_t *p_block;
1877
1878     if( !p_subpic || !p_subpic->p_region ) return NULL;
1879
1880     /* FIXME: this is a hack to convert VLC_FOURCC('Y','U','V','A') into
1881      *  VLC_FOURCC('Y','U','V','P')
1882      */
1883     p_region = p_subpic->p_region;
1884     if( p_region->fmt.i_chroma == VLC_FOURCC('Y','U','V','A') )
1885     {
1886         p_temp = YuvaYuvp( p_enc, p_subpic );
1887         if( !p_temp )
1888         {
1889             msg_Err( p_enc, "no picture in subpicture" );
1890             return NULL;
1891         }
1892         p_region = p_subpic->p_region;
1893     }
1894
1895     /* Sanity check */
1896     if( !p_region ) return NULL;
1897
1898     if( p_region->fmt.i_chroma != VLC_FOURCC('T','E','X','T') &&
1899         p_region->fmt.i_chroma != VLC_FOURCC('Y','U','V','P') ) return NULL;
1900
1901     if( p_region->fmt.p_palette )
1902     {
1903         switch( p_region->fmt.p_palette->i_entries )
1904         {
1905             case 0:
1906             case 4:
1907             case 16:
1908             case 256:
1909                 break;
1910             default:
1911                 msg_Err( p_enc, "subpicture palette (%d) not handled",
1912                             p_region->fmt.p_palette->i_entries );
1913                 return NULL;
1914         }
1915     }
1916     /* End of hack */
1917
1918 #ifdef DEBUG_DVBSUB
1919     msg_Dbg( p_enc, "encoding subpicture" );
1920 #endif
1921     p_block = block_New( p_enc, 64000 );
1922     bs_init( s, p_block->p_buffer, p_block->i_buffer );
1923
1924     bs_write( s, 8, 0x20 ); /* Data identifier */
1925     bs_write( s, 8, 0x0 );  /* Subtitle stream id */
1926
1927     encode_page_composition( p_enc, s, p_subpic );
1928     encode_region_composition( p_enc, s, p_subpic );
1929     encode_clut( p_enc, s, p_subpic );
1930     encode_object( p_enc, s, p_subpic );
1931
1932     /* End of display */
1933     bs_write( s, 8, 0x0f ); /* Sync byte */
1934     bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
1935     bs_write( s, 16, 1 );  /* Page id */
1936     bs_write( s, 16, 0 );  /* Segment length */
1937
1938     bs_write( s, 8, 0xff );/* End marker */
1939     p_block->i_buffer = bs_pos( s ) / 8;
1940     p_block->i_pts = p_block->i_dts = p_subpic->i_start;
1941     if( !p_subpic->b_ephemer && p_subpic->i_stop > p_subpic->i_start )
1942     {
1943         block_t *p_block_stop;
1944
1945         p_block->i_length = p_subpic->i_stop - p_subpic->i_start;
1946
1947         /* Send another (empty) subtitle to signal the end of display */
1948         p_block_stop = block_New( p_enc, 64000 );
1949         bs_init( s, p_block_stop->p_buffer, p_block_stop->i_buffer );
1950         bs_write( s, 8, 0x20 ); /* Data identifier */
1951         bs_write( s, 8, 0x0 );  /* Subtitle stream id */
1952         encode_page_composition( p_enc, s, 0 );
1953         bs_write( s, 8, 0x0f ); /* Sync byte */
1954         bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
1955         bs_write( s, 16, 1 );  /* Page id */
1956         bs_write( s, 16, 0 );  /* Segment length */
1957         bs_write( s, 8, 0xff );/* End marker */
1958         p_block_stop->i_buffer = bs_pos( s ) / 8;
1959         p_block_stop->i_pts = p_block_stop->i_dts = p_subpic->i_stop;
1960         block_ChainAppend( &p_block, p_block_stop );
1961         p_block_stop->i_length = 100000; /* p_subpic->i_stop - p_subpic->i_start; */
1962     }
1963 #ifdef DEBUG_DVBSUB
1964     msg_Dbg( p_enc, "subpicture encoded properly" );
1965 #endif
1966     return p_block;
1967 }
1968
1969 /*****************************************************************************
1970  * CloseEncoder: encoder destruction
1971  *****************************************************************************/
1972 static void CloseEncoder( vlc_object_t *p_this )
1973 {
1974     encoder_t *p_enc = (encoder_t *)p_this;
1975     encoder_sys_t *p_sys = p_enc->p_sys;
1976
1977     var_Destroy( p_this , ENC_CFG_PREFIX "x" );
1978     var_Destroy( p_this , ENC_CFG_PREFIX "y" );
1979     var_Destroy( p_this , ENC_CFG_PREFIX "timeout" );
1980
1981     if( p_sys->i_regions ) free( p_sys->p_regions );
1982     free( p_sys );
1983 }
1984
1985 static void encode_page_composition( encoder_t *p_enc, bs_t *s,
1986                                      subpicture_t *p_subpic )
1987 {
1988     encoder_sys_t *p_sys = p_enc->p_sys;
1989     subpicture_region_t *p_region;
1990     vlc_bool_t b_mode_change = VLC_FALSE;
1991     int i_regions, i_timeout;
1992
1993     bs_write( s, 8, 0x0f ); /* Sync byte */
1994     bs_write( s, 8, DVBSUB_ST_PAGE_COMPOSITION ); /* Segment type */
1995     bs_write( s, 16, 1 ); /* Page id */
1996
1997     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
1998          p_region; p_region = p_region->p_next, i_regions++ )
1999     {
2000         if( i_regions >= p_sys->i_regions )
2001         {
2002             encoder_region_t region;
2003             region.i_width = region.i_height = 0;
2004             p_sys->p_regions =
2005                 realloc( p_sys->p_regions, sizeof(encoder_region_t) *
2006                          (p_sys->i_regions + 1) );
2007             p_sys->p_regions[p_sys->i_regions++] = region;
2008         }
2009
2010         if( ( p_sys->p_regions[i_regions].i_width <
2011               (int)p_region->fmt.i_visible_width ) || 
2012             ( p_sys->p_regions[i_regions].i_width >
2013               (int)p_region->fmt.i_visible_width ) )
2014         {
2015             b_mode_change = VLC_TRUE;
2016             msg_Dbg( p_enc, "region %i width change: %i -> %i",
2017                      i_regions, p_sys->p_regions[i_regions].i_width,
2018                      p_region->fmt.i_visible_width );
2019             p_sys->p_regions[i_regions].i_width =
2020                 p_region->fmt.i_visible_width;
2021         }
2022         if( p_sys->p_regions[i_regions].i_height <
2023              (int)p_region->fmt.i_visible_height )
2024         {
2025             b_mode_change = VLC_TRUE;
2026             msg_Dbg( p_enc, "region %i height change: %i -> %i",
2027                      i_regions, p_sys->p_regions[i_regions].i_height,
2028                      p_region->fmt.i_visible_height );
2029             p_sys->p_regions[i_regions].i_height =
2030                 p_region->fmt.i_visible_height;
2031         }
2032     }
2033
2034     bs_write( s, 16, i_regions * 6 + 2 ); /* Segment length */
2035
2036     i_timeout = 0;
2037     if( p_subpic && !p_subpic->b_ephemer &&
2038         p_subpic->i_stop > p_subpic->i_start )
2039     {
2040         i_timeout = (p_subpic->i_stop - p_subpic->i_start) / 1000000;
2041     }
2042
2043     bs_write( s, 8, i_timeout ); /* Timeout */
2044     bs_write( s, 4, p_sys->i_page_ver++ );
2045     bs_write( s, 2, b_mode_change ?
2046               DVBSUB_PCS_STATE_CHANGE : DVBSUB_PCS_STATE_ACQUISITION );
2047     bs_write( s, 2, 0 ); /* Reserved */
2048
2049     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
2050          p_region; p_region = p_region->p_next, i_regions++ )
2051     {
2052         bs_write( s, 8, i_regions );
2053         bs_write( s, 8, 0 ); /* Reserved */
2054         if( (p_sys->i_offset_x > 0) && (p_sys->i_offset_y > 0) )
2055         {
2056             bs_write( s, 16, p_sys->i_offset_x ); /* override x position */
2057             bs_write( s, 16, p_sys->i_offset_y ); /* override y position */
2058         }
2059         else
2060         {
2061             bs_write( s, 16, p_region->i_x );
2062             bs_write( s, 16, p_region->i_y );
2063         }
2064     }
2065 }
2066
2067 static void encode_clut( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
2068 {
2069     encoder_sys_t *p_sys = p_enc->p_sys;
2070     subpicture_region_t *p_region = p_subpic->p_region;
2071     video_palette_t *p_pal, pal;
2072     int i;
2073
2074     /* Sanity check */
2075     if( !p_region ) return;
2076
2077     if( p_region->fmt.i_chroma == VLC_FOURCC('Y','U','V','P') )
2078     {
2079         p_pal = p_region->fmt.p_palette;
2080     }
2081     else
2082     {
2083         pal.i_entries = 4;
2084         for( i = 0; i < 4; i++ )
2085         {
2086             pal.palette[i][0] = 0;
2087             pal.palette[i][1] = 0;
2088             pal.palette[i][2] = 0;
2089             pal.palette[i][3] = 0;
2090         }
2091         p_pal = &pal;
2092     }
2093
2094     bs_write( s, 8, 0x0f ); /* Sync byte */
2095     bs_write( s, 8, DVBSUB_ST_CLUT_DEFINITION ); /* Segment type */
2096     bs_write( s, 16, 1 );  /* Page id */
2097
2098     bs_write( s, 16, p_pal->i_entries * 6 + 2 ); /* Segment length */
2099     bs_write( s, 8, 1 ); /* Clut id */
2100     bs_write( s, 4, p_sys->i_clut_ver++ );
2101     bs_write( s, 4, 0 ); /* Reserved */
2102
2103     for( i = 0; i < p_pal->i_entries; i++ )
2104     {
2105         bs_write( s, 8, i ); /* Clut entry id */
2106         bs_write( s, 1, p_pal->i_entries == 4 );   /* 2bit/entry flag */
2107         bs_write( s, 1, p_pal->i_entries == 16 );  /* 4bit/entry flag */
2108         bs_write( s, 1, p_pal->i_entries == 256 ); /* 8bit/entry flag */
2109         bs_write( s, 4, 0 ); /* Reserved */
2110         bs_write( s, 1, 1 ); /* Full range flag */
2111         bs_write( s, 8, p_pal->palette[i][3] ?  /* Y value */
2112                   (p_pal->palette[i][0] ? p_pal->palette[i][0] : 16) : 0 );
2113         bs_write( s, 8, p_pal->palette[i][1] ); /* Cr value */
2114         bs_write( s, 8, p_pal->palette[i][2] ); /* Cb value */
2115         bs_write( s, 8, 0xff - p_pal->palette[i][3] ); /* T value */
2116     }
2117 }
2118
2119 static void encode_region_composition( encoder_t *p_enc, bs_t *s,
2120                                        subpicture_t *p_subpic )
2121 {
2122     encoder_sys_t *p_sys = p_enc->p_sys;
2123     subpicture_region_t *p_region;
2124     int i_region;
2125
2126     for( i_region = 0, p_region = p_subpic->p_region; p_region;
2127          p_region = p_region->p_next, i_region++ )
2128     {
2129         int i_entries = 4, i_depth = 0x1, i_bg = 0;
2130         vlc_bool_t b_text =
2131             p_region->fmt.i_chroma == VLC_FOURCC('T','E','X','T');
2132
2133         if( !b_text )
2134         {
2135             video_palette_t *p_pal = p_region->fmt.p_palette;
2136
2137             if( !p_pal )
2138             {
2139                 msg_Err( p_enc, "subpicture has no palette - ignoring it" );
2140                 break;
2141             }
2142
2143             i_entries = p_pal->i_entries;
2144             i_depth = i_entries == 4 ? 0x1 : i_entries == 16 ? 0x2 : 0x3;
2145
2146             for( i_bg = 0; i_bg < p_pal->i_entries; i_bg++ )
2147             {
2148                 if( !p_pal->palette[i_bg][3] ) break;
2149             }
2150         }
2151
2152         bs_write( s, 8, 0x0f ); /* Sync byte */
2153         bs_write( s, 8, DVBSUB_ST_REGION_COMPOSITION ); /* Segment type */
2154         bs_write( s, 16, 1 );   /* Page id */
2155
2156         bs_write( s, 16, 10 + 6 + (b_text ? 2 : 0) ); /* Segment length */
2157         bs_write( s, 8, i_region );
2158         bs_write( s, 4, p_sys->i_region_ver++ );
2159
2160         /* Region attributes */
2161         bs_write( s, 1, i_bg < i_entries ); /* Fill */
2162         bs_write( s, 3, 0 ); /* Reserved */
2163         bs_write( s, 16, p_sys->p_regions[i_region].i_width );
2164         bs_write( s, 16, p_sys->p_regions[i_region].i_height );
2165         bs_write( s, 3, i_depth );  /* Region level of compatibility */
2166         bs_write( s, 3, i_depth  ); /* Region depth */
2167         bs_write( s, 2, 0 ); /* Reserved */
2168         bs_write( s, 8, 1 ); /* Clut id */
2169         bs_write( s, 8, i_bg ); /* region 8bit pixel code */
2170         bs_write( s, 4, i_bg ); /* region 4bit pixel code */
2171         bs_write( s, 2, i_bg ); /* region 2bit pixel code */
2172         bs_write( s, 2, 0 ); /* Reserved */
2173
2174         /* In our implementation we only have 1 object per region */
2175         bs_write( s, 16, i_region );
2176         bs_write( s, 2, b_text ? DVBSUB_OT_BASIC_CHAR:DVBSUB_OT_BASIC_BITMAP );
2177         bs_write( s, 2, 0 ); /* object provider flag */
2178         bs_write( s, 12, 0 );/* object horizontal position */
2179         bs_write( s, 4, 0 ); /* Reserved */
2180         bs_write( s, 12, 0 );/* object vertical position */
2181
2182         if( b_text )
2183         {
2184             bs_write( s, 8, 1 ); /* foreground pixel code */
2185             bs_write( s, 8, 0 ); /* background pixel code */
2186         }
2187     }
2188 }
2189
2190 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
2191                                subpicture_region_t *p_region,
2192                                vlc_bool_t b_top );
2193
2194 static void encode_object( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
2195 {
2196     encoder_sys_t *p_sys = p_enc->p_sys;
2197     subpicture_region_t *p_region;
2198     int i_region;
2199
2200     int i_length_pos, i_update_pos, i_pixel_data_pos;
2201
2202     for( i_region = 0, p_region = p_subpic->p_region; p_region;
2203          p_region = p_region->p_next, i_region++ )
2204     {
2205         bs_write( s, 8, 0x0f ); /* Sync byte */
2206         bs_write( s, 8, DVBSUB_ST_OBJECT_DATA ); /* Segment type */
2207         bs_write( s, 16, 1 ); /* Page id */
2208
2209         i_length_pos = bs_pos( s );
2210         bs_write( s, 16, 0 ); /* Segment length */
2211         bs_write( s, 16, i_region ); /* Object id */
2212         bs_write( s, 4, p_sys->i_region_ver++ );
2213
2214         /* object coding method */
2215         switch( p_region->fmt.i_chroma )
2216         {
2217         case VLC_FOURCC( 'Y','U','V','P' ):
2218             bs_write( s, 2, 0 );
2219             break;
2220         case VLC_FOURCC( 'T','E','X','T' ):
2221             bs_write( s, 2, 1 );
2222             break;
2223         default:
2224             msg_Err( p_enc, "FOURCC %d not supported by encoder.", p_region->fmt.i_chroma );
2225             continue;
2226         }
2227
2228         bs_write( s, 1, 0 ); /* non modifying color flag */
2229         bs_write( s, 1, 0 ); /* Reserved */
2230
2231         if( p_region->fmt.i_chroma == VLC_FOURCC( 'T','E','X','T' ) )
2232         {
2233             int i_size, i;
2234
2235             if( !p_region->psz_text ) continue;
2236
2237             i_size = __MIN( strlen( p_region->psz_text ), 256 );
2238
2239             bs_write( s, 8, i_size ); /* number of characters in string */
2240             for( i = 0; i < i_size; i++ )
2241             {
2242                 bs_write( s, 16, p_region->psz_text[i] );
2243             }
2244
2245             /* Update segment length */
2246             SetWBE( &s->p_start[i_length_pos/8],
2247                     (bs_pos(s) - i_length_pos)/8 -2 );
2248             continue;
2249         }
2250
2251         /* Coding of a bitmap object */
2252         i_update_pos = bs_pos( s );
2253         bs_write( s, 16, 0 ); /* topfield data block length */
2254         bs_write( s, 16, 0 ); /* bottomfield data block length */
2255
2256         /* Top field */
2257         i_pixel_data_pos = bs_pos( s );
2258         encode_pixel_data( p_enc, s, p_region, VLC_TRUE );
2259         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
2260         SetWBE( &s->p_start[i_update_pos/8], i_pixel_data_pos );
2261
2262         /* Bottom field */
2263         i_pixel_data_pos = bs_pos( s );
2264         encode_pixel_data( p_enc, s, p_region, VLC_FALSE );
2265         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
2266         SetWBE( &s->p_start[i_update_pos/8+2], i_pixel_data_pos );
2267
2268         /* Stuffing for word alignment */
2269         bs_align_0( s );
2270         if( bs_pos( s ) % 16 ) bs_write( s, 8, 0 );
2271
2272         /* Update segment length */
2273         SetWBE( &s->p_start[i_length_pos/8], (bs_pos(s) - i_length_pos)/8 -2 );
2274     }
2275 }
2276
2277 static void encode_pixel_line_2bp( encoder_t *p_enc, bs_t *s,
2278                                    subpicture_region_t *p_region,
2279                                    int i_line );
2280 static void encode_pixel_line_4bp( encoder_t *p_enc, bs_t *s,
2281                                    subpicture_region_t *p_region,
2282                                    int i_line );
2283 static void encode_pixel_line_8bp( encoder_t *p_enc, bs_t *s,
2284                                    subpicture_region_t *p_region,
2285                                    int i_line );
2286 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
2287                                subpicture_region_t *p_region,
2288                                vlc_bool_t b_top )
2289 {
2290     unsigned int i_line;
2291
2292     /* Sanity check */
2293     if( p_region->fmt.i_chroma != VLC_FOURCC('Y','U','V','P') ) return;
2294
2295     /* Encode line by line */
2296     for( i_line = !b_top; i_line < p_region->fmt.i_visible_height;
2297          i_line += 2 )
2298     {
2299         switch( p_region->fmt.p_palette->i_entries )
2300         {
2301         case 0:
2302             break;
2303
2304         case 4:
2305             bs_write( s, 8, 0x10 ); /* 2 bit/pixel code string */
2306             encode_pixel_line_2bp( p_enc, s, p_region, i_line );
2307             break;
2308
2309         case 16:
2310             bs_write( s, 8, 0x11 ); /* 4 bit/pixel code string */
2311             encode_pixel_line_4bp( p_enc, s, p_region, i_line );
2312             break;
2313
2314         case 256:
2315             bs_write( s, 8, 0x12 ); /* 8 bit/pixel code string */
2316             encode_pixel_line_8bp( p_enc, s, p_region, i_line );
2317             break;
2318
2319         default:
2320             msg_Err( p_enc, "subpicture palette (%i) not handled",
2321                      p_region->fmt.p_palette->i_entries );
2322             break;
2323         }
2324
2325         bs_write( s, 8, 0xf0 ); /* End of object line code */
2326     }
2327 }
2328
2329 static void encode_pixel_line_2bp( encoder_t *p_enc, bs_t *s,
2330                                    subpicture_region_t *p_region,
2331                                    int i_line )
2332 {
2333     unsigned int i, i_length = 0;
2334     int i_pitch = p_region->picture.p->i_pitch;
2335     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
2336     int i_last_pixel = p_data[0];
2337
2338     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2339     {
2340         if( i != p_region->fmt.i_visible_width &&
2341             p_data[i] == i_last_pixel && i_length != 284 )
2342         {
2343             i_length++;
2344             continue;
2345         }
2346
2347         if( i_length == 1 || i_length == 11 || i_length == 28 )
2348         {
2349             /* 2bit/pixel code */
2350             if( i_last_pixel ) bs_write( s, 2, i_last_pixel );
2351             else
2352             {
2353                 bs_write( s, 2, 0 );
2354                 bs_write( s, 1, 0 );
2355                 bs_write( s, 1, 1 ); /* pseudo color 0 */
2356             }
2357             i_length--;
2358         }
2359
2360         if( i_length == 2 )
2361         {
2362             if( i_last_pixel )
2363             {
2364                 bs_write( s, 2, i_last_pixel );
2365                 bs_write( s, 2, i_last_pixel );
2366             }
2367             else
2368             {
2369                 bs_write( s, 2, 0 );
2370                 bs_write( s, 1, 0 );
2371                 bs_write( s, 1, 0 );
2372                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
2373             }
2374         }
2375         else if( i_length > 2 )
2376         {
2377             bs_write( s, 2, 0 );
2378             if( i_length <= 10 )
2379             {
2380                 bs_write( s, 1, 1 );
2381                 bs_write( s, 3, i_length - 3 );
2382                 bs_write( s, 2, i_last_pixel );
2383             }
2384             else
2385             {
2386                 bs_write( s, 1, 0 );
2387                 bs_write( s, 1, 0 );
2388
2389                 if( i_length <= 27 )
2390                 {
2391                     bs_write( s, 2, 2 );
2392                     bs_write( s, 4, i_length - 12 );
2393                     bs_write( s, 2, i_last_pixel );
2394                 }
2395                 else
2396                 {
2397                     bs_write( s, 2, 3 );
2398                     bs_write( s, 8, i_length - 29 );
2399                     bs_write( s, 2, i_last_pixel );
2400                 }
2401             }
2402         }
2403
2404         if( i == p_region->fmt.i_visible_width ) break;
2405
2406         i_last_pixel = p_data[i];
2407         i_length = 1;
2408     }
2409
2410     /* Stop */
2411     bs_write( s, 2, 0 );
2412     bs_write( s, 1, 0 );
2413     bs_write( s, 1, 0 );
2414     bs_write( s, 2, 0 );
2415
2416     /* Stuffing */
2417     bs_align_0( s );
2418 }
2419
2420 static void encode_pixel_line_4bp( encoder_t *p_enc, bs_t *s,
2421                                    subpicture_region_t *p_region,
2422                                    int i_line )
2423 {
2424     unsigned int i, i_length = 0;
2425     int i_pitch = p_region->picture.p->i_pitch;
2426     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
2427     int i_last_pixel = p_data[0];
2428
2429     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2430     {
2431         if( i != p_region->fmt.i_visible_width &&
2432             p_data[i] == i_last_pixel && i_length != 280 )
2433         {
2434             i_length++;
2435             continue;
2436         }
2437
2438         if( i_length == 1 || (i_length == 3 && i_last_pixel) || i_length == 8 )
2439         {
2440             /* 4bit/pixel code */
2441             if( i_last_pixel ) bs_write( s, 4, i_last_pixel );
2442             else
2443             {
2444                 bs_write( s, 4, 0 );
2445                 bs_write( s, 1, 1 );
2446                 bs_write( s, 1, 1 );
2447                 bs_write( s, 2, 0 ); /* pseudo color 0 */
2448             }
2449             i_length--;
2450         }
2451
2452         if( i_length == 2 )
2453         {
2454             if( i_last_pixel )
2455             {
2456                 bs_write( s, 4, i_last_pixel );
2457                 bs_write( s, 4, i_last_pixel );
2458             }
2459             else
2460             {
2461                 bs_write( s, 4, 0 );
2462                 bs_write( s, 1, 1 );
2463                 bs_write( s, 1, 1 );
2464                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
2465             }
2466         }
2467         else if( !i_last_pixel && i_length >= 3 && i_length <= 9 )
2468         {
2469             bs_write( s, 4, 0 );
2470             bs_write( s, 1, 0 );
2471             bs_write( s, 3, i_length - 2 ); /* (i_length - 2) * color 0 */
2472         }
2473         else if( i_length > 2 )
2474         {
2475             bs_write( s, 4, 0 );
2476             bs_write( s, 1, 1 );
2477
2478             if( i_length <= 7 )
2479             {
2480                 bs_write( s, 1, 0 );
2481                 bs_write( s, 2, i_length - 4 );
2482                 bs_write( s, 4, i_last_pixel );
2483             }
2484             else
2485             {
2486                 bs_write( s, 1, 1 );
2487
2488                 if( i_length <= 24 )
2489                 {
2490                     bs_write( s, 2, 2 );
2491                     bs_write( s, 4, i_length - 9 );
2492                     bs_write( s, 4, i_last_pixel );
2493                 }
2494                 else
2495                 {
2496                     bs_write( s, 2, 3 );
2497                     bs_write( s, 8, i_length - 25 );
2498                     bs_write( s, 4, i_last_pixel );
2499                 }
2500             }
2501         }
2502
2503         if( i == p_region->fmt.i_visible_width ) break;
2504
2505         i_last_pixel = p_data[i];
2506         i_length = 1;
2507     }
2508
2509     /* Stop */
2510     bs_write( s, 8, 0 );
2511
2512     /* Stuffing */
2513     bs_align_0( s );
2514 }
2515
2516 static void encode_pixel_line_8bp( encoder_t *p_enc, bs_t *s,
2517                                    subpicture_region_t *p_region,
2518                                    int i_line )
2519 {
2520     unsigned int i, i_length = 0;
2521     int i_pitch = p_region->picture.p->i_pitch;
2522     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
2523     int i_last_pixel = p_data[0];
2524
2525     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2526     {
2527         if( i != p_region->fmt.i_visible_width &&
2528             p_data[i] == i_last_pixel && i_length != 127 )
2529         {
2530             i_length++;
2531             continue;
2532         }
2533
2534         if( i_length == 1 && i_last_pixel )
2535         {
2536             /* 8bit/pixel code */
2537             bs_write( s, 8, i_last_pixel );
2538         }
2539         else if( i_length == 2 && i_last_pixel )
2540         {
2541             /* 8bit/pixel code */
2542             bs_write( s, 8, i_last_pixel );
2543             bs_write( s, 8, i_last_pixel );
2544         }
2545         else if( i_length <= 127 )
2546         {
2547             bs_write( s, 8, 0 );
2548
2549             if( !i_last_pixel )
2550             {
2551                 bs_write( s, 1, 0 );
2552                 bs_write( s, 7, i_length ); /* pseudo color 0 */
2553             }
2554             else
2555             {
2556                 bs_write( s, 1, 1 );
2557                 bs_write( s, 7, i_length );
2558                 bs_write( s, 8, i_last_pixel );
2559             }
2560         }
2561
2562         if( i == p_region->fmt.i_visible_width ) break;
2563
2564         i_last_pixel = p_data[i];
2565         i_length = 1;
2566     }
2567
2568     /* Stop */
2569     bs_write( s, 8, 0 );
2570     bs_write( s, 8, 0 );
2571
2572     /* Stuffing */
2573     bs_align_0( s );
2574 }