418169aff8
This reverts commit fe6aa21e9e
.
Change-Id: I8bb1e5d6c52ed1478002d2140ef494ec5d62b8e3
179 lines
3.9 KiB
C
179 lines
3.9 KiB
C
|
|
#include <string.h>
|
|
#include "lcd.h"
|
|
void lcd_copy_buffer_rect(fb_data *dst, fb_data *src, int width, int height)
|
|
{
|
|
do {
|
|
memcpy(dst, src, width * sizeof(fb_data));
|
|
src += LCD_WIDTH;
|
|
dst += LCD_WIDTH;
|
|
} while (--height);
|
|
}
|
|
|
|
#define YFAC (74)
|
|
#define RVFAC (101)
|
|
#define GUFAC (-24)
|
|
#define GVFAC (-51)
|
|
#define BUFAC (128)
|
|
|
|
static inline int clamp(int val, int min, int max)
|
|
{
|
|
if (val < min)
|
|
val = min;
|
|
else if (val > max)
|
|
val = max;
|
|
return val;
|
|
}
|
|
|
|
extern void lcd_write_yuv420_lines(fb_data *dst,
|
|
unsigned char const * const src[3],
|
|
int width,
|
|
int stride)
|
|
{
|
|
/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
|
|
in the core */
|
|
const unsigned char *ysrc, *usrc, *vsrc;
|
|
fb_data *row_end;
|
|
|
|
/* width and height must be >= 2 and an even number */
|
|
width &= ~1;
|
|
|
|
#if LCD_WIDTH >= LCD_HEIGHT
|
|
row_end = dst + width;
|
|
#else
|
|
row_end = dst + LCD_WIDTH * width;
|
|
#endif
|
|
|
|
ysrc = src[0];
|
|
usrc = src[1];
|
|
vsrc = src[2];
|
|
|
|
/* stride => amount to jump from end of last row to start of next */
|
|
stride -= width;
|
|
|
|
/* upsampling, YUV->RGB conversion and reduction to RGB in one go */
|
|
|
|
do
|
|
{
|
|
int y, cb, cr, rv, guv, bu, r, g, b;
|
|
|
|
y = YFAC*(*ysrc++ - 16);
|
|
cb = *usrc++ - 128;
|
|
cr = *vsrc++ - 128;
|
|
|
|
rv = RVFAC*cr;
|
|
guv = GUFAC*cb + GVFAC*cr;
|
|
bu = BUFAC*cb;
|
|
|
|
r = y + rv;
|
|
g = y + guv;
|
|
b = y + bu;
|
|
|
|
if ((unsigned)(r | g | b) > 64*256-1)
|
|
{
|
|
r = clamp(r, 0, 64*256-1);
|
|
g = clamp(g, 0, 64*256-1);
|
|
b = clamp(b, 0, 64*256-1);
|
|
}
|
|
|
|
*dst = FB_RGBPACK(r >> 6, g >> 6, b >> 6);
|
|
|
|
#if LCD_WIDTH >= LCD_HEIGHT
|
|
dst++;
|
|
#else
|
|
dst += LCD_WIDTH;
|
|
#endif
|
|
|
|
y = YFAC*(*ysrc++ - 16);
|
|
r = y + rv;
|
|
g = y + guv;
|
|
b = y + bu;
|
|
|
|
if ((unsigned)(r | g | b) > 64*256-1)
|
|
{
|
|
r = clamp(r, 0, 64*256-1);
|
|
g = clamp(g, 0, 64*256-1);
|
|
b = clamp(b, 0, 64*256-1);
|
|
}
|
|
|
|
*dst = FB_RGBPACK(r >> 6, g >> 6, b >> 6);
|
|
|
|
#if LCD_WIDTH >= LCD_HEIGHT
|
|
dst++;
|
|
#else
|
|
dst += LCD_WIDTH;
|
|
#endif
|
|
}
|
|
while (dst < row_end);
|
|
|
|
ysrc += stride;
|
|
usrc -= width >> 1;
|
|
vsrc -= width >> 1;
|
|
|
|
#if LCD_WIDTH >= LCD_HEIGHT
|
|
row_end += LCD_WIDTH;
|
|
dst += LCD_WIDTH - width;
|
|
#else
|
|
row_end -= 1;
|
|
dst -= LCD_WIDTH*width + 1;
|
|
#endif
|
|
|
|
do
|
|
{
|
|
int y, cb, cr, rv, guv, bu, r, g, b;
|
|
|
|
y = YFAC*(*ysrc++ - 16);
|
|
cb = *usrc++ - 128;
|
|
cr = *vsrc++ - 128;
|
|
|
|
rv = RVFAC*cr;
|
|
guv = GUFAC*cb + GVFAC*cr;
|
|
bu = BUFAC*cb;
|
|
|
|
r = y + rv;
|
|
g = y + guv;
|
|
b = y + bu;
|
|
|
|
if ((unsigned)(r | g | b) > 64*256-1)
|
|
{
|
|
r = clamp(r, 0, 64*256-1);
|
|
g = clamp(g, 0, 64*256-1);
|
|
b = clamp(b, 0, 64*256-1);
|
|
}
|
|
|
|
*dst = FB_RGBPACK(r >> 6, g >> 6, b >> 6);
|
|
|
|
#if LCD_WIDTH >= LCD_HEIGHT
|
|
dst++;
|
|
#else
|
|
dst += LCD_WIDTH;
|
|
#endif
|
|
|
|
y = YFAC*(*ysrc++ - 16);
|
|
r = y + rv;
|
|
g = y + guv;
|
|
b = y + bu;
|
|
|
|
if ((unsigned)(r | g | b) > 64*256-1)
|
|
{
|
|
r = clamp(r, 0, 64*256-1);
|
|
g = clamp(g, 0, 64*256-1);
|
|
b = clamp(b, 0, 64*256-1);
|
|
}
|
|
|
|
*dst = FB_RGBPACK(r >> 6, g >> 6, b >> 6);
|
|
|
|
#if LCD_WIDTH >= LCD_HEIGHT
|
|
dst++;
|
|
#else
|
|
dst += LCD_WIDTH;
|
|
#endif
|
|
}
|
|
while (dst < row_end);
|
|
}
|
|
|
|
void lcd_write_yuv420_lines_odither(fb_data *dst,
|
|
unsigned char const * const src[3],
|
|
int width, int stride,
|
|
int x_screen, int y_screen)
|
|
__attribute__((alias("lcd_write_yuv420_lines")));
|