render.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:65k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * render.c : Philips OGT and CVD (VCD Subtitle) blending routines.
  3.  *            stuff from here might be pulled out, abstracted or used
  4.  *            by DVD subtitles.
  5.  *****************************************************************************
  6.  * Copyright (C) 2003, 2004 VideoLAN
  7.  * $Id: render.c 8686 2004-09-10 18:03:25Z gbazin $
  8.  *
  9.  * Author: Rocky Bernstein <rocky@panix.com>
  10.  *   based on code from: 
  11.  *          Sam Hocevar <sam@zoy.org>
  12.  *          Rudolf Cornelissen <rag.cornelissen@inter.nl.net>
  13.  *          Roine Gustafsson <roine@popstar.com>
  14.  *
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2 of the License, or
  18.  * (at your option) any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; if not, write to the Free Software
  27.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  28.  *****************************************************************************/
  29. /*#define TESTING_TRANSPARENCY 1*/
  30. /*****************************************************************************
  31.  * Preamble
  32.  *****************************************************************************/
  33. #include <vlc/vlc.h>
  34. #include <vlc/vout.h>
  35. #include <vlc/decoder.h>
  36. #include "pixmap.h"
  37. #include "subtitle.h"
  38. #include "render.h"
  39. /* We use 4 bits for an transparency value: 0..15, 15 is completely
  40.    transparent and 0 completely opaque. Note that although SVCD allow
  41.    8-bits, for these routines pixels should previously have been be
  42.    scaled down to 4 bits (the range used by DVDs).
  43. */
  44. #define TRANS_BITS (4)
  45. #define MAX_TRANS  ((1<<TRANS_BITS) - 1) 
  46. #define TRANS_SCALEDOWN (8-TRANS_BITS)
  47. /* We use a fixed-point arithmetic in scaling ratios so that we
  48.    can use integer arithmetic and still get fairly precise
  49.    results. ASCALE is a left shift amount. 
  50. */
  51. #define ASCALE 6  /* 2^6 = 32 */
  52. /* Horrible hack to get dbg_print to do the right thing */
  53. #define p_dec p_vout
  54. /**
  55.    Take two 8-bit RGB values and a transparency and do a weighted
  56.    average of them. The "weight" comes from i_trans which is in the
  57.    range 0..MAX_TRANS. To have greater precision using integer
  58.    arithmetic, the RGB values are scaled. The uint16_t cast below is
  59.    to make sure we don't overflow the product in the multiplication
  60.    (MAX_TRANS - i_trans) is the additive "inverse" of i_trans, i.e.
  61.    i_trans + (MAX_TRANS - i_trans) = MAX_TRANS. So the resulting sum
  62.    of rgb1*i_trans + rgb2*(MAX_TRANS-i_trans) will be scaled by
  63.    MAX_TRANS. To reduce the value back down to 8 bits, we shift by
  64.    TRANS_BITS, noting that 1 << TRANS_BITS is roughly
  65.    MAX_TRANS. (Actually it is MAX_TRANS - 1).
  66. */
  67. #define avg_8bit_rgb(rgb_vout, rgb_sub, i_trans)                   
  68. {                                                                  
  69.    int i;                                                          
  70.    for (i=0; i < RGB_SIZE; i++) {                                  
  71.    rgb_vout[i] = ( (uint16_t) rgb_vout[i]*(MAX_TRANS-i_trans) +    
  72.                    (uint16_t) rgb_sub [i]*i_trans ) >> TRANS_BITS; 
  73.    }                                                               
  74. }
  75. /*****************************************************************************
  76.  * Local prototypes
  77.  *****************************************************************************/
  78. static void BlendI420( vout_thread_t *, picture_t *, const subpicture_t *,
  79.                         vlc_bool_t );
  80. static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
  81.                         const subpicture_t *p_spu, vlc_bool_t b_crop );
  82. static void BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
  83.                        const subpicture_t *p_spu, vlc_bool_t b_crop,
  84.                        vlc_bool_t b_15bpp );
  85. static void BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
  86.                         const subpicture_t *p_spu, vlc_bool_t b_crop );
  87. static void BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
  88.                         const subpicture_t *p_spu, vlc_bool_t b_crop );
  89. static void BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
  90.                         const subpicture_t *p_spu, vlc_bool_t b_crop );
  91. /*****************************************************************************
  92.  * BlendSPU: blend a subtitle into a picture
  93.  *****************************************************************************
  94.  
  95.   This blends subtitles (a subpicture) into the underlying
  96.   picture. Subtitle data has been preprocessed as YUV + transparancy
  97.   or 4 bytes per pixel with interleaving of rows in the subtitle
  98.   removed. 
  99.  *****************************************************************************/
  100. void VCDSubBlend( vout_thread_t *p_vout, picture_t *p_pic,
  101.    const subpicture_t *p_spu )
  102. {
  103.     struct subpicture_sys_t *p_sys = p_spu->p_sys;
  104.   
  105.     dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  106.        "chroma %x", p_vout->output.i_chroma );
  107.     switch( p_vout->output.i_chroma )
  108.     {
  109.         /* I420 target, no scaling */
  110.         case VLC_FOURCC('I','4','2','0'):
  111.         case VLC_FOURCC('I','Y','U','V'):
  112.         case VLC_FOURCC('Y','V','1','2'):
  113.             BlendI420( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
  114.             break;
  115.         /* RGB 555 - scaled */
  116.         case VLC_FOURCC('R','V','1','5'):
  117.             BlendRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop, 
  118.                        VLC_TRUE );
  119.             break;
  120.           
  121.         case VLC_FOURCC('R','V','1','6'):
  122.             BlendRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop,
  123.                        /* Not sure under what conditions RV16 is really
  124.                           RV16 and not RV15.
  125.                         */
  126. #if 0
  127.                        VLC_FALSE );
  128. #else
  129.                        VLC_TRUE );
  130. #endif
  131.     break;
  132.         /* RV24 target, scaling */
  133.         case VLC_FOURCC('R','V','2','4'):
  134.             BlendRV24( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
  135.     break;
  136.         /* RV32 target, scaling */
  137.         case VLC_FOURCC('R','V','3','2'):
  138.             BlendRV32( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
  139.     break;
  140.         /* NVidia overlay, no scaling */
  141.         case VLC_FOURCC('Y','U','Y','2'):
  142.             BlendYUY2( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
  143.     break;
  144.         /* Palettized 8 bits per pixel (256 colors). Each
  145.            pixel is an uint8_t index in the palette
  146.            Used in ASCII Art. 
  147.         */
  148.         case VLC_FOURCC('R','G','B','2'):
  149.             BlendRGB2( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
  150.           
  151.     break;
  152.         default:
  153.             msg_Err( p_vout, "unknown chroma, can't render SPU" );
  154.             break;
  155.     }
  156. }
  157. /* Following functions are local */
  158. /* 
  159.   YV12 format:  
  160.   All Y samples are found first in memory as an array of bytes
  161.   (possibly with a larger stride for memory alignment), followed
  162.   immediately by all Cr (=U) samples (with half the stride of the Y
  163.   lines, and half the number of lines), then followed immediately by
  164.   all Cb (=V) samples in a similar fashion.
  165. */
  166. static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
  167.                         const subpicture_t *p_spu, vlc_bool_t b_crop )
  168. {
  169.   /* Common variables */
  170.   uint8_t *p_pixel_base_Y, *p_pixel_base_V, *p_pixel_base_U;
  171.   ogt_yuvt_t *p_source; /* This is the where the subtitle pixels come from */
  172.   int i_x, i_y;
  173.   vlc_bool_t even_scanline = VLC_FALSE;
  174.   /* Crop-specific */
  175.   int i_x_start, i_y_start, i_x_end, i_y_end;
  176.   /* int i=0; */
  177.   const struct subpicture_sys_t *p_sys = p_spu->p_sys;
  178.   
  179.   dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  180.      "spu width x height: (%dx%d), (x,y)=(%d,%d), yuv pitch (%d,%d,%d)", 
  181.      p_spu->i_width,  p_spu->i_height, p_spu->i_x, p_spu->i_y,
  182.      p_pic->Y_PITCH, p_pic->U_PITCH, p_pic->V_PITCH );
  183.   
  184.   p_pixel_base_Y = p_pic->p[Y_PLANE].p_pixels + p_spu->i_x
  185.                  + p_pic->p[Y_PLANE].i_pitch * p_spu->i_y;
  186.   
  187.   p_pixel_base_U = p_pic->p[U_PLANE].p_pixels + p_spu->i_x/2
  188.                  + p_pic->p[U_PLANE].i_pitch * p_spu->i_y/2;
  189.   
  190.   p_pixel_base_V = p_pic->p[V_PLANE].p_pixels + p_spu->i_x/2
  191.                  + p_pic->p[V_PLANE].i_pitch * p_spu->i_y/2;
  192.   
  193.   i_x_start = p_sys->i_x_start;
  194.   i_y_start = p_pic->p[Y_PLANE].i_pitch * p_sys->i_y_start;
  195.   
  196.   i_x_end   = p_sys->i_x_end;
  197.   i_y_end   = p_pic->p[Y_PLANE].i_pitch * p_sys->i_y_end;
  198.   
  199.   p_source = (ogt_yuvt_t *)p_sys->p_data;
  200.   
  201.   /* Draw until we reach the bottom of the subtitle */
  202.   for( i_y = 0; 
  203.        i_y < p_spu->i_height * p_pic->p[Y_PLANE].i_pitch ;
  204.        i_y += p_pic->p[Y_PLANE].i_pitch )
  205.     {
  206.       uint8_t *p_pixel_base_Y_y = p_pixel_base_Y + i_y;
  207.       uint8_t *p_pixel_base_U_y = p_pixel_base_U + i_y/4;
  208.       uint8_t *p_pixel_base_V_y = p_pixel_base_V + i_y/4;
  209.       i_x = 0;
  210.       if ( b_crop ) {
  211.         if ( i_y > i_y_end ) break;
  212.         if (i_x_start) {
  213.           i_x = i_x_start;
  214.           p_source += i_x_start;
  215.         }
  216.       }
  217.       even_scanline = !even_scanline;
  218.       /* Draw until we reach the end of the line */
  219.       for( ; i_x < p_spu->i_width; i_x++, p_source++ )
  220. {
  221.   if( b_crop ) {
  222.             /* FIXME: y cropping should be dealt with outside of this loop.*/
  223.             if ( i_y < i_y_start) continue;
  224.             if ( i_x > i_x_end )
  225.     {
  226.       p_source += p_spu->i_width - i_x;
  227.               break;
  228.     }
  229.           }
  230. #ifdef TESTING_TRANSPARENCY
  231.           if (p_source->s.t == MAX_TRANS) p_source->s.t >>= 1;
  232. #endif
  233.   switch( p_source->s.t )
  234.     {
  235.     case 0: 
  236.       /* Completely transparent. Don't change pixel. */
  237.       break;
  238.       
  239.     case MAX_TRANS:
  240.       {
  241. /* Completely opaque. Completely overwrite underlying
  242.    pixel with subtitle pixel. */
  243. /* This is the location that's going to get changed.*/
  244. uint8_t *p_pixel_Y = p_pixel_base_Y_y + i_x;
  245. *p_pixel_Y = p_source->plane[Y_PLANE];
  246. if ( even_scanline && i_x % 2 == 0 ) {
  247.   uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2;
  248.   uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2;
  249.   *p_pixel_U = p_source->plane[U_PLANE];
  250.   *p_pixel_V = p_source->plane[V_PLANE];
  251. }
  252. break;
  253.       }
  254.       
  255.     default:
  256.       {
  257. /* Blend in underlying subtitle pixel. */
  258. /* This is the location that's going to get changed. */
  259. uint8_t *p_pixel_Y = p_pixel_base_Y_y + i_x;
  260. /* This is the weighted part of the subtitle. The
  261.    color plane is 8 bits and transparancy is 4 bits so
  262.    when multiplied we get up to 12 bits.
  263.  */
  264. uint16_t i_sub_color_Y = 
  265.   (uint16_t) ( p_source->plane[Y_PLANE] *
  266.        (uint16_t) (p_source->s.t) );
  267. /* This is the weighted part of the underlying pixel.
  268.    For the same reasons above, the result is up to 12
  269.    bits.  However since the transparancies are
  270.    inverses, the sum of i_sub_color and i_pixel_color
  271.    will not exceed 12 bits.
  272. */
  273. uint16_t i_pixel_color_Y = 
  274.   (uint16_t) ( *p_pixel_Y * 
  275.        (uint16_t) (MAX_TRANS - p_source->s.t) ) ;
  276. /* Scale the 12-bit result back down to 8 bits. A
  277.    precise scaling after adding the two components,
  278.    would divide by one less than a power of 2. However
  279.    to simplify and speed things we use a power of
  280.    2. This means the boundaries (either all
  281.    transparent and all opaque) aren't handled properly.
  282.    But we deal with them in special cases above. */
  283. *p_pixel_Y = ( i_sub_color_Y + i_pixel_color_Y ) >> TRANS_BITS;
  284. if ( even_scanline && i_x % 2 == 0 ) {
  285.   uint8_t *p_pixel_U = p_pixel_base_U_y + i_x/2
  286.                     - p_pic->p[U_PLANE].i_pitch / 2;
  287.   uint8_t *p_pixel_V = p_pixel_base_V_y + i_x/2
  288.                     - p_pic->p[V_PLANE].i_pitch / 2;
  289.   uint16_t i_sub_color_U = 
  290.     (uint16_t) ( p_source->plane[U_PLANE] *
  291.  (uint16_t) (p_source->s.t) );
  292.   
  293.   uint16_t i_sub_color_V = 
  294.     (uint16_t) ( p_source->plane[V_PLANE] *
  295.  (uint16_t) (p_source->s.t) );
  296.   uint16_t i_pixel_color_U = 
  297.     (uint16_t) ( *p_pixel_U * 
  298.  (uint16_t) (MAX_TRANS - p_source->s.t) ) ;
  299.   uint16_t i_pixel_color_V = 
  300.     (uint16_t) ( *p_pixel_V * 
  301.  (uint16_t) (MAX_TRANS - p_source->s.t) ) ;
  302.   *p_pixel_U = ( i_sub_color_U + i_pixel_color_U )>>TRANS_BITS;
  303.   *p_pixel_V = ( i_sub_color_V + i_pixel_color_V )>>TRANS_BITS;
  304. }
  305. break;
  306.       }
  307.       
  308.     }
  309. }
  310.     }
  311. }
  312. /*
  313.   YUY2 Format:
  314.   Data is found in memory as an array of bytes in which the first byte
  315.   contains the first sample of Y, the second byte contains the first
  316.   sample of Cb (=U), the third byte contains the second sample of Y,
  317.   the fourth byte contains the first sample of Cr (=V); and so
  318.   on. Each 32-bit word then contains information for two contiguous
  319.   horizontal pixels, two 8-bit Y values plus a single Cb and Cr which
  320.   spans the two pixels.
  321. */
  322. #define BYTES_PER_PIXEL 4
  323. static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
  324.                         const subpicture_t *p_spu, vlc_bool_t b_crop )
  325. {
  326.   /* Common variables */
  327.   uint8_t *p_pixel_base;
  328.   /* This is the where the subtitle pixels come from */
  329.   ogt_yuvt_t *p_source = (ogt_yuvt_t *) p_spu->p_sys->p_data;
  330.   ogt_yuvt_t *p_source_end = (ogt_yuvt_t *)p_spu->p_sys->p_data + 
  331.     (p_spu->i_width * p_spu->i_height);
  332.   uint16_t i_x, i_y;
  333.   /* Make sure we start on a word (4-byte) boundary. */
  334.   uint16_t i_spu_x = (p_spu->i_x & 0xFFFE) * 2;
  335.   /* Crop-specific */
  336.   int i_x_start, i_y_start, i_x_end, i_y_end;
  337.   const struct subpicture_sys_t *p_sys = p_spu->p_sys;
  338.   
  339.   dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  340.      "spu width x height: (%dx%d), (x,y)=(%d,%d), pitch: %d", 
  341.      p_spu->i_width,  p_spu->i_height, p_spu->i_x, p_spu->i_y,
  342.      p_pic->p->i_pitch );
  343.   
  344.   p_pixel_base = p_pic->p->p_pixels + 
  345.     + ( p_spu->i_y * p_pic->p->i_pitch ) + i_spu_x;
  346.   i_x_start = p_sys->i_x_start;
  347.   i_y_start = p_sys->i_y_start * p_pic->p->i_pitch;
  348.   
  349.   i_x_end   = p_sys->i_x_end;
  350.   i_y_end   = p_sys->i_y_end   * p_pic->p->i_pitch;
  351.   /* Draw until we reach the bottom of the subtitle */
  352.   for( i_y = 0; 
  353.        i_y < p_spu->i_height * p_pic->p[Y_PLANE].i_pitch ;
  354.        i_y += p_pic->p[Y_PLANE].i_pitch )
  355.     {
  356.       uint8_t *p_pixel_base_y = p_pixel_base + i_y;
  357.       i_x = 0;
  358.       if ( b_crop ) {
  359.         if ( i_y > i_y_end ) break;
  360.         if (i_x_start) {
  361.           i_x = i_x_start;
  362.           p_source += (i_x_start*2);
  363.         }
  364.       }
  365.   
  366.       /* Draw until we reach the end of the line. Each output pixel
  367.          is a combination of two source pixels. 
  368.        */
  369.       for( i_x = 0;  i_x < p_spu->i_width / 2; i_x++, p_source +=2 )
  370. {
  371.           uint16_t i_avg_tr; /* transparancy sort of averaged over 2 pixels*/
  372.           if (p_source > p_source_end-1) {
  373.             msg_Err( p_vout, "Trying to access beyond subtitle x: %d y: %d",
  374.                      i_x, i_y);
  375.             return;
  376.           }
  377.   if( b_crop ) {
  378.             /* FIXME: y cropping should be dealt with outside of this loop.*/
  379.             if ( i_y < i_y_start) continue;
  380.             if ( i_x > i_x_end )
  381.     {
  382.       p_source += p_spu->i_width - (i_x*2);
  383.               break;
  384.     }
  385.           }
  386.   
  387.   
  388.           /* Favor opaque subtitle pixels. */
  389.   if ( (p_source->s.t == 0) && (p_source+1)->s.t == MAX_TRANS )
  390.             i_avg_tr = (p_source+1)->s.t;
  391.           else if ( (p_source->s.t == MAX_TRANS) && (p_source+1)->s.t == 0 )
  392.             i_avg_tr = p_source->s.t;
  393.           else 
  394.             i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2;
  395.           
  396. #ifdef TESTING_TRANSPARENCY 
  397.           if (i_avg_tr == MAX_TRANS) i_avg_tr >>= 1;
  398. #endif
  399.   switch( i_avg_tr )
  400.     {
  401.     case 0: 
  402.       /* Completely transparent. Don't change pixel. */
  403.       break;
  404.       
  405.     case MAX_TRANS:
  406.       {
  407. /* Completely opaque. Completely overwrite underlying
  408.    pixel with subtitle pixel. */
  409. /* This is the location that's going to get changed. */
  410. uint8_t *p_pixel = p_pixel_base_y + i_x * BYTES_PER_PIXEL;
  411. uint8_t i_avg_u;
  412. uint8_t i_avg_v;
  413.                 /* Favor opaque subtitle pixel. */
  414.                 if (p_source->s.t == MAX_TRANS ) {
  415.                   i_avg_u = p_source->plane[U_PLANE] ;
  416.                   i_avg_v = p_source->plane[V_PLANE] ;
  417.                 } else if ( (p_source+1)->s.t == MAX_TRANS ) {
  418.                   i_avg_u = (p_source+1)->plane[U_PLANE] ;
  419.                   i_avg_v = (p_source+1)->plane[V_PLANE] ;
  420.                 } else {
  421.                   i_avg_u = ( p_source->plane[U_PLANE] 
  422.                               + (p_source+1)->plane[U_PLANE] ) / 2;
  423.                   i_avg_v = ( p_source->plane[V_PLANE] 
  424.                               + (p_source+1)->plane[V_PLANE] ) / 2;
  425.                 }
  426. /* draw a two contiguous pixels: 2 Y values, 1 U, and 1 V. */
  427. *p_pixel++ = p_source->plane[Y_PLANE] ;
  428.                 *p_pixel++ = i_avg_u;
  429. *p_pixel++ = (p_source+1)->plane[Y_PLANE] ;
  430.                 *p_pixel++ = i_avg_v;
  431.                 
  432. break;
  433.       }
  434.     default:
  435.       {
  436. /* Blend in underlying subtitle pixels. */
  437. /* This is the location that's going to get changed. */
  438. uint8_t *p_pixel = p_pixel_base_y + i_x * BYTES_PER_PIXEL;
  439. uint8_t i_avg_u = ( p_source->plane[U_PLANE] 
  440.                                     + (p_source+1)->plane[U_PLANE] ) / 2;
  441. uint8_t i_avg_v = ( p_source->plane[V_PLANE] 
  442.                                     + (p_source+1)->plane[V_PLANE] ) / 2;
  443. /* This is the weighted part of the two subtitle
  444.    pixels. The color plane is 8 bits and transparancy
  445.    is 4 bits so when multiplied we get up to 12 bits.
  446.  */
  447. uint16_t i_sub_color_Y1 = 
  448.   (uint16_t) ( p_source->plane[Y_PLANE] *
  449.        (uint16_t) (p_source->s.t) );
  450. uint16_t i_sub_color_Y2 = 
  451.   (uint16_t) ( (p_source+1)->plane[Y_PLANE] *
  452.        (uint16_t) ((p_source+1)->s.t) );
  453. /* This is the weighted part of the underlying pixels.
  454.    For the same reasons above, the result is up to 12
  455.    bits.  However since the transparancies are
  456.    inverses, the sum of i_sub_color and i_pixel_color
  457.    will not exceed 12 bits.
  458. */
  459. uint16_t i_sub_color_U = 
  460.   (uint16_t) ( i_avg_u * (uint16_t) i_avg_tr );
  461. uint16_t i_sub_color_V = 
  462.   (uint16_t) ( i_avg_v * (uint16_t) i_avg_tr );
  463. uint16_t i_pixel_color_Y1 = 
  464.   (uint16_t) ( *(p_pixel) * 
  465.        (uint16_t) (MAX_TRANS - i_avg_tr) ) ;
  466. uint16_t i_pixel_color_Y2 = 
  467.   (uint16_t) ( *(p_pixel+2) * 
  468.        (uint16_t) (MAX_TRANS - i_avg_tr) ) ;
  469. uint16_t i_pixel_color_U = 
  470.   (uint16_t) ( *(p_pixel+1) * 
  471.        (uint16_t) (MAX_TRANS - i_avg_tr) ) ;
  472. uint16_t i_pixel_color_V = 
  473.   (uint16_t) ( *(p_pixel+3) * 
  474.        (uint16_t) (MAX_TRANS - i_avg_tr) ) ;
  475. /* draw a two contiguous pixels: 2 Y values, 1 U, and 1 V. */
  476. /* Scale the 12-bit result back down to 8 bits. A
  477.    precise scaling after adding the two components,
  478.    would divide by one less than a power of 2. However
  479.    to simplify and speed things we use a power of
  480.    2. This means the boundaries (either all
  481.    transparent and all opaque) aren't handled properly.
  482.    But we deal with them in special cases above. */
  483. *p_pixel++ = ( i_sub_color_Y1 + i_pixel_color_Y1 )>>TRANS_BITS;
  484. *p_pixel++ = ( i_sub_color_U + i_pixel_color_U )  >>TRANS_BITS;
  485. *p_pixel++ = ( i_sub_color_Y2 + i_pixel_color_Y2 )>>TRANS_BITS;
  486. *p_pixel++ = ( i_sub_color_V + i_pixel_color_V )  >>TRANS_BITS;
  487. break;
  488.       }
  489.     }
  490. }
  491.       /* For an odd width source, we'll just have to drop off a pixel. */
  492.       if (p_spu->i_width % 2) p_source++;
  493.     }
  494. }
  495. /**
  496.    Convert a YUV pixel into a 16-bit RGB 5-5-5 pixel.
  497.    A RGB 5-5-5 pixel looks like this:
  498.    RGB 5-5-5   bit  (MSB) 7  6   5  4  3  2  1  0 (LSB)
  499.                  p    ? B4  B3 B2 B1 B0 R4  R3
  500.                  q   R2 R1  R0 G4 G3 G2 G1  G0
  501. **/
  502. static inline void
  503. yuv2rgb555(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 )
  504. {
  505.   uint8_t rgb[RGB_SIZE];
  506.   yuv2rgb(p_yuv, rgb);
  507.   
  508.   /* Scale RGB from 8 bits down to 5. */
  509.   rgb[RED_PIXEL]   >>= (8-5);
  510.   rgb[GREEN_PIXEL] >>= (8-5);
  511.   rgb[BLUE_PIXEL]  >>= (8-5);
  512.   
  513.   *p_rgb1 = ( (rgb[BLUE_PIXEL] << 2)&0x7c ) | ( (rgb[RED_PIXEL]>>3) & 0x03 );
  514.   *p_rgb2 = ( (rgb[RED_PIXEL]  << 5)&0xe0 ) | ( rgb[GREEN_PIXEL]&0x1f );
  515. #if 0
  516.   printf("Y,Cb,Cr,T=(%02x,%02x,%02x,%02x), r,g,b=(%d,%d,%d), "
  517.          "rgb1: %02x, rgb2 %02xn",
  518.          p_yuv->s.y, p_yuv->s.u, p_yuv->s.v, p_yuv->s.t,
  519.          rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL],
  520.          *p_rgb1, *p_rgb2);
  521. #endif
  522. }
  523. /**
  524.    Convert a YUV pixel into a 16-bit RGB 5-6-5 pixel.
  525.    A RGB 5-6-5 pixel looks like this:
  526.    RGB 5-6-5   bit  (MSB) 7  6   5  4  3  2  1  0 (LSB)
  527.                  p   B4 B3  B2 B1 B0 R5 R4  R3
  528.                  q   R2 R1  R0 G4 G3 G2 G1  G0
  529. **/
  530. static inline void
  531. yuv2rgb565(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 )
  532. {
  533.   uint8_t rgb[RGB_SIZE];
  534.   yuv2rgb(p_yuv, rgb);
  535.   
  536.   /* Scale RGB from 8 bits down to 5 or 6 bits. */
  537.   rgb[RED_PIXEL]   >>= (8-6);
  538.   rgb[GREEN_PIXEL] >>= (8-5);
  539.   rgb[BLUE_PIXEL]  >>= (8-5);
  540.   
  541.   *p_rgb1 = ( (rgb[BLUE_PIXEL] << 3)&0xF8 ) | ( (rgb[RED_PIXEL]>>3) & 0x07 );
  542.   *p_rgb2 = ( (rgb[RED_PIXEL]  << 5)&0xe0 ) | ( rgb[GREEN_PIXEL]&0x1f );
  543. #if 0
  544.   printf("Y,Cb,Cr,T=(%02x,%02x,%02x,%02x), r,g,b=(%d,%d,%d), "
  545.          "rgb1: %02x, rgb2 %02xn",
  546.          p_yuv->s.y, p_yuv->s.u, p_yuv->s.v, p_yuv->s.t,
  547.          rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL],
  548.          *p_rgb1, *p_rgb2);
  549. #endif
  550. }
  551. static inline void
  552. rv16_pack_blend(uint8_t *p_pixel, ogt_yuvt_t *p_source,  uint8_t *p_rgb1,
  553.                 uint8_t *p_rgb2, vlc_bool_t b_15bpp, uint8_t i_trans, 
  554.                 int a_scale_down )
  555. {
  556.   uint8_t rgb_sub[3];
  557.   uint8_t rgb_vout[RGB_SIZE];
  558.   int i;
  559.   yuv2rgb(p_source, rgb_sub);
  560.   /* Scale RGB from 8 bits down to 6 or 5. */
  561.   rgb_sub[GREEN_PIXEL] >>= (8-5);
  562.   rgb_sub[BLUE_PIXEL]  >>= (8-5);
  563.   rgb_vout[GREEN_PIXEL] = *(p_pixel+1)    & 0x1f;
  564.   if (b_15bpp) {
  565.     rgb_sub[RED_PIXEL]   >>= (8-5);
  566.     rgb_vout[BLUE_PIXEL]  = ((*p_pixel)>>2) & 0x1f;
  567.     rgb_vout[RED_PIXEL]   = ((*p_pixel & 0x03) << 3) | ((*(p_pixel+1)&0xe0)>>5);
  568.   } else {
  569.     rgb_sub[RED_PIXEL]   >>= (8-6);
  570.     rgb_vout[BLUE_PIXEL]  = ((*p_pixel)>>3) & 0x1f;
  571.     rgb_vout[RED_PIXEL]   = ((*p_pixel & 0x07) << 3) | ((*(p_pixel+1)&0xe0)>>5);
  572.   }
  573.   
  574. #if 0
  575.   printf("r,g,b=(%d,%d,%d), sub r,g,b=(%d,%d,%d), trans %d, inv_trans %dn",
  576.          rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL],
  577.          rgb_sub[RED_PIXEL], rgb_sub[GREEN_PIXEL], 
  578.          rgb_sub[BLUE_PIXEL], i_trans, i_inv_trans);
  579. #endif
  580. #ifdef FIXED_RV16_TRANSPARENCY
  581.   avg_8bit_rgb(rgb_vout, rgb_sub, i_trans);
  582. #else 
  583.   for (i=0; i < RGB_SIZE; i++) {
  584.     /* For now the Best we can do is fade the color. Picking up 
  585.        video underneath doesn't work. */
  586.     /* rgb_vout[i] = ( (uint16_t) rgb_vout[i]*i_inv_trans ) >> TRANS_BITS; */
  587.     rgb_vout[i] = ( (uint16_t) rgb_sub[i]*i_trans ) >> TRANS_BITS;
  588. #endif 
  589.   }
  590.   
  591. #if 0
  592.   printf("avg r,g,b=(%d,%d,%d)n",
  593.          rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL] );
  594. #endif
  595. #if 0
  596.   if (b_15bpp) {
  597.     *p_rgb1 = ( (rgb_vout[BLUE_PIXEL] << 2)&0x7c )|( (rgb_vout[RED_PIXEL]>>3)&0x03 );
  598.   } else {
  599.     *p_rgb1 = ( (rgb_vout[BLUE_PIXEL] << 3)&0xF8 )|( (rgb_vout[RED_PIXEL]>>3)&0x07 );
  600.   }
  601.   *p_rgb2 = ( (rgb_vout[RED_PIXEL]  << 5)&0xe0 ) | ( rgb_vout[GREEN_PIXEL]&0x1f );
  602. #else 
  603.   *p_rgb1 = (*p_rgb1)+1;
  604.   *p_rgb2 = (*p_rgb2)+1;
  605. #endif
  606.   
  607. }
  608. #undef BYTES_PER_PIXEL
  609. #define BYTES_PER_PIXEL 2
  610. static void 
  611. BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
  612.            const subpicture_t *p_spu, vlc_bool_t b_crop,
  613.            vlc_bool_t b_15bpp )
  614. {
  615.     /* Common variables */
  616.     uint8_t *p_pixel_base;
  617.     ogt_yuvt_t *p_src_start = (ogt_yuvt_t *)p_spu->p_sys->p_data;
  618.     ogt_yuvt_t *p_src_end   = &p_src_start[p_spu->i_height * p_spu->i_width];
  619.     ogt_yuvt_t *p_source;
  620.     int i_x, i_y;
  621.     int i_y_src;
  622.     /* Chroma specific */
  623.     uint32_t i_xscale;   /* Amount we scale subtitle in the x direction,
  624.                             multiplied by 2**ASCALE. */
  625.     uint32_t i_yscale;   /* Amount we scale subtitle in the y direction.
  626.                             multiplied by 2**ASCALE. */
  627.     int i_width, i_height, i_ytmp, i_ynext;
  628.     /* Crop-specific */
  629.     int i_x_start, i_y_start, i_x_end, i_y_end;
  630.     struct subpicture_sys_t *p_sys = p_spu->p_sys;
  631.     i_xscale = ( p_vout->output.i_width << ASCALE ) / p_vout->render.i_width;
  632.     i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;
  633.     dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  634.        "spu: %dx%d, scaled: %dx%d, vout render: %dx%d, scale %dx%d", 
  635.        p_spu->i_width,  p_spu->i_height, 
  636.        p_vout->output.i_width, p_vout->output.i_height,
  637.        p_vout->render.i_width, p_vout->render.i_height,
  638.        i_xscale, i_yscale
  639.        );
  640.     i_width  = p_spu->i_width  * i_xscale;
  641.     i_height = p_spu->i_height * i_yscale;
  642.     /* Set where we will start blending subtitle from using
  643.        the picture coordinates subtitle offsets
  644.     */
  645.     p_pixel_base = p_pic->p->p_pixels 
  646.               + ( (p_spu->i_x * i_xscale) >> ASCALE ) * BYTES_PER_PIXEL
  647.               + ( (p_spu->i_y * i_yscale) >> ASCALE ) * p_pic->p->i_pitch;
  648.     i_x_start = p_sys->i_x_start;
  649.     i_y_start = i_yscale * p_sys->i_y_start;
  650.     i_x_end   = p_sys->i_x_end;
  651.     i_y_end   = i_yscale * p_sys->i_y_end;
  652.     p_source = (ogt_yuvt_t *)p_sys->p_data;
  653.   
  654.     /* Draw until we reach the bottom of the subtitle */
  655.     i_y = 0;
  656.     for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width; 
  657.          i_y_src += p_spu->i_width )
  658.     {
  659. uint8_t *p_pixel_base_y;
  660.         i_ytmp = i_y >> ASCALE;
  661.         i_y += i_yscale;
  662. p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);
  663. i_x = 0;
  664.         if ( b_crop ) {
  665.           if ( i_y > i_y_end ) break;
  666.           if (i_x_start) {
  667.             i_x = i_x_start;
  668.             p_source += i_x_start;
  669.           }
  670.         }
  671.         /* Check whether we need to draw one line or more than one */
  672.         if( i_ytmp + 1 >= ( i_y >> ASCALE ) )
  673.         {
  674.           /* Draw until we reach the end of the line */
  675.           for( ; i_x < p_spu->i_width;  i_x++, p_source++ )
  676.             {
  677. #if 0              
  678.               uint8_t *p=(uint8_t *) p_source;
  679.               printf("+++ %02x %02x %02x %02xn", 
  680.                      p[0], p[1], p[2], p[3]);
  681. #endif
  682.     
  683.               if( b_crop ) {
  684.                 
  685.                 /* FIXME: y cropping should be dealt with outside of this 
  686.                    loop.*/
  687.                 if ( i_y < i_y_start) continue;
  688.                 
  689.                 if ( i_x > i_x_end )
  690.                   {
  691.                     p_source += p_spu->i_width - i_x;
  692.                     break;
  693.                   }
  694.               }
  695.       if (p_source >= p_src_end) {
  696. msg_Err( p_vout, "Trying to access beyond subtitle %dx%d %d",
  697.  i_x, i_y / i_yscale, i_height);
  698. return;
  699.       }
  700.       
  701. #ifdef TESTING_TRANSPARENCY
  702.               if (p_source->s.t == MAX_TRANS) p_source->s.t >>= 1;
  703. #endif
  704.       switch( p_source->s.t )
  705.                 {
  706.                 case 0:
  707.   /* Completely transparent. Don't change pixel. */
  708.   break;
  709.   
  710.                 case MAX_TRANS:
  711.   {
  712.     /* Completely opaque. Completely overwrite underlying
  713.        pixel with subtitle pixel. */
  714.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  715.                                          * BYTES_PER_PIXEL );
  716.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  717.                                          * BYTES_PER_PIXEL );
  718.                     uint32_t len     = i_xlast - i_xdest;
  719.                     uint8_t i_rgb1;
  720.                     uint8_t i_rgb2;
  721.     /* This is the location that's going to get changed. */
  722.     uint8_t *p_dest = p_pixel_base_y + i_x * BYTES_PER_PIXEL;
  723.                     if (b_15bpp) 
  724.                       yuv2rgb555(p_source, &i_rgb1, &i_rgb2);
  725.                     else 
  726.                       yuv2rgb565(p_source, &i_rgb1, &i_rgb2);
  727.                     for ( len = i_xlast - i_xdest; len ; len--) {
  728.                       *p_dest++ = i_rgb1;
  729.                       *p_dest++ = i_rgb2;
  730.                     }
  731.     break;
  732.   }
  733.                 default:
  734.   {
  735.     /* Blend in underlying pixel subtitle pixel. */
  736.     
  737.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  738.                                          * BYTES_PER_PIXEL );
  739.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  740.                                          * BYTES_PER_PIXEL );
  741.                     uint8_t i_rgb1;
  742.                     uint8_t i_rgb2;
  743.                     uint32_t len     = i_xlast - i_xdest;
  744.     /* This is the location that's going to get changed. */
  745.     uint8_t *p_dest = p_pixel_base_y + i_x * BYTES_PER_PIXEL;
  746.                     for ( len = i_xlast - i_xdest; len ; len--) {
  747.                       rv16_pack_blend(p_dest, p_source, &i_rgb1, &i_rgb2, 
  748.                                       b_15bpp, p_source->s.t, TRANS_SCALEDOWN);
  749.                       *p_dest++ = i_rgb1;
  750.                       *p_dest++ = i_rgb2;
  751.                     }
  752.     break;
  753.   }
  754.                 }
  755.             }
  756.         }
  757.         else
  758.         {
  759.             i_ynext = p_pic->p->i_pitch * i_y >> ASCALE;
  760.             /* Draw until we reach the end of the line */
  761.             for( ; i_x < p_spu->i_width; i_x++, p_source++ )
  762.             {
  763.               if( b_crop ) {
  764.                 
  765.                 /* FIXME: y cropping should be dealt with outside of this 
  766.                    loop.*/
  767.                 if ( i_y < i_y_start) continue;
  768.                 
  769.                 if ( i_x > i_x_end )
  770.                   {
  771.                     p_source += p_spu->i_width - i_x;
  772.                     break;
  773.                   }
  774.               }
  775.       
  776.       if (p_source >= p_src_end) {
  777. msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
  778.  i_x, i_y / i_yscale, i_height);
  779. return;
  780.       }
  781.       
  782.       switch( p_source->s.t )
  783.                 {
  784.                 case 0:
  785.     /* Completely transparent. Don't change pixel. */
  786.                     break;
  787.                 case MAX_TRANS: 
  788.   {
  789.     /* Completely opaque. Completely overwrite underlying
  790.        pixel with subtitle pixel. */
  791.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  792.                                          * BYTES_PER_PIXEL );
  793.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  794.                                          * BYTES_PER_PIXEL );
  795.                     uint32_t len     = i_xlast - i_xdest;
  796.     uint8_t *p_pixel_base_x = p_pixel_base + i_xdest;
  797.                     for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
  798.                     {
  799.       /* This is the location that's going to get changed. */
  800.       uint8_t *p_dest = p_pixel_base_x + i_ytmp;
  801.                       uint8_t i_rgb1, i_rgb2;
  802.                       if (b_15bpp) 
  803.                         yuv2rgb555(p_source, &i_rgb1, &i_rgb2);
  804.                       else 
  805.                         yuv2rgb565(p_source, &i_rgb1, &i_rgb2);
  806.                       for ( len = i_xlast - i_xdest; len ; len--) {
  807.                         *p_dest++ = i_rgb1;
  808.                         *p_dest++ = i_rgb2;
  809.                       }
  810.                     }
  811.                     break;
  812.   }
  813.                 default: 
  814.                   {
  815.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  816.                                          * BYTES_PER_PIXEL );
  817.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  818.                                          * BYTES_PER_PIXEL );
  819.                     uint32_t len     = i_xlast - i_xdest;
  820.                     uint8_t i_rgb1, i_rgb2;
  821.                     for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
  822.                     {
  823.       /* Blend in underlying pixel subtitle pixel. */
  824.       uint8_t *p_dest = p_pixel_base + i_ytmp;
  825.                       for ( len = i_xlast - i_xdest; len ; len--) {
  826.                         rv16_pack_blend(p_dest, p_source, &i_rgb1, &i_rgb2,
  827.                                       b_15bpp, p_source->s.t, TRANS_SCALEDOWN);
  828.                         *p_dest++ = i_rgb1;
  829.                         *p_dest++ = i_rgb2;
  830.                       }
  831.                     }
  832.                     break;
  833.                   }
  834. }
  835.     }
  836. }
  837.     }
  838. }
  839. #undef  BYTES_PER_PIXEL
  840. #define BYTES_PER_PIXEL 4
  841. static inline void
  842. rv24_pack_blend(uint8_t *rgb_vout, const uint8_t *rgb_sub,  uint8_t i_trans,  
  843.                 int a_scale_down )
  844. {
  845. #if 0
  846.   printf("r,g,b=(%d,%d,%d), source r,g,b=(%d,%d,%d), trans %dn",
  847.          rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL],
  848.          rgb_sub[RED_PIXEL], rgb_sub[GREEN_PIXEL], 
  849.          rgb_sub[BLUE_PIXEL], i_trans);
  850. #endif
  851. #ifdef WORDS_BIGENDIAN
  852.   *rgb_vout++;
  853. #endif
  854.   avg_8bit_rgb(rgb_vout, rgb_sub, i_trans);
  855.   
  856. #if 0
  857.   printf("avg r,g,b=(%d,%d,%d)n",
  858.          rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL] );
  859. #endif
  860. }
  861. /* 
  862.   RV24 format??? Is this just for X11? Or just not for Win32? Is this
  863.   the same as RV32?
  864.   a pixel is represented by 3 bytes containing a red,
  865.   blue and green sample with blue stored at the lowest address, green
  866.   next then red. One padding byte is added between pixels. Although
  867.   this may not be part of a spec, images should be stored with each
  868.   line padded to a u_int32 boundary. 
  869. */
  870. static void 
  871. BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
  872.             const subpicture_t *p_spu, vlc_bool_t b_crop )
  873. {
  874.   /* Common variables */
  875.   uint8_t *p_pixel_base;
  876.   ogt_yuvt_t *p_src_start = (ogt_yuvt_t *)p_spu->p_sys->p_data;
  877.   ogt_yuvt_t *p_src_end   = &p_src_start[p_spu->i_height * p_spu->i_width];
  878.   ogt_yuvt_t *p_source; /* This is the where the subtitle pixels come from */
  879.   
  880.   int i_x, i_y;
  881.   int i_y_src;
  882.   
  883.   /* Make sure we start on a word (4-byte) boundary. */
  884.   uint32_t i_spu_x;
  885.   
  886.   /* Chroma specific */
  887.   uint32_t i_xscale;   /* Amount we scale subtitle in the x direction,
  888.                           multiplied by 2**ASCALE. */
  889.   uint32_t i_yscale;   /* Amount we scale subtitle in the y direction.
  890.                           multiplied by 2**ASCALE. */
  891.   
  892.   int i_width, i_height, i_ytmp, i_ynext;
  893.   
  894.   /* Crop-specific */
  895.   int32_t i_x_start, i_y_start, i_x_end, i_y_end;
  896.   
  897.   struct subpicture_sys_t *p_sys = p_spu->p_sys;
  898.   int i_aspect_x, i_aspect_y;
  899.   
  900.   vlc_reduce( &i_aspect_x, &i_aspect_y, p_vout->render.i_aspect,
  901.                VOUT_ASPECT_FACTOR, 0 );
  902.   
  903.   i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x)
  904.     / (i_aspect_y * p_vout->render.i_width);
  905.   i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;
  906.   
  907.   dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  908.              "spu: %dx%d, scaled: %dx%d, vout render: %dx%d, scale %dx%d", 
  909.              p_spu->i_width,  p_spu->i_height, 
  910.              p_vout->output.i_width, p_vout->output.i_height,
  911.              p_vout->render.i_width, p_vout->render.i_height,
  912.              i_xscale, i_yscale
  913.              );
  914.   
  915.   i_width  = p_spu->i_width  * i_xscale;
  916.   i_height = p_spu->i_height * i_yscale;
  917.   
  918.   /* Set where we will start blending subtitle from using
  919.      the picture coordinates subtitle offsets.
  920.   */
  921.   i_spu_x = ((p_spu->i_x * i_xscale) >> ASCALE) * BYTES_PER_PIXEL;
  922.   
  923.   p_pixel_base = p_pic->p->p_pixels + i_spu_x
  924.     + ( (p_spu->i_y * i_yscale) >> ASCALE ) * p_pic->p->i_pitch;
  925.   
  926.   i_x_start = p_sys->i_x_start;
  927.   i_y_start = i_yscale * p_sys->i_y_start;
  928.   i_x_end   = p_sys->i_x_end;
  929.   i_y_end   = i_yscale * p_sys->i_y_end;
  930.   
  931.   p_source = (ogt_yuvt_t *)p_sys->p_data;
  932.   
  933.   /* Draw until we reach the bottom of the subtitle */
  934.   i_y = 0;
  935.   for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width; 
  936.        i_y_src += p_spu->i_width )
  937.     {
  938.       uint8_t *p_pixel_base_y;
  939.       i_ytmp = i_y >> ASCALE;
  940.       i_y += i_yscale;
  941.       p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);
  942.       i_x = 0;
  943.       
  944.       if ( b_crop ) {
  945.         if ( i_y > i_y_end ) break;
  946.         if (i_x_start) {
  947.           i_x = i_x_start;
  948.           p_source += i_x_start;
  949.         }
  950.       }
  951.       
  952.       /* Check whether we need to draw one line or more than one */
  953.       if( i_ytmp + 1 >= ( i_y >> ASCALE ) )
  954.         {
  955.           /* Draw until we reach the end of the line */
  956.           for( ; i_x < p_spu->i_width;  i_x++, p_source++ )
  957.             {
  958.               
  959.               if( b_crop ) {
  960.                 
  961.                 /* FIXME: y cropping should be dealt with outside of this 
  962.                    loop.*/
  963.                 if ( i_y < i_y_start) continue;
  964.                 
  965.                 if ( i_x > i_x_end )
  966.                   {
  967.                     p_source += p_spu->i_width - i_x;
  968.                     break;
  969.                   }
  970.               }
  971.               
  972.       if (p_source >= p_src_end) {
  973. msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
  974.  i_x, i_y / i_yscale, i_height);
  975. return;
  976.       }
  977.       
  978. #ifdef TESTING_TRANSPARENCY
  979.               if (p_source->s.t == MAX_TRANS) p_source->s.t >>= 2;
  980. #endif
  981.       switch( p_source->s.t )
  982.                 {
  983.                 case 0:
  984.   /* Completely transparent. Don't change pixel. */
  985.   break;
  986.   
  987.                 case MAX_TRANS:
  988.   {
  989.     /* Completely opaque. Completely overwrite underlying
  990.        pixel with subtitle pixel. */
  991.                     
  992.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  993.                                          * BYTES_PER_PIXEL );
  994.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  995.                                          * BYTES_PER_PIXEL );
  996.                     uint32_t len     = i_xlast - i_xdest;
  997.                     
  998.                     uint8_t rgb[RGB_SIZE];
  999.                     
  1000.     /* This is the location that's going to get changed. */
  1001.     uint8_t *p_dest = p_pixel_base_y + i_xdest;
  1002.                     
  1003.                     yuv2rgb(p_source, rgb);
  1004.                     
  1005.                     for ( len = i_xlast - i_xdest; len ; len--) {
  1006.                       put_rgb24_pixel(rgb, p_dest);
  1007.                       p_dest += BYTES_PER_PIXEL;
  1008.                     }
  1009.                     
  1010.                   default:
  1011.                     {
  1012.                       /* Blend in underlying pixel subtitle pixel. */
  1013.                       
  1014.                       uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1015.                                            * BYTES_PER_PIXEL );
  1016.                       uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1017.                                            * BYTES_PER_PIXEL );
  1018.                       uint32_t len     = i_xlast - i_xdest * BYTES_PER_PIXEL;
  1019.                       
  1020.                       /* To be able to scale correctly for full
  1021.                          opaqueness, we add 1 to the transparency.
  1022.                          This means transparency value 0 won't be
  1023.                          completely transparent which is not correct.
  1024.                          But that's handled in a special case above
  1025.                          anyway. */
  1026.                       
  1027.                       /* This is the location that's going to get changed. */
  1028.                       uint8_t *p_dest = p_pixel_base_y + i_xdest;
  1029.                       uint8_t rgb[RGB_SIZE];
  1030.                       
  1031.                       yuv2rgb(p_source, rgb);
  1032.                       for ( len = i_xlast - i_xdest; len ; len--) {
  1033.                         rv24_pack_blend(p_dest, rgb, p_source->s.t,
  1034.                                         TRANS_SCALEDOWN);
  1035.                         p_dest += BYTES_PER_PIXEL;
  1036.                       }
  1037.                       break;
  1038.                     }
  1039.                   }
  1040.                 }
  1041.             }
  1042.         } 
  1043.         else
  1044.         {
  1045.             i_ynext = p_pic->p->i_pitch * i_y >> ASCALE;
  1046.             /* Draw until we reach the end of the line */
  1047.             for( ; i_x < p_spu->i_width; i_x++, p_source++ )
  1048.             {
  1049.               if( b_crop ) {
  1050.                 
  1051.                 /* FIXME: y cropping should be dealt with outside of this 
  1052.                    loop.*/
  1053.                 if ( i_y < i_y_start) continue;
  1054.                 
  1055.                 if ( i_x > i_x_end )
  1056.                   {
  1057.                     p_source += p_spu->i_width - i_x;
  1058.                     break;
  1059.                   }
  1060.               }
  1061.       
  1062.       if (p_source >= p_src_end) {
  1063. msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
  1064.  i_x, i_y / i_yscale, i_height);
  1065. return;
  1066.       }
  1067.       
  1068.       switch( p_source->s.t )
  1069.                 {
  1070.                 case 0:
  1071.     /* Completely transparent. Don't change pixel. */
  1072.                     break;
  1073.                 case MAX_TRANS: 
  1074.   {
  1075.     /* Completely opaque. Completely overwrite underlying
  1076.        pixel with subtitle pixel. */
  1077.     /* This is the location that's going to get changed. */
  1078.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1079.                                          * BYTES_PER_PIXEL );
  1080.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1081.                                          * BYTES_PER_PIXEL );
  1082.                     uint32_t len     = i_xlast - i_xdest;
  1083.                     uint8_t rgb[RGB_SIZE];
  1084.                     yuv2rgb(p_source, rgb); 
  1085.                     for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
  1086.                     {
  1087.                       /* Completely opaque. Completely overwrite underlying
  1088.                          pixel with subtitle pixel. */
  1089.                       
  1090.                       /* This is the location that's going to get changed. */
  1091.                       uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
  1092.                       
  1093.                       for ( len = i_xlast - i_xdest; len ; len--) {
  1094.                         put_rgb24_pixel(rgb, p_dest);
  1095.                         p_dest += BYTES_PER_PIXEL;
  1096.                       }
  1097.                     }
  1098.                     break;
  1099.   }
  1100.                 default: 
  1101.                   {
  1102.                     
  1103.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1104.                                          * BYTES_PER_PIXEL );
  1105.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1106.                                          * BYTES_PER_PIXEL );
  1107.                     uint32_t len     = i_xlast - i_xdest;
  1108.                     uint8_t  rgb[RGB_SIZE];
  1109.                     yuv2rgb(p_source, rgb);
  1110.                     for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
  1111.                     {
  1112.       /* Blend in underlying pixel subtitle pixel. */
  1113.       
  1114.                       /* This is the location that's going to get changed. */
  1115.                       uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
  1116.       /* To be able to scale correctly for full opaqueness, we
  1117.  add 1 to the alpha.  This means alpha value 0 won't
  1118.  be completely transparent and is not correct, but
  1119.  that's handled in a special case above anyway. */
  1120.                       for ( len = i_xlast - i_xdest; len ; len--) {
  1121.                         rv24_pack_blend(p_dest, rgb, p_source->s.t,
  1122.                                         TRANS_SCALEDOWN);
  1123.                         p_dest += BYTES_PER_PIXEL;
  1124.                       }
  1125.                     }
  1126.                     break;
  1127.                   }
  1128.                 }
  1129.             }
  1130. }
  1131.     }
  1132. }
  1133. #undef  BYTES_PER_PIXEL
  1134. #define BYTES_PER_PIXEL 4
  1135. /* 
  1136.   RV32 format??? Is this just for X11? Or just not for Win32? Is this
  1137.   the same as RV24?
  1138.   RV32 format: a pixel is represented by 4 bytes containing a red,
  1139.   blue and green sample with blue stored at the lowest address, green
  1140.   next then red. One padding byte is added between pixels. Although
  1141.   this may not be part of a spec, images should be stored with each
  1142.   line padded to a u_int32 boundary. 
  1143. */
  1144. static void 
  1145. BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
  1146.             const subpicture_t *p_spu, vlc_bool_t b_crop )
  1147. {
  1148.     /* Common variables */
  1149.     uint8_t *p_pixel_base;
  1150.     ogt_yuvt_t *p_src_start = (ogt_yuvt_t *)p_spu->p_sys->p_data;
  1151.     ogt_yuvt_t *p_src_end   = &p_src_start[p_spu->i_height * p_spu->i_width];
  1152.     ogt_yuvt_t *p_source; /* This is the where the subtitle pixels come from */
  1153.     int i_x, i_y;
  1154.     int i_y_src;
  1155.     /* Make sure we start on a word (4-byte) boundary. */
  1156.     uint32_t i_spu_x;
  1157.     /* Chroma specific */
  1158.     uint32_t i_xscale;   /* Amount we scale subtitle in the x direction,
  1159.                             multiplied by 2**ASCALE. */
  1160.     uint32_t i_yscale;   /* Amount we scale subtitle in the y direction.
  1161.                             multiplied by 2**ASCALE. */
  1162.     int i_width, i_height, i_ytmp, i_ynext;
  1163.     /* Crop-specific */
  1164.     int32_t i_x_start, i_y_start, i_x_end, i_y_end;
  1165.     struct subpicture_sys_t *p_sys = p_spu->p_sys;
  1166.     int i_aspect_x, i_aspect_y;
  1167.     vlc_reduce( &i_aspect_x, &i_aspect_y, p_vout->render.i_aspect,
  1168.                 VOUT_ASPECT_FACTOR, 0 );
  1169.     i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x)
  1170.       / (i_aspect_y * p_vout->render.i_width);
  1171.     i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;
  1172.     dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  1173.        "spu: %dx%d, scaled: %dx%d, vout render: %dx%d, scale %dx%d", 
  1174.        p_spu->i_width,  p_spu->i_height, 
  1175.        p_vout->output.i_width, p_vout->output.i_height,
  1176.        p_vout->render.i_width, p_vout->render.i_height,
  1177.        i_xscale, i_yscale
  1178.        );
  1179.     i_width  = p_spu->i_width  * i_xscale;
  1180.     i_height = p_spu->i_height * i_yscale;
  1181.     /* Set where we will start blending subtitle from using
  1182.        the picture coordinates subtitle offsets.
  1183.     */
  1184.     i_spu_x = ((p_spu->i_x * i_xscale) >> ASCALE) * BYTES_PER_PIXEL; 
  1185.     p_pixel_base = p_pic->p->p_pixels + i_spu_x
  1186.               + ( (p_spu->i_y * i_yscale) >> ASCALE ) * p_pic->p->i_pitch;
  1187.     i_x_start = p_sys->i_x_start;
  1188.     i_y_start = i_yscale * p_sys->i_y_start;
  1189.     i_x_end   = p_sys->i_x_end;
  1190.     i_y_end   = i_yscale * p_sys->i_y_end;
  1191.     p_source = (ogt_yuvt_t *)p_sys->p_data;
  1192.   
  1193.     /* Draw until we reach the bottom of the subtitle */
  1194.     i_y = 0;
  1195.     for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width; 
  1196.          i_y_src += p_spu->i_width )
  1197.     {
  1198. uint8_t *p_pixel_base_y;
  1199.         i_ytmp = i_y >> ASCALE;
  1200.         i_y += i_yscale;
  1201. p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);
  1202. i_x = 0;
  1203.         if ( b_crop ) {
  1204.           if ( i_y > i_y_end ) break;
  1205.           if (i_x_start) {
  1206.             i_x = i_x_start;
  1207.             p_source += i_x_start;
  1208.           }
  1209.         }
  1210.         /* Check whether we need to draw one line or more than one */
  1211.         if( i_ytmp + 1 >= ( i_y >> ASCALE ) )
  1212.         {
  1213.           /* Draw until we reach the end of the line */
  1214.           for( ; i_x < p_spu->i_width;  i_x++, p_source++ )
  1215.             {
  1216.               if( b_crop ) {
  1217.                 
  1218.                 /* FIXME: y cropping should be dealt with outside of this 
  1219.                    loop.*/
  1220.                 if ( i_y < i_y_start) continue;
  1221.                 
  1222.                 if ( i_x > i_x_end )
  1223.                   {
  1224.                     p_source += p_spu->i_width - i_x;
  1225.                     break;
  1226.                   }
  1227.               }
  1228.       if (p_source >= p_src_end) {
  1229. msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
  1230.  i_x, i_y / i_yscale, i_height);
  1231. return;
  1232.       }
  1233.       
  1234.       switch( p_source->s.t )
  1235.                 {
  1236.                 case 0:
  1237.   /* Completely transparent. Don't change pixel. */
  1238.   break;
  1239.   
  1240.                 default:
  1241.                 case MAX_TRANS:
  1242.   {
  1243.     /* Completely opaque. Completely overwrite underlying
  1244.        pixel with subtitle pixel. */
  1245.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1246.                                          * BYTES_PER_PIXEL );
  1247.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1248.                                          * BYTES_PER_PIXEL );
  1249.                     uint32_t len     = i_xlast - i_xdest;
  1250.                     uint8_t rgb[RGB_SIZE];
  1251.     /* This is the location that's going to get changed. */
  1252.     uint8_t *p_dest = p_pixel_base_y + i_xdest;
  1253.                     yuv2rgb(p_source, rgb);
  1254.                     for ( len = i_xlast - i_xdest; len ; len--) {
  1255.                       *p_dest++ = rgb[BLUE_PIXEL];
  1256.                       *p_dest++ = rgb[GREEN_PIXEL];
  1257.                       *p_dest++ = rgb[RED_PIXEL];
  1258.                       *p_dest++;
  1259.                     }
  1260. #ifdef TRANSPARENCY_FINISHED
  1261.                   default:
  1262.                     {
  1263.                       /* Blend in underlying pixel subtitle pixel. */
  1264.                       
  1265.                       uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1266.                                            * BYTES_PER_PIXEL );
  1267.                       uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1268.                                            * BYTES_PER_PIXEL );
  1269.                       uint32_t len     = i_xlast - i_xdest;
  1270.                       /* To be able to scale correctly for full opaqueness, we
  1271.                          add 1 to the alpha.  This means alpha value 0 won't
  1272.                          be completely transparent and is not correct, but
  1273.                          that's handled in a special case above anyway. */
  1274.                       
  1275.                       uint8_t i_destalpha = MAX_TRANS - p_source->s.t;
  1276.                       uint8_t rgb[RGB_SIZE];
  1277.                       /* This is the location that's going to get changed. */
  1278.                       uint8_t *p_dest = p_pixel_base_y + i_xdest;
  1279.                       
  1280.                       yuv2rgb(p_source, rgb);
  1281.                       rv32_pack_blend(p_dest, rgb, dest_alpha, 
  1282.                                       TRANS_SCALEDOWN);
  1283.                       for ( len = i_xlast - i_xdest; len ; len--) {
  1284.                         *p_dest++ = rgb[BLUE_PIXEL];
  1285.                         *p_dest++ = rgb[GREEN_PIXEL];
  1286.                         *p_dest++ = rgb[RED_PIXEL];
  1287.                         *p_dest++;
  1288.                       }
  1289.                       break;
  1290.                     }
  1291. #endif /*TRANSPARENCY_FINISHED*/
  1292.                   }
  1293.                 }
  1294.             }
  1295.         } 
  1296.         else
  1297.         {
  1298.             i_ynext = p_pic->p->i_pitch * i_y >> ASCALE;
  1299.             /* Draw until we reach the end of the line */
  1300.             for( ; i_x < p_spu->i_width; i_x++, p_source++ )
  1301.             {
  1302.               if( b_crop ) {
  1303.                 
  1304.                 /* FIXME: y cropping should be dealt with outside of this 
  1305.                    loop.*/
  1306.                 if ( i_y < i_y_start) continue;
  1307.                 
  1308.                 if ( i_x > i_x_end )
  1309.                   {
  1310.                     p_source += p_spu->i_width - i_x;
  1311.                     break;
  1312.                   }
  1313.               }
  1314.       
  1315.       if (p_source >= p_src_end) {
  1316. msg_Err( p_vout, "Trying to access beyond subtitle %dx%d %d",
  1317.  i_x, i_y / i_yscale, i_height);
  1318. return;
  1319.       }
  1320.       
  1321.       switch( p_source->s.t )
  1322.                 {
  1323.                 case 0:
  1324.     /* Completely transparent. Don't change pixel. */
  1325.                     break;
  1326.                 default:
  1327.                 case MAX_TRANS: 
  1328.   {
  1329.     /* Completely opaque. Completely overwrite underlying
  1330.        pixel with subtitle pixel. */
  1331.     /* This is the location that's going to get changed. */
  1332.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1333.                                          * BYTES_PER_PIXEL );
  1334.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1335.                                          * BYTES_PER_PIXEL );
  1336.                     uint32_t len     = i_xlast - i_xdest;
  1337.                     uint8_t rgb[RGB_SIZE];
  1338.                     yuv2rgb(p_source, rgb); 
  1339.                     for(  ; i_ytmp < i_ynext ; i_ytmp += p_pic->p->i_pitch )
  1340.                     {
  1341.                       /* Completely opaque. Completely overwrite underlying
  1342.                          pixel with subtitle pixel. */
  1343.                       
  1344.                       /* This is the location that's going to get changed. */
  1345.                       uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
  1346.                       
  1347.                       for ( len = i_xlast - i_xdest; len ; len--) {
  1348.                         put_rgb24_pixel(rgb, p_dest);
  1349.                       }
  1350.                     }
  1351.                     break;
  1352.   }
  1353. #ifdef TRANSPARENCY_FINISHED
  1354.                 default: 
  1355.                   {
  1356.                     
  1357.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1358.                                          * BYTES_PER_PIXEL );
  1359.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1360.                                          * BYTES_PER_PIXEL );
  1361.                     uint32_t len     = i_xlast - i_xdest;
  1362.                     uint8_t rgb[RGB_SIZE];
  1363.                     yuv2rgb(p_source, rgb);
  1364.                     for(  ; i_ytmp < i_ynext ; y_ytmp += p_pic->p->i_pitch )
  1365.                     {
  1366.       /* Blend in underlying pixel subtitle pixel. */
  1367.       
  1368.                       /* This is the location that's going to get changed. */
  1369.                       uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
  1370.       /* To be able to scale correctly for full opaqueness, we
  1371.  add 1 to the alpha.  This means alpha value 0 won't
  1372.  be completely transparent and is not correct, but
  1373.  that's handled in a special case above anyway. */
  1374.                       uint8_t i_destalpha = MAX_TRANS - p_source->s.t;
  1375.                       rv32_pack_blend(p_dest, rgb, dest_alpha,
  1376.                                       TRANS_SCALEDOWN);
  1377.                     }
  1378.                     break;
  1379. #endif /*TRANSPARENCY_FINISHED*/
  1380. }
  1381.     }
  1382. }
  1383.     }
  1384. }
  1385. /* 4-entry array of colormap indices */
  1386. static  uint8_t cmap[NUM_SUBTITLE_COLORS];
  1387. /* Actual RGB values for above; this is used in blending.*/
  1388. static uint8_t cmap_rgb[NUM_SUBTITLE_COLORS][RGB_SIZE];
  1389. /*
  1390.   Return the colormap index for the average of i_pixel and a subtitle
  1391.   pixel whose subtitle palette entry is i_cmap. 
  1392.  */
  1393. static inline cmap_t
  1394. avg_rgb2(const vout_thread_t *p_vout, uint8_t i_pixel, uint8_t i_trans, 
  1395.          int i_cmap, mtime_t i_pts)
  1396. {
  1397.   uint8_t rgb_vout[RGB_SIZE];
  1398.   /* Cache the average of a vout colormap entry and a subtitle palette
  1399.      entry. There are not too many of these 256*4 = 1024.
  1400.    */
  1401.   static cmap_t avg_cache[CMAP_RGB2_SIZE][NUM_SUBTITLE_COLORS];
  1402.   /* subtitle palettes might change between two subtitles. i_last_pts
  1403.      will be used to figure out if the subtitle has changed, and
  1404.      we have to invalidate the cache. */
  1405.   static mtime_t i_last_pts = -1;
  1406.   if (i_pts != i_last_pts) 
  1407.     {
  1408.       /* Hack: We rely on the fact that INVALID_CMAP_ENTRY is repeated
  1409.          0xFF.
  1410.        */
  1411.       memset(avg_cache, 0xFF, sizeof(avg_cache));
  1412.       i_last_pts = i_pts;
  1413.     }
  1414.   if ( avg_cache[i_pixel][i_cmap] != INVALID_CMAP_ENTRY ) 
  1415.     return avg_cache[i_pixel][i_cmap];
  1416.   if ( !query_color(p_vout, i_pixel, rgb_vout) ) return INVALID_CMAP_ENTRY;
  1417.   avg_8bit_rgb(rgb_vout, cmap_rgb[i_cmap], i_trans);
  1418. #if 0
  1419.  {
  1420.   uint8_t rgb_approx[RGB_SIZE];
  1421.   avg_cache[i_pixel][i_cmap] = 
  1422.     find_cmap_rgb8_nearest(p_vout, rgb_vout, rgb_approx);
  1423.   printf(
  1424.          "cmap old %0x avg approx 0%x sub: %d sub=(%0x, %0x, %0x) "
  1425.          "approx=(%0x, %0x, %0x) avg vout=(%0x, %0x, %0x)n", 
  1426.          i_pixel, avg_cache[i_pixel][i_cmap], i_cmap,
  1427.          cmap_rgb[i_cmap][RED_PIXEL], cmap_rgb[i_cmap][GREEN_PIXEL], 
  1428.          cmap_rgb[i_cmap][BLUE_PIXEL],
  1429.          rgb_approx[RED_PIXEL], rgb_approx[GREEN_PIXEL], rgb_approx[BLUE_PIXEL],
  1430.          rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL]);
  1431.  }  
  1432. #else 
  1433.   avg_cache[i_pixel][i_cmap] = 
  1434.     find_cmap_rgb8_nearest(p_vout, rgb_vout, NULL);
  1435. #endif
  1436.   return avg_cache[i_pixel][i_cmap];
  1437. }
  1438. #undef  BYTES_PER_PIXEL
  1439. #define BYTES_PER_PIXEL 1
  1440. static void 
  1441. BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
  1442.             const subpicture_t *p_spu, vlc_bool_t b_crop )
  1443. {
  1444.     /* Common variables */
  1445.     uint8_t *p_pixel_base;
  1446.     uint8_t *p_src_start = (uint8_t *)p_spu->p_sys->p_data;
  1447.     uint8_t *p_src_end   = &p_src_start[p_spu->i_height * p_spu->i_width];
  1448.     uint8_t *p_source; /* This is the where the subtitle pixels come from */
  1449.     int i;
  1450.     int i_x, i_y;
  1451.     int i_y_src;
  1452.     /* Chroma specific */
  1453.     uint32_t i_xscale;   /* Amount we scale subtitle in the x direction,
  1454.                             multiplied by 2**ASCALE. */
  1455.     uint32_t i_yscale;   /* Amount we scale subtitle in the y direction.
  1456.                             multiplied by 2**ASCALE. */
  1457.     int i_width, i_height, i_ytmp;
  1458.     /* Crop-specific */
  1459.     int i_x_start, i_y_start, i_x_end, i_y_end;
  1460.     struct subpicture_sys_t *p_sys = p_spu->p_sys;
  1461.     int i_aspect_x, i_aspect_y;
  1462.     vlc_reduce( &i_aspect_x, &i_aspect_y, p_vout->render.i_aspect,
  1463.                 VOUT_ASPECT_FACTOR, 0 );
  1464.     
  1465.     i_xscale = (( p_vout->output.i_width << ASCALE ) * i_aspect_x)
  1466.       / (i_aspect_y * p_vout->render.i_width);
  1467.     i_yscale = ( p_vout->output.i_height << ASCALE ) / p_vout->render.i_height;
  1468.     dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER), 
  1469.        "spu: %dx%d, scaled: %dx%d, vout render: %dx%d, scale %dx%d", 
  1470.        p_spu->i_width,  p_spu->i_height, 
  1471.        p_vout->output.i_width, p_vout->output.i_height,
  1472.        p_vout->render.i_width, p_vout->render.i_height,
  1473.        i_xscale, i_yscale
  1474.        );
  1475.     i_width  = p_spu->i_width  * i_xscale;
  1476.     i_height = p_spu->i_height * i_yscale;
  1477.     /** FIXME: do once per subtitle in subtitle processing, not here
  1478.         each time we render.  */
  1479.     /* Find a corresponding colormap entries for our palette entries. */
  1480.     for( i = 0; i < NUM_SUBTITLE_COLORS; i++ )
  1481.     {
  1482.       if ( p_sys->p_palette[i].s.t != 0 ) {
  1483.         uint8_t rgb[RGB_SIZE]; 
  1484.         yuv2rgb(&(p_sys->p_palette[i]), rgb);
  1485.         cmap[i] = 
  1486.           find_cmap_rgb8_nearest(p_vout, rgb, cmap_rgb[i]);
  1487.         dbg_print( (DECODE_DBG_RENDER), 
  1488.                    "palette %d RGB=(%0x, %0x, %0x)n", i,
  1489.                    rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL]);
  1490.       }
  1491.     }
  1492.     /* Set where we will start blending subtitle from using
  1493.        the picture coordinates subtitle offsets
  1494.     */
  1495.     p_pixel_base = p_pic->p->p_pixels 
  1496.               + ( (p_spu->i_x * i_xscale) >> ASCALE ) * BYTES_PER_PIXEL
  1497.               + ( (p_spu->i_y * i_yscale) >> ASCALE ) * p_pic->p->i_pitch;
  1498.     i_x_start = p_sys->i_x_start;
  1499.     i_y_start = i_yscale * p_sys->i_y_start;
  1500.     i_x_end   = p_sys->i_x_end;
  1501.     i_y_end   = i_yscale * p_sys->i_y_end;
  1502.     p_source = (uint8_t *)p_sys->p_data;
  1503.   
  1504.     /* Draw until we reach the bottom of the subtitle */
  1505.     i_y = 0;
  1506.     for( i_y_src = 0 ; i_y_src < p_spu->i_height * p_spu->i_width; 
  1507.          i_y_src += p_spu->i_width )
  1508.       {
  1509. uint8_t *p_pixel_base_y;
  1510.         i_ytmp = i_y >> ASCALE;
  1511.         i_y += i_yscale;
  1512. p_pixel_base_y = p_pixel_base + (i_ytmp * p_pic->p->i_pitch);
  1513. i_x = 0;
  1514.         if ( b_crop ) {
  1515.           if ( i_y > i_y_end ) break;
  1516.           if (i_x_start) {
  1517.             i_x = i_x_start;
  1518.             p_source += i_x_start;
  1519.           }
  1520.         }
  1521.         
  1522.         /* Check whether we need to draw one line or more than one */
  1523.         if( i_ytmp + 1 >= ( i_y >> ASCALE ) )
  1524.         {
  1525.           /* Draw until we reach the end of the line */
  1526.           for( ; i_x < p_spu->i_width; i_x ++, p_source++ )
  1527.             {
  1528.               ogt_yuvt_t p_yuvt;
  1529.               if( b_crop ) {
  1530.                 
  1531.                 /* FIXME: y cropping should be dealt with outside of this 
  1532.                    loop.*/
  1533.                 if ( i_y < i_y_start) continue;
  1534.                 
  1535.                 if ( i_x > i_x_end )
  1536.                   {
  1537.                     p_source += p_spu->i_width - i_x;
  1538.                     break;
  1539.                   }
  1540.               }
  1541.               
  1542.               if (p_source >= p_src_end) {
  1543.                 msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
  1544.                          i_x, i_y / i_yscale, i_height);
  1545.                 return;
  1546.               }
  1547.               
  1548.               p_yuvt = p_sys->p_palette[*p_source & 0x3];
  1549. #ifdef TESTING_TRANSPARENCY
  1550.               if (p_yuvt.s.t == MAX_TRANS) p_yuvt.s.t >>= 1;
  1551. #endif
  1552.               switch ( p_yuvt.s.t ) 
  1553.                 {
  1554.                 case 0:
  1555.   /* Completely transparent. Don't change pixel. */
  1556. #if 0
  1557.                   printf(" "); /*++++*/
  1558. #endif
  1559.                   break;
  1560.                 case MAX_TRANS: 
  1561.                   {
  1562.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1563.                                          * BYTES_PER_PIXEL );
  1564.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1565.                                          * BYTES_PER_PIXEL );
  1566.                     /* This is the pixel that's going to change;*/
  1567.                     uint8_t *p_dest = p_pixel_base_y + i_xdest;
  1568.                     memset( p_dest, cmap[*p_source & 0x3], i_xlast - i_xdest );
  1569. #if 0
  1570.                     printf("%1d", *p_source); /*++++*/
  1571. #endif
  1572.                     break;
  1573.                   }
  1574.                 default:
  1575.                   {
  1576.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1577.                                          * BYTES_PER_PIXEL );
  1578.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1579.                                          * BYTES_PER_PIXEL );
  1580.                     /* This is the pixel that's going to change;*/
  1581.                     uint8_t *p_pixel = p_pixel_base_y + i_xdest;
  1582.                     uint32_t len     = i_xlast - i_xdest;
  1583. #if FULL_TRANSPARENCY
  1584.                     /* This is what should be done, but it may be too
  1585.        slow.  */
  1586.                     for ( len = i_xlast - i_xdest -1; len >= 0; len-- ) 
  1587.                       {
  1588.                         cmap_t i_cmap  = avg_rgb2(p_vout, *p_pixel, p_yuvt.s.t,
  1589.                                                   *p_source, p_sys->i_pts);
  1590.                                                   
  1591.                         if (i_cmap != INVALID_CMAP_ENTRY) 
  1592.                           *p_pixel= (uint8_t) i_cmap;
  1593.                         p_pixel++;
  1594.                       }
  1595. #else
  1596.                     cmap_t i_cmap  = avg_rgb2(p_vout, *p_pixel, p_yuvt.s.t,
  1597.                                               *p_source, p_sys->i_pts);
  1598.                     if (i_cmap != INVALID_CMAP_ENTRY) 
  1599.                       memset(p_pixel, i_cmap, len);
  1600. #endif 
  1601. #if 0
  1602.                     printf("%1d", *p_source); /*++++*/
  1603. #endif
  1604.                   }
  1605.                 }
  1606.             }
  1607. #if 0
  1608.           printf("n"); /*++++*/
  1609. #endif
  1610.         } else {
  1611.           /* Have to scale over many lines. */
  1612.           int i_yreal = p_pic->p->i_pitch * i_ytmp;
  1613.           int i_ynext = p_pic->p->i_pitch * i_y >> ASCALE;
  1614.            /* Draw until we reach the end of the line */
  1615.            for( ; i_x < p_spu->i_width; i_x ++, p_source++ )
  1616.              {
  1617.               ogt_yuvt_t p_yuvt = p_sys->p_palette[*p_source & 0x3];
  1618.               if( b_crop ) {
  1619.                 
  1620.                 /* FIXME: y cropping should be dealt with outside of this 
  1621.                    loop.*/
  1622.                 if ( i_y < i_y_start) continue;
  1623.                 
  1624.                 if ( i_x > i_x_end )
  1625.                   {
  1626.                     p_source += p_spu->i_width - i_x;
  1627.                     break;
  1628.                   }
  1629.               }
  1630.               
  1631.               if (p_source >= p_src_end) {
  1632.                 msg_Err( p_vout, "trying to access beyond subtitle %dx%d %d",
  1633.                          i_x, i_y / i_yscale, i_height);
  1634.                 return;
  1635.               }
  1636.               
  1637. #ifdef TESTING_TRANSPARENCY
  1638.               if (p_yuvt.s.t == MAX_TRANS) p_yuvt.s.t >>= 1;
  1639. #endif
  1640.               switch ( p_yuvt.s.t ) 
  1641.                 {
  1642.                 case 0:
  1643.   /* Completely transparent. Don't change pixel. */
  1644. #if 0
  1645.                   printf(" "); /*++++*/
  1646. #endif
  1647.                   break;
  1648.                 case MAX_TRANS: 
  1649.                   {
  1650.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1651.                                          * BYTES_PER_PIXEL );
  1652.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1653.                                          * BYTES_PER_PIXEL );
  1654.                     uint32_t len     = i_xlast - i_xdest;
  1655. #if 0
  1656.                     printf("%1d", *p_source); /*++++*/
  1657. #endif
  1658.                     for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
  1659.                          i_ytmp += p_pic->p->i_pitch ) {
  1660.                       uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
  1661.                       memset( p_dest, cmap[*p_source & 0x3], len );
  1662.                     }
  1663.                     break;
  1664.                   }
  1665.                 default:
  1666.                   {
  1667.                     uint32_t i_xdest = ( ((i_x*i_xscale) >> ASCALE) 
  1668.                                          * BYTES_PER_PIXEL );
  1669.                     uint32_t i_xlast = ( (((i_x+1)*i_xscale) >> ASCALE)
  1670.                                          * BYTES_PER_PIXEL );
  1671.                     int32_t len = i_xlast - i_xdest;
  1672. #if 0
  1673.                     printf("%1d", *p_source); /*++++*/
  1674. #endif
  1675.                     for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
  1676.                          i_ytmp += p_pic->p->i_pitch ) {
  1677.                       /* This is the pixel that's going to change;*/
  1678.                       uint8_t *p_pixel = p_pixel_base + i_ytmp + i_xdest;
  1679. #if FULL_TRANSPARENCY
  1680.                     /* This is what should be done, but it may be too
  1681.        slow.  */
  1682.                       for ( len = i_xlast - i_xdest -1; len >= 0; len-- ) 
  1683.                         {
  1684.                           cmap_t i_cmap  = avg_rgb2(p_vout, *p_pixel, 
  1685.                                                     p_yuvt.s.t, *p_source, 
  1686.                                                     p_sys->i_pts);
  1687.                           if (i_cmap != INVALID_CMAP_ENTRY) 
  1688.                             *p_pixel= (uint8_t) i_cmap;
  1689.                           p_pixel++;
  1690.                         }
  1691. #else
  1692.                     cmap_t i_cmap  = avg_rgb2(p_vout, *p_pixel, p_yuvt.s.t, 
  1693.                                               *p_source, p_sys->i_pts);
  1694.                     if (i_cmap != INVALID_CMAP_ENTRY) 
  1695.                       memset(p_pixel, i_cmap, len);
  1696. #endif 
  1697.                     }
  1698.                   }
  1699.                 }
  1700.              }
  1701.         }
  1702.       }
  1703. }
  1704. /* 
  1705.  * Local variables:
  1706.  *  c-file-style: "gnu"
  1707.  *  tab-width: 8
  1708.  *  indent-tabs-mode: nil
  1709.  * End:
  1710.  */