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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * i420_rgb.h : YUV to bitmap RGB conversion module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2004 VideoLAN
  5.  * $Id: i420_rgb.h 7194 2004-03-29 19:57:07Z fenrir $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  * 
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /** Number of entries in RGB palette/colormap */
  24. #define CMAP_RGB2_SIZE 256
  25. /**
  26.  * chroma_sys_t: chroma method descriptor
  27.  * This structure is part of the chroma transformation descriptor, it
  28.  * describes the yuv2rgb specific properties.
  29.  */
  30. struct chroma_sys_t
  31. {
  32.     uint8_t  *p_buffer;
  33.     int *p_offset;
  34. #ifdef MODULE_NAME_IS_i420_rgb
  35.     /**< Pre-calculated conversion tables */
  36.     void *p_base;                      /**< base for all conversion tables */
  37.     uint8_t   *p_rgb8;                 /**< RGB 8 bits table */
  38.     uint16_t  *p_rgb16;                /**< RGB 16 bits table */
  39.     uint32_t  *p_rgb32;                /**< RGB 32 bits table */
  40.     /**< To get RGB value for palette entry i, use (p_rgb_r[i], p_rgb_g[i],
  41.        p_rgb_b[i]). Note these are 16 bits per pixel. For 8bpp entries,
  42.        shift right 8 bits.
  43.     */
  44.     uint16_t  p_rgb_r[CMAP_RGB2_SIZE];  /**< Red values of palette */
  45.     uint16_t  p_rgb_g[CMAP_RGB2_SIZE];  /**< Green values of palette */
  46.     uint16_t  p_rgb_b[CMAP_RGB2_SIZE];  /**< Blue values of palette */
  47. #endif
  48. };
  49. /*****************************************************************************
  50.  * Prototypes
  51.  *****************************************************************************/
  52. #ifdef MODULE_NAME_IS_i420_rgb
  53. void E_(I420_RGB8)         ( vout_thread_t *, picture_t *, picture_t * );
  54. void E_(I420_RGB16_dither) ( vout_thread_t *, picture_t *, picture_t * );
  55. #endif
  56. void E_(I420_RGB16)        ( vout_thread_t *, picture_t *, picture_t * );
  57. void E_(I420_RGB32)        ( vout_thread_t *, picture_t *, picture_t * );
  58. /*****************************************************************************
  59.  * CONVERT_*_PIXEL: pixel conversion macros
  60.  *****************************************************************************
  61.  * These conversion routines are used by YUV conversion functions.
  62.  * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
  63.  * which is also modified. CONVERT_4YUV_PIXEL is used for 8bpp dithering,
  64.  * CONVERT_4YUV_PIXEL_SCALE does the same but also scales the output.
  65.  *****************************************************************************/
  66. #define CONVERT_Y_PIXEL( BPP )                                                
  67.     /* Only Y sample is present */                                            
  68.     p_ybase = p_yuv + *p_y++;                                                 
  69.     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] |     
  70.         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT)       
  71.         + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
  72. #define CONVERT_YUV_PIXEL( BPP )                                              
  73.     /* Y, U and V samples are present */                                      
  74.     i_uval =    *p_u++;                                                       
  75.     i_vval =    *p_v++;                                                       
  76.     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                               
  77.     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;     
  78.     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                              
  79.     CONVERT_Y_PIXEL( BPP )                                                    
  80. #define CONVERT_Y_PIXEL_DITHER( BPP )                                         
  81.     /* Only Y sample is present */                                            
  82.     p_ybase = p_yuv + *p_y++;                                                 
  83.     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128+p_dither[i_real_y])>>SHIFT) + i_red] |     
  84.         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128+p_dither[i_real_y])>>SHIFT)       
  85.         + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128+p_dither[i_real_y])>>SHIFT) + i_blue];
  86. #define CONVERT_YUV_PIXEL_DITHER( BPP )                                       
  87.     /* Y, U and V samples are present */                                      
  88.     i_uval =    *p_u++;                                                       
  89.     i_vval =    *p_v++;                                                       
  90.     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                               
  91.     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;     
  92.     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                              
  93.     CONVERT_Y_PIXEL_DITHER( BPP )                                             
  94. #define CONVERT_4YUV_PIXEL( CHROMA )                                          
  95.     *p_pic++ = p_lookup[                                                      
  96.         (((*p_y++ + dither10[i_real_y]) >> 4) << 7)                           
  97.       + ((*p_u + dither20[i_real_y]) >> 5) * 9                                
  98.       + ((*p_v + dither20[i_real_y]) >> 5) ];                                 
  99.     *p_pic++ = p_lookup[                                                      
  100.         (((*p_y++ + dither11[i_real_y]) >> 4) << 7)                           
  101.       + ((*p_u++ + dither21[i_real_y]) >> 5) * 9                              
  102.       + ((*p_v++ + dither21[i_real_y]) >> 5) ];                               
  103.     *p_pic++ = p_lookup[                                                      
  104.         (((*p_y++ + dither12[i_real_y]) >> 4) << 7)                           
  105.       + ((*p_u + dither22[i_real_y]) >> 5) * 9                                
  106.       + ((*p_v + dither22[i_real_y]) >> 5) ];                                 
  107.     *p_pic++ = p_lookup[                                                      
  108.         (((*p_y++ + dither13[i_real_y]) >> 4) << 7)                           
  109.       + ((*p_u++ + dither23[i_real_y]) >> 5) * 9                              
  110.       + ((*p_v++ + dither23[i_real_y]) >> 5) ];                               
  111. #define CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                    
  112.     *p_pic++ = p_lookup[                                                      
  113.         ( ((*p_y + dither10[i_real_y]) >> 4) << 7)                            
  114.         + ((*p_u + dither20[i_real_y]) >> 5) * 9                              
  115.         + ((*p_v + dither20[i_real_y]) >> 5) ];                               
  116.     p_y += *p_offset++;                                                       
  117.     p_u += *p_offset;                                                         
  118.     p_v += *p_offset++;                                                       
  119.     *p_pic++ = p_lookup[                                                      
  120.         ( ((*p_y + dither11[i_real_y]) >> 4) << 7)                            
  121.         + ((*p_u + dither21[i_real_y]) >> 5) * 9                              
  122.         + ((*p_v + dither21[i_real_y]) >> 5) ];                               
  123.     p_y += *p_offset++;                                                       
  124.     p_u += *p_offset;                                                         
  125.     p_v += *p_offset++;                                                       
  126.     *p_pic++ = p_lookup[                                                      
  127.         ( ((*p_y + dither12[i_real_y]) >> 4) << 7)                            
  128.         + ((*p_u + dither22[i_real_y]) >> 5) * 9                              
  129.         + ((*p_v + dither22[i_real_y]) >> 5) ];                               
  130.     p_y += *p_offset++;                                                       
  131.     p_u += *p_offset;                                                         
  132.     p_v += *p_offset++;                                                       
  133.     *p_pic++ = p_lookup[                                                      
  134.         ( ((*p_y + dither13[i_real_y]) >> 4) << 7)                            
  135.         + ((*p_u + dither23[i_real_y]) >> 5) * 9                              
  136.         + ((*p_v + dither23[i_real_y]) >> 5) ];                               
  137.     p_y += *p_offset++;                                                       
  138.     p_u += *p_offset;                                                         
  139.     p_v += *p_offset++;                                                       
  140. /*****************************************************************************
  141.  * SCALE_WIDTH: scale a line horizontally
  142.  *****************************************************************************
  143.  * This macro scales a line using rendering buffer and offset array. It works
  144.  * for 1, 2 and 4 Bpp.
  145.  *****************************************************************************/
  146. #define SCALE_WIDTH                                                           
  147.     if( b_hscale )                                                            
  148.     {                                                                         
  149.         /* Horizontal scaling, conversion has been done to buffer.            
  150.          * Rewind buffer and offset, then copy and scale line */              
  151.         p_buffer = p_buffer_start;                                            
  152.         p_offset = p_offset_start;                                            
  153.         for( i_x = p_vout->output.i_width / 16; i_x--; )                      
  154.         {                                                                     
  155.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  156.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  157.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  158.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  159.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  160.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  161.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  162.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  163.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  164.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  165.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  166.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  167.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  168.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  169.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  170.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  171.         }                                                                     
  172.         for( i_x = p_vout->output.i_width & 15; i_x--; )                      
  173.         {                                                                     
  174.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  175.         }                                                                     
  176.         p_pic = (void*)((uint8_t*)p_pic + i_right_margin );                   
  177.     }                                                                         
  178.     else                                                                      
  179.     {                                                                         
  180.         /* No scaling, conversion has been done directly in picture memory.   
  181.          * Increment of picture pointer to end of line is still needed */     
  182.         p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch );               
  183.     }                                                                         
  184. /*****************************************************************************
  185.  * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
  186.  *****************************************************************************
  187.  * This macro scales a line using an offset array.
  188.  *****************************************************************************/
  189. #define SCALE_WIDTH_DITHER( CHROMA )                                          
  190.     if( b_hscale )                                                            
  191.     {                                                                         
  192.         /* Horizontal scaling - we can't use a buffer due to dithering */     
  193.         p_offset = p_offset_start;                                            
  194.         for( i_x = p_vout->output.i_width / 16; i_x--; )                      
  195.         {                                                                     
  196.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  197.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  198.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  199.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  200.         }                                                                     
  201.     }                                                                         
  202.     else                                                                      
  203.     {                                                                         
  204.         for( i_x = p_vout->render.i_width / 16; i_x--;  )                     
  205.         {                                                                     
  206.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  207.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  208.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  209.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  210.         }                                                                     
  211.     }                                                                         
  212.     /* Increment of picture pointer to end of line is still needed */         
  213.     p_pic = (void*)((uint8_t*)p_pic + i_right_margin );                       
  214.                                                                               
  215.     /* Increment the Y coordinate in the matrix, modulo 4 */                  
  216.     i_real_y = (i_real_y + 1) & 0x3;                                          
  217. /*****************************************************************************
  218.  * SCALE_HEIGHT: handle vertical scaling
  219.  *****************************************************************************
  220.  * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
  221.  * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
  222.  * and 4 Bpp.
  223.  *****************************************************************************/
  224. #define SCALE_HEIGHT( CHROMA, BPP )                                           
  225.     /* If line is odd, rewind 4:2:0 U and V samples */                        
  226.     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                
  227.     {                                                                         
  228.         p_u -= i_chroma_width;                                                
  229.         p_v -= i_chroma_width;                                                
  230.     }                                                                         
  231.                                                                               
  232.     /*                                                                        
  233.      * Handle vertical scaling. The current line can be copied or next one    
  234.      * can be ignored.                                                        
  235.      */                                                                       
  236.     switch( i_vscale )                                                        
  237.     {                                                                         
  238.     case -1:                             /* vertical scaling factor is < 1 */ 
  239.         while( (i_scale_count -= p_vout->output.i_height) > 0 )               
  240.         {                                                                     
  241.             /* Height reduction: skip next source line */                     
  242.             p_y += p_vout->render.i_width;                                    
  243.             i_y++;                                                            
  244.             if( (CHROMA == 420) || (CHROMA == 422) )                          
  245.             {                                                                 
  246.                 if( i_y & 0x1 )                                               
  247.                 {                                                             
  248.                     p_u += i_chroma_width;                                    
  249.                     p_v += i_chroma_width;                                    
  250.                 }                                                             
  251.             }                                                                 
  252.             else if( CHROMA == 444 )                                          
  253.             {                                                                 
  254.                 p_u += p_vout->render.i_width;                                
  255.                 p_v += p_vout->render.i_width;                                
  256.             }                                                                 
  257.         }                                                                     
  258.         i_scale_count += p_vout->render.i_height;                             
  259.         break;                                                                
  260.     case 1:                              /* vertical scaling factor is > 1 */ 
  261.         while( (i_scale_count -= p_vout->render.i_height) > 0 )               
  262.         {                                                                     
  263.             /* Height increment: copy previous picture line */                
  264.             p_vout->p_vlc->pf_memcpy( p_pic, p_pic_start,                     
  265.                                       p_vout->output.i_width * BPP );         
  266.             p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch );           
  267.         }                                                                     
  268.         i_scale_count += p_vout->output.i_height;                             
  269.         break;                                                                
  270.     }                                                                         
  271. /*****************************************************************************
  272.  * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
  273.  *****************************************************************************
  274.  * This macro handles vertical scaling for a picture. CHROMA may be 420,
  275.  * 422 or 444 for RGB conversion, or 400 for gray conversion.
  276.  *****************************************************************************/
  277. #define SCALE_HEIGHT_DITHER( CHROMA )                                         
  278.                                                                               
  279.     /* If line is odd, rewind 4:2:0 U and V samples */                        
  280.     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                
  281.     {                                                                         
  282.         p_u -= i_chroma_width;                                                
  283.         p_v -= i_chroma_width;                                                
  284.     }                                                                         
  285.                                                                               
  286.     /*                                                                        
  287.      * Handle vertical scaling. The current line can be copied or next one    
  288.      * can be ignored.                                                        
  289.      */                                                                       
  290.                                                                               
  291.     switch( i_vscale )                                                        
  292.     {                                                                         
  293.     case -1:                             /* vertical scaling factor is < 1 */ 
  294.         while( (i_scale_count -= p_vout->output.i_height) > 0 )               
  295.         {                                                                     
  296.             /* Height reduction: skip next source line */                     
  297.             p_y += p_vout->render.i_width;                                    
  298.             i_y++;                                                            
  299.             if( (CHROMA == 420) || (CHROMA == 422) )                          
  300.             {                                                                 
  301.                 if( i_y & 0x1 )                                               
  302.                 {                                                             
  303.                     p_u += i_chroma_width;                                    
  304.                     p_v += i_chroma_width;                                    
  305.                 }                                                             
  306.             }                                                                 
  307.             else if( CHROMA == 444 )                                          
  308.             {                                                                 
  309.                 p_u += p_vout->render.i_width;                                
  310.                 p_v += p_vout->render.i_width;                                
  311.             }                                                                 
  312.         }                                                                     
  313.         i_scale_count += p_vout->render.i_height;                             
  314.         break;                                                                
  315.     case 1:                              /* vertical scaling factor is > 1 */ 
  316.         while( (i_scale_count -= p_vout->render.i_height) > 0 )               
  317.         {                                                                     
  318.             p_y -= p_vout->render.i_width;                                    
  319.             p_u -= i_chroma_width;                                            
  320.             p_v -= i_chroma_width;                                            
  321.             SCALE_WIDTH_DITHER( CHROMA );                                     
  322.         }                                                                     
  323.         i_scale_count += p_vout->output.i_height;                             
  324.         break;                                                                
  325.     }