diff options
| author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2007-08-21 04:39:52 +0100 |
|---|---|---|
| committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2007-08-21 04:39:52 +0100 |
| commit | 141558ac76e39d7f39400da0ecb6ca1f92ffee22 (patch) | |
| tree | 4f800af1614d7fc998034dc9e7f58d877c154b10 /src/libsputext | |
| parent | bc19407410f6467638888f917f9e7832f6eaee28 (diff) | |
| parent | cbd017c8bc0139311d149c58fabba4e783dd95a9 (diff) | |
| download | xine-lib-141558ac76e39d7f39400da0ecb6ca1f92ffee22.tar.gz xine-lib-141558ac76e39d7f39400da0ecb6ca1f92ffee22.tar.bz2 | |
Merge from 1.1.
Diffstat (limited to 'src/libsputext')
| -rw-r--r-- | src/libsputext/xine_sputext_decoder.c | 201 |
1 files changed, 91 insertions, 110 deletions
diff --git a/src/libsputext/xine_sputext_decoder.c b/src/libsputext/xine_sputext_decoder.c index d4dd103ec..ea3a69189 100644 --- a/src/libsputext/xine_sputext_decoder.c +++ b/src/libsputext/xine_sputext_decoder.c @@ -44,6 +44,39 @@ #define SUB_MAX_TEXT 5 /* lines */ #define SUB_BUFSIZE 256 /* chars per line */ +#define rgb2yuv(R,G,B) ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128)) + +static uint32_t sub_palette[22]={ +/* RED */ + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(50,10,10), + rgb2yuv(120,20,20), + rgb2yuv(185,50,50), + rgb2yuv(255,70,70), +/* BLUE */ + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,30,50), + rgb2yuv(0,90,120), + rgb2yuv(0,140,185), + rgb2yuv(0,170,255) +}; + +static uint8_t sub_trans[22]={ + 0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15, + 0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 +}; typedef enum { SUBTITLE_SIZE_TINY = 0, @@ -103,6 +136,9 @@ typedef struct sputext_decoder_s { osd_renderer_t *renderer; osd_object_t *osd; + int current_osd_text; + uint32_t spu_palette[OVL_PALETTE_SIZE]; + uint8_t spu_trans[OVL_PALETTE_SIZE]; int64_t img_duration; int64_t last_subtitle_end; /* no new subtitle before this vpts */ @@ -235,115 +271,74 @@ static int parse_utf8_size(unsigned char *c) return 1; } -static int ogm_get_width(sputext_decoder_t *this, char* text) { - int i=0,width=0,w,dummy; - char letter[5]={0, 0, 0, 0, 0}; - int shift, isutf8 = 0; - char *encoding = (this->buf_encoding)?this->buf_encoding: - this->class->src_encoding; - if( strcmp(encoding, "utf-8") == 0 ) - isutf8 = 1; - - while (i<=strlen(text)) { - switch (text[i]) { - case '<': - if (!strncmp("<b>", text+i, 3)) { - /*Do somethink to enable BOLD typeface*/ - i=i+3; - break; - } else if (!strncmp("</b>", text+i, 3)) { - /*Do somethink to disable BOLD typeface*/ - i=i+4; - break; - } else if (!strncmp("<i>", text+i, 3)) { - /*Do somethink to enable italics typeface*/ - i=i+3; - break; - } else if (!strncmp("</i>", text+i, 3)) { - /*Do somethink to disable italics typeface*/ - i=i+4; - break; - } else if (!strncmp("<font>", text+i, 3)) { - /*Do somethink to disable typing - fixme - no teststreams*/ - i=i+6; - break; - } else if (!strncmp("</font>", text+i, 3)) { - /*Do somethink to enable typing - fixme - no teststreams*/ - i=i+7; - break; - } -default: - if ( isutf8 ) - shift = parse_utf8_size(&text[i]); - else - shift = 1; - memcpy(letter,&text[i],shift); - letter[shift]=0; - - this->renderer->get_text_size(this->osd, letter, &w, &dummy); - width=width+w; - i+=shift; - } - } - - return width; -} - -static void ogm_render_line(sputext_decoder_t *this, int x, int y, char* text) { - int i=0,w,dummy; +static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const char *text, int render) +{ + int i = 0, w, dummy; char letter[5]={0, 0, 0, 0, 0}; - int shift, isutf8 = 0; - char *encoding = (this->buf_encoding)?this->buf_encoding: - this->class->src_encoding; - if( strcmp(encoding, "utf-8") == 0 ) - isutf8 = 1; + const char *encoding = this->buf_encoding ? this->buf_encoding + : this->class->src_encoding; + int shift, isutf8 = !strcmp(encoding, "utf-8"); + size_t length = strlen (text); - while (i<=strlen(text)) { + while (i <= length) { switch (text[i]) { case '<': if (!strncmp("<b>", text+i, 3)) { - /*Do somethink to enable BOLD typeface*/ + /* enable Bold color */ + if (render) + this->current_osd_text = OSD_TEXT2; i=i+3; break; - } else if (!strncmp("</b>", text+i, 3)) { - /*Do somethink to disable BOLD typeface*/ + } else if (!strncmp("</b>", text+i, 4)) { + /* disable BOLD */ + if (render) + this->current_osd_text = OSD_TEXT1; i=i+4; break; } else if (!strncmp("<i>", text+i, 3)) { - /*Do somethink to enable italics typeface*/ + /* enable italics color */ + if (render) + this->current_osd_text = OSD_TEXT3; i=i+3; break; - } else if (!strncmp("</i>", text+i, 3)) { - /*Do somethink to disable italics typeface*/ + } else if (!strncmp("</i>", text+i, 4)) { + /* disable italics */ + if (render) + this->current_osd_text = OSD_TEXT1; i=i+4; break; - } else if (!strncmp("<font>", text+i, 3)) { + } else if (!strncmp("<font>", text+i, 6)) { /*Do somethink to disable typing fixme - no teststreams*/ i=i+6; break; - } else if (!strncmp("</font>", text+i, 3)) { + } else if (!strncmp("</font>", text+i, 7)) { /*Do somethink to enable typing fixme - no teststreams*/ i=i+7; break; } default: - if ( isutf8 ) - shift = parse_utf8_size(&text[i]); - else - shift = 1; + shift = isutf8 ? parse_utf8_size (&text[i]) : 1; memcpy(letter,&text[i],shift); letter[shift]=0; - this->renderer->render_text(this->osd, x, y, letter, OSD_TEXT1); + if (render) + this->renderer->render_text(this->osd, x, y, letter, this->current_osd_text); this->renderer->get_text_size(this->osd, letter, &w, &dummy); x=x+w; i+=shift; } } + return x; +} + +static inline int ogm_get_width(sputext_decoder_t *this, char* text) { + return ogm_render_line_internal (this, 0, 0, text, 0); +} + +static inline void ogm_render_line(sputext_decoder_t *this, int x, int y, char* text) { + ogm_render_line_internal (this, x, y, text, 1); } static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t sub_end ) { @@ -373,11 +368,8 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */ { - int w, h; - if( this->ogm ) - w = ogm_get_width( this, this->text[line]); - else - this->renderer->get_text_size( this->osd, this->text[line], &w, &h); + int w; + w = ogm_get_width( this, this->text[line]); if( w > this->width ) { /* line is too long */ int chunks=(int)(w/this->width)+(w%this->width?1:0); if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */ @@ -411,7 +403,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->lines+=chunks-1; } else { /* regenerate all the lines to find something that better fits */ char buf[SUB_BUFSIZE*SUB_MAX_TEXT]; - int a,w,h,chunks; + int a,w,chunks; buf[0]='\0'; for(a=0;a<this->lines;a++) { if(a) { @@ -421,10 +413,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } strcat(buf,this->text[a]); } - if( this->ogm ) - w = ogm_get_width( this, buf); - else - this->renderer->get_text_size( this->osd, buf, &w, &h); + w = ogm_get_width( this, buf); chunks=(int)(w/this->width)+(w%this->width?1:0); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks); if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */ @@ -461,11 +450,8 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */ { - int w, h; - if( this->ogm ) - w = ogm_get_width( this, this->text[line]); - else - this->renderer->get_text_size( this->osd, this->text[line], &w, &h); + int w; + w = ogm_get_width( this, this->text[line]); if( w > this->width ) { /* line is too long */ int chunks=(int)(w/this->width)+(w%this->width?1:0); if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */ @@ -499,7 +485,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->lines+=chunks-1; } else { /* regenerate all the lines to find something that better fits */ char buf[SUB_BUFSIZE*SUB_MAX_TEXT]; - int a,w,h,chunks; + int a,w,chunks; buf[0]='\0'; for(a=0;a<this->lines;a++) { if(a) { @@ -509,10 +495,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } strcat(buf,this->text[a]); } - if( this->ogm ) - w = ogm_get_width( this, buf); - else - this->renderer->get_text_size( this->osd, buf, &w, &h); + w = ogm_get_width( this, buf); chunks=(int)(w/this->width)+(w%this->width?1:0); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks); if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */ @@ -548,14 +531,10 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su y = (SUB_MAX_TEXT - this->lines) * this->line_height; for (line = 0; line < this->lines; line++) { - int w, h, x; + int w, x; while(1) { - if( this->ogm ) - w = ogm_get_width( this, this->text[line]); - else - this->renderer->get_text_size( this->osd, this->text[line], - &w, &h); + w = ogm_get_width( this, this->text[line]); x = (this->width - w) / 2; if( w > this->width && font_size > 16 ) { @@ -566,12 +545,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } } - if( this->ogm ) { - ogm_render_line(this, x, y + line*this->line_height, this->text[line]); - } else { - this->renderer->render_text (this->osd, x, y + line * this->line_height, - this->text[line], OSD_TEXT1); - } + ogm_render_line(this, x, y + line*this->line_height, this->text[line]); } if( font_size != this->font_size ) @@ -583,6 +557,11 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->last_subtitle_end = sub_end; this->renderer->set_text_palette (this->osd, -1, OSD_TEXT1); + this->renderer->get_palette(this->osd, this->spu_palette, this->spu_trans); + /* append some colors for colored typeface tag */ + memcpy(this->spu_palette+OSD_TEXT2, sub_palette, sizeof(sub_palette)); + memcpy(this->spu_trans+OSD_TEXT2, sub_trans, sizeof(sub_trans)); + this->renderer->set_palette(this->osd, this->spu_palette, this->spu_trans); if (this->unscaled) this->renderer->show_unscaled (this->osd, sub_start); @@ -626,7 +605,9 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { this->buf_encoding = buf->decoder_info_ptr[2]; else this->buf_encoding = NULL; - + + this->current_osd_text = OSD_TEXT1; + if( (buf->type & 0xFFFF0000) == BUF_SPU_OGM ) { this->ogm = 1; |
