i420_rgb.h
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:24k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * i420_rgb.h : YUV to bitmap RGB conversion module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2004 the VideoLAN team
  5.  * $Id: 260f63e6afcc25b5229bd96f92e8ee19fac90b69 $
  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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /** Number of entries in RGB palette/colormap */
  24. #define CMAP_RGB2_SIZE 256
  25. /**
  26.  * filter_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 filter_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 I420_RGB8         ( filter_t *, picture_t *, picture_t * );
  54. void I420_RGB16_dither ( filter_t *, picture_t *, picture_t * );
  55. void I420_RGB16        ( filter_t *, picture_t *, picture_t * );
  56. void I420_RGB32        ( filter_t *, picture_t *, picture_t * );
  57. static picture_t *I420_RGB8_Filter         ( filter_t *, picture_t * );
  58. static picture_t *I420_RGB16_dither_Filter ( filter_t *, picture_t * );
  59. static picture_t *I420_RGB16_Filter        ( filter_t *, picture_t * );
  60. static picture_t *I420_RGB32_Filter        ( filter_t *, picture_t * );
  61. #else // if defined(MODULE_NAME_IS_i420_rgb_mmx)
  62. void I420_R5G5B5       ( filter_t *, picture_t *, picture_t * );
  63. void I420_R5G6B5       ( filter_t *, picture_t *, picture_t * );
  64. void I420_A8R8G8B8     ( filter_t *, picture_t *, picture_t * );
  65. void I420_R8G8B8A8     ( filter_t *, picture_t *, picture_t * );
  66. void I420_B8G8R8A8     ( filter_t *, picture_t *, picture_t * );
  67. void I420_A8B8G8R8     ( filter_t *, picture_t *, picture_t * );
  68. static picture_t *I420_R5G5B5_Filter       ( filter_t *, picture_t * );
  69. static picture_t *I420_R5G6B5_Filter       ( filter_t *, picture_t * );
  70. static picture_t *I420_A8R8G8B8_Filter     ( filter_t *, picture_t * );
  71. static picture_t *I420_R8G8B8A8_Filter     ( filter_t *, picture_t * );
  72. static picture_t *I420_B8G8R8A8_Filter     ( filter_t *, picture_t * );
  73. static picture_t *I420_A8B8G8R8_Filter     ( filter_t *, picture_t * );
  74. #endif
  75. /*****************************************************************************
  76.  * CONVERT_*_PIXEL: pixel conversion macros
  77.  *****************************************************************************
  78.  * These conversion routines are used by YUV conversion functions.
  79.  * conversion are made from p_y, p_u, p_v, which are modified, to p_buffer,
  80.  * which is also modified. CONVERT_4YUV_PIXEL is used for 8bpp dithering,
  81.  * CONVERT_4YUV_PIXEL_SCALE does the same but also scales the output.
  82.  *****************************************************************************/
  83. #define CONVERT_Y_PIXEL( BPP )                                                
  84.     /* Only Y sample is present */                                            
  85.     p_ybase = p_yuv + *p_y++;                                                 
  86.     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] |     
  87.         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT)       
  88.         + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
  89. #define CONVERT_YUV_PIXEL( BPP )                                              
  90.     /* Y, U and V samples are present */                                      
  91.     i_uval =    *p_u++;                                                       
  92.     i_vval =    *p_v++;                                                       
  93.     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                               
  94.     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;     
  95.     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                              
  96.     CONVERT_Y_PIXEL( BPP )                                                    
  97. #define CONVERT_Y_PIXEL_DITHER( BPP )                                         
  98.     /* Only Y sample is present */                                            
  99.     p_ybase = p_yuv + *p_y++;                                                 
  100.     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128+p_dither[i_real_y])>>SHIFT) + i_red] |     
  101.         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128+p_dither[i_real_y])>>SHIFT)       
  102.         + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128+p_dither[i_real_y])>>SHIFT) + i_blue];
  103. #define CONVERT_YUV_PIXEL_DITHER( BPP )                                       
  104.     /* Y, U and V samples are present */                                      
  105.     i_uval =    *p_u++;                                                       
  106.     i_vval =    *p_v++;                                                       
  107.     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                               
  108.     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;     
  109.     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                              
  110.     CONVERT_Y_PIXEL_DITHER( BPP )                                             
  111. #define CONVERT_4YUV_PIXEL( 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_pic++ = p_lookup[                                                      
  117.         (((*p_y++ + dither11[i_real_y]) >> 4) << 7)                           
  118.       + ((*p_u++ + dither21[i_real_y]) >> 5) * 9                              
  119.       + ((*p_v++ + dither21[i_real_y]) >> 5) ];                               
  120.     *p_pic++ = p_lookup[                                                      
  121.         (((*p_y++ + dither12[i_real_y]) >> 4) << 7)                           
  122.       + ((*p_u + dither22[i_real_y]) >> 5) * 9                                
  123.       + ((*p_v + dither22[i_real_y]) >> 5) ];                                 
  124.     *p_pic++ = p_lookup[                                                      
  125.         (((*p_y++ + dither13[i_real_y]) >> 4) << 7)                           
  126.       + ((*p_u++ + dither23[i_real_y]) >> 5) * 9                              
  127.       + ((*p_v++ + dither23[i_real_y]) >> 5) ];                               
  128. #define CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                    
  129.     *p_pic++ = p_lookup[                                                      
  130.         ( ((*p_y + dither10[i_real_y]) >> 4) << 7)                            
  131.         + ((*p_u + dither20[i_real_y]) >> 5) * 9                              
  132.         + ((*p_v + dither20[i_real_y]) >> 5) ];                               
  133.     p_y += *p_offset++;                                                       
  134.     p_u += *p_offset;                                                         
  135.     p_v += *p_offset++;                                                       
  136.     *p_pic++ = p_lookup[                                                      
  137.         ( ((*p_y + dither11[i_real_y]) >> 4) << 7)                            
  138.         + ((*p_u + dither21[i_real_y]) >> 5) * 9                              
  139.         + ((*p_v + dither21[i_real_y]) >> 5) ];                               
  140.     p_y += *p_offset++;                                                       
  141.     p_u += *p_offset;                                                         
  142.     p_v += *p_offset++;                                                       
  143.     *p_pic++ = p_lookup[                                                      
  144.         ( ((*p_y + dither12[i_real_y]) >> 4) << 7)                            
  145.         + ((*p_u + dither22[i_real_y]) >> 5) * 9                              
  146.         + ((*p_v + dither22[i_real_y]) >> 5) ];                               
  147.     p_y += *p_offset++;                                                       
  148.     p_u += *p_offset;                                                         
  149.     p_v += *p_offset++;                                                       
  150.     *p_pic++ = p_lookup[                                                      
  151.         ( ((*p_y + dither13[i_real_y]) >> 4) << 7)                            
  152.         + ((*p_u + dither23[i_real_y]) >> 5) * 9                              
  153.         + ((*p_v + dither23[i_real_y]) >> 5) ];                               
  154.     p_y += *p_offset++;                                                       
  155.     p_u += *p_offset;                                                         
  156.     p_v += *p_offset++;                                                       
  157. /*****************************************************************************
  158.  * SCALE_WIDTH: scale a line horizontally
  159.  *****************************************************************************
  160.  * This macro scales a line using rendering buffer and offset array. It works
  161.  * for 1, 2 and 4 Bpp.
  162.  *****************************************************************************/
  163. #define SCALE_WIDTH                                                           
  164.     if( b_hscale )                                                            
  165.     {                                                                         
  166.         /* Horizontal scaling, conversion has been done to buffer.            
  167.          * Rewind buffer and offset, then copy and scale line */              
  168.         p_buffer = p_buffer_start;                                            
  169.         p_offset = p_offset_start;                                            
  170.         for( i_x = p_filter->fmt_out.video.i_width / 16; i_x--; )             
  171.         {                                                                     
  172.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  173.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  174.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  175.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  176.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  177.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  178.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  179.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  180.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  181.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  182.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  183.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  184.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  185.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  186.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  187.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  188.         }                                                                     
  189.         for( i_x = p_filter->fmt_out.video.i_width & 15; i_x--; )             
  190.         {                                                                     
  191.             *p_pic++ = *p_buffer;   p_buffer += *p_offset++;                  
  192.         }                                                                     
  193.         p_pic = (void*)((uint8_t*)p_pic + i_right_margin );                   
  194.     }                                                                         
  195.     else                                                                      
  196.     {                                                                         
  197.         /* No scaling, conversion has been done directly in picture memory.   
  198.          * Increment of picture pointer to end of line is still needed */     
  199.         p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch );               
  200.     }                                                                         
  201. /*****************************************************************************
  202.  * SCALE_WIDTH_DITHER: scale a line horizontally for dithered 8 bpp
  203.  *****************************************************************************
  204.  * This macro scales a line using an offset array.
  205.  *****************************************************************************/
  206. #define SCALE_WIDTH_DITHER( CHROMA )                                          
  207.     if( b_hscale )                                                            
  208.     {                                                                         
  209.         /* Horizontal scaling - we can't use a buffer due to dithering */     
  210.         p_offset = p_offset_start;                                            
  211.         for( i_x = p_filter->fmt_out.video.i_width / 16; i_x--; )             
  212.         {                                                                     
  213.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  214.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  215.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  216.             CONVERT_4YUV_PIXEL_SCALE( CHROMA )                                
  217.         }                                                                     
  218.     }                                                                         
  219.     else                                                                      
  220.     {                                                                         
  221.         for( i_x = p_filter->fmt_in.video.i_width / 16; i_x--;  )             
  222.         {                                                                     
  223.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  224.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  225.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  226.             CONVERT_4YUV_PIXEL( CHROMA )                                      
  227.         }                                                                     
  228.     }                                                                         
  229.     /* Increment of picture pointer to end of line is still needed */         
  230.     p_pic = (void*)((uint8_t*)p_pic + i_right_margin );                       
  231.                                                                               
  232.     /* Increment the Y coordinate in the matrix, modulo 4 */                  
  233.     i_real_y = (i_real_y + 1) & 0x3;                                          
  234. /*****************************************************************************
  235.  * SCALE_HEIGHT: handle vertical scaling
  236.  *****************************************************************************
  237.  * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
  238.  * 444 for RGB conversion, or 400 for gray conversion. It works for 1, 2, 3
  239.  * and 4 Bpp.
  240.  *****************************************************************************/
  241. #define SCALE_HEIGHT( CHROMA, BPP )                                           
  242.     /* If line is odd, rewind 4:2:0 U and V samples */                        
  243.     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                
  244.     {                                                                         
  245.         p_u -= i_chroma_width;                                                
  246.         p_v -= i_chroma_width;                                                
  247.     }                                                                         
  248.                                                                               
  249.     /*                                                                        
  250.      * Handle vertical scaling. The current line can be copied or next one    
  251.      * can be ignored.                                                        
  252.      */                                                                       
  253.     switch( i_vscale )                                                        
  254.     {                                                                         
  255.     case -1:                             /* vertical scaling factor is < 1 */ 
  256.         while( (i_scale_count -= p_filter->fmt_out.video.i_height) > 0 )      
  257.         {                                                                     
  258.             /* Height reduction: skip next source line */                     
  259.             p_y += p_filter->fmt_in.video.i_width;                            
  260.             i_y++;                                                            
  261.             if( (CHROMA == 420) || (CHROMA == 422) )                          
  262.             {                                                                 
  263.                 if( i_y & 0x1 )                                               
  264.                 {                                                             
  265.                     p_u += i_chroma_width;                                    
  266.                     p_v += i_chroma_width;                                    
  267.                 }                                                             
  268.             }                                                                 
  269.             else if( CHROMA == 444 )                                          
  270.             {                                                                 
  271.                 p_u += p_filter->fmt_in.video.i_width;                        
  272.                 p_v += p_filter->fmt_in.video.i_width;                        
  273.             }                                                                 
  274.         }                                                                     
  275.         i_scale_count += p_filter->fmt_in.video.i_height;                     
  276.         break;                                                                
  277.     case 1:                              /* vertical scaling factor is > 1 */ 
  278.         while( (i_scale_count -= p_filter->fmt_in.video.i_height) > 0 )       
  279.         {                                                                     
  280.             /* Height increment: copy previous picture line */                
  281.             vlc_memcpy( p_pic, p_pic_start, p_filter->fmt_out.video.i_width * BPP ); 
  282.             p_pic = (void*)((uint8_t*)p_pic + p_dest->p->i_pitch );           
  283.         }                                                                     
  284.         i_scale_count += p_filter->fmt_out.video.i_height;                    
  285.         break;                                                                
  286.     }                                                                         
  287. /*****************************************************************************
  288.  * SCALE_HEIGHT_DITHER: handle vertical scaling for dithered 8 bpp
  289.  *****************************************************************************
  290.  * This macro handles vertical scaling for a picture. CHROMA may be 420,
  291.  * 422 or 444 for RGB conversion, or 400 for gray conversion.
  292.  *****************************************************************************/
  293. #define SCALE_HEIGHT_DITHER( CHROMA )                                         
  294.                                                                               
  295.     /* If line is odd, rewind 4:2:0 U and V samples */                        
  296.     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                
  297.     {                                                                         
  298.         p_u -= i_chroma_width;                                                
  299.         p_v -= i_chroma_width;                                                
  300.     }                                                                         
  301.                                                                               
  302.     /*                                                                        
  303.      * Handle vertical scaling. The current line can be copied or next one    
  304.      * can be ignored.                                                        
  305.      */                                                                       
  306.                                                                               
  307.     switch( i_vscale )                                                        
  308.     {                                                                         
  309.     case -1:                             /* vertical scaling factor is < 1 */ 
  310.         while( (i_scale_count -= p_filter->fmt_out.video.i_height) > 0 )      
  311.         {                                                                     
  312.             /* Height reduction: skip next source line */                     
  313.             p_y += p_filter->fmt_in.video.i_width;                            
  314.             i_y++;                                                            
  315.             if( (CHROMA == 420) || (CHROMA == 422) )                          
  316.             {                                                                 
  317.                 if( i_y & 0x1 )                                               
  318.                 {                                                             
  319.                     p_u += i_chroma_width;                                    
  320.                     p_v += i_chroma_width;                                    
  321.                 }                                                             
  322.             }                                                                 
  323.             else if( CHROMA == 444 )                                          
  324.             {                                                                 
  325.                 p_u += p_filter->fmt_in.video.i_width;                        
  326.                 p_v += p_filter->fmt_in.video.i_width;                        
  327.             }                                                                 
  328.         }                                                                     
  329.         i_scale_count += p_filter->fmt_in.video.i_height;                     
  330.         break;                                                                
  331.     case 1:                              /* vertical scaling factor is > 1 */ 
  332.         while( (i_scale_count -= p_filter->fmt_in.video.i_height) > 0 )       
  333.         {                                                                     
  334.             p_y -= p_filter->fmt_in.video.i_width;                            
  335.             p_u -= i_chroma_width;                                            
  336.             p_v -= i_chroma_width;                                            
  337.             SCALE_WIDTH_DITHER( CHROMA );                                     
  338.         }                                                                     
  339.         i_scale_count += p_filter->fmt_out.video.i_height;                    
  340.         break;                                                                
  341.     }