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