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