diff options
Diffstat (limited to 'firmware/target/arm/gigabeat')
-rw-r--r-- | firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | 99 |
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 */ | ||
47 | void 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 | } | ||