+ for( ; i_x < p_spu->i_width; i_x++, p_source++ )
+ {
+
+ if( b_crop ) {
+
+ /* FIXME: y cropping should be dealt with outside of this
+ loop.*/
+ if ( i_y < i_y_start) continue;
+
+ if ( i_x > i_x_end )
+ {
+ p_source += p_spu->i_width - i_x;
+ break;
+ }
+ }
+
+ if (p_source >= p_src_end) {
+ msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
+ i_x, i_y / i_yscale, i_height);
+ return;
+ }
+
+ switch( p_source->s.t )
+ {
+ case 0:
+ /* Completely transparent. Don't change pixel. */
+ break;
+
+ default:
+ case MAX_ALPHA:
+ {
+ /* Completely opaque. Completely overwrite underlying
+ pixel with subtitle pixel. */
+
+ uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE)
+ * BYTES_PER_PIXEL );
+ uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
+ * BYTES_PER_PIXEL );
+ uint32_t len = i_xlast - i_xdest;
+
+ uint8_t *p_pixel_base_x = p_pixel_base + i_xdest;
+
+ for( ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
+ {
+ /* This is the location that's going to get changed. */
+ uint8_t *p_dest = p_pixel_base_x + i_ytmp;
+ uint8_t i_rgb1;
+ uint8_t i_rgb2;
+ if (b_15bpp)
+ yuv2rgb555(p_source, &i_rgb1, &i_rgb2);
+ else
+ yuv2rgb565(p_source, &i_rgb1, &i_rgb2);
+
+ for ( len = i_xlast - i_xdest; len ; len--) {
+ *p_dest++ = i_rgb1;
+ *p_dest++ = i_rgb2;
+ }
+ }
+ break;
+ }
+#ifdef TRANSPARENCY_FINISHED
+ default:
+ for( ; i_ytmp < i_ynext ; y_ytmp += p_pic->p->i_pitch )
+ {
+ /* Blend in underlying pixel subtitle pixel. */
+
+ /* To be able to scale correctly for full opaqueness, we
+ add 1 to the alpha. This means alpha value 0 won't
+ be completely transparent and is not correct, but
+ that's handled in a special case above anyway. */
+
+ uint8_t *p_dest = p_pixel_base + i_ytmp;
+ uint8_t i_destalpha = MAX_ALPHA - p_source->s.t;
+ uint8_t i_rgb1;
+ uint8_t i_rgb2;
+
+ if (b_15bpp)
+ yuv2rgb555(p_source, &i_rgb1, &i_rgb2);
+ else
+ yuv2rgb565(p_source, &i_rgb1, &i_rgb2);
+ rv16_pack_blend(p_dest, rgb, dest_alpha,ALPHA_SCALEDOWN);
+ }
+ break;
+#endif /*TRANSPARENCY_FINISHED*/
+ }
+ }
+ }
+ }
+}
+
+#undef BYTES_PER_PIXEL
+#define BYTES_PER_PIXEL 4
+
+/*
+ RV24 format??? Is this just for X11? Or just not for Win32? Is this
+ the same as RV32?
+
+ a pixel is represented by 3 bytes containing a red,
+ blue and green sample with blue stored at the lowest address, green
+ next then red. One padding byte is added between pixels. Although
+ this may not be part of a spec, images should be stored with each
+ line padded to a u_int32 boundary.
+*/
+static void
+BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
+ const subpicture_t *p_spu, vlc_bool_t b_crop )
+{
+ /* Common variables */
+ uint8_t *p_pixel_base;
+ ogt_yuvt_t *p_src_start = (ogt_yuvt_t *)p_spu->p_sys->p_data;
+ ogt_yuvt_t *p_src_end = &p_src_start[p_spu->i_height * p_spu->i_width];
+ ogt_yuvt_t *p_source; /* This is the where the subtitle pixels come from */
+
+ int i_x, i_y;
+ int i_y_src;
+
+ /* Make sure we start on a word (4-byte) boundary. */
+ uint32_t i_spu_x;
+
+ /* Chroma specific */
+ uint32_t i_xscale; /* Amount we scale subtitle in the x direction,
+ multiplied by 2**ASCALE. */
+ uint32_t i_yscale; /* Amount we scale subtitle in the y direction.
+ multiplied by 2**ASCALE. */
+
+ int i_width, i_height, i_ytmp, i_ynext;
+
+ /* Crop-specific */
+ int32_t i_x_start, i_y_start, i_x_end, i_y_end;
+
+ struct subpicture_sys_t *p_sys = p_spu->p_sys;
+ unsigned int i_aspect_x, i_aspect_y;
+
+ vout_AspectRatio( p_vout->render.i_aspect, &i_aspect_y,
+ &i_aspect_x );
+
+ i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x)
+ / (i_aspect_y * p_vout->render.i_width);
+ i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;
+
+ dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER),
+ "spu: %dx%d, scaled: %dx%d, vout render: %dx%d, scale %dx%d",
+ p_spu->i_width, p_spu->i_height,
+ p_vout->output.i_width, p_vout->output.i_height,
+ p_vout->render.i_width, p_vout->render.i_height,
+ i_xscale, i_yscale
+ );
+
+ i_width = p_spu->i_width * i_xscale;
+ i_height = p_spu->i_height * i_yscale;
+
+ /* Set where we will start blending subtitle from using
+ the picture coordinates subtitle offsets.
+ */
+ i_spu_x = ((p_spu->i_x * i_xscale) >> ASCALE) * BYTES_PER_PIXEL;
+
+ p_pixel_base = p_pic->p->p_pixels + i_spu_x
+ + ( (p_spu->i_y * i_yscale) >> ASCALE ) * p_pic->p->i_pitch;
+
+ i_x_start = p_sys->i_x_start;
+ i_y_start = i_yscale * p_sys->i_y_start;
+ i_x_end = p_sys->i_x_end;
+ i_y_end = i_yscale * p_sys->i_y_end;
+
+ p_source = (ogt_yuvt_t *)p_sys->p_data;
+
+ /* Draw until we reach the bottom of the subtitle */
+ i_y = 0;
+ for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width;
+ i_y_src += p_spu->i_width )
+ {
+ uint8_t *p_pixel_base_y;
+ i_ytmp = i_y >> ASCALE;
+ i_y += i_yscale;
+ p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);
+ i_x = 0;
+
+ if ( b_crop ) {
+ if ( i_y > i_y_end ) break;
+ if (i_x_start) {
+ i_x = i_x_start;
+ p_source += i_x_start;
+ }
+ }
+
+ /* Check whether we need to draw one line or more than one */
+ if( i_ytmp + 1 >= ( i_y >> ASCALE ) )
+ {
+ /* Draw until we reach the end of the line */
+ for( ; i_x < p_spu->i_width; i_x++, p_source++ )