📄 565.c
字号:
(CLIP8[y1 + bu]) |
(CLIP8[y1 + guv] << 11) |
(CLIP8[y1 + rv] << 22) ;
/* second line 00rrrrrr.rr000ggg.ggggg000.bbbbbbbb: */
*(unsigned int *)(d2+0) =
(CLIP8[y2 + bu]) |
(CLIP8[y2 + guv] << 11) |
(CLIP8[y2 + rv] << 22) ;
sy1 += 1; sy2 += 1;
su += 1; sv += 1;
d1 += BPP4; d2 += BPP4;
dx --;
}
/* convert all integral 2x2 blocks: */
for (i = 0; i < dx/2; i ++) {
bu = pcd->butab[su[0]];
guv = pcd->gutab[su[0]] + pcd->gvtab[sv[0]];
rv = pcd->rvtab[sv[0]];
y1 = pcd->ytab[sy1[0]];
y2 = pcd->ytab[sy2[0]];
/* first line 00rrrrrr.rr000ggg.ggggg000.bbbbbbbb: */
*(unsigned int *)(d1+0) =
(CLIP8[y1 + bu]) |
(CLIP8[y1 + guv] << 11) |
(CLIP8[y1 + rv] << 22) ;
/* second line 00rrrrrr.rr000ggg.ggggg000.bbbbbbbb: */
*(unsigned int *)(d2+0) =
(CLIP8[y2 + bu]) |
(CLIP8[y2 + guv] << 11) |
(CLIP8[y2 + rv] << 22) ;
/* 2nd row: */
y1 = pcd->ytab[sy1[1]];
y2 = pcd->ytab[sy2[1]];
/* first line 00rrrrrr.rr000ggg.ggggg000.bbbbbbbb: */
*(unsigned int *)(d1+BPP4) =
(CLIP8[y1 + bu]) |
(CLIP8[y1 + guv] << 11) |
(CLIP8[y1 + rv] << 22) ;
/* second line 00rrrrrr.rr000ggg.ggggg000.bbbbbbbb: */
*(unsigned int *)(d2+BPP4) =
(CLIP8[y2 + bu]) |
(CLIP8[y2 + guv] << 11) |
(CLIP8[y2 + rv] << 22) ;
/* next 2x2 block */
sy1 += 2; sy2 += 2;
su += 1; sv += 1;
d1 += 2*BPP4; d2 += 2*BPP4;
}
/* convert last 2x1 block: */
if (dx & 1) {
bu = pcd->butab[su[0]];
guv = pcd->gutab[su[0]] + pcd->gvtab[sv[0]];
rv = pcd->rvtab[sv[0]];
y1 = pcd->ytab[sy1[0]];
y2 = pcd->ytab[sy2[0]];
/* first line 00rrrrrr.rr000ggg.ggggg000.bbbbbbbb: */
*(unsigned int *)(d1+0) =
(CLIP8[y1 + bu]) |
(CLIP8[y1 + guv] << 11) |
(CLIP8[y1 + rv] << 22) ;
/* second line BGR0 */
*(unsigned int *)(d2+0) =
(CLIP8[y2 + bu]) |
(CLIP8[y2 + guv] << 11) |
(CLIP8[y2 + rv] << 22) ;
}
}
/*
* I420->RGB565 converter:
*/
int I420toRGB565 (unsigned char *dest_ptr, int dest_width, int dest_height,
int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
int src_x, int src_y, int src_dx, int src_dy,
color_data_t* pcd)
{
/* scale factors: */
int scale_x, scale_y;
/* check arguments: */
if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
return -1;
/* check if bottop-up images: */
if (dest_pitch < 0) dest_ptr -= (dest_height-1) * dest_pitch;
if (src_pitch <= 0) return -1; /* not supported */
/* check if 1:1 scale: */
if (scale_x == 1 && scale_y == 1) {
/* color converter to use: */
void (*dbline) (unsigned char *d1, unsigned char *d2, int dest_x,
unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
int src_x, int dx, color_data_t* pcd) =
dblineI420toRGB565;
/* local variables: */
unsigned char *sy1, *sy2, *su, *sv, *d1, *d2;
register int j;
/* get pointers: */
sy1 = src_ptr + (src_x + src_y * src_pitch); /* luma offset */
sy2 = sy1 + src_pitch;
su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
sv = su + src_height * src_pitch / 4;
d1 = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* RGB offset */
d2 = d1 + dest_pitch;
/* convert a top line: */
if (src_y & 1) { /* chroma shift */
/* this is a bit inefficient, but who cares??? */
(* dbline) (d1, d1, dest_x, sy1, sy1, su, sv, src_x, src_dx, pcd);
sy1 += src_pitch; sy2 += src_pitch;
su += src_pitch/2; sv += src_pitch/2;
d1 += dest_pitch; d2 += dest_pitch;
dest_dy --;
}
/* convert aligned portion of the image: */
for (j = 0; j < dest_dy/2; j ++) {
/* convert two lines a time: */
(* dbline) (d1, d2, dest_x, sy1, sy2, su, sv, src_x, src_dx, pcd);
sy1 += src_pitch*2; sy2 += src_pitch*2;
su += src_pitch/2; sv += src_pitch/2;
d1 += dest_pitch*2; d2 += dest_pitch*2;
}
/* convert bottom line (if dest_dy is odd): */
if (dest_dy & 1) {
/* convert one line only: */
(* dbline) (d1, d1, dest_x, sy1, sy1, su, sv, src_x, src_dx, pcd);
}
return 0;
}
/* check if 2:1 scale: */
if (scale_x == 2 && scale_y == 2) {
/* color converter & interpolator to use: */
void (*cvt) (unsigned char *d1, unsigned char *d2, int dest_x,
unsigned char *sy1, unsigned char *sy2, unsigned char *su, unsigned char *sv,
int src_x, int dx, color_data_t* pcd) = dblineI420toXRGB;
void (*x2) (unsigned char *d1, unsigned char *d2, int dest_x,
unsigned char *s1, unsigned char *s2, int src_x, int dx, color_data_t* pcd) = dblineXRGBtoRGB565x2;
/* local variables: */
unsigned char *sy1, *sy2, *su, *sv, *d1, *d2;
register int dy = src_dy;
/* line buffers (we want them to be as compact as possible): */
int ibuf = 0; /* circular buffer index */
unsigned char * buf[3]; /* actual pointers */
buf[0] = pcd->linebuf;
buf[1] = pcd->linebuf + src_dx * BPP4;
buf[2] = pcd->linebuf + 2 * src_dx * BPP4;
/* get pointers: */
sy1 = src_ptr + (src_x + src_y * src_pitch); /* luma offset */
sy2 = sy1 + src_pitch;
su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
sv = su + src_height * src_pitch / 4;
d1 = dest_ptr + dest_x * BYTESPERPIXEL + dest_y * dest_pitch; /* RGB offset */
d2 = d1 + dest_pitch;
/* check if we have misaligned top line: */
if (src_y & 1) {
/* convert an odd first line: */
(*cvt) (buf[ibuf], buf[ibuf], 0, sy1, sy1, su, sv, src_x, src_dx, pcd);
sy1 += src_pitch; sy2 += src_pitch;
su += src_pitch/2; sv += src_pitch/2;
dy --;
} else {
/* otherwise, convert first two lines: */
(*cvt) (buf[next[ibuf]], buf[next2[ibuf]], 0, sy1, sy2, su, sv, src_x, src_dx, pcd);
sy1 += src_pitch*2; sy2 += src_pitch*2;
su += src_pitch/2; sv += src_pitch/2;
ibuf = next[ibuf]; /* skip first interpolation: */
(*x2) (d1, d2, dest_x, buf[ibuf], buf[next[ibuf]], 0, src_dx, pcd);
d1 += dest_pitch*2; d2 += dest_pitch*2;
ibuf = next[ibuf];
dy -= 2;
}
/*
* Convert & interpolate the main portion of image:
*
* source: temp.store: destination:
*
* buf[ibuf] -------\ /--> d1
* x2 --> d2
* s1 --\ /-> buf[next[ibuf]] -< /--> d1'=d1+2*pitch
* cvt x2 ---> d2'=d2+2*pitch
* s2 --/ \-> buf[next2[ibuf]] /
*/
while (dy >= 2) {
/* convert two lines into XRGB buffers: */
(*cvt) (buf[next[ibuf]], buf[next2[ibuf]], 0, sy1, sy2, su, sv, src_x, src_dx, pcd);
sy1 += src_pitch*2; sy2 += src_pitch*2;
su += src_pitch/2; sv += src_pitch/2;
/* interpolate first line: */
(*x2) (d1, d2, dest_x, buf[ibuf], buf[next[ibuf]], 0, src_dx, pcd);
d1 += dest_pitch*2; d2 += dest_pitch*2;
ibuf = next[ibuf];
/* interpolate second one: */
(*x2) (d1, d2, dest_x, buf[ibuf], buf[next[ibuf]], 0, src_dx, pcd);
d1 += dest_pitch*2; d2 += dest_pitch*2;
ibuf = next[ibuf];
dy -= 2;
}
/* check the # of remaining rows: */
if (dy & 1) {
/* convert the last odd line: */
(*cvt) (buf[next[ibuf]], buf[next[ibuf]], 0, sy1, sy1, su, sv, src_x, src_dx, pcd);
/* interpolate first line: */
(*x2) (d1, d2, dest_x, buf[ibuf], buf[next[ibuf]], 0, src_dx, pcd);
d1 += dest_pitch*2; d2 += dest_pitch*2;
ibuf = next[ibuf];
/* replicate the last line: */
(*x2) (d1, d2, dest_x, buf[ibuf], buf[ibuf], 0, src_dx, pcd);
} else {
/* replicate the last line: */
(*x2) (d1, d2, dest_x, buf[ibuf], buf[ibuf], 0, src_dx, pcd);
}
return 0;
}
/* check for 1/2 X scaling */
if (scale_x == 0 && scale_y == 0) {
/* local variables: */
unsigned char *sy1, *sy2, *su, *sv, *d1, *d2;
register int j;
/* get pointers: */
sy1 = src_ptr + (src_x + src_y * src_pitch); /* luma offset */
sy2 = sy1 + src_pitch;
su = src_ptr + src_height * src_pitch + (src_x/2 + src_y/2 * src_pitch);
sv = su + src_height * src_pitch / 4;
d1 = dest_ptr + dest_x * 2 + dest_y * dest_pitch; /* RGB offset */
d2 = d1 + dest_pitch;
/* convert aligned portion of the image: */
for (j = 0; j < dest_dy>>1; j ++) {
/* convert two lines a time: */
halfI420toRGB565 (d1, dest_x, sy1, sy2, su, sv, src_x, src_dx, 0, pcd);
sy1 += src_pitch*2; sy2 += src_pitch*2;
su += src_pitch/2; sv += src_pitch/2;
d1 += dest_pitch;
halfI420toRGB565 (d1, dest_x, sy1, sy2, su, sv, src_x, src_dx, 1, pcd);
sy1 += src_pitch*2; sy2 += src_pitch*2;
su += src_pitch/2; sv += src_pitch/2;
d1 += dest_pitch;
}
return 0;
}
/* conversion is not supported */
return -1;
}
/*
* InitI420toRGB565 initializes the minimum set of clip tables necessary to perform
* color conversion to 16 bit RGB. The 8-bit clip table is necessary for 2x
* interpolation.
*
* This routine also calls SetSrcI420Colors, which initializes color conversion tables
* and adds color balance.
*/
void InitI420toRGB565(float brightness, float contrast, float saturation, float hue,
color_data_t* pcd)
{
InitColorData(pcd);
SetSrcI420Colors (brightness, contrast, saturation, hue, pcd);
}
void UninitI420toRGB565( ){
/* noop */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -