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