]> git.sesse.net Git - vlc/commitdiff
render.c: RGB2 now gets the right color from the RGB color map.
authorRocky Bernstein <rocky@videolan.org>
Sat, 31 Jan 2004 05:53:35 +0000 (05:53 +0000)
committerRocky Bernstein <rocky@videolan.org>
Sat, 31 Jan 2004 05:53:35 +0000 (05:53 +0000)
  And a first cut at handling transparancy values properly. However
  to do this we merely needed to

pixmap.[ch]: write our own routines for retrieving a close colormap index
  given a pixel value. Well, and also had to

video_chroma/i420_rgb.[ch]: save the RGB colormap that is allocated.

Modules.am: forgot new pixmap.c

others: more misc abstraction/cleanup

modules/codec/ogt/Modules.am
modules/codec/ogt/common.c
modules/codec/ogt/pixmap.c
modules/codec/ogt/pixmap.h
modules/codec/ogt/render.c
modules/video_chroma/i420_rgb.c
modules/video_chroma/i420_rgb.h

index d8445293ef8c8ee9258d45001bf067312a819e14..4dc261c1daef41b9d3b6eab70846127223889acd 100644 (file)
@@ -20,6 +20,7 @@ SOURCES_cvdsub = \
        cvd.h \
        subtitle.h \
        cvd_parse.c \
+       pixmap.c \
        pixmap.h \
        render.c \
        render.h \
index 3619d43b2479d73ab8dbac2efb9ce78e8d50044e..9c974a407f06a65c191f46fef6529e851a87c866 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * Common SVCD and VCD subtitle routines.
+ * Common SVCD and CVD subtitle routines.
  *****************************************************************************
  * Copyright (C) 2003, 2004 VideoLAN
- * $Id: common.c,v 1.11 2004/01/30 13:17:12 rocky Exp $
+ * $Id: common.c,v 1.12 2004/01/31 05:53:35 rocky Exp $
  *
  * Author: Rocky Bernstein <rocky@panix.com>
  *   based on code from:
index 576677788509641977291ba0c3b5f5b3bf3a22d0..42e45366da41382742c9afc241aa69795d0b62fb 100644 (file)
@@ -2,7 +2,7 @@
  * Common pixel/chroma manipulation routines.
  *****************************************************************************
  * Copyright (C) 2003, 2004 VideoLAN
- * $Id: pixmap.c,v 1.2 2004/01/30 13:23:08 rocky Exp $
+ * $Id: pixmap.c,v 1.3 2004/01/31 05:53:35 rocky Exp $
  *
  * Author: Rocky Bernstein
  *
@@ -50,15 +50,12 @@ struct chroma_sys_t
     /* To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i],
        p_rgb_b[i])
      */
-    uint8_t  *p_rgb_r;                   /* Red values of palette */
-    uint8_t  *p_rgb_g;                   /* Green values of palette */
-    uint8_t  *p_rgb_b;                   /* Blue values of palette */
+    uint16_t  p_rgb_r[CMAP_RGB2_SIZE];    /* Red values of palette */
+    uint16_t  p_rgb_g[CMAP_RGB2_SIZE];    /* Green values of palette */
+    uint16_t  p_rgb_b[CMAP_RGB2_SIZE];    /* Blue values of palette */
 };
 
 
-/* Number of entries in RGB palette/colormap*/
-#define CMAP_SIZE 256
-
 /* 
     From
     http://www.inforamp.net/~poynton/notes/colour_and_gamma/ColorFAQ.html#RTFToC11
@@ -110,9 +107,9 @@ struct chroma_sys_t
 
 /** 
    Find the nearest colormap entry in p_vout (assumed to have RGB2
-   chroma, i.e. 256 RGB entries) that is closest in color to p_yuv.  Set
-   RGB to the color found and return the colormap index. -1 is returned
-   if there is some error.
+   chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb.  Set
+   out_rgb to the color found and return the colormap index.
+   INVALID_CMAP_ENTRY is returned if there is some error.
 
    The closest match is determined by the the Euclidean distance
    using integer-scaled 601-2 coefficients described above.
@@ -121,31 +118,28 @@ struct chroma_sys_t
    comparisons it amounts to the same thing.
 */
 
-int
-find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv,
+cmap_t
+find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *rgb,
                       uint8_t *out_rgb) 
 {
-  uint8_t *p_cmap_r;
-  uint8_t *p_cmap_g;
-  uint8_t *p_cmap_b;
-  uint8_t rgb[RGB_SIZE];
+  uint16_t *p_cmap_r;
+  uint16_t *p_cmap_g;
+  uint16_t *p_cmap_b;
   
   int i;
-  int i_bestmatch=0;
+  cmap_t i_bestmatch = INVALID_CMAP_ENTRY;
   uint32_t i_mindist = 0xFFFFFFFF; /* The largest number here. */
 
   /* Check that we really have RGB2. */
   
   if ( !p_vout && p_vout->output.i_chroma  != VLC_FOURCC('R','G','B','2') )
-    return -1;
+    return INVALID_CMAP_ENTRY;
 
   p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
   p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
   p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
 
-  yuv2rgb(p_yuv, rgb);
-
-  for (i = 0; i < CMAP_SIZE; i++) {
+  for (i = 0; i < CMAP_RGB2_SIZE; i++) {
     /* Interval range calculations to show that we don't overflow the
        word sizes below. pixels component values start out 8
        bits. When we subtract two components we get 9 bits, then
@@ -170,27 +164,73 @@ find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv,
 #define SCALEBITS 6 
 #define int32_sqr(x) ( ((int32_t) (x)) * ((int32_t) x) )
 
-    uint32_t dr = ( RED_COEF   * ( int32_sqr(rgb[RED_PIXEL]   - p_cmap_r[i])
+    /* colormap entires are scaled to 16 bits, so we need to shift
+       them back down to 8. */
+#define CMAP8_RED(i) (p_cmap_r[i]>>8)
+#define CMAP8_GREEN(i) (p_cmap_g[i]>>8)
+#define CMAP8_BLUE(i) (p_cmap_b[i]>>8)
+
+    uint32_t dr = ( RED_COEF   * ( int32_sqr(rgb[RED_PIXEL]   - CMAP8_RED(i))
                                 << SCALEBITS ) ) >> (SCALEBITS*2);
-    uint32_t dg = ( GREEN_COEF * ( int32_sqr(rgb[GREEN_PIXEL] - p_cmap_g[i])
+    uint32_t dg = ( GREEN_COEF * ( int32_sqr(rgb[GREEN_PIXEL] - CMAP8_GREEN(i))
+                                << SCALEBITS ) ) >> (SCALEBITS*2);
+    uint32_t db = ( BLUE_COEF  * ( int32_sqr(rgb[BLUE_PIXEL]  - CMAP8_BLUE(i))
                                 << SCALEBITS ) ) >> (SCALEBITS*2);
-    uint32_t db = ( BLUE_COEF  * ( int32_sqr(rgb[BLUE_PIXEL]  - p_cmap_b[i])
-                                 << SCALEBITS ) ) >> (SCALEBITS*2);
 
     uint32_t i_dist = dr + dg + db;
     if (i_dist < i_mindist) {
       i_bestmatch = i;
       i_mindist = i_dist;
+#if 0      
+      printf("+++Change dist to %d RGB cmap %d (%0x, %0x, %0x)\n", 
+             i_dist, i, p_cmap_r[ i ], p_cmap_g[ i ], p_cmap_b[ i ]);
+#endif
     }
   }
 
-  out_rgb[RED_PIXEL]   = p_cmap_r[i_bestmatch];
-  out_rgb[GREEN_PIXEL] = p_cmap_g[i_bestmatch];
-  out_rgb[BLUE_PIXEL]  = p_cmap_b[i_bestmatch];
+  if (out_rgb) 
+    {
+      out_rgb[RED_PIXEL]   = CMAP8_RED(i_bestmatch);
+      out_rgb[GREEN_PIXEL] = CMAP8_GREEN(i_bestmatch);
+      out_rgb[BLUE_PIXEL]  = CMAP8_BLUE(i_bestmatch);
+    }
 
   return i_bestmatch;
 }
 
+/**
+   Get the the rgb value for a given colormap entry for p_vout (which is'
+   assumed to have RGB2 chroma). 
+
+   VLC_FALSE is returned if there was some error.
+*/
+vlc_bool_t
+query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
+            /*out*/ uint8_t *out_rgb) 
+{
+  uint16_t *p_cmap_r;
+  uint16_t *p_cmap_g;
+  uint16_t *p_cmap_b;
+
+  /* Check that we really have RGB2. */
+  
+  if ( !p_vout && p_vout->output.i_chroma  != VLC_FOURCC('R','G','B','2') )
+    return VLC_FALSE;
+
+  if ( !out_rgb ) 
+    return VLC_FALSE;
+
+  p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
+  p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
+  p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
+
+  out_rgb[RED_PIXEL]   = CMAP8_RED(i_cmap);
+  out_rgb[GREEN_PIXEL] = CMAP8_GREEN(i_cmap);
+  out_rgb[BLUE_PIXEL]  = CMAP8_BLUE(i_cmap);
+
+  return VLC_TRUE;
+}
+
 \f
 /* 
  * Local variables:
index 9f59139568c73728ce2762ad694195fd2a0639b4..8ec015830e255a14a337d359a49b90de2edc80d9 100644 (file)
@@ -2,7 +2,7 @@
  * Common pixel/chroma manipulation routines.
  *****************************************************************************
  * Copyright (C) 2003, 2004 VideoLAN
- * $Id: pixmap.h,v 1.4 2004/01/30 13:17:12 rocky Exp $
+ * $Id: pixmap.h,v 1.5 2004/01/31 05:53:35 rocky Exp $
  *
  * Author: Rocky Bernstein
  *
@@ -36,6 +36,15 @@ typedef union {
   } s;
 } ogt_yuvt_t;
 
+/** An undefined or invalid colormap index. */
+#define INVALID_CMAP_ENTRY -1
+
+/** Type of a palette/colormap index*/
+typedef int16_t cmap_t;
+
+/** Number of entries in RGB palette/colormap*/
+#define CMAP_RGB2_SIZE 256
+
 /**
    Force v in the range 0..255. In video_chroma/i420_rgb.c, this
    is macro is called CLIP. FIXME: Combine with that.
@@ -113,7 +122,7 @@ yuv2rgb(const ogt_yuvt_t *p_yuv, uint8_t *p_rgb_out )
    to do.)
  */
 static inline void
-put_rgb24_pixel(const uint8_t *rgb, uint8_t *p_pixel)
+put_rgb24_pixel(const uint8_t *rgb, /*out*/ uint8_t *p_pixel)
 {
 #ifdef WORDS_BIGENDIAN
   *p_pixel++;
@@ -124,14 +133,24 @@ put_rgb24_pixel(const uint8_t *rgb, uint8_t *p_pixel)
 }
 
 /**
- Find the nearest colormap entry in p_vout (assumed to have RGB2
- chroma, i.e. 256 RGB entries) that is closest in color to p_yuv.  Set
- rgb to the color found and return the colormap index. -1 is returned
- if there is some error.
+   Find the nearest colormap entry in p_vout (assumed to have RGB2
+   chroma, i.e. 256 RGB 8bpp entries) that is closest in color to p_rgb.  Set
+   out_rgb to the color found and return the colormap index. 
+   INVALID_CMAP_ENTRY is returned if there is some error.
+*/
+cmap_t
+find_cmap_rgb8_nearest(const vout_thread_t *p_vout, const uint8_t *p_rgb,
+                       /*out*/ uint8_t *out_rgb);
+
+/**
+   Get the the rgb value for a given colormap entry for p_vout (which is'
+   assumed to have RGB2 chroma). 
+   
+   VLC_FALSE is returned if there was some error.
 */
-int
-find_cmap_nearest(const vout_thread_t *p_vout, const ogt_yuvt_t *p_yuv,
-                 uint8_t *rgb);
+vlc_bool_t
+query_color(const vout_thread_t *p_vout, cmap_t i_cmap,
+            /*out*/ uint8_t *rgb);
 
 #endif /* PIXMAP_H */
 
index 16339834160c7953db281106cadc26c0f986be82..3eaa37a98b64af92f69da253b34c23cdd4643156 100644 (file)
@@ -2,7 +2,7 @@
  * render.c : Philips OGT and CVD (VCD Subtitle) blending routines
  *****************************************************************************
  * Copyright (C) 2003, 2004 VideoLAN
- * $Id: render.c,v 1.26 2004/01/29 11:50:22 rocky Exp $
+ * $Id: render.c,v 1.27 2004/01/31 05:53:35 rocky Exp $
  *
  * Author: Rocky Bernstein <rocky@panix.com>
  *   based on code from: 
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-/*#define TESTING_BLENDING 1*/
+/*#define TESTING_TRANSPARENCY 1*/
 
 /*****************************************************************************
  * Preamble
@@ -235,7 +235,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
            }
           }
 
-#ifdef TESTING_BLENDING
+#ifdef TESTING_TRANSPARENCY
           if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1;
 #endif
 
@@ -434,7 +434,7 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
           else 
             i_avg_tr = ( p_source->s.t + (p_source+1)->s.t ) / 2;
           
-#ifdef TESTING_BLENDING 
+#ifdef TESTING_TRANSPARENCY 
           if (i_avg_tr == MAX_ALPHA) i_avg_tr >>= 1;
 #endif
 
@@ -801,7 +801,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
                return;
              }
              
-#ifdef TESTING_BLENDING
+#ifdef TESTING_TRANSPARENCY
               if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 1;
 #endif
 
@@ -1110,7 +1110,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
                return;
              }
              
-#ifdef TESTING_BLENDING
+#ifdef TESTING_TRANSPARENCY
               if (p_source->s.t == MAX_ALPHA) p_source->s.t >>= 2;
 #endif
 
@@ -1574,6 +1574,62 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
     }
 }
 
+/*
+  Return the colormap index for the average of p_pixel and a subtitle
+  pixel in RGB form.
+ */
+static inline cmap_t
+avg_rgb2(const vout_thread_t *p_vout, uint8_t i_pixel, cmap_t i_cmap_sub,
+         const uint8_t rgb_sub[] )
+{
+  uint8_t rgb_vout[RGB_SIZE];
+  static cmap_t avg_cache[CMAP_RGB2_SIZE][NUM_SUBTITLE_COLORS];
+  static vlc_bool_t b_first_time = VLC_TRUE;
+  int i;
+
+  /* FIXME: really we need to save subtitle number since in theory
+     the palette can change each on each distinct subtitle. In practice
+     this doesn't happen that much.
+   */
+  if (b_first_time) 
+    {
+      int i, j;
+      for (i=0; i<CMAP_RGB2_SIZE; i++) 
+        for (j=0; j<NUM_SUBTITLE_COLORS; j++) 
+          avg_cache[i][j] = INVALID_CMAP_ENTRY;
+    }
+
+  if ( avg_cache[i_pixel][i_cmap_sub] != INVALID_CMAP_ENTRY ) 
+    return avg_cache[i_pixel][i_cmap_sub];
+
+  if ( !query_color(p_vout, i_pixel, rgb_vout) ) return INVALID_CMAP_ENTRY;
+
+  for (i = 0; i < RGB_SIZE; i++) 
+    {
+      rgb_vout[i] = (rgb_vout[i] + rgb_sub[i]) / 2;
+    }
+
+#if 0
+ {
+  uint8_t rgb_approx[RGB_SIZE];
+
+  avg_cache[i_pixel][i_cmap_sub] = 
+    find_cmap_rgb8_nearest(p_vout, rgb_vout, rgb_approx);
+  printf(
+         "cmap old %0x new 0%x sub=(%0x, %0x, %0x) "
+         "avg=(%0x, %0x, %0x) vout=(%0x, %0x, %0x)\n", 
+         i_pixel, i_cmap,
+         rgb_sub[RED_PIXEL], rgb_sub[GREEN_PIXEL], rgb_sub[BLUE_PIXEL],
+         rgb_approx[RED_PIXEL], rgb_approx[GREEN_PIXEL], rgb_approx[BLUE_PIXEL],
+         rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL]);
+ }  
+#else 
+  avg_cache[i_pixel][i_cmap_sub] = 
+    find_cmap_rgb8_nearest(p_vout, rgb_vout, NULL);
+#endif
+  return avg_cache[i_pixel][i_cmap_sub];
+}
+
 #undef  BYTES_PER_PIXEL
 #define BYTES_PER_PIXEL 1
 
@@ -1601,9 +1657,12 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
     /* Crop-specific */
     int i_x_start, i_y_start, i_x_end, i_y_end;
 
-    /* 4 entry colormap */
+    /* 4-entry array of colormap indices */
     uint8_t cmap[NUM_SUBTITLE_COLORS];
-    int i_cmap;
+    int i;
+
+    /* Actual RGB values for above; this is used in blending.*/
+    uint8_t cmap_rgb[NUM_SUBTITLE_COLORS][RGB_SIZE];
 
     struct subpicture_sys_t *p_sys = p_spu->p_sys;
     unsigned int i_aspect_x, i_aspect_y;
@@ -1611,24 +1670,6 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
     vout_AspectRatio( p_vout->render.i_aspect, &i_aspect_y, 
                       &i_aspect_x );
     
-    /* Find a corresponding colormap entries for our palette entries. */
-    for( i_cmap = 0; i_cmap < NUM_SUBTITLE_COLORS; i_cmap++ )
-    {
-      uint8_t Y = p_sys->p_palette[i_cmap].s.y;
-
-      /* FIXME: when we have a way to look at colormap entries we can
-         do better.  For now we have to use 0xff for white 0x00 for
-         black and 0x44 for something in between. To do this we use
-         only the Y component.
-      */
-      if (Y > 0x70) 
-        cmap[i_cmap] = 0xff; /* Use white. */
-      else if (Y < 0x10) 
-        cmap[i_cmap] = 0x00; /* Use black. */
-      else 
-        cmap[i_cmap] = 0x44; /* Use something else. */
-    }
-
     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;
@@ -1644,6 +1685,25 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
     i_width  = p_spu->i_width  * i_xscale;
     i_height = p_spu->i_height * i_yscale;
 
+
+    /** FIXME: do once per subtitle in subtitle processing, not here
+        each time we render.  */
+    /* Find a corresponding colormap entries for our palette entries. */
+    for( i = 0; i < NUM_SUBTITLE_COLORS; i++ )
+    {
+
+      if ( p_sys->p_palette[i].s.t != 0 ) {
+        uint8_t rgb[RGB_SIZE]; 
+        uint8_t approx_rgb[RGB_SIZE]; 
+        yuv2rgb(&(p_sys->p_palette[i]), rgb);
+        cmap[i] = 
+          find_cmap_rgb8_nearest(p_vout, rgb, approx_rgb);
+        dbg_print( (DECODE_DBG_RENDER), 
+                   "palette %d RGB=(%0x, %0x, %0x)\n", i,
+                   rgb[RED_PIXEL], rgb[GREEN_PIXEL], rgb[BLUE_PIXEL]);
+      }
+    }
+
     /* Set where we will start blending subtitle from using
        the picture coordinates subtitle offsets
     */
@@ -1706,25 +1766,57 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
               }
               
               p_yuvt = p_sys->p_palette[*p_source & 0x3];
-              if ( (p_yuvt.s.t) < (MAX_ALPHA) / 2 ) {
-                /* Completely or relatively transparent. Don't change pixel. */
-                ;
+
+#ifdef TESTING_TRANSPARENCY
+              if (p_yuvt.s.t == MAX_ALPHA) p_yuvt.s.t >>= 1;
+#endif
+
+              switch ( p_yuvt.s.t ) 
+                {
+                case 0:
+                 /* Completely transparent. Don't change pixel. */
 #if 0
-                printf(" "); /*++++*/
+                  printf(" "); /*++++*/
 #endif
-              } else {
-                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 );
-                /* This is the pixel that's going to change;*/
-                uint8_t *p_dest = p_pixel_base_y + i_xdest;
-                memset( p_dest, cmap[*p_source & 0x3], i_xlast - i_xdest );
+                  break;
+                case MAX_ALPHA: 
+                  {
+                    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 );
+                    /* This is the pixel that's going to change;*/
+                    uint8_t *p_dest = p_pixel_base_y + i_xdest;
+                    memset( p_dest, cmap[*p_source & 0x3], i_xlast - i_xdest );
 #if 0
-                printf("%1d", *p_source); /*++++*/
+                    printf("%1d", *p_source); /*++++*/
 #endif
-              }
-              
+                    break;
+                  }
+                default:
+                  {
+                    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 );
+                    /* This is the pixel that's going to change;*/
+                    uint8_t *p_pixel = p_pixel_base_y + i_xdest;
+                    uint32_t len     = i_xlast - i_xdest;
+
+                    for ( len = i_xlast - i_xdest -1; len >= 0; len-- ) 
+                      {
+                        cmap_t i_cmap  = avg_rgb2(p_vout, *p_pixel, 
+                                                  cmap[*p_source],
+                                                  cmap_rgb[*p_source]);
+                        if (i_cmap != INVALID_CMAP_ENTRY) 
+                          *p_pixel= (uint8_t) i_cmap;
+                        p_pixel++;
+                      }
+#if 0
+                    printf("%1d", *p_source); /*++++*/
+#endif
+                  }
+                }
             }
 #if 0
           printf("\n"); /*++++*/
@@ -1758,29 +1850,62 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
                 return;
               }
               
-              if ( (p_yuvt.s.t) < (MAX_ALPHA) / 2 ) {
-                /* Completely or relatively transparent. Don't change pixel. */
-                ;
+#ifdef TESTING_TRANSPARENCY
+              if (p_yuvt.s.t == MAX_ALPHA) p_yuvt.s.t >>= 1;
+#endif
+              switch ( p_yuvt.s.t ) 
+                {
+                case 0:
+                 /* Completely transparent. Don't change pixel. */
+#if 0
+                  printf(" "); /*++++*/
+#endif
+                  break;
+                case MAX_ALPHA: 
+                  {
+                    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;
 #if 0
-                printf(" "); /*++++*/
+                    printf("%1d", *p_source); /*++++*/
 #endif
-              } else {
-                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;
+                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
+                         i_ytmp += p_pic->p->i_pitch ) {
+                      uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
+                      memset( p_dest, cmap[*p_source & 0x3], len );
+                    }
+                    break;
+                  }
+                default:
+                  {
+                    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 );
+                    int32_t len;
 #if 0
-                printf("%1d", *p_source); /*++++*/
+                    printf("%1d", *p_source); /*++++*/
 #endif
-                for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
-                     i_ytmp += p_pic->p->i_pitch ) {
-                  uint8_t *p_dest = p_pixel_base + i_ytmp + i_xdest;
-                  memset( p_dest, cmap[*p_source & 0x3], len );
-                }
-              }
-            }
 
+                    for( i_ytmp = i_yreal ; i_ytmp < i_ynext ;
+                         i_ytmp += p_pic->p->i_pitch ) {
+                      /* This is the pixel that's going to change;*/
+                      uint8_t *p_pixel = p_pixel_base + i_ytmp + i_xdest;
+                      for ( len = i_xlast - i_xdest -1; len >= 0; len-- ) 
+                        {
+                          cmap_t i_cmap  = avg_rgb2(p_vout, *p_pixel, 
+                                                    cmap[*p_source],
+                                                    cmap_rgb[*p_source]);
+                          if (i_cmap != INVALID_CMAP_ENTRY) 
+                            *p_pixel= (uint8_t) i_cmap;
+                          p_pixel++;
+                        }
+                    }
+                  }
+                }
+             }
         }
       }
 }
index 5522a2022bdbce9df2e66567cbf0385b9f8051b5..850d14bdfad6544de2d248391a559862dfb1f85c 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * i420_rgb.c : YUV to bitmap RGB conversion module for vlc
  *****************************************************************************
- * Copyright (C) 2000, 2001 VideoLAN
- * $Id: i420_rgb.c,v 1.6 2003/12/22 14:32:56 sam Exp $
+ * Copyright (C) 2000, 2001, 2004 VideoLAN
+ * $Id: i420_rgb.c,v 1.7 2004/01/31 05:53:35 rocky Exp $
  *
  * Author: Sam Hocevar <sam@zoy.org>
  *
@@ -344,7 +344,10 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
     int y,u,v;
     int r,g,b;
     int i = 0, j = 0;
-    uint16_t red[ 256 ], green[ 256 ], blue[ 256 ];
+    uint16_t *p_cmap_r=p_vout->chroma.p_sys->p_rgb_r;
+    uint16_t *p_cmap_g=p_vout->chroma.p_sys->p_rgb_g;
+    uint16_t *p_cmap_b=p_vout->chroma.p_sys->p_rgb_b;
+
     unsigned char p_lookup[PALETTE_TABLE_SIZE];
 
     /* This loop calculates the intersection of an YUV box and the RGB cube. */
@@ -371,9 +374,15 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
                     }
 
                     /* Clip the colors */
-                    red[ j ] = CLIP( r );
-                    green[ j ] = CLIP( g );
-                    blue[ j ] = CLIP( b );
+                    p_cmap_r[ j ] = CLIP( r );
+                    p_cmap_g[ j ] = CLIP( g );
+                    p_cmap_b[ j ] = CLIP( b );
+
+#if 0
+                   printf("+++Alloc RGB cmap %d (%d, %d, %d)\n", j,
+                          p_cmap_r[ j ] >>8, p_cmap_g[ j ] >>8, 
+                          p_cmap_b[ j ] >>8);
+#endif
 
                     /* Allocate color */
                     p_lookup[ i ] = 1;
@@ -390,7 +399,7 @@ static void Set8bppPalette( vout_thread_t *p_vout, uint8_t *p_rgb8 )
     }
 
     /* The colors have been allocated, we can set the palette */
-    p_vout->output.pf_setpalette( p_vout, red, green, blue );
+    p_vout->output.pf_setpalette( p_vout, p_cmap_r, p_cmap_g, p_cmap_b );
 
 #if 0
     /* There will eventually be a way to know which colors
index e90cbab92a989ab1d4832e8e69678bf577ddb2d1..a61b14ada9d1877ebbe21a8af502e41559fa256c 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * i420_rgb.h : YUV to bitmap RGB conversion module for vlc
  *****************************************************************************
- * Copyright (C) 2000 VideoLAN
- * $Id: i420_rgb.h,v 1.4 2003/08/29 18:58:05 fenrir Exp $
+ * Copyright (C) 2000, 2004 VideoLAN
+ * $Id: i420_rgb.h,v 1.5 2004/01/31 05:53:35 rocky Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-/*****************************************************************************
+/** Number of entries in RGB palette/colormap */
+#define CMAP_RGB2_SIZE 256
+
+/**
  * chroma_sys_t: chroma method descriptor
- *****************************************************************************
+
  * This structure is part of the chroma transformation descriptor, it
  * describes the yuv2rgb specific properties.
- *****************************************************************************/
+ */
 struct chroma_sys_t
 {
     uint8_t  *p_buffer;
     int *p_offset;
 
 #ifdef MODULE_NAME_IS_i420_rgb
-    /* Pre-calculated conversion tables */
-    void *p_base;                          /* base for all conversion tables */
-    uint8_t   *p_rgb8;                                   /* RGB 8 bits table */
-    uint16_t  *p_rgb16;                                 /* RGB 16 bits table */
-    uint32_t  *p_rgb32;                                 /* RGB 32 bits table */
+    /**< Pre-calculated conversion tables */
+    void *p_base;                      /**< base for all conversion tables */
+    uint8_t   *p_rgb8;                 /**< RGB 8 bits table */
+    uint16_t  *p_rgb16;                /**< RGB 16 bits table */
+    uint32_t  *p_rgb32;                /**< RGB 32 bits table */
+
+    /**< To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i],
+       p_rgb_b[i]). Note these are 16 bits per pixel. For 8bpp entries,
+       shift right 8 bits.
+    */
+    uint16_t  p_rgb_r[CMAP_RGB2_SIZE];  /**< Red values of palette */
+    uint16_t  p_rgb_g[CMAP_RGB2_SIZE];  /**< Green values of palette */
+    uint16_t  p_rgb_b[CMAP_RGB2_SIZE];  /**< Blue values of palette */
 #endif
 };