📄 scale_2d_yc_doub_buf.c
字号:
/* ========================================================================= */
/* Copyright (C) 2000 Texas Instruments Incorporated. */
/* All Rights Reserved */
/* ========================================================================= */
/* The code scales 3 planes of y, Cr, Cb data in varying combinations */
/* where Y denotes luma, Cr is red chrominance and Cb is blue chrominance */
/* NOTES */
/* When the phrase "pixels" is used this measn a color pixel, this has */
/* a color combination of 4:2:2, 4:4:4 or 4:2:0 */
/* for 4:4:4 there are 3 identical coloe spaces all the same size */
/* for 4:2:2 there planes are the same height but only half as wide */
/* for 4:2:0 the planes are 1/2 the width and 1/2 the height */
/* */
/* The scaler will automatically filter output data only within the display */
/* if it is larger than the display it will write to the boundary, if smaller*/
/* it will centre the image in the middle. */
/* */
/* This function can be applied to R, G, B data also R->Y, G->Cr, B->Cb */
/* ========================================================================= */
/* Copyright (C) 2000 Texas Instruments Incorporated. */
/* All Rights Reserved */
/* ========================================================================= */
#include <csl.h>
#include <csl_dat.h>
#include "ycbcr422pl16_to_rgb565_h.h"
#include "scale_horz_h.h"
#include "scale_vert_h.h"
#include "pix_expand_h.h"
#define f4_4_4 2
#define f4_2_2 1
#define f4_2_0 0
#pragma CODE_SECTION(scale_2d_ycrcb,".opt_gp");
/* ========================================================================= */
void scale_2d_ycrcb (
int format, /* 4:4:4 == 2, 4:2:2 == 1, 4:2:0 == 0 */
int p_h, /* numerator for horizontal scale factor p/q */
int q_h, /* denominator for horizontal scale factor p/q */
short * hpatch, /* stride table for cr/b horizontal scaling jumps*/
short * hh, /* pntr to horz filter bank */
int l_hh, /* number of taps in each horz filter */
int n_hh, /* number of filters in horz filter bank */
int p_v, /* numerator for vertical scale factor p/q */
int q_v, /* denominator for vertical scale factor p/q */
short * vpatch, /* stride table for vertical scaling jumps */
short * hv, /* pntr to vert filter bank */
int l_hv, /* number of taps in each vert filter */
int n_hv, /* number of filters in vert filter bank */
int in_pic_height, /* height of picture in Pixels multiple of 2 */
int in_pic_width, /* width of picture in Pixels multiple of 8 */
int display_height, /* height of picture in Pixels multiple of 2 */
int display_width, /* width of picture in Pixels multiple of 8 */
unsigned char * image_y, /* pntr to input image planar y values */
unsigned char * image_cr, /* pntr to input image planar cr values */
unsigned char * image_cb, /* pntr to input image planar cb values */
void * L2scratch_pad, /* temp space for internal buffers and stores */
/* aligned to a double boundary */
unsigned char * image_rgb)/* pntr to output image, scaled in color */
/* ========================================================================= */
{
short * vpatchy; /* copy of patch table for y scaling */
short * vpatchc; /* copy of patch table for cr and cb scaling */
short * t_filt; /* pntr to temporary buffer length l_hh */
int y_width; /* width of raw y plane image */
int y_height; /* height of raw y plane image */
int in_y_width; /* width of data to be scaled, sub section of y buffer */
int in_y_offset; /* offset from left edge of raw Y plane buffer */
int in_y_offset_1; /* offset from left edge of raw Y plane buffer */
int y_rd_index; /* index into the raw Y buffer */
int y_filter_no; /* the current vertical filter being used for the
vertical filtering of Y */
int out_y_width; /* width of data scaled Y buffer */
int main_out_y_width; /* width of scaled chroma image */
int total_out_y_width;/* width of scaled chroma image */
int hylines; /* number of horizontally scaled y lines
put in y r(otating)b(uffer) */
int y_rb_write_line; /* index into y r(otating)b(uffer) */
int y_rb_read_line; /* index into y r(otating)b(uffer) for removal */
int out_color_offset;/* offset into the display buffer depends on display
and scaled picture size */
int in_vert_offset; /* generic intermediate offset to top of scaled image */
int in_c_offset; /* offset to (cropped) corner of raw chroma images */
int in_c_offset_1; /* offset to (cropped) corner of raw chroma images */
int c_width; /* width of chroma raw image */
int in_c_width; /* width of cropped raw chroma image */
int out_c_width; /* width of scaled chroma image */
int c_rd_index; /* index into the raw C buffers */
int hclines; /* number of horizontally scaled c lines
put in c r(otating)b(uffer) */
int c_rb_write_line; /* index into c r(otating)b(uffer) for addition*/
int c_rb_read_line; /* index into c r(otating)b(uffer) for removal */
int c_filter_no; /* the current vertical filter being used for the
vertical filtering of C */
int max_clines; /* number of color lines needed by colr format
e.g. 444 needs 2 lines, 420 needs only 1 */
int display_lines; /* number of color lines written to display so far */
int display_pixels; /* number of color pixels written to display so far */
int window_height; /* number of lines to display */
int color; /* number of color elements/pixel rgb=3, 4:2:2 = 1.5 */
int color_shift; /* divider for whether output is 422,420 or 444 */
unsigned char *buf_y0;/*pointer to 1st pingpong buffer for y raw image data */
int in_y_buf_size;/* size of the input ping or pong buffer */
short *buf_y1; /* pointer to 2nd buffer containing expanded y pixels */
short *rot_buf_y2; /* pntr to circular line buffer containing l_hv lines of
horizontally scaled raw y data */
short *buf_y3; /* pntr to output buffer 2 lines of vertically &
horizontally scaled y data ready for combining
into color pixels */
short *y_filt_state; /* packed last filter number and input index */
unsigned char *buf_cr0;/* pointer to 1st ping pong buffer for c raw image data */
int in_c_buf_size;/* size of the input ping or pong buffer */
short *buf_cr1; /* pointer to 2nd buffer containing expanded c pixels */
short *rot_buf_cr2; /* pntr to circular line buffer containing l_hv lines of
horizontally scaled raw c data */
short *buf_cr3; /* pntr to buffer of 2 lines of vertically and horizontally
scaled c data ready for combining into color pixels */
unsigned char *buf_cb0;/* pointer to 1st ping pong buffer for c raw image data */
short *buf_cb1; /* pntr to 2nd buffer containing expanded c pixels */
short *rot_buf_cb2; /* pntr to circular line buffer containing l_hv lines of
horizontally scaled raw c data */
short *buf_cb3; /* pntr to buffer of 2 lines of vertically & horizontally
scaled c data ready for combining into color pixels */
short *c_filt_state;/* packed last filter number and input index */
int y_scaled; /*num. of finished y lines in output buffer pre color*/
int c_scaled; /*num. of finished c clines in output buffer pre color*/
unsigned char *buf_rgb; /* pntr to ping pong buffer containing 2 lines of
color pixels formed from the y,cr,cb data */
short cmatrix[5] = {0x2543, 0x3313, -0x0C8A, -0x1A04, 0x408D};
unsigned char *gp_store; /* pointer to the scratchpad space */
int store_index; /* index into main scratch pad for buffers */
int divider; /* number of strips needed for cache allocation */
int i; /* current strip being worked on */
int ping_in_y, pong_in_y;/* tags for buffers, ping or pong */
int ping_in_c, pong_in_c;/* tags for buffers, ping or pong */
unsigned int in_id_y ; /* input EDMA xfer id */
unsigned int in_id_cr; /* input EDMA xfer id */
unsigned int in_id_cb; /* input EDMA xfer id */
int first; /* tag for out buffer */
unsigned int out_id0; /* output EDMA xfer id */
int ping_out, pong_out; /* tags for buffers, ping or pong */
int write_buf;
/* ========================= set up dimensions ============================== */
/* and align all offsets to 8 element boundaries and counts to mutliples */
/* of 8 elements */
color = 2; /* each color is now 2 bytes, 565 */
y_width = in_pic_width;
y_height = in_pic_height;
/* the scaled output width is bigger than the display ? */
if (p_h * in_pic_width >= q_h * display_width)
{
in_y_offset = (y_width * p_h - q_h * display_width)/(2*p_h);
in_y_width = (q_h * display_width)/p_h;
out_y_width = display_width;
out_color_offset = 0;
/* the scaled image width is smaller than the display ? */
} else
{
in_y_offset = 0;
in_y_width = y_width;
out_y_width = (y_width * p_h) / q_h;
out_color_offset = color*((display_width * q_h - p_h * y_width)/(q_h*2));
}
/* the scaled output is bigger than the display ? */
if (p_v * in_pic_height >= q_v * display_height)
{
in_vert_offset= y_width*((y_height * p_v - q_v * display_height)/(2*p_v));
window_height = display_height;
/* the scaled image is smaller than the display ? */
} else
{
in_vert_offset = 0;
window_height = (in_pic_height * p_v)/q_v;
window_height = (window_height + 2) & ~ 1;
out_color_offset += color * display_width *
((display_height * q_v - p_v * y_height)/(2*q_v));
}
out_color_offset &= ~3;
if (format == f4_4_4)
{
in_c_offset = in_y_offset + in_vert_offset;
c_width = y_width;
in_c_width = in_y_width;
out_c_width = out_y_width;
max_clines = 2;
color_shift = 0;
} else if (format == f4_2_2)
{
c_width = y_width >> 1;
in_c_offset = in_y_offset ? (c_width*p_h - q_h*(display_width>>1))/(2*p_h):0;
in_c_offset += (in_vert_offset >> 1);
in_c_width = in_y_width >> 1;
out_c_width = out_y_width >> 1;
max_clines = 2;
color_shift = 1;
} else /* format == f4_2_0 */
{
c_width = y_width >> 1;
in_c_offset = in_y_offset ? (c_width*p_h - q_h*(display_width>>1))/(4*p_h) : 0;
in_c_offset += (in_vert_offset >> 2);
in_c_width = in_y_width >> 1;
out_c_width = out_y_width >> 1;
max_clines = 1;
color_shift = 1;
}
in_y_offset += in_vert_offset;
in_y_offset_1 = in_y_offset + (hpatch[1] >> 1);
in_c_offset_1 = in_c_offset + (hpatch[1] >> 1);
/* ========================= set up buffers ============================= */
gp_store = (unsigned char *) L2scratch_pad;
/* scratch pad is already set up to be aligned on a double boundary */
/* Y buffers */
store_index = 16;
store_index += 2*l_hh + 16 + 32;
store_index += 2*((in_y_width & ~7) + 16);
store_index += sizeof(short)*((in_y_width & ~7) + 32); /* */
store_index += sizeof(short)*((out_y_width & ~7) + 16)*l_hv;
store_index += 2*sizeof(short)*((out_y_width & ~7) + 16);
store_index += 2*((in_c_width & ~7) + 16);
store_index += sizeof(short)*((in_c_width & ~7) + 32); /* */
store_index += sizeof(short)*((out_c_width & ~7) + 16) *l_hv;
store_index += 2*sizeof(short)*((out_c_width & ~7) + 16);
/* Cb buffers */
store_index += 2*((in_c_width & ~7) + 16);
store_index += sizeof(short)*((in_c_width & ~7) + 32); /* */
store_index += sizeof(short)*((out_c_width & ~7) + 16) *l_hv;
store_index += 2*sizeof(short)*((out_c_width & ~7) + 16);
/* total data required is now known */
divider = (store_index + 24*1024)/(16*1024);
main_out_y_width = out_y_width ;
in_y_width /= divider;
out_y_width /= divider;
in_c_width /= divider;
/* round up to nearest end */
total_out_y_width = 0;
out_y_width += 8;
out_y_width &= ~7;
out_c_width = out_y_width >> color_shift;
/* Y buffers */
store_index = 0;
t_filt = (short *) &gp_store[0];
store_index += 2*l_hh + 16;
y_filt_state = (short *) &gp_store[store_index];
store_index += 16;
c_filt_state = (short *) &gp_store[store_index];
store_index += 16;
buf_y0 = &gp_store[store_index];
store_index += 2*((in_y_width & ~7) + 32); /* 16 */
store_index += 64;
buf_y1 = (short *) &gp_store[store_index];
store_index += sizeof(short)*((in_y_width & ~7) + 16);
store_index += 64;
rot_buf_y2 = (short *) &gp_store[store_index];
store_index += sizeof(short)*((out_y_width & ~7) + 16)*l_hv;
buf_y3 = (short *) &gp_store[store_index];
store_index += 2*sizeof(short)*((out_y_width & ~7) + 16);
/* Cr buffers */
buf_cr0 = &gp_store[store_index];
store_index += 2*((in_c_width & ~7) + 32); /* 16 */
store_index += 64;
buf_cr1 = (short *) &gp_store[store_index];
store_index += sizeof(short)*((in_c_width & ~7) + 16);
store_index += 64;
rot_buf_cr2 = (short *) &gp_store[store_index];
store_index += sizeof(short)*((out_c_width & ~7) + 16) *l_hv;
buf_cr3 = (short *) &gp_store[store_index];
store_index += 2*sizeof(short)*((out_c_width & ~7) + 16);
/* Cb buffers */
buf_cb0 = &gp_store[store_index];
store_index += 2*((in_c_width & ~7) + 32); /* 16 */
store_index += 64;
buf_cb1 = (short *) &gp_store[store_index];
store_index += sizeof(short)*((in_c_width & ~7) + 16);
store_index += 64;
rot_buf_cb2 = (short *) &gp_store[store_index];
store_index += sizeof(short)*((out_c_width & ~7) + 16) *l_hv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -