www.pudn.com > scaling.rar > color_conv_image_org.c


/*-------------------------------------------------------------------------*/ 
/* The following function demonstrates the use of optimized color          */ 
/* space conversion routine "ycbcr422pl_to_rgb565". It accepts             */ 
/* pointers to even and odd fields data for (YCRCB) and converts           */ 
/* data to RGB565 format. This function has been modified to drop          */ 
/* one field of data, and scale the other field by a factor of 2           */ 
/* horizontally. Thus this function prepares a 320x240 4:2:0  Y,           */ 
/* Cr, Cb data in memory. The Cr and Cb data are each 160x240.             */ 
/*-------------------------------------------------------------------------*/    
 
/*-------------------------------------------------------------------------*/ 
/* Include header files for image processing and ImageDataManager          */ 
/*-------------------------------------------------------------------------*/ 
 
#include "img_proc.h" 
#include "dstr_2d.h" 
#include "csl_dat.h" 
#include "csl_irq.h" 
 
/*-------------------------------------------------------------------------*/ 
/* if DEBUG flag is turned ON, then use the LOG Object trace               */ 
/*-------------------------------------------------------------------------*/ 
 
#ifdef DEBUG 
#include  
#include  
extern LOG_Obj trace; 
#endif  
 
/*-------------------------------------------------------------------------*/ 
/* The function color_convert repeatedly calls "ycbcr422pl_to_rgb565"      */ 
/* to perform color space conversion from 4:2:2 YCrCb format to RGB565     */ 
/* The function has the following prototype:                               */ 
/*                                                                         */ 
/* void color_convert                                                      */ 
/*(                                                                        */   
/*  IMAGE *in_image_luma_ev, IMAGE *in_image_cr_ev, IMAGE *in_image_cb_ev, */ 
/*  IMAGE *in_image_luma_od, IMAGE *in_image_cr_od, IMAGE *in_image_cb_od, */ 
/*  IMAGE *out_image,        SCRATCH_PAD  *scratch_pad)                    */ 
/*                                                                         */ 
/* where:                                                                  */ 
/*                                                                         */ 
/* in_image_luma_ev: IMAGE pointer to even Y or luma field                 */ 
/* in_image_cr_ev:   IMAGE pointer to even CR   field                      */ 
/* in_image_cb_ev:   IMAGE pointer to even CB   field                      */ 
/* in_image_luma_od: IMAGE pointer to odd  Y or luma field                 */ 
/* in_image_cr_od:   IMAGE pointer to odd  CR   field                      */ 
/* in_image_cb_od:   IMAGE pointer to odd  CB   field                      */ 
/* out_image:        IMAGE pointer to output    image                      */ 
/* scratch_pad:      SCRATCH_PAD pointer to temporary external and inter-  */ 
/*                   nal scratch buffers.                                  */ 
/*                                                                         */ 
/* This function allows the user to work on multiple lines, (in this case  */ 
/* 2). The results of working on all the even lines first followed by the  */ 
/* odd lines next are merged by using DMA's with appropriate offsets. The  */ 
/* pixel cache on the Imaging daughter card supports bursting through the  */ 
/* lines in the even or odd field better than accessing the lines of the   */ 
/* even and odd field back to back.                                        */ 
/*-------------------------------------------------------------------------*/ 
 
 
void color_convert 
( 
   IMAGE *in_image_luma_ev, IMAGE *in_image_cr_ev, IMAGE *in_image_cb_ev, 
   IMAGE *in_image_luma_od, IMAGE *in_image_cr_od, IMAGE *in_image_cb_od, 
   IMAGE *out_image,        SCRATCH_PAD  *scratch_pad) 
{   
 
    /*---------------------------------------------------------------------*/ 
    /* "int_mem" is start of internal meory. The # rows and # cols for the */ 
    /* luma even field and the output image are also initialized at this   */ 
    /* point.                                                              */ 
    /*---------------------------------------------------------------------*/ 
     
    char *int_mem = scratch_pad->int_data; 
    char *ext_mem = scratch_pad->ext_data; 
    
    int  rows     = in_image_luma_ev->img_rows; 
    int  cols     = in_image_luma_ev->img_cols; 
    int  out_rows = out_image->img_rows; 
    int  out_cols = out_image->img_cols; 
     
    int     i, j; 
    dstr_t  i_luma_ev, i_cr_ev, i_cb_ev; 
    
     
    int err_code; 
    int num_lines = 1;  
    unsigned int id; 
     
    unsigned char *ext_Y, *ext_CR, *ext_CB; 
     
    /*---------------------------------------------------------------------*/ 
    /* Internal memory allocation is done to scale with the image size. In */ 
    /* this file since both the even and odd fields are processed simulta- */ 
    /* neously, six input streams and one output stream are required to    */ 
    /* handle the processing. The data for these streams needs to be bro-  */ 
    /* ught into internal memory. The internal memory is partitioned as    */ 
    /* follows for this purpose:                                           */ 
    /*                                                                     */ 
    /* Even luma data: int_luma_ev      Double buffering width : 2 * cols  */ 
    /* Even Cr   data: int_cr_ev        Double buffering width : cols      */ 
    /* Even Cb   data: int_cb_ev        Double buffering width : cols      */ 
    /*                                                                     */ 
    /* out_data: Internal memory to hold processed RGB data                */ 
    /* Double buffering width: 2 * out_cols                                */  
    /*                                                                     */ 
    /* Note that this method uses reduced memory as compared to having to  */ 
    /* work with both even and odd fields at the same time.                */ 
    /*---------------------------------------------------------------------*/ 
     
    char *int_luma_ev = int_mem; 
    char *int_cr_ev   = int_mem  + (2 * cols * num_lines); 
    char *int_cb_ev   = int_mem  + (3 * cols * num_lines); 
    char *out_data    = int_mem  + (4 * cols * num_lines);  
     
    
     
    
    /*---------------------------------------------------------------------*/ 
    /* These pointers will be assigned to internal memory as and when they */ 
    /* become available from DMA                                           */ 
    /*---------------------------------------------------------------------*/ 
     
    unsigned char *Y, *Cr, *Cb, *RGB; 
         
   /*---------------------------------------------------------------------*/ 
   /* Coefficients to be used for Color space conversion                  */ 
   /*---------------------------------------------------------------------*/ 
 
    short coeffs[] = { 0x2543, 0x3313, -0x0C8A, -0x1A04, 0x408D };  
     
     
    /*--------------------------------------------------------------------*/ 
    /* Use scratch pad memory. These are the locations into which the     */ 
    /* modified Y, Cr, Cb data are written to. The scaling function will  */ 
    /* be passed on these locations for use.                              */ 
    /*--------------------------------------------------------------------*/ 
     
    ext_Y  = (unsigned char) ext_mem; 
    ext_CR = ext_Y   + (720 * 240); 
    ext_CB = ext_CR  + (360 * 240); 
     
   /*---------------------------------------------------------------------*/ 
   /* Initialize sream for luma data for even field, to bring in 1 line   */ 
   /* at a time                                                           */ 
   /*---------------------------------------------------------------------*/ 
     
    err_code = dstr_open( &i_luma_ev, 
                          in_image_luma_ev->img_data, 
                          2 * rows * cols, 
                          int_luma_ev, 
                          2 * cols * num_lines, 
                          cols, 
                          num_lines, 
                          2 * cols, 
                          1, 
                          DSTR_INPUT); 
    
   #ifdef DEBUG                        
   if (err_code) 
   { 
       LOG_printf(&trace, "error opening luma stream %d \n", 
       err_code); 
   } 
   #else 
   (void)(err_code);  
   #endif  
    
       
   /*---------------------------------------------------------------------*/ 
   /* Initialize stream for Cr  data for even field, to bring in 1 line   */ 
   /* at a time                                                           */ 
   /*---------------------------------------------------------------------*/ 
    
   err_code = dstr_open( &i_cr_ev, 
                         in_image_cr_ev->img_data, 
                         (2 * rows * cols), 
                         int_cr_ev, 
                         cols * num_lines, 
                         cols >> 1, 
                         num_lines, 
                         cols, 
                         1, 
                         DSTR_INPUT); 
    
   #ifdef DEBUG                       
   if (err_code) 
   { 
       LOG_printf(&trace, "error opening cr stream %d \n", 
       err_code); 
   }  
   #else 
   (void)(err_code); 
   #endif  
    
          
   /*---------------------------------------------------------------------*/ 
   /* Initialize stream for Cb  data for even field, to bring in 1 line   */ 
   /* at a time                                                           */ 
   /*---------------------------------------------------------------------*/ 
    
   err_code = dstr_open( &i_cb_ev, 
                         in_image_cb_ev->img_data, 
                         (2 * rows * cols), 
                         int_cb_ev, 
                         cols * num_lines, 
                         cols >> 1, 
                         num_lines, 
                         cols, 
                         1, 
                         DSTR_INPUT 
                       ); 
    
   #ifdef DEBUG                       
   if (err_code) 
   { 
       LOG_printf(&trace, "error opening cb stream %d \n", 
       err_code); 
   } 
   #else 
   (void)(err_code);  
   #endif  
    
   /*-------------------------------------------------------------------*/ 
   /* The previous code performed color space conversion. This is done  */ 
   /* from within the scaling function and hence the output stream is   */ 
   /* commented out.                                                    */ 
   /*-------------------------------------------------------------------*/ 
    
    
    
 
    
   /*--------------------------------------------------------------------*/ 
   /* For all rows of the even field obtain luma Y, Cr and               */ 
   /* Cb data and call optimized color space conversion routine. Commit  */ 
   /* results to display buffer. Update luma Y, Cr and Cb with pointers  */ 
   /* for odd fields and commit results to external memory. In this ex-  */ 
   /* ample 1 line of the image from the even field and 1 line of the    */ 
   /* image from the odd field are processed back to back.               */ 
   /*--------------------------------------------------------------------*/ 
    
   for ( i = 0; i < rows; i++) 
   { 
       /*----------------------------------------------------------------*/ 
       /* Obtain Y, Cr, Cb pointers for even/odd field. The call to put  */ 
       /* routine returns information on where the output results are to */ 
       /* be written. These calls need to be to the 2D routines as mul-  */ 
       /* tiple lines need to be read and written at the same time.      */ 
       /*----------------------------------------------------------------*/ 
        
       Y  = (unsigned char *) dstr_get_2D(&i_luma_ev); 
       Cr = (unsigned char *) dstr_get_2D(&i_cr_ev); 
       Cb = (unsigned char *) dstr_get_2D(&i_cb_ev); 
        
                     
        
       if (i) DAT_wait(id); 
        
       DAT_copy(Y,       ext_Y  + (i * 720),  720); 
       DAT_copy(Cr,      ext_CR + (i * 360),  360); 
       id = DAT_copy(Cb, ext_CB + (i * 360),  360); 
                        
   }  
    
    
   /*--------------------------------------------------------------------*/ 
   /* Commit last set of results to output buffer for both even/odd      */ 
   /* field.                                                             */ 
   /*--------------------------------------------------------------------*/ 
    
   DAT_wait(id); 
    
    
     
    
     
   /*-------------------------------------------------------------------*/ 
   /* Close streams for Y, Cr and Cb                                    */ 
   /*-------------------------------------------------------------------*/ 
   
   #if 0 
   dstr_close(&i_luma_ev); 
   dstr_close(&i_cr_ev); 
   dstr_close(&i_cb_ev);  
   #endif 
    
}