📄 565.c
字号:
/* convert last 2x2 block: */
if (dx & 2) {
rv = pcd->rvtab[sv[0]];
guv = pcd->gutab[su[0]] + pcd->gvtab[sv[0]];
bu = pcd->butab[su[0]];
y11 = pcd->ytab[sy1[0]];
y12 = pcd->ytab[sy1[1]];
/* output 4 bytes at a time */
*(unsigned int *)(d1+0) =
(CLIP5[y11 + bu + DITH5L] << 0) |
(CLIP6[y11 + guv + DITH6L] << 5) |
(CLIP5[y11 + rv + DITH5L] << 11) |
(CLIP5[y12 + bu + DITH5H] << 16) |
(CLIP6[y12 + guv + DITH6H] << 21) |
(CLIP5[y12 + rv + DITH5H] << 27) ;
y21 = pcd->ytab[sy2[0]];
y22 = pcd->ytab[sy2[1]];
*(unsigned int *)(d2+0) =
(CLIP5[y21 + bu + DITH5H] << 0) |
(CLIP6[y21 + guv + DITH6H] << 5) |
(CLIP5[y21 + rv + DITH5H] << 11) |
(CLIP5[y22 + bu + DITH5L] << 16) |
(CLIP6[y22 + guv + DITH6L] << 21) |
(CLIP5[y22 + rv + DITH5L] << 27) ;
sy1 += 2; sy2 += 2;
su += 1; sv += 1;
d1 += 2*BPP2; d2 += 2*BPP2;
dx -= 2;
}
/* convert last 2x1 block: */
if (dx & 1) {
rv = pcd->rvtab[sv[0]];
guv = pcd->gutab[su[0]] + pcd->gvtab[sv[0]];
bu = pcd->butab[su[0]];
y11 = pcd->ytab[sy1[0]];
y21 = pcd->ytab[sy2[0]];
/* output 2 bytes at a time */
*(unsigned short *)(d1+0) =
(CLIP5[y11 + bu + DITH5L] << 0) |
(CLIP6[y11 + guv + DITH6L] << 5) |
(CLIP5[y11 + rv + DITH5L] << 11) ;
*(unsigned short *)(d2+0) =
(CLIP5[y21 + bu + DITH5H] << 0) |
(CLIP6[y21 + guv + DITH6H] << 5) |
(CLIP5[y21 + rv + DITH5H] << 11) ;
}
}
}
#define DITH1X4L 0x01002004
#define DITH1X4H 0x0300600C
#define DITH2X4L 0x02004008
#define DITH2X4H 0x0600C018
#define DITH4X4L 0x04008010
#define DITH4X4H 0x0C018030
/* RGB565 version: */
static void dblineXRGBtoRGB565x2 (unsigned char *d1, unsigned char *d2, int dest_x,
unsigned char *s1, unsigned char *s2, int src_x, int dx,
color_data_t* pcd)
{
register unsigned int a, b, c, d, e, f;
register unsigned int w, x, y, z;
/* convert first 2x1 block: */
if (dest_x & 1) {
/* Input pels => Output pels
* a b w x
* c d w' x'
*/
/* top line */
a = *(unsigned int *)s1;
b = *(unsigned int *)(s1+BPP4);
w = a + DITH1X4L;
x = a + b + DITH2X4H;
/* pack and store */
*(unsigned int *)d1 =
((w & 0x000000f8) >> 3) |
((w & 0x0007e000) >> 8) |
((w & 0x3e000000) >> 14) |
((x & 0x000001f0) << 12) |
((x & 0x000fc000) << 7) |
((x & 0x7c000000) << 1);
/* bottom line */
c = *(unsigned int *)s2;
d = *(unsigned int *)(s2+BPP4);
w = a + c + DITH2X4H;
x = a + b + c + d + DITH4X4L;
/* pack and store */
*(unsigned int *)d2 =
((w & 0x000001f0) >> 4) |
((w & 0x000fc000) >> 9) |
((w & 0x7c000000) >> 15) |
((x & 0x000003e0) << 11) |
((x & 0x001f8000) << 6) |
((x & 0xf8000000) << 0);
/* bump pointers to next block */
s1 += BPP4; s2 += BPP4;
d1 += 2*BPP2; d2 += 2*BPP2;
dx -= 1;
}
/* process all integral 2x2 blocks: */
while (dx > 2) { /* we need to leave at least one block */
/*
* Input stored as 00 RRRRRRRR 000 GGGGGGGG 000 BBBBBBBB
*
* Input pels Output pels
* a b e w x y z
* c d f w' x' y' z'
*/
/* top line */
a = *(unsigned int *)s1;
b = *(unsigned int *)(s1+BPP4);
e = *(unsigned int *)(s1+2*BPP4);
w = a + DITH1X4L;
x = a + b + DITH2X4H;
y = b + DITH1X4L;
z = b + e + DITH2X4H;
/* pack and store */
*(unsigned int *)d1 =
((w & 0x000000f8) >> 3) |
((w & 0x0007e000) >> 8) |
((w & 0x3e000000) >> 14) |
((x & 0x000001f0) << 12) |
((x & 0x000fc000) << 7) |
((x & 0x7c000000) << 1);
*(unsigned int *)(d1+2*BPP2) =
((y & 0x000000f8) >> 3) |
((y & 0x0007e000) >> 8) |
((y & 0x3e000000) >> 14) |
((z & 0x000001f0) << 12) |
((z & 0x000fc000) << 7) |
((z & 0x7c000000) << 1);
/* bottom line */
c = *(unsigned int *)s2;
d = *(unsigned int *)(s2+BPP4);
f = *(unsigned int *)(s2+2*BPP4);
w = a + c + DITH2X4H;
x = a + b + c + d + DITH4X4L;
y = b + d + DITH2X4H;
z = b + e + d + f + DITH4X4L;
/* pack and store */
*(unsigned int *)d2 =
((w & 0x000001f0) >> 4) |
((w & 0x000fc000) >> 9) |
((w & 0x7c000000) >> 15) |
((x & 0x000003e0) << 11) |
((x & 0x001f8000) << 6) |
((x & 0xf8000000) << 0);
*(unsigned int *)(d2+2*BPP2) =
((y & 0x000001f0) >> 4) |
((y & 0x000fc000) >> 9) |
((y & 0x7c000000) >> 15) |
((z & 0x000003e0) << 11) |
((z & 0x001f8000) << 6) |
((z & 0xf8000000) << 0);
/* next 2x2 input block */
s1 += 2*BPP4; s2 += 2*BPP4;
d1 += 4*BPP2; d2 += 4*BPP2;
dx -= 2;
}
/* check if this is the last 2x2 block: */
if (dx > 1) {
/*
* For last 4 output pels, repeat final input pel
* for offscreen input. Equivalent to pixel-doubling the
* last output pel.
*/
/* top line */
a = *(unsigned int *)s1;
b = *(unsigned int *)(s1+BPP4);
e = b; /* repeat last input pel */
w = a + DITH1X4L;
x = a + b + DITH2X4H;
y = b + DITH1X4L;
z = b + e + DITH2X4H;
/* pack and store */
*(unsigned int *)d1 =
((w & 0x000000f8) >> 3) |
((w & 0x0007e000) >> 8) |
((w & 0x3e000000) >> 14) |
((x & 0x000001f0) << 12) |
((x & 0x000fc000) << 7) |
((x & 0x7c000000) << 1);
*(unsigned int *)(d1+2*BPP2) =
((y & 0x000000f8) >> 3) |
((y & 0x0007e000) >> 8) |
((y & 0x3e000000) >> 14) |
((z & 0x000001f0) << 12) |
((z & 0x000fc000) << 7) |
((z & 0x7c000000) << 1);
/* bottom line */
c = *(unsigned int *)s2;
d = *(unsigned int *)(s2+BPP4);
f = d; /* repeat last input pel */
w = a + c + DITH2X4H;
x = a + b + c + d + DITH4X4L;
y = b + d + DITH2X4H;
z = b + e + d + f + DITH4X4L;
/* pack and store */
*(unsigned int *)d2 =
((w & 0x000001f0) >> 4) |
((w & 0x000fc000) >> 9) |
((w & 0x7c000000) >> 15) |
((x & 0x000003e0) << 11) |
((x & 0x001f8000) << 6) |
((x & 0xf8000000) << 0);
*(unsigned int *)(d2+2*BPP2) =
((y & 0x000001f0) >> 4) |
((y & 0x000fc000) >> 9) |
((y & 0x7c000000) >> 15) |
((z & 0x000003e0) << 11) |
((z & 0x001f8000) << 6) |
((z & 0xf8000000) << 0);
} else {
/* last 2x1 block: */
/* Input pels => Output pels
* a b w x
* c d w' x'
*/
/* top line */
a = *(unsigned int *)s1;
b = a; /* repeat last input pel */
w = a + DITH1X4L;
x = a + b + DITH2X4H;
/* pack and store */
*(unsigned int *)d1 =
((w & 0x000000f8) >> 3) |
((w & 0x0007e000) >> 8) |
((w & 0x3e000000) >> 14) |
((x & 0x000001f0) << 12) |
((x & 0x000fc000) << 7) |
((x & 0x7c000000) << 1);
/* bottom line */
c = *(unsigned int *)s2;
d = c; /* repeat last input pel */
w = a + c + DITH2X4H;
x = a + b + c + d + DITH4X4L;
/* pack and store */
*(unsigned int *)d2 =
((w & 0x000001f0) >> 4) |
((w & 0x000fc000) >> 9) |
((w & 0x7c000000) >> 15) |
((x & 0x000003e0) << 11) |
((x & 0x001f8000) << 6) |
((x & 0xf8000000) << 0);
}
}
/*
* Convert two YUV lines into RGB linebufs.
* Produces two RGB lines per call.
* Output in padded RGB format, needed for SIMD interpolation.
*/
static void dblineI420toXRGB (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)
{
register int y1, y2, rv, guv, bu;
register int i;
/* convert first 2x1 block: */
if (src_x & 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) =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -