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