www.pudn.com > scaling.rar > color_conv_image.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 }