Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

i420_rgb8.c

00001 /*****************************************************************************
00002  * i420_rgb8.c : YUV to bitmap RGB conversion module for vlc
00003  *****************************************************************************
00004  * Copyright (C) 2000 the VideoLAN team
00005  * $Id: i420_rgb8.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Samuel Hocevar <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <string.h>                                            /* strerror() */
00028 #include <stdlib.h>                                      /* malloc(), free() */
00029 
00030 #include <vlc/vlc.h>
00031 #include <vlc/vout.h>
00032 
00033 #include "i420_rgb.h"
00034 #include "i420_rgb_c.h"
00035 
00036 static void SetOffset( int, int, int, int, vlc_bool_t *, int *, int * );
00037 
00038 /*****************************************************************************
00039  * I420_RGB8: color YUV 4:2:0 to RGB 8 bpp
00040  *****************************************************************************/
00041 void E_(I420_RGB8)( vout_thread_t *p_vout, picture_t *p_src, picture_t *p_dest )
00042 {
00043     /* We got this one from the old arguments */
00044     uint8_t *p_pic = (uint8_t*)p_dest->p->p_pixels;
00045     uint8_t *p_y   = p_src->Y_PIXELS;
00046     uint8_t *p_u   = p_src->U_PIXELS;
00047     uint8_t *p_v   = p_src->V_PIXELS;
00048 
00049     vlc_bool_t  b_hscale;                         /* horizontal scaling type */
00050     unsigned int i_vscale;                          /* vertical scaling type */
00051     unsigned int i_x, i_y;                /* horizontal and vertical indexes */
00052     unsigned int i_real_y;                                          /* y % 4 */
00053     int          i_right_margin;
00054     int          i_scale_count;                      /* scale modulo counter */
00055     unsigned int i_chroma_width = p_vout->render.i_width / 2;/* chroma width */
00056 
00057     /* Lookup table */
00058     uint8_t *        p_lookup = p_vout->chroma.p_sys->p_base;
00059 
00060     /* Offset array pointer */
00061     int *       p_offset_start = p_vout->chroma.p_sys->p_offset;
00062     int *       p_offset;
00063 
00064     const int i_source_margin = p_src->p[0].i_pitch
00065                                  - p_src->p[0].i_visible_pitch;
00066     const int i_source_margin_c = p_src->p[1].i_pitch
00067                                  - p_src->p[1].i_visible_pitch;
00068 
00069     /* The dithering matrices */
00070     static int dither10[4] = {  0x0,  0x8,  0x2,  0xa };
00071     static int dither11[4] = {  0xc,  0x4,  0xe,  0x6 };
00072     static int dither12[4] = {  0x3,  0xb,  0x1,  0x9 };
00073     static int dither13[4] = {  0xf,  0x7,  0xd,  0x5 };
00074 
00075     static int dither20[4] = {  0x0, 0x10,  0x4, 0x14 };
00076     static int dither21[4] = { 0x18,  0x8, 0x1c,  0xc };
00077     static int dither22[4] = {  0x6, 0x16,  0x2, 0x12 };
00078     static int dither23[4] = { 0x1e,  0xe, 0x1a,  0xa };
00079 
00080     SetOffset( p_vout->render.i_width, p_vout->render.i_height,
00081                p_vout->output.i_width, p_vout->output.i_height,
00082                &b_hscale, &i_vscale, p_offset_start );
00083 
00084     i_right_margin = p_dest->p->i_pitch - p_dest->p->i_visible_pitch;
00085 
00086     /*
00087      * Perform conversion
00088      */
00089     i_scale_count = ( i_vscale == 1 ) ?
00090                     p_vout->output.i_height : p_vout->render.i_height;
00091     for( i_y = 0, i_real_y = 0; i_y < p_vout->render.i_height; i_y++ )
00092     {
00093         /* Do horizontal and vertical scaling */
00094         SCALE_WIDTH_DITHER( 420 );
00095         SCALE_HEIGHT_DITHER( 420 );
00096     }
00097 
00098     p_y += i_source_margin;
00099     if( i_y % 2 )
00100     {
00101         p_u += i_source_margin_c;
00102         p_v += i_source_margin_c;
00103     }
00104 }
00105 
00106 /* Following functions are local */
00107 
00108 /*****************************************************************************
00109  * SetOffset: build offset array for conversion functions
00110  *****************************************************************************
00111  * This function will build an offset array used in later conversion functions.
00112  * It will also set horizontal and vertical scaling indicators. The p_offset
00113  * structure has interleaved Y and U/V offsets.
00114  *****************************************************************************/
00115 static void SetOffset( int i_width, int i_height, int i_pic_width,
00116                        int i_pic_height, vlc_bool_t *pb_hscale,
00117                        int *pi_vscale, int *p_offset )
00118 {
00119     int i_x;                                    /* x position in destination */
00120     int i_scale_count;                                     /* modulo counter */
00121 
00122     /*
00123      * Prepare horizontal offset array
00124      */
00125     if( i_pic_width - i_width == 0 )
00126     {
00127         /* No horizontal scaling: YUV conversion is done directly to picture */
00128         *pb_hscale = 0;
00129     }
00130     else if( i_pic_width - i_width > 0 )
00131     {
00132         int i_dummy = 0;
00133 
00134         /* Prepare scaling array for horizontal extension */
00135         *pb_hscale = 1;
00136         i_scale_count = i_pic_width;
00137         for( i_x = i_width; i_x--; )
00138         {
00139             while( (i_scale_count -= i_width) > 0 )
00140             {
00141                 *p_offset++ = 0;
00142                 *p_offset++ = 0;
00143             }
00144             *p_offset++ = 1;
00145             *p_offset++ = i_dummy;
00146             i_dummy = 1 - i_dummy;
00147             i_scale_count += i_pic_width;
00148         }
00149     }
00150     else /* if( i_pic_width - i_width < 0 ) */
00151     {
00152         int i_remainder = 0;
00153         int i_jump;
00154 
00155         /* Prepare scaling array for horizontal reduction */
00156         *pb_hscale = 1;
00157         i_scale_count = i_width;
00158         for( i_x = i_pic_width; i_x--; )
00159         {
00160             i_jump = 1;
00161             while( (i_scale_count -= i_pic_width) > 0 )
00162             {
00163                 i_jump += 1;
00164             }
00165             *p_offset++ = i_jump;
00166             *p_offset++ = ( i_jump += i_remainder ) >> 1;
00167             i_remainder = i_jump & 1;
00168             i_scale_count += i_width;
00169         }
00170     }
00171 
00172     /*
00173      * Set vertical scaling indicator
00174      */
00175     if( i_pic_height - i_height == 0 )
00176     {
00177         *pi_vscale = 0;
00178     }
00179     else if( i_pic_height - i_height > 0 )
00180     {
00181         *pi_vscale = 1;
00182     }
00183     else /* if( i_pic_height - i_height < 0 ) */
00184     {
00185         *pi_vscale = -1;
00186     }
00187 }
00188 

Generated on Tue Dec 20 10:14:50 2005 for vlc-0.8.4a by  doxygen 1.4.2