summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
index 5ec62271ad..7c8185d6c8 100644
--- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
+++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
@@ -29,3 +29,102 @@ void lcd_update(void)
29{ 29{
30 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 30 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
31} 31}
32
33#define CSUB_X 2
34#define CSUB_Y 2
35
36#define RYFAC (31*257)
37#define GYFAC (63*257)
38#define BYFAC (31*257)
39#define RVFAC 11170 /* 31 * 257 * 1.402 */
40#define GVFAC (-11563) /* 63 * 257 * -0.714136 */
41#define GUFAC (-5572) /* 63 * 257 * -0.344136 */
42#define BUFAC 14118 /* 31 * 257 * 1.772 */
43
44#define ROUNDOFFS (127*257)
45
46/* Performance function to blit a YUV bitmap directly to the LCD */
47void lcd_yuv_blit(unsigned char * const src[3],
48 int src_x, int src_y, int stride,
49 int x, int y, int width, int height)
50{
51 fb_data *dst, *dst_end;
52
53 width = (width + 1) & ~1;
54
55 dst = (fb_data*)FRAME + LCD_WIDTH * y + x;
56 dst_end = dst + LCD_WIDTH * height;
57
58 do
59 {
60 fb_data *dst_row = dst;
61 fb_data *row_end = dst_row + width;
62 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
63 int y, u, v;
64 int red, green, blue;
65 unsigned rbits, gbits, bbits;
66
67 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
68 const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y)
69 + (src_x/CSUB_X);
70 const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y)
71 + (src_x/CSUB_X);
72 int xphase = src_x % CSUB_X;
73 int rc, gc, bc;
74
75 u = *usrc++ - 128;
76 v = *vsrc++ - 128;
77 rc = RVFAC * v + ROUNDOFFS;
78 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
79 bc = BUFAC * u + ROUNDOFFS;
80
81 do
82 {
83 y = *ysrc++;
84 red = RYFAC * y + rc;
85 green = GYFAC * y + gc;
86 blue = BYFAC * y + bc;
87
88 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
89 {
90 if (red < 0)
91 red = 0;
92 else
93 red = (RYFAC*255+ROUNDOFFS);
94 }
95 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
96 {
97 if (green < 0)
98 green = 0;
99 else
100 green = (GYFAC*255+ROUNDOFFS);
101 }
102 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
103 {
104 if (blue < 0)
105 blue = 0;
106 else
107 blue = (BYFAC*255+ROUNDOFFS);
108 }
109 rbits = ((unsigned)red) >> 16 ;
110 gbits = ((unsigned)green) >> 16 ;
111 bbits = ((unsigned)blue) >> 16 ;
112 *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
113
114 if (++xphase >= CSUB_X)
115 {
116 u = *usrc++ - 128;
117 v = *vsrc++ - 128;
118 rc = RVFAC * v + ROUNDOFFS;
119 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
120 bc = BUFAC * u + ROUNDOFFS;
121 xphase = 0;
122 }
123 }
124 while (dst_row < row_end);
125
126 src_y++;
127 dst += LCD_WIDTH;
128 }
129 while (dst < dst_end);
130}