]> git.sesse.net Git - vlc/blob - modules/codec/dvbsub.c
4fecfc3d889f79a423a70a568370a9763b672657
[vlc] / modules / codec / dvbsub.c
1 /*****************************************************************************
2  * dvbsub.c : DVB subtitles decoder
3  *            DVB subtitles encoder (developed for Anevia, www.anevia.com)
4  *****************************************************************************
5  * Copyright (C) 2003 ANEVIA
6  * Copyright (C) 2003-2009 the VideoLAN team
7  * $Id$
8  *
9  * Authors: Gildas Bazin <gbazin@videolan.org>
10  *          Damien LUCAS <damien.lucas@anevia.com>
11  *          Laurent Aimar <fenrir@via.ecp.fr>
12  *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
13  *          Derk-Jan Hartman <hartman #at# videolan dot org>
14  *          Simon Hailes <simon _a_ screen.subtitling.com>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software Foundation, Inc.,
28  * 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 <assert.h>
75
76 #include <vlc_common.h>
77 #include <vlc_plugin.h>
78 #include <vlc_codec.h>
79 #include <vlc_sout.h>
80 #include <vlc_memory.h>
81
82 #include <vlc_bits.h>
83
84 /* #define DEBUG_DVBSUB 1 */
85
86 #define POSX_TEXT N_("Decoding X coordinate")
87 #define POSX_LONGTEXT N_("X coordinate of the rendered subtitle")
88
89 #define POSY_TEXT N_("Decoding Y coordinate")
90 #define POSY_LONGTEXT N_("Y coordinate of the rendered subtitle")
91
92 #define POS_TEXT N_("Subpicture position")
93 #define POS_LONGTEXT N_( \
94   "You can enforce the subpicture position on the video " \
95   "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
96   "also use combinations of these values, e.g. 6=top-right).")
97
98 #define ENC_POSX_TEXT N_("Encoding X coordinate")
99 #define ENC_POSX_LONGTEXT N_("X coordinate of the encoded subtitle" )
100 #define ENC_POSY_TEXT N_("Encoding Y coordinate")
101 #define ENC_POSY_LONGTEXT N_("Y coordinate of the encoded subtitle" )
102
103 static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
104 static const char *const ppsz_pos_descriptions[] =
105 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
106   N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
107
108 /*****************************************************************************
109  * Module descriptor.
110  *****************************************************************************/
111 static int  Open ( vlc_object_t * );
112 static void Close( vlc_object_t * );
113 static subpicture_t *Decode( decoder_t *, block_t ** );
114
115 static int OpenEncoder  ( vlc_object_t * );
116 static void CloseEncoder( vlc_object_t * );
117 static block_t *Encode  ( encoder_t *, subpicture_t * );
118
119 vlc_module_begin ()
120 #   define DVBSUB_CFG_PREFIX "dvbsub-"
121     set_description( N_("DVB subtitles decoder") )
122     set_shortname( N_("DVB subtitles") )
123     set_capability( "decoder", 50 )
124     set_category( CAT_INPUT )
125     set_subcategory( SUBCAT_INPUT_SCODEC )
126     set_callbacks( Open, Close )
127
128     add_integer( DVBSUB_CFG_PREFIX "position", 8, NULL, POS_TEXT, POS_LONGTEXT, true )
129         change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL )
130     add_integer( DVBSUB_CFG_PREFIX "x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, false )
131     add_integer( DVBSUB_CFG_PREFIX "y", -1, NULL, POSY_TEXT, POSY_LONGTEXT, false )
132
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, NULL, ENC_POSX_TEXT, ENC_POSX_LONGTEXT, false )
140     add_integer( ENC_CFG_PREFIX "y", -1, NULL, ENC_POSY_TEXT, ENC_POSY_LONGTEXT, false )
141     add_obsolete_integer( ENC_CFG_PREFIX "timeout" ) /* Suppressed since 0.8.5 */
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          = (mtime_t) 0;
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 <= 0 )
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 ) != 0xff ) /* 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_region_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 = malloc( i_height * i_width );
920         assert( p_region->p_pixbuf );
921         p_region->i_depth = 0;
922         b_fill = true;
923     }
924     if( p_region->i_depth &&
925         ( ( p_region->i_depth != i_depth ) ||
926           ( p_region->i_level_comp != i_level_comp ) ||
927           ( p_region->i_clut != i_clut) ) )
928     {
929         msg_Dbg( p_dec, "region parameters changed (not allowed)" );
930     }
931
932     /* Erase background of region */
933     if( b_fill )
934     {
935         int i_background = ( p_region->i_depth == 1 ) ? i_2_bg :
936             ( ( p_region->i_depth == 2 ) ? i_4_bg : i_8_bg );
937         memset( p_region->p_pixbuf, i_background, i_width * i_height );
938     }
939
940     p_region->i_width = i_width;
941     p_region->i_height = i_height;
942     p_region->i_level_comp = i_level_comp;
943     p_region->i_depth = i_depth;
944     p_region->i_clut = i_clut;
945
946     /* List of objects in the region */
947     i_processed_length = 10;
948     while( i_processed_length < i_segment_length )
949     {
950         dvbsub_objectdef_t *p_obj;
951
952         /* We create a new object */
953         p_region->i_object_defs++;
954         p_region->p_object_defs = realloc_or_free( p_region->p_object_defs,
955                      sizeof(dvbsub_objectdef_t) * p_region->i_object_defs );
956         assert( p_region->p_object_defs );
957
958         /* We parse object properties */
959         p_obj = &p_region->p_object_defs[p_region->i_object_defs - 1];
960         p_obj->i_id         = bs_read( s, 16 );
961         p_obj->i_type       = bs_read( s, 2 );
962         bs_skip( s, 2 ); /* Provider */
963         p_obj->i_x          = bs_read( s, 12 );
964         bs_skip( s, 4 ); /* Reserved */
965         p_obj->i_y          = bs_read( s, 12 );
966         p_obj->psz_text     = NULL;
967
968         i_processed_length += 6;
969
970         if( ( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ) ||
971             ( p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING ) )
972         {
973             p_obj->i_fg_pc =  bs_read( s, 8 );
974             p_obj->i_bg_pc =  bs_read( s, 8 );
975             i_processed_length += 2;
976         }
977     }
978 }
979
980 /* ETSI 300 743 [7.2.1] */
981 static void decode_display_definition( decoder_t *p_dec, bs_t *s )
982 {
983     decoder_sys_t *p_sys = p_dec->p_sys;
984     uint16_t      i_segment_length;
985     uint16_t      i_processed_length = 40;
986     int           i_version;
987
988     i_segment_length = bs_read( s, 16 );
989     i_version        = bs_read( s, 4 );
990
991     /* Check version number */
992     if( p_sys->display.i_version == i_version )
993     {
994         /* The definition did not change */
995         bs_skip( s, 8*i_segment_length - 4 );
996         return;
997     }
998
999 #ifdef DEBUG_DVBSUB
1000     msg_Dbg( p_dec, "new display definition: %i", i_version );
1001 #endif
1002
1003     /* We don't have this version of the display definition: Parse it */
1004     p_sys->display.i_version = i_version;
1005     p_sys->display.b_windowed = bs_read( s, 1 );
1006     bs_skip( s, 3 ); /* Reserved bits */
1007     p_sys->display.i_width = bs_read( s, 16 )+1;
1008     p_sys->display.i_height = bs_read( s, 16 )+1;
1009
1010     if( p_sys->display.b_windowed )
1011     {
1012 #ifdef DEBUG_DVBSUB
1013         msg_Dbg( p_dec, "display definition with offsets (windowed)" );
1014 #endif
1015         /* Coordinates are measured from the top left corner */
1016         p_sys->display.i_x     = bs_read( s, 16 );
1017         p_sys->display.i_max_x = bs_read( s, 16 );
1018         p_sys->display.i_y     = bs_read( s, 16 );
1019         p_sys->display.i_max_y = bs_read( s, 16 );
1020         i_processed_length += 64;
1021     }
1022     else
1023     {
1024         /* if not windowed, setup the window variables to good defaults */
1025         /* not necessary, but to avoid future confusion.. */
1026         p_sys->display.i_x     = 0;
1027         p_sys->display.i_max_x = p_sys->display.i_width-1;
1028         p_sys->display.i_y     = 0;
1029         p_sys->display.i_max_y = p_sys->display.i_height-1;
1030     }
1031
1032     if( i_processed_length != i_segment_length*8 )
1033     {
1034         msg_Err( p_dec, "processed length %d bytes != segment length %d bytes",
1035                  i_processed_length / 8 , i_segment_length );
1036     }
1037
1038 #ifdef DEBUG_DVBSUB
1039     msg_Dbg( p_dec, "version: %d, width: %d, height: %d",
1040              p_sys->display.i_version, p_sys->display.i_width, p_sys->display.i_height );
1041     if( p_sys->display.b_windowed )
1042         msg_Dbg( p_dec, "xmin: %d, xmax: %d, ymin: %d, ymax: %d",
1043                  p_sys->display.i_x, p_sys->display.i_max_x, p_sys->display.i_y, p_sys->display.i_max_y );
1044 #endif
1045 }
1046
1047 static void dvbsub_render_pdata( decoder_t *, dvbsub_region_t *, int, int,
1048                                  uint8_t *, int );
1049 static void dvbsub_pdata2bpp( bs_t *, uint8_t *, int, int * );
1050 static void dvbsub_pdata4bpp( bs_t *, uint8_t *, int, int * );
1051 static void dvbsub_pdata8bpp( bs_t *, uint8_t *, int, int * );
1052
1053 static void decode_object( decoder_t *p_dec, bs_t *s )
1054 {
1055     decoder_sys_t *p_sys = p_dec->p_sys;
1056     dvbsub_region_t *p_region;
1057     int i_segment_length, i_coding_method, i_version, i_id, i;
1058     bool b_non_modify_color;
1059
1060     /* ETSI 300-743 paragraph 7.2.4
1061      * sync_byte, segment_type and page_id have already been processed.
1062      */
1063     i_segment_length = bs_read( s, 16 );
1064     i_id             = bs_read( s, 16 );
1065     i_version        = bs_read( s, 4 );
1066     i_coding_method  = bs_read( s, 2 );
1067
1068     if( i_coding_method > 1 )
1069     {
1070         msg_Dbg( p_dec, "unknown DVB subtitling coding %d is not handled!", i_coding_method );
1071         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
1072         return;
1073     }
1074
1075     /* Check if the object needs to be rendered in at least one
1076      * of the regions */
1077     for( p_region = p_sys->p_regions; p_region != NULL;
1078          p_region = p_region->p_next )
1079     {
1080         for( i = 0; i < p_region->i_object_defs; i++ )
1081             if( p_region->p_object_defs[i].i_id == i_id ) break;
1082
1083         if( i != p_region->i_object_defs ) break;
1084     }
1085     if( !p_region )
1086     {
1087         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
1088         return;
1089     }
1090
1091 #ifdef DEBUG_DVBSUB
1092     msg_Dbg( p_dec, "new object: %i", i_id );
1093 #endif
1094
1095     b_non_modify_color = bs_read( s, 1 );
1096     bs_skip( s, 1 ); /* Reserved */
1097
1098     if( i_coding_method == 0x00 )
1099     {
1100         int i_topfield, i_bottomfield;
1101         uint8_t *p_topfield, *p_bottomfield;
1102
1103         i_topfield    = bs_read( s, 16 );
1104         i_bottomfield = bs_read( s, 16 );
1105         p_topfield    = s->p_start + bs_pos( s ) / 8;
1106         p_bottomfield = p_topfield + i_topfield;
1107
1108         bs_skip( s, 8 * (i_segment_length - 7) );
1109
1110         /* Sanity check */
1111         if( ( i_segment_length < ( i_topfield + i_bottomfield + 7 ) ) ||
1112             ( ( p_topfield + i_topfield + i_bottomfield ) > s->p_end ) )
1113         {
1114             msg_Dbg( p_dec, "corrupted object data" );
1115             return;
1116         }
1117
1118         for( p_region = p_sys->p_regions; p_region != NULL;
1119              p_region = p_region->p_next )
1120         {
1121             for( i = 0; i < p_region->i_object_defs; i++ )
1122             {
1123                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
1124
1125                 dvbsub_render_pdata( p_dec, p_region,
1126                                      p_region->p_object_defs[i].i_x,
1127                                      p_region->p_object_defs[i].i_y,
1128                                      p_topfield, i_topfield );
1129
1130                 if( i_bottomfield )
1131                 {
1132                     dvbsub_render_pdata( p_dec, p_region,
1133                                          p_region->p_object_defs[i].i_x,
1134                                          p_region->p_object_defs[i].i_y + 1,
1135                                          p_bottomfield, i_bottomfield );
1136                 }
1137                 else
1138                 {
1139                     /* Duplicate the top field */
1140                     dvbsub_render_pdata( p_dec, p_region,
1141                                          p_region->p_object_defs[i].i_x,
1142                                          p_region->p_object_defs[i].i_y + 1,
1143                                          p_topfield, i_topfield );
1144                 }
1145             }
1146         }
1147     }
1148     else
1149     {
1150         /* DVB subtitling as characters */
1151         int i_number_of_codes = bs_read( s, 8 );
1152         uint8_t* p_start = s->p_start + bs_pos( s ) / 8;
1153
1154         /* Sanity check */
1155         if( ( i_segment_length < ( i_number_of_codes*2 + 4 ) ) ||
1156             ( ( p_start + i_number_of_codes*2 ) > s->p_end ) )
1157         {
1158             msg_Dbg( p_dec, "corrupted object data" );
1159             return;
1160         }
1161
1162         for( p_region = p_sys->p_regions; p_region != NULL;
1163              p_region = p_region->p_next )
1164         {
1165             for( i = 0; i < p_region->i_object_defs; i++ )
1166             {
1167                 int j;
1168
1169                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
1170
1171                 p_region->p_object_defs[i].psz_text =
1172                     realloc_or_free( p_region->p_object_defs[i].psz_text,
1173                              i_number_of_codes + 1 );
1174                 assert( p_region->p_object_defs[i].psz_text );
1175
1176                 /* FIXME 16bits -> char ??? See Preamble */
1177                 for( j = 0; j < i_number_of_codes; j++ )
1178                 {
1179                     p_region->p_object_defs[i].psz_text[j] = (char)(bs_read( s, 16 ) & 0xFF);
1180                 }
1181                 /* Null terminate the string */
1182                 p_region->p_object_defs[i].psz_text[j] = 0;
1183             }
1184         }
1185     }
1186
1187 #ifdef DEBUG_DVBSUB
1188     msg_Dbg( p_dec, "end object: %i", i_id );
1189 #endif
1190 }
1191
1192 static void dvbsub_render_pdata( decoder_t *p_dec, dvbsub_region_t *p_region,
1193                                  int i_x, int i_y,
1194                                  uint8_t *p_field, int i_field )
1195 {
1196     uint8_t *p_pixbuf;
1197     int i_offset = 0;
1198     bs_t bs;
1199
1200     /* Sanity check */
1201     if( !p_region->p_pixbuf )
1202     {
1203         msg_Err( p_dec, "region %i has no pixel buffer!", p_region->i_id );
1204         return;
1205     }
1206     if( i_y < 0 || i_x < 0 || i_y >= p_region->i_height ||
1207         i_x >= p_region->i_width )
1208     {
1209         msg_Dbg( p_dec, "invalid offset (%i,%i)", i_x, i_y );
1210         return;
1211     }
1212
1213     p_pixbuf = p_region->p_pixbuf + i_y * p_region->i_width;
1214     bs_init( &bs, p_field, i_field );
1215
1216     while( !bs_eof( &bs ) )
1217     {
1218         /* Sanity check */
1219         if( i_y >= p_region->i_height ) return;
1220
1221         switch( bs_read( &bs, 8 ) )
1222         {
1223         case 0x10:
1224             dvbsub_pdata2bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1225                               &i_offset );
1226             break;
1227
1228         case 0x11:
1229             dvbsub_pdata4bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1230                               &i_offset );
1231             break;
1232
1233         case 0x12:
1234             dvbsub_pdata8bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1235                               &i_offset );
1236             break;
1237
1238         case 0x20:
1239         case 0x21:
1240         case 0x22:
1241             /* We don't use map tables */
1242             break;
1243
1244         case 0xf0: /* End of line code */
1245             p_pixbuf += 2*p_region->i_width;
1246             i_offset = 0; i_y += 2;
1247             break;
1248         }
1249     }
1250 }
1251
1252 static void dvbsub_pdata2bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1253 {
1254     bool b_stop = false;
1255
1256     while( !b_stop && !bs_eof( s ) )
1257     {
1258         int i_count = 0, i_color = 0;
1259
1260         i_color = bs_read( s, 2 );
1261         if( i_color != 0x00 )
1262         {
1263             i_count = 1;
1264         }
1265         else
1266         {
1267             if( bs_read( s, 1 ) == 0x01 )         // Switch1
1268             {
1269                 i_count = 3 + bs_read( s, 3 );
1270                 i_color = bs_read( s, 2 );
1271             }
1272             else
1273             {
1274                 if( bs_read( s, 1 ) == 0x00 )     //Switch2
1275                 {
1276                     switch( bs_read( s, 2 ) )     //Switch3
1277                     {
1278                     case 0x00:
1279                         b_stop = true;
1280                         break;
1281                     case 0x01:
1282                         i_count = 2;
1283                         break;
1284                     case 0x02:
1285                         i_count =  12 + bs_read( s, 4 );
1286                         i_color = bs_read( s, 2 );
1287                         break;
1288                     case 0x03:
1289                         i_count =  29 + bs_read( s, 8 );
1290                         i_color = bs_read( s, 2 );
1291                         break;
1292                     default:
1293                         break;
1294                     }
1295                 }
1296                 else
1297                 {
1298                     /* 1 pixel color 0 */
1299                     i_count = 1;
1300                 }
1301             }
1302         }
1303
1304         if( !i_count ) continue;
1305
1306         /* Sanity check */
1307         if( ( i_count + *pi_off ) > i_width ) break;
1308
1309         if( i_count == 1 ) p[*pi_off] = i_color;
1310         else memset( ( p + *pi_off ), i_color, i_count );
1311
1312         (*pi_off) += i_count;
1313     }
1314
1315     bs_align( s );
1316 }
1317
1318 static void dvbsub_pdata4bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1319 {
1320     bool b_stop = false;
1321
1322     while( !b_stop && !bs_eof( s ) )
1323     {
1324         int i_count = 0, i_color = 0;
1325
1326         i_color = bs_read( s, 4 );
1327         if( i_color != 0x00 )
1328         {
1329             /* Add 1 pixel */
1330             i_count = 1;
1331         }
1332         else
1333         {
1334             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1335             {
1336                 if( bs_show( s, 3 ) != 0x00 )
1337                 {
1338                     i_count = 2 + bs_read( s, 3 );
1339                 }
1340                 else
1341                 {
1342                     bs_skip( s, 3 );
1343                     b_stop = true;
1344                 }
1345             }
1346             else
1347             {
1348                 if( bs_read( s, 1 ) == 0x00)        //Switch2
1349                 {
1350                     i_count =  4 + bs_read( s, 2 );
1351                     i_color = bs_read( s, 4 );
1352                 }
1353                 else
1354                 {
1355                     switch ( bs_read( s, 2 ) )     //Switch3
1356                     {
1357                     case 0x0:
1358                         i_count = 1;
1359                         break;
1360                     case 0x1:
1361                         i_count = 2;
1362                         break;
1363                     case 0x2:
1364                         i_count = 9 + bs_read( s, 4 );
1365                         i_color = bs_read( s, 4 );
1366                         break;
1367                     case 0x3:
1368                         i_count= 25 + bs_read( s, 8 );
1369                         i_color = bs_read( s, 4 );
1370                         break;
1371                     }
1372                 }
1373             }
1374         }
1375
1376         if( !i_count ) continue;
1377
1378         /* Sanity check */
1379         if( ( i_count + *pi_off ) > i_width ) break;
1380
1381         if( i_count == 1 ) p[*pi_off] = i_color;
1382         else memset( ( p + *pi_off ), i_color, i_count );
1383
1384         (*pi_off) += i_count;
1385     }
1386
1387     bs_align( s );
1388 }
1389
1390 static void dvbsub_pdata8bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1391 {
1392     bool b_stop = false;
1393
1394     while( !b_stop && !bs_eof( s ) )
1395     {
1396         int i_count = 0, i_color = 0;
1397
1398         i_color = bs_read( s, 8 );
1399         if( i_color != 0x00 )
1400         {
1401             /* Add 1 pixel */
1402             i_count = 1;
1403         }
1404         else
1405         {
1406             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1407             {
1408                 if( bs_show( s, 7 ) != 0x00 )
1409                 {
1410                     i_count = bs_read( s, 7 );
1411                 }
1412                 else
1413                 {
1414                     bs_skip( s, 7 );
1415                     b_stop = true;
1416                 }
1417             }
1418             else
1419             {
1420                 i_count = bs_read( s, 7 );
1421                 i_color = bs_read( s, 8 );
1422             }
1423         }
1424
1425         if( !i_count ) continue;
1426
1427         /* Sanity check */
1428         if( ( i_count + *pi_off ) > i_width ) break;
1429
1430         if( i_count == 1 ) p[*pi_off] = i_color;
1431         else memset( ( p + *pi_off ), i_color, i_count );
1432
1433         (*pi_off) += i_count;
1434     }
1435
1436     bs_align( s );
1437 }
1438
1439 static void free_all( decoder_t *p_dec )
1440 {
1441     decoder_sys_t *p_sys = p_dec->p_sys;
1442     dvbsub_region_t *p_reg, *p_reg_next;
1443     dvbsub_clut_t *p_clut, *p_clut_next;
1444
1445     /*free( p_sys->p_display ); No longer malloced */
1446
1447     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut_next )
1448     {
1449         p_clut_next = p_clut->p_next;
1450         free( p_clut );
1451     }
1452     p_sys->p_cluts = NULL;
1453
1454     for( p_reg = p_sys->p_regions; p_reg != NULL; p_reg = p_reg_next )
1455     {
1456         int i;
1457
1458         p_reg_next = p_reg->p_next;
1459         for( i = 0; i < p_reg->i_object_defs; i++ )
1460             free( p_reg->p_object_defs[i].psz_text );
1461         if( p_reg->i_object_defs ) free( p_reg->p_object_defs );
1462         free( p_reg->p_pixbuf );
1463         free( p_reg );
1464     }
1465     p_sys->p_regions = NULL;
1466
1467     if( p_sys->p_page )
1468     {
1469         if( p_sys->p_page->i_region_defs )
1470             free( p_sys->p_page->p_region_defs );
1471         free( p_sys->p_page );
1472     }
1473     p_sys->p_page = NULL;
1474 }
1475
1476 static subpicture_t *render( decoder_t *p_dec )
1477 {
1478     decoder_sys_t *p_sys = p_dec->p_sys;
1479     subpicture_t *p_spu;
1480     subpicture_region_t **pp_spu_region;
1481     int i, j, i_timeout = 0;
1482     int i_base_x;
1483     int i_base_y;
1484
1485     /* Allocate the subpicture internal data. */
1486     p_spu = decoder_NewSubpicture( p_dec );
1487     if( !p_spu )
1488         return NULL;
1489
1490     p_spu->b_absolute = p_sys->b_absolute;
1491     /* Set the pf_render callback */
1492     p_spu->i_start = (mtime_t) p_sys->i_pts;
1493     //p_spu->i_stop = (mtime_t) 0;
1494     p_spu->b_ephemer = true;
1495     //p_spu->b_fade = true;
1496     //p_spu->i_stop = p_spu->i_start + (mtime_t) (i_timeout * 1000000);
1497
1498     /* Correct positioning of SPU */
1499     i_base_x = p_sys->i_spu_x;
1500     i_base_y = p_sys->i_spu_y;
1501     p_spu->i_original_picture_width = 720;
1502     p_spu->i_original_picture_height = 576;
1503
1504     p_spu->i_original_picture_width = p_sys->display.i_width;
1505     p_spu->i_original_picture_height = p_sys->display.i_height;
1506
1507     if( p_sys->display.b_windowed )
1508     {
1509         /* From en_300743v01 - */
1510         /* the DDS is there to indicate intended size/position of text */
1511         /* the intended video area is ->i_width/height */
1512         /* the window is within this... SO... we should leave i_original_picture_width etc. as is */
1513         /* and ONLY change i_base_x.  effectively i_max_x/y are only there to limit memory requirements*/
1514         /* we COULD use the upper limits to limit rendering to within these? */
1515
1516         /* see notes on DDS at the top of the file */
1517         i_base_x += p_sys->display.i_x;
1518         i_base_y += p_sys->display.i_y;
1519     }
1520
1521     pp_spu_region = &p_spu->p_region;
1522
1523     /* Loop on region definitions */
1524 #ifdef DEBUG_DVBSUB
1525     if( p_sys->p_page )
1526         msg_Dbg( p_dec, "rendering %i regions", p_sys->p_page->i_region_defs );
1527 #endif
1528
1529     for( i = 0; p_sys->p_page && ( i < p_sys->p_page->i_region_defs ); i++ )
1530     {
1531         dvbsub_region_t     *p_region;
1532         dvbsub_regiondef_t  *p_regiondef;
1533         dvbsub_clut_t       *p_clut;
1534         dvbsub_color_t      *p_color;
1535         subpicture_region_t *p_spu_region;
1536         uint8_t *p_src, *p_dst;
1537         video_format_t fmt;
1538         video_palette_t palette;
1539         int i_pitch;
1540
1541         i_timeout = p_sys->p_page->i_timeout;
1542
1543         p_regiondef = &p_sys->p_page->p_region_defs[i];
1544
1545         /* Find associated region */
1546         for( p_region = p_sys->p_regions; p_region != NULL;
1547              p_region = p_region->p_next )
1548         {
1549             if( p_regiondef->i_id == p_region->i_id ) break;
1550         }
1551
1552 #ifdef DEBUG_DVBSUB
1553         /* if a region exists, then print it's size */
1554         if (p_region)
1555         {
1556                 msg_Dbg( p_dec, "rendering region %i (%i,%i) to (%i,%i)", i,
1557                         p_regiondef->i_x, p_regiondef->i_y,
1558                 p_regiondef->i_x + p_region->i_width,
1559                 p_regiondef->i_y + p_region->i_height );
1560         }
1561         else
1562         {
1563                 msg_Dbg( p_dec, "rendering region %i (%i,%i) (no region matched to render)", i,
1564                       p_regiondef->i_x, p_regiondef->i_y );
1565         }
1566 #endif
1567
1568         if( !p_region )
1569         {
1570             msg_Dbg( p_dec, "region %i not found", p_regiondef->i_id );
1571             continue;
1572         }
1573
1574         /* Find associated CLUT */
1575         for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
1576         {
1577             if( p_region->i_clut == p_clut->i_id ) break;
1578         }
1579         if( !p_clut )
1580         {
1581             msg_Dbg( p_dec, "clut %i not found", p_region->i_clut );
1582             continue;
1583         }
1584
1585         /* FIXME: don't create a subpicture region with VLC CODEC YUVP
1586          * when it actually is a TEXT region */
1587
1588         /* Create new SPU region */
1589         memset( &fmt, 0, sizeof(video_format_t) );
1590         fmt.i_chroma = VLC_CODEC_YUVP;
1591         fmt.i_aspect = 0; /* 0 means use aspect ratio of background video */
1592         fmt.i_width = fmt.i_visible_width = p_region->i_width;
1593         fmt.i_height = fmt.i_visible_height = p_region->i_height;
1594         fmt.i_x_offset = fmt.i_y_offset = 0;
1595         fmt.p_palette = &palette;
1596         fmt.p_palette->i_entries = ( p_region->i_depth == 1 ) ? 4 :
1597             ( ( p_region->i_depth == 2 ) ? 16 : 256 );
1598         p_color = ( p_region->i_depth == 1 ) ? p_clut->c_2b :
1599             ( ( p_region->i_depth == 2 ) ? p_clut->c_4b : p_clut->c_8b );
1600         for( j = 0; j < fmt.p_palette->i_entries; j++ )
1601         {
1602             fmt.p_palette->palette[j][0] = p_color[j].Y;
1603             fmt.p_palette->palette[j][1] = p_color[j].Cb; /* U == Cb */
1604             fmt.p_palette->palette[j][2] = p_color[j].Cr; /* V == Cr */
1605             fmt.p_palette->palette[j][3] = 0xff - p_color[j].T;
1606         }
1607
1608         p_spu_region = subpicture_region_New( &fmt );
1609         if( !p_spu_region )
1610         {
1611             msg_Err( p_dec, "cannot allocate SPU region" );
1612             continue;
1613         }
1614         p_spu_region->i_x = i_base_x + p_regiondef->i_x;
1615         p_spu_region->i_y = i_base_y + p_regiondef->i_y;
1616         p_spu_region->i_align = p_sys->i_spu_position;
1617         *pp_spu_region = p_spu_region;
1618         pp_spu_region = &p_spu_region->p_next;
1619
1620         p_src = p_region->p_pixbuf;
1621         p_dst = p_spu_region->p_picture->Y_PIXELS;
1622         i_pitch = p_spu_region->p_picture->Y_PITCH;
1623
1624         /* Copy pixel buffer */
1625         for( j = 0; j < p_region->i_height; j++ )
1626         {
1627             memcpy( p_dst, p_src, p_region->i_width );
1628             p_src += p_region->i_width;
1629             p_dst += i_pitch;
1630         }
1631
1632         /* Check subtitles encoded as strings of characters
1633          * (since there are not rendered in the pixbuffer) */
1634         for( j = 0; j < p_region->i_object_defs; j++ )
1635         {
1636             dvbsub_objectdef_t *p_object_def = &p_region->p_object_defs[j];
1637
1638             if( ( p_object_def->i_type != 1 ) || !p_object_def->psz_text )
1639                 continue;
1640
1641             /* Create new SPU region */
1642             memset( &fmt, 0, sizeof(video_format_t) );
1643             fmt.i_chroma = VLC_CODEC_TEXT;
1644             fmt.i_aspect = VOUT_ASPECT_FACTOR;
1645             fmt.i_width = fmt.i_visible_width = p_region->i_width;
1646             fmt.i_height = fmt.i_visible_height = p_region->i_height;
1647             fmt.i_x_offset = fmt.i_y_offset = 0;
1648             p_spu_region = subpicture_region_New( &fmt );
1649             if( !p_region )
1650             {
1651                 msg_Err( p_dec, "cannot allocate SPU region" );
1652                 continue;
1653             }
1654
1655             p_spu_region->psz_text = strdup( p_object_def->psz_text );
1656             p_spu_region->i_x = i_base_x + p_regiondef->i_x + p_object_def->i_x;
1657             p_spu_region->i_y = i_base_y + p_regiondef->i_y + p_object_def->i_y;
1658             p_spu_region->i_align = p_sys->i_spu_position;
1659             *pp_spu_region = p_spu_region;
1660             pp_spu_region = &p_spu_region->p_next;
1661         }
1662     }
1663
1664     return p_spu;
1665 }
1666
1667 /*****************************************************************************
1668  * encoder_sys_t : encoder descriptor
1669  *****************************************************************************/
1670 typedef struct encoder_region_t
1671 {
1672     int i_width;
1673     int i_height;
1674
1675 } encoder_region_t;
1676
1677 struct encoder_sys_t
1678 {
1679     unsigned int i_page_ver;
1680     unsigned int i_region_ver;
1681     unsigned int i_clut_ver;
1682
1683     int i_regions;
1684     encoder_region_t *p_regions;
1685
1686     mtime_t i_pts;
1687
1688     /* subpicture positioning */
1689     int i_offset_x;
1690     int i_offset_y;
1691 };
1692
1693 static void encode_page_composition( encoder_t *, bs_t *, subpicture_t * );
1694 static void encode_clut( encoder_t *, bs_t *, subpicture_t * );
1695 static void encode_region_composition( encoder_t *, bs_t *, subpicture_t * );
1696 static void encode_object( encoder_t *, bs_t *, subpicture_t * );
1697
1698 /*****************************************************************************
1699  * OpenEncoder: probe the encoder and return score
1700  *****************************************************************************/
1701 static int OpenEncoder( vlc_object_t *p_this )
1702 {
1703     encoder_t *p_enc = (encoder_t *)p_this;
1704     encoder_sys_t *p_sys;
1705
1706     if( ( p_enc->fmt_out.i_codec != VLC_CODEC_DVBS ) &&
1707         !p_enc->b_force )
1708     {
1709         return VLC_EGENERIC;
1710     }
1711
1712     /* Allocate the memory needed to store the decoder's structure */
1713     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
1714         return VLC_ENOMEM;
1715     p_enc->p_sys = p_sys;
1716
1717     p_enc->pf_encode_sub = Encode;
1718     p_enc->fmt_out.i_codec = VLC_CODEC_DVBS;
1719     p_enc->fmt_out.subs.dvb.i_id  = 1 << 16 | 1;
1720
1721     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
1722
1723     p_sys->i_page_ver = 0;
1724     p_sys->i_region_ver = 0;
1725     p_sys->i_clut_ver = 0;
1726     p_sys->i_regions = 0;
1727     p_sys->p_regions = 0;
1728
1729     p_sys->i_offset_x = var_CreateGetInteger( p_this, ENC_CFG_PREFIX "x" );
1730     p_sys->i_offset_y = var_CreateGetInteger( p_this, ENC_CFG_PREFIX "y" );
1731
1732     return VLC_SUCCESS;
1733 }
1734
1735 /* FIXME: this routine is a hack to convert VLC_CODEC_YUVA
1736  *        into VLC_CODEC_YUVP
1737  */
1738 static subpicture_t *YuvaYuvp( subpicture_t *p_subpic )
1739 {
1740     subpicture_region_t *p_region = NULL;
1741
1742     if( !p_subpic ) return NULL;
1743
1744     for( p_region = p_subpic->p_region; p_region; p_region = p_region->p_next )
1745     {
1746         video_format_t *p_fmt = &p_region->fmt;
1747         int i = 0, j = 0, n = 0, p = 0;
1748         int i_max_entries = 256;
1749
1750 #ifdef RANDOM_DITHERING
1751         int i_seed = 0xdeadbeef; /* random seed */
1752 #else
1753         int *pi_delta;
1754 #endif
1755         int i_pixels = p_region->p_picture->p[0].i_visible_lines
1756                         * p_region->p_picture->p[0].i_pitch;
1757         int i_iterator = p_region->p_picture->p[0].i_visible_lines * 3 / 4
1758                             * p_region->p_picture->p[0].i_pitch
1759                         + p_region->p_picture->p[0].i_pitch * 1 / 3;
1760         int i_tolerance = 0;
1761
1762 #ifdef DEBUG_DVBSUB1
1763         /* p_enc not valid here */
1764         msg_Dbg( p_enc, "YuvaYuvp: i_pixels=%d, i_iterator=%d", i_pixels, i_iterator );
1765 #endif
1766         p_fmt->i_chroma = VLC_CODEC_YUVP;
1767         p_fmt->p_palette = (video_palette_t *) malloc( sizeof( video_palette_t ) );
1768         if( !p_fmt->p_palette ) break;
1769         p_fmt->p_palette->i_entries = 0;
1770
1771         /* Find best iterator using Euclide’s algorithm */
1772         for( ; i_iterator > 1 ; i_iterator-- )
1773         {
1774             int a = i_pixels;
1775             int b = i_iterator;
1776             int c;
1777
1778             while( b )
1779             {
1780                 c = a % b;
1781                 a = b;
1782                 b = c;
1783             }
1784
1785             if( a == 1 )
1786             {
1787                 break;
1788             }
1789         }
1790
1791         /* Count colors, build best palette */
1792         for( i_tolerance = 0; i_tolerance < 128; i_tolerance++ )
1793         {
1794             bool b_success = true;
1795             p_fmt->p_palette->i_entries = 0;
1796
1797             for( i = 0; i < i_pixels ; )
1798             {
1799                 uint8_t y, u, v, a;
1800                 y = p_region->p_picture->p[0].p_pixels[i];
1801                 u = p_region->p_picture->p[1].p_pixels[i];
1802                 v = p_region->p_picture->p[2].p_pixels[i];
1803                 a = p_region->p_picture->p[3].p_pixels[i];
1804                 for( j = 0; j < p_fmt->p_palette->i_entries; j++ )
1805                 {
1806                     if( abs((int)p_fmt->p_palette->palette[j][0] - (int)y) <= i_tolerance &&
1807                         abs((int)p_fmt->p_palette->palette[j][1] - (int)u) <= i_tolerance &&
1808                         abs((int)p_fmt->p_palette->palette[j][2] - (int)v) <= i_tolerance &&
1809                         abs((int)p_fmt->p_palette->palette[j][3] - (int)a) <= i_tolerance / 2 )
1810                     {
1811                         break;
1812                     }
1813                 }
1814                 if( j == p_fmt->p_palette->i_entries )
1815                 {
1816                     p_fmt->p_palette->palette[j][0] = y;
1817                     p_fmt->p_palette->palette[j][1] = u;
1818                     p_fmt->p_palette->palette[j][2] = v;
1819                     p_fmt->p_palette->palette[j][3] = a;
1820                     p_fmt->p_palette->i_entries++;
1821                 }
1822                 if( p_fmt->p_palette->i_entries >= i_max_entries )
1823                 {
1824                     b_success = false;
1825                     break;
1826                 }
1827                 i += i_iterator;
1828                 if( i > i_pixels )
1829                 {
1830                     i -= i_pixels;
1831                 }
1832             }
1833
1834             if( b_success )
1835             {
1836                 break;
1837             }
1838         }
1839
1840 #ifdef DEBUG_DVBSUB1
1841         /* p_enc not valid here */
1842         msg_Dbg( p_enc, "best palette has %d colors", p_fmt->p_palette->i_entries );
1843 #endif
1844
1845 #ifndef RANDOM_DITHERING
1846         pi_delta = malloc( ( p_region->p_picture->p[0].i_pitch + 1 )
1847                             * sizeof(int) * 4  );
1848         assert( pi_delta );
1849         for( i = 0; i < (p_region->p_picture->p[0].i_pitch + 1) * 4 ; i++ )
1850         {
1851             pi_delta[ i ] = 0;
1852         }
1853 #endif
1854
1855         /* Fill image with our new colours */
1856         for( p = 0; p < p_region->p_picture->p[0].i_visible_lines ; p++ )
1857         {
1858             int i_ydelta = 0, i_udelta = 0, i_vdelta = 0, i_adelta = 0;
1859
1860             for( n = 0; n < p_region->p_picture->p[0].i_pitch ; n++ )
1861             {
1862                 int i_offset = p * p_region->p_picture->p[0].i_pitch + n;
1863                 int y, u, v, a;
1864                 int i_mindist, i_best;
1865
1866                 y = (int)p_region->p_picture->p[0].p_pixels[i_offset];
1867                 u = (int)p_region->p_picture->p[1].p_pixels[i_offset];
1868                 v = (int)p_region->p_picture->p[2].p_pixels[i_offset];
1869                 a = (int)p_region->p_picture->p[3].p_pixels[i_offset];
1870
1871                 /* Add dithering compensation */
1872 #ifdef RANDOM_DITHERING
1873                 y += ((i_seed & 0xff) - 0x80) * i_tolerance / 0x80;
1874                 u += (((i_seed >> 8) & 0xff) - 0x80) * i_tolerance / 0x80;
1875                 v += (((i_seed >> 16) & 0xff) - 0x80) * i_tolerance / 0x80;
1876                 a += (((i_seed >> 24) & 0xff) - 0x80) * i_tolerance / 0x80;
1877 #else
1878                 y += i_ydelta + pi_delta[ n * 4 ];
1879                 u += i_udelta + pi_delta[ n * 4 + 1 ];
1880                 v += i_vdelta + pi_delta[ n * 4 + 2 ];
1881                 a += i_adelta + pi_delta[ n * 4 + 3 ];
1882 #endif
1883
1884                 /* Find best colour in palette */
1885                 for( i_mindist = 99999999, i_best = 0, j = 0; j < p_fmt->p_palette->i_entries; j++ )
1886                 {
1887                     int i_dist = 0;
1888
1889                     i_dist += abs((int)p_fmt->p_palette->palette[j][0] - y);
1890                     i_dist += abs((int)p_fmt->p_palette->palette[j][1] - u);
1891                     i_dist += abs((int)p_fmt->p_palette->palette[j][2] - v);
1892                     i_dist += 2 * abs((int)p_fmt->p_palette->palette[j][3] - a);
1893
1894                     if( i_dist < i_mindist )
1895                     {
1896                         i_mindist = i_dist;
1897                         i_best = j;
1898                     }
1899                 }
1900
1901                 /* Set pixel to best color */
1902                 p_region->p_picture->p[0].p_pixels[i_offset] = i_best;
1903
1904                 /* Update dithering state */
1905 #ifdef RANDOM_DITHERING
1906                 i_seed = (i_seed * 0x1283837) ^ 0x789479 ^ (i_seed >> 13);
1907 #else
1908                 i_ydelta = y - (int)p_fmt->p_palette->palette[i_best][0];
1909                 i_udelta = u - (int)p_fmt->p_palette->palette[i_best][1];
1910                 i_vdelta = v - (int)p_fmt->p_palette->palette[i_best][2];
1911                 i_adelta = a - (int)p_fmt->p_palette->palette[i_best][3];
1912                 pi_delta[ n * 4 ] = i_ydelta * 3 / 8;
1913                 pi_delta[ n * 4 + 1 ] = i_udelta * 3 / 8;
1914                 pi_delta[ n * 4 + 2 ] = i_vdelta * 3 / 8;
1915                 pi_delta[ n * 4 + 3 ] = i_adelta * 3 / 8;
1916                 i_ydelta = i_ydelta * 5 / 8;
1917                 i_udelta = i_udelta * 5 / 8;
1918                 i_vdelta = i_vdelta * 5 / 8;
1919                 i_adelta = i_adelta * 5 / 8;
1920 #endif
1921             }
1922         }
1923 #ifndef RANDOM_DITHERING
1924         free( pi_delta );
1925 #endif
1926
1927         /* pad palette */
1928         for( i = p_fmt->p_palette->i_entries; i < i_max_entries; i++ )
1929         {
1930             p_fmt->p_palette->palette[i][0] = 0;
1931             p_fmt->p_palette->palette[i][1] = 0;
1932             p_fmt->p_palette->palette[i][2] = 0;
1933             p_fmt->p_palette->palette[i][3] = 0;
1934         }
1935         p_fmt->p_palette->i_entries = i_max_entries;
1936 #ifdef DEBUG_DVBSUB1
1937         /* p_enc not valid here */
1938         msg_Dbg( p_enc, "best palette has %d colors", p_fmt->p_palette->i_entries );
1939 #endif
1940     }
1941     return p_subpic;
1942 } /* End of hack */
1943
1944 /****************************************************************************
1945  * Encode: the whole thing
1946  ****************************************************************************/
1947 static block_t *Encode( encoder_t *p_enc, subpicture_t *p_subpic )
1948 {
1949     subpicture_t *p_temp = NULL;
1950     subpicture_region_t *p_region = NULL;
1951     bs_t bits, *s = &bits;
1952     block_t *p_block;
1953
1954     if( !p_subpic || !p_subpic->p_region ) return NULL;
1955
1956     /* FIXME: this is a hack to convert VLC_CODEC_YUVA into
1957      *  VLC_CODEC_YUVP
1958      */
1959     p_region = p_subpic->p_region;
1960     if( p_region->fmt.i_chroma == VLC_CODEC_YUVA )
1961     {
1962         p_temp = YuvaYuvp( p_subpic );
1963         if( !p_temp )
1964         {
1965             msg_Err( p_enc, "no picture in subpicture" );
1966             return NULL;
1967         }
1968         p_region = p_subpic->p_region;
1969     }
1970
1971     /* Sanity check */
1972     if( !p_region ) return NULL;
1973
1974     if( ( p_region->fmt.i_chroma != VLC_CODEC_TEXT ) &&
1975         ( p_region->fmt.i_chroma != VLC_CODEC_YUVP ) )
1976     {
1977         char psz_fourcc[5];
1978         memset( &psz_fourcc, 0, sizeof( psz_fourcc ) );
1979         vlc_fourcc_to_char( p_region->fmt.i_chroma, &psz_fourcc );
1980         msg_Err( p_enc, "chroma %4s not supported", psz_fourcc );
1981         return NULL;
1982     }
1983
1984     if( p_region->fmt.p_palette )
1985     {
1986         switch( p_region->fmt.p_palette->i_entries )
1987         {
1988             case 0:
1989             case 4:
1990             case 16:
1991             case 256:
1992                 break;
1993             default:
1994                 msg_Err( p_enc, "subpicture palette (%d) not handled",
1995                             p_region->fmt.p_palette->i_entries );
1996                 return NULL;
1997         }
1998     }
1999     /* End of hack */
2000
2001 #ifdef DEBUG_DVBSUB
2002     msg_Dbg( p_enc, "encoding subpicture" );
2003 #endif
2004     p_block = block_New( p_enc, 64000 );
2005     bs_init( s, p_block->p_buffer, p_block->i_buffer );
2006
2007     bs_write( s, 8, 0x20 ); /* Data identifier */
2008     bs_write( s, 8, 0x0 );  /* Subtitle stream id */
2009
2010     encode_page_composition( p_enc, s, p_subpic );
2011     encode_region_composition( p_enc, s, p_subpic );
2012     encode_clut( p_enc, s, p_subpic );
2013     encode_object( p_enc, s, p_subpic );
2014
2015     /* End of display */
2016     bs_write( s, 8, 0x0f ); /* Sync byte */
2017     bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
2018     bs_write( s, 16, 1 );  /* Page id */
2019     bs_write( s, 16, 0 );  /* Segment length */
2020
2021     bs_write( s, 8, 0xff );/* End marker */
2022     p_block->i_buffer = bs_pos( s ) / 8;
2023     p_block->i_pts = p_block->i_dts = p_subpic->i_start;
2024     if( !p_subpic->b_ephemer && ( p_subpic->i_stop > p_subpic->i_start ) )
2025     {
2026         block_t *p_block_stop;
2027
2028         p_block->i_length = p_subpic->i_stop - p_subpic->i_start;
2029
2030         /* Send another (empty) subtitle to signal the end of display */
2031         p_block_stop = block_New( p_enc, 64000 );
2032         bs_init( s, p_block_stop->p_buffer, p_block_stop->i_buffer );
2033         bs_write( s, 8, 0x20 ); /* Data identifier */
2034         bs_write( s, 8, 0x0 );  /* Subtitle stream id */
2035         encode_page_composition( p_enc, s, 0 );
2036         bs_write( s, 8, 0x0f ); /* Sync byte */
2037         bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
2038         bs_write( s, 16, 1 );  /* Page id */
2039         bs_write( s, 16, 0 );  /* Segment length */
2040         bs_write( s, 8, 0xff );/* End marker */
2041         p_block_stop->i_buffer = bs_pos( s ) / 8;
2042         p_block_stop->i_pts = p_block_stop->i_dts = p_subpic->i_stop;
2043         block_ChainAppend( &p_block, p_block_stop );
2044         p_block_stop->i_length = 100000; /* p_subpic->i_stop - p_subpic->i_start; */
2045     }
2046 #ifdef DEBUG_DVBSUB
2047     msg_Dbg( p_enc, "subpicture encoded properly" );
2048 #endif
2049     return p_block;
2050 }
2051
2052 /*****************************************************************************
2053  * CloseEncoder: encoder destruction
2054  *****************************************************************************/
2055 static void CloseEncoder( vlc_object_t *p_this )
2056 {
2057     encoder_t *p_enc = (encoder_t *)p_this;
2058     encoder_sys_t *p_sys = p_enc->p_sys;
2059
2060     var_Destroy( p_this , ENC_CFG_PREFIX "x" );
2061     var_Destroy( p_this , ENC_CFG_PREFIX "y" );
2062     var_Destroy( p_this , ENC_CFG_PREFIX "timeout" );
2063
2064     if( p_sys->i_regions ) free( p_sys->p_regions );
2065     free( p_sys );
2066 }
2067
2068 static void encode_page_composition( encoder_t *p_enc, bs_t *s,
2069                                      subpicture_t *p_subpic )
2070 {
2071     encoder_sys_t *p_sys = p_enc->p_sys;
2072     subpicture_region_t *p_region;
2073     bool b_mode_change = false;
2074     int i_regions, i_timeout;
2075
2076     bs_write( s, 8, 0x0f ); /* Sync byte */
2077     bs_write( s, 8, DVBSUB_ST_PAGE_COMPOSITION ); /* Segment type */
2078     bs_write( s, 16, 1 ); /* Page id */
2079
2080     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
2081          p_region; p_region = p_region->p_next, i_regions++ )
2082     {
2083         if( i_regions >= p_sys->i_regions )
2084         {
2085             encoder_region_t region;
2086             region.i_width = region.i_height = 0;
2087             p_sys->p_regions = realloc_or_free( p_sys->p_regions,
2088                           sizeof(encoder_region_t) * (p_sys->i_regions + 1) );
2089             assert( p_sys->p_regions );
2090             p_sys->p_regions[p_sys->i_regions++] = region;
2091         }
2092
2093         if( ( p_sys->p_regions[i_regions].i_width <
2094               (int)p_region->fmt.i_visible_width ) ||
2095             ( p_sys->p_regions[i_regions].i_width >
2096               (int)p_region->fmt.i_visible_width ) )
2097         {
2098             b_mode_change = true;
2099             msg_Dbg( p_enc, "region %i width change: %i -> %i",
2100                      i_regions, p_sys->p_regions[i_regions].i_width,
2101                      p_region->fmt.i_visible_width );
2102             p_sys->p_regions[i_regions].i_width =
2103                 p_region->fmt.i_visible_width;
2104         }
2105         if( p_sys->p_regions[i_regions].i_height <
2106              (int)p_region->fmt.i_visible_height )
2107         {
2108             b_mode_change = true;
2109             msg_Dbg( p_enc, "region %i height change: %i -> %i",
2110                      i_regions, p_sys->p_regions[i_regions].i_height,
2111                      p_region->fmt.i_visible_height );
2112             p_sys->p_regions[i_regions].i_height =
2113                 p_region->fmt.i_visible_height;
2114         }
2115     }
2116
2117     bs_write( s, 16, i_regions * 6 + 2 ); /* Segment length */
2118
2119     i_timeout = 0;
2120     if( p_subpic && !p_subpic->b_ephemer &&
2121         ( p_subpic->i_stop > p_subpic->i_start ) )
2122     {
2123         i_timeout = (p_subpic->i_stop - p_subpic->i_start) / 1000000;
2124     }
2125
2126     bs_write( s, 8, i_timeout ); /* Timeout */
2127     bs_write( s, 4, p_sys->i_page_ver++ );
2128     bs_write( s, 2, b_mode_change ?
2129               DVBSUB_PCS_STATE_CHANGE : DVBSUB_PCS_STATE_ACQUISITION );
2130     bs_write( s, 2, 0 ); /* Reserved */
2131
2132     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
2133          p_region; p_region = p_region->p_next, i_regions++ )
2134     {
2135         bs_write( s, 8, i_regions );
2136         bs_write( s, 8, 0 ); /* Reserved */
2137         if( (p_sys->i_offset_x > 0) && (p_sys->i_offset_y > 0) )
2138         {
2139             bs_write( s, 16, p_sys->i_offset_x ); /* override x position */
2140             bs_write( s, 16, p_sys->i_offset_y ); /* override y position */
2141         }
2142         else
2143         {
2144             bs_write( s, 16, p_region->i_x );
2145             bs_write( s, 16, p_region->i_y );
2146         }
2147     }
2148 }
2149
2150 static void encode_clut( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
2151 {
2152     encoder_sys_t *p_sys = p_enc->p_sys;
2153     subpicture_region_t *p_region = p_subpic->p_region;
2154     video_palette_t *p_pal, pal;
2155     int i;
2156
2157     /* Sanity check */
2158     if( !p_region ) return;
2159
2160     if( p_region->fmt.i_chroma == VLC_CODEC_YUVP )
2161     {
2162         p_pal = p_region->fmt.p_palette;
2163     }
2164     else
2165     {
2166         pal.i_entries = 4;
2167         for( i = 0; i < 4; i++ )
2168         {
2169             pal.palette[i][0] = 0;
2170             pal.palette[i][1] = 0;
2171             pal.palette[i][2] = 0;
2172             pal.palette[i][3] = 0;
2173         }
2174         p_pal = &pal;
2175     }
2176
2177     bs_write( s, 8, 0x0f ); /* Sync byte */
2178     bs_write( s, 8, DVBSUB_ST_CLUT_DEFINITION ); /* Segment type */
2179     bs_write( s, 16, 1 );  /* Page id */
2180
2181     bs_write( s, 16, p_pal->i_entries * 6 + 2 ); /* Segment length */
2182     bs_write( s, 8, 1 ); /* Clut id */
2183     bs_write( s, 4, p_sys->i_clut_ver++ );
2184     bs_write( s, 4, 0 ); /* Reserved */
2185
2186     for( i = 0; i < p_pal->i_entries; i++ )
2187     {
2188         bs_write( s, 8, i ); /* Clut entry id */
2189         bs_write( s, 1, p_pal->i_entries == 4 );   /* 2bit/entry flag */
2190         bs_write( s, 1, p_pal->i_entries == 16 );  /* 4bit/entry flag */
2191         bs_write( s, 1, p_pal->i_entries == 256 ); /* 8bit/entry flag */
2192         bs_write( s, 4, 0 ); /* Reserved */
2193         bs_write( s, 1, 1 ); /* Full range flag */
2194         bs_write( s, 8, p_pal->palette[i][3] ?  /* Y value */
2195                   (p_pal->palette[i][0] ? p_pal->palette[i][0] : 16) : 0 );
2196         bs_write( s, 8, p_pal->palette[i][1] ); /* Cr value */
2197         bs_write( s, 8, p_pal->palette[i][2] ); /* Cb value */
2198         bs_write( s, 8, 0xff - p_pal->palette[i][3] ); /* T value */
2199     }
2200 }
2201
2202 static void encode_region_composition( encoder_t *p_enc, bs_t *s,
2203                                        subpicture_t *p_subpic )
2204 {
2205     encoder_sys_t *p_sys = p_enc->p_sys;
2206     subpicture_region_t *p_region;
2207     int i_region;
2208
2209     for( i_region = 0, p_region = p_subpic->p_region; p_region;
2210          p_region = p_region->p_next, i_region++ )
2211     {
2212         int i_entries = 4, i_depth = 0x1, i_bg = 0;
2213         bool b_text =
2214             ( p_region->fmt.i_chroma == VLC_CODEC_TEXT );
2215
2216         if( !b_text )
2217         {
2218             video_palette_t *p_pal = p_region->fmt.p_palette;
2219
2220             if( !p_pal )
2221             {
2222                 msg_Err( p_enc, "subpicture has no palette - ignoring it" );
2223                 break;
2224             }
2225
2226             i_entries = p_pal->i_entries;
2227             i_depth = i_entries == 4 ? 0x1 : i_entries == 16 ? 0x2 : 0x3;
2228
2229             for( i_bg = 0; i_bg < p_pal->i_entries; i_bg++ )
2230             {
2231                 if( !p_pal->palette[i_bg][3] ) break;
2232             }
2233         }
2234
2235         bs_write( s, 8, 0x0f ); /* Sync byte */
2236         bs_write( s, 8, DVBSUB_ST_REGION_COMPOSITION ); /* Segment type */
2237         bs_write( s, 16, 1 );   /* Page id */
2238
2239         bs_write( s, 16, 10 + 6 + (b_text ? 2 : 0) ); /* Segment length */
2240         bs_write( s, 8, i_region );
2241         bs_write( s, 4, p_sys->i_region_ver++ );
2242
2243         /* Region attributes */
2244         bs_write( s, 1, i_bg < i_entries ); /* Fill */
2245         bs_write( s, 3, 0 ); /* Reserved */
2246         bs_write( s, 16, p_sys->p_regions[i_region].i_width );
2247         bs_write( s, 16, p_sys->p_regions[i_region].i_height );
2248         bs_write( s, 3, i_depth );  /* Region level of compatibility */
2249         bs_write( s, 3, i_depth  ); /* Region depth */
2250         bs_write( s, 2, 0 ); /* Reserved */
2251         bs_write( s, 8, 1 ); /* Clut id */
2252         bs_write( s, 8, i_bg ); /* region 8bit pixel code */
2253         bs_write( s, 4, i_bg ); /* region 4bit pixel code */
2254         bs_write( s, 2, i_bg ); /* region 2bit pixel code */
2255         bs_write( s, 2, 0 ); /* Reserved */
2256
2257         /* In our implementation we only have 1 object per region */
2258         bs_write( s, 16, i_region );
2259         bs_write( s, 2, b_text ? DVBSUB_OT_BASIC_CHAR:DVBSUB_OT_BASIC_BITMAP );
2260         bs_write( s, 2, 0 ); /* object provider flag */
2261         bs_write( s, 12, 0 );/* object horizontal position */
2262         bs_write( s, 4, 0 ); /* Reserved */
2263         bs_write( s, 12, 0 );/* object vertical position */
2264
2265         if( b_text )
2266         {
2267             bs_write( s, 8, 1 ); /* foreground pixel code */
2268             bs_write( s, 8, 0 ); /* background pixel code */
2269         }
2270     }
2271 }
2272
2273 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
2274                                subpicture_region_t *p_region,
2275                                bool b_top );
2276
2277 static void encode_object( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
2278 {
2279     encoder_sys_t *p_sys = p_enc->p_sys;
2280     subpicture_region_t *p_region;
2281     int i_region;
2282
2283     int i_length_pos, i_update_pos, i_pixel_data_pos;
2284
2285     for( i_region = 0, p_region = p_subpic->p_region; p_region;
2286          p_region = p_region->p_next, i_region++ )
2287     {
2288         bs_write( s, 8, 0x0f ); /* Sync byte */
2289         bs_write( s, 8, DVBSUB_ST_OBJECT_DATA ); /* Segment type */
2290         bs_write( s, 16, 1 ); /* Page id */
2291
2292         i_length_pos = bs_pos( s );
2293         bs_write( s, 16, 0 ); /* Segment length */
2294         bs_write( s, 16, i_region ); /* Object id */
2295         bs_write( s, 4, p_sys->i_region_ver++ );
2296
2297         /* object coding method */
2298         switch( p_region->fmt.i_chroma )
2299         {
2300         case VLC_CODEC_YUVP:
2301             bs_write( s, 2, 0 );
2302             break;
2303         case VLC_CODEC_TEXT:
2304             bs_write( s, 2, 1 );
2305             break;
2306         default:
2307             msg_Err( p_enc, "FOURCC %d not supported by encoder.", p_region->fmt.i_chroma );
2308             continue;
2309         }
2310
2311         bs_write( s, 1, 0 ); /* non modifying color flag */
2312         bs_write( s, 1, 0 ); /* Reserved */
2313
2314         if( p_region->fmt.i_chroma == VLC_CODEC_TEXT )
2315         {
2316             int i_size, i;
2317
2318             if( !p_region->psz_text ) continue;
2319
2320             i_size = __MIN( strlen( p_region->psz_text ), 256 );
2321
2322             bs_write( s, 8, i_size ); /* number of characters in string */
2323             for( i = 0; i < i_size; i++ )
2324             {
2325                 bs_write( s, 16, p_region->psz_text[i] );
2326             }
2327
2328             /* Update segment length */
2329             SetWBE( &s->p_start[i_length_pos/8],
2330                     (bs_pos(s) - i_length_pos)/8 -2 );
2331             continue;
2332         }
2333
2334         /* Coding of a bitmap object */
2335         i_update_pos = bs_pos( s );
2336         bs_write( s, 16, 0 ); /* topfield data block length */
2337         bs_write( s, 16, 0 ); /* bottomfield data block length */
2338
2339         /* Top field */
2340         i_pixel_data_pos = bs_pos( s );
2341         encode_pixel_data( p_enc, s, p_region, true );
2342         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
2343         SetWBE( &s->p_start[i_update_pos/8], i_pixel_data_pos );
2344
2345         /* Bottom field */
2346         i_pixel_data_pos = bs_pos( s );
2347         encode_pixel_data( p_enc, s, p_region, false );
2348         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
2349         SetWBE( &s->p_start[i_update_pos/8+2], i_pixel_data_pos );
2350
2351         /* Stuffing for word alignment */
2352         bs_align_0( s );
2353         if( bs_pos( s ) % 16 ) bs_write( s, 8, 0 );
2354
2355         /* Update segment length */
2356         SetWBE( &s->p_start[i_length_pos/8], (bs_pos(s) - i_length_pos)/8 -2 );
2357     }
2358 }
2359
2360 static void encode_pixel_line_2bp( bs_t *s, subpicture_region_t *p_region,
2361                                    int i_line );
2362 static void encode_pixel_line_4bp( bs_t *s, subpicture_region_t *p_region,
2363                                    int i_line );
2364 static void encode_pixel_line_8bp( bs_t *s, subpicture_region_t *p_region,
2365                                    int i_line );
2366 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
2367                                subpicture_region_t *p_region,
2368                                bool b_top )
2369 {
2370     unsigned int i_line;
2371
2372     /* Sanity check */
2373     if( p_region->fmt.i_chroma != VLC_CODEC_YUVP ) return;
2374
2375     /* Encode line by line */
2376     for( i_line = !b_top; i_line < p_region->fmt.i_visible_height;
2377          i_line += 2 )
2378     {
2379         switch( p_region->fmt.p_palette->i_entries )
2380         {
2381         case 0:
2382             break;
2383
2384         case 4:
2385             bs_write( s, 8, 0x10 ); /* 2 bit/pixel code string */
2386             encode_pixel_line_2bp( s, p_region, i_line );
2387             break;
2388
2389         case 16:
2390             bs_write( s, 8, 0x11 ); /* 4 bit/pixel code string */
2391             encode_pixel_line_4bp( s, p_region, i_line );
2392             break;
2393
2394         case 256:
2395             bs_write( s, 8, 0x12 ); /* 8 bit/pixel code string */
2396             encode_pixel_line_8bp( s, p_region, i_line );
2397             break;
2398
2399         default:
2400             msg_Err( p_enc, "subpicture palette (%i) not handled",
2401                      p_region->fmt.p_palette->i_entries );
2402             break;
2403         }
2404
2405         bs_write( s, 8, 0xf0 ); /* End of object line code */
2406     }
2407 }
2408
2409 static void encode_pixel_line_2bp( bs_t *s, subpicture_region_t *p_region,
2410                                    int i_line )
2411 {
2412     unsigned int i, i_length = 0;
2413     int i_pitch = p_region->p_picture->p->i_pitch;
2414     uint8_t *p_data = &p_region->p_picture->p->p_pixels[ i_pitch * i_line ];
2415     int i_last_pixel = p_data[0];
2416
2417     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2418     {
2419         if( ( i != p_region->fmt.i_visible_width ) &&
2420             ( p_data[i] == i_last_pixel ) && ( i_length != 284 ) )
2421         {
2422             i_length++;
2423             continue;
2424         }
2425
2426         if( ( i_length == 1 ) || ( i_length == 11 ) || ( i_length == 28 ) )
2427         {
2428             /* 2bit/pixel code */
2429             if( i_last_pixel )
2430                 bs_write( s, 2, i_last_pixel );
2431             else
2432             {
2433                 bs_write( s, 2, 0 );
2434                 bs_write( s, 1, 0 );
2435                 bs_write( s, 1, 1 ); /* pseudo color 0 */
2436             }
2437             i_length--;
2438         }
2439
2440         if( i_length == 2 )
2441         {
2442             if( i_last_pixel )
2443             {
2444                 bs_write( s, 2, i_last_pixel );
2445                 bs_write( s, 2, i_last_pixel );
2446             }
2447             else
2448             {
2449                 bs_write( s, 2, 0 );
2450                 bs_write( s, 1, 0 );
2451                 bs_write( s, 1, 0 );
2452                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
2453             }
2454         }
2455         else if( i_length > 2 )
2456         {
2457             bs_write( s, 2, 0 );
2458             if( i_length <= 10 )
2459             {
2460                 bs_write( s, 1, 1 );
2461                 bs_write( s, 3, i_length - 3 );
2462                 bs_write( s, 2, i_last_pixel );
2463             }
2464             else
2465             {
2466                 bs_write( s, 1, 0 );
2467                 bs_write( s, 1, 0 );
2468
2469                 if( i_length <= 27 )
2470                 {
2471                     bs_write( s, 2, 2 );
2472                     bs_write( s, 4, i_length - 12 );
2473                     bs_write( s, 2, i_last_pixel );
2474                 }
2475                 else
2476                 {
2477                     bs_write( s, 2, 3 );
2478                     bs_write( s, 8, i_length - 29 );
2479                     bs_write( s, 2, i_last_pixel );
2480                 }
2481             }
2482         }
2483
2484         if( i == p_region->fmt.i_visible_width ) break;
2485
2486         i_last_pixel = p_data[i];
2487         i_length = 1;
2488     }
2489
2490     /* Stop */
2491     bs_write( s, 2, 0 );
2492     bs_write( s, 1, 0 );
2493     bs_write( s, 1, 0 );
2494     bs_write( s, 2, 0 );
2495
2496     /* Stuffing */
2497     bs_align_0( s );
2498 }
2499
2500 static void encode_pixel_line_4bp( bs_t *s, subpicture_region_t *p_region,
2501                                    int i_line )
2502 {
2503     unsigned int i, i_length = 0;
2504     int i_pitch = p_region->p_picture->p->i_pitch;
2505     uint8_t *p_data = &p_region->p_picture->p->p_pixels[ i_pitch * i_line ];
2506     int i_last_pixel = p_data[0];
2507
2508     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2509     {
2510         if( i != p_region->fmt.i_visible_width &&
2511             p_data[i] == i_last_pixel && i_length != 280 )
2512         {
2513             i_length++;
2514             continue;
2515         }
2516
2517         if( ( i_length == 1 ) ||
2518             ( ( i_length == 3 ) && i_last_pixel ) ||
2519             ( i_length == 8 ) )
2520         {
2521             /* 4bit/pixel code */
2522             if( i_last_pixel )
2523                 bs_write( s, 4, i_last_pixel );
2524             else
2525             {
2526                 bs_write( s, 4, 0 );
2527                 bs_write( s, 1, 1 );
2528                 bs_write( s, 1, 1 );
2529                 bs_write( s, 2, 0 ); /* pseudo color 0 */
2530             }
2531             i_length--;
2532         }
2533
2534         if( i_length == 2 )
2535         {
2536             if( i_last_pixel )
2537             {
2538                 bs_write( s, 4, i_last_pixel );
2539                 bs_write( s, 4, i_last_pixel );
2540             }
2541             else
2542             {
2543                 bs_write( s, 4, 0 );
2544                 bs_write( s, 1, 1 );
2545                 bs_write( s, 1, 1 );
2546                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
2547             }
2548         }
2549         else if( !i_last_pixel && ( i_length >= 3 ) && ( i_length <= 9 ) )
2550         {
2551             bs_write( s, 4, 0 );
2552             bs_write( s, 1, 0 );
2553             bs_write( s, 3, i_length - 2 ); /* (i_length - 2) * color 0 */
2554         }
2555         else if( i_length > 2 )
2556         {
2557             bs_write( s, 4, 0 );
2558             bs_write( s, 1, 1 );
2559
2560             if( i_length <= 7 )
2561             {
2562                 bs_write( s, 1, 0 );
2563                 bs_write( s, 2, i_length - 4 );
2564                 bs_write( s, 4, i_last_pixel );
2565             }
2566             else
2567             {
2568                 bs_write( s, 1, 1 );
2569
2570                 if( i_length <= 24 )
2571                 {
2572                     bs_write( s, 2, 2 );
2573                     bs_write( s, 4, i_length - 9 );
2574                     bs_write( s, 4, i_last_pixel );
2575                 }
2576                 else
2577                 {
2578                     bs_write( s, 2, 3 );
2579                     bs_write( s, 8, i_length - 25 );
2580                     bs_write( s, 4, i_last_pixel );
2581                 }
2582             }
2583         }
2584
2585         if( i == p_region->fmt.i_visible_width ) break;
2586
2587         i_last_pixel = p_data[i];
2588         i_length = 1;
2589     }
2590
2591     /* Stop */
2592     bs_write( s, 8, 0 );
2593
2594     /* Stuffing */
2595     bs_align_0( s );
2596 }
2597
2598 static void encode_pixel_line_8bp( bs_t *s, subpicture_region_t *p_region,
2599                                    int i_line )
2600 {
2601     unsigned int i, i_length = 0;
2602     int i_pitch = p_region->p_picture->p->i_pitch;
2603     uint8_t *p_data = &p_region->p_picture->p->p_pixels[ i_pitch * i_line ];
2604     int i_last_pixel = p_data[0];
2605
2606     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2607     {
2608         if( ( i != p_region->fmt.i_visible_width ) &&
2609             ( p_data[i] == i_last_pixel ) && ( i_length != 127 ) )
2610         {
2611             i_length++;
2612             continue;
2613         }
2614
2615         if( ( i_length == 1 ) && i_last_pixel )
2616         {
2617             /* 8bit/pixel code */
2618             bs_write( s, 8, i_last_pixel );
2619         }
2620         else if( ( i_length == 2 ) && i_last_pixel )
2621         {
2622             /* 8bit/pixel code */
2623             bs_write( s, 8, i_last_pixel );
2624             bs_write( s, 8, i_last_pixel );
2625         }
2626         else if( i_length <= 127 )
2627         {
2628             bs_write( s, 8, 0 );
2629
2630             if( !i_last_pixel )
2631             {
2632                 bs_write( s, 1, 0 );
2633                 bs_write( s, 7, i_length ); /* pseudo color 0 */
2634             }
2635             else
2636             {
2637                 bs_write( s, 1, 1 );
2638                 bs_write( s, 7, i_length );
2639                 bs_write( s, 8, i_last_pixel );
2640             }
2641         }
2642
2643         if( i == p_region->fmt.i_visible_width ) break;
2644
2645         i_last_pixel = p_data[i];
2646         i_length = 1;
2647     }
2648
2649     /* Stop */
2650     bs_write( s, 8, 0 );
2651     bs_write( s, 8, 0 );
2652
2653     /* Stuffing */
2654     bs_align_0( s );
2655 }
2656
2657
2658 static void default_dds_init( decoder_t * p_dec )
2659 {
2660     decoder_sys_t *p_sys = p_dec->p_sys;
2661
2662     /* see notes on DDS at the top of the file */
2663
2664     /* configure for SD res in case DDS is not present */
2665     p_sys->display.i_version = 0xff; /* an invalid version so it's always different */
2666     p_sys->display.i_width = 720;
2667     p_sys->display.i_height = 576;
2668     p_sys->display.b_windowed = false;
2669 }
2670