summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/lcd-bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/sdl/lcd-bitmap.c')
-rw-r--r--uisimulator/sdl/lcd-bitmap.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/uisimulator/sdl/lcd-bitmap.c b/uisimulator/sdl/lcd-bitmap.c
index da6acce1bc..12cc063288 100644
--- a/uisimulator/sdl/lcd-bitmap.c
+++ b/uisimulator/sdl/lcd-bitmap.c
@@ -159,3 +159,207 @@ void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height)
159} 159}
160#endif 160#endif
161 161
162#ifdef HAVE_LCD_COLOR
163/**
164 * |R| |1.000000 -0.000001 1.402000| |Y'|
165 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
166 * |B| |1.000000 1.772000 0.000000| |Pr|
167 * Scaled, normalized, rounded and tweaked to yield RGB 565:
168 * |R| |74 0 101| |Y' - 16| >> 9
169 * |G| = |74 -24 -51| |Cb - 128| >> 8
170 * |B| |74 128 0| |Cr - 128| >> 9
171 */
172#define YFAC (74)
173#define RVFAC (101)
174#define GUFAC (-24)
175#define GVFAC (-51)
176#define BUFAC (128)
177
178static inline int clamp(int val, int min, int max)
179{
180 if (val < min)
181 val = min;
182 else if (val > max)
183 val = max;
184 return val;
185}
186
187void lcd_yuv_set_options(unsigned options)
188{
189 (void)options;
190}
191
192/* Draw a partial YUV colour bitmap - similiar behavior to lcd_yuv_blit
193 in the core */
194void lcd_yuv_blit(unsigned char * const src[3],
195 int src_x, int src_y, int stride,
196 int x, int y, int width, int height)
197{
198 const unsigned char *ysrc, *usrc, *vsrc;
199 int linecounter;
200 fb_data *dst, *row_end;
201 long z;
202
203 /* width and height must be >= 2 and an even number */
204 width &= ~1;
205 linecounter = height >> 1;
206
207#if LCD_WIDTH >= LCD_HEIGHT
208 dst = &lcd_framebuffer[y][x];
209 row_end = dst + width;
210#else
211 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
212 row_end = dst + LCD_WIDTH * width;
213#endif
214
215 z = stride * src_y;
216 ysrc = src[0] + z + src_x;
217 usrc = src[1] + (z >> 2) + (src_x >> 1);
218 vsrc = src[2] + (usrc - src[1]);
219
220 /* stride => amount to jump from end of last row to start of next */
221 stride -= width;
222
223 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
224
225 do
226 {
227 do
228 {
229 int y, cb, cr, rv, guv, bu, r, g, b;
230
231 y = YFAC*(*ysrc++ - 16);
232 cb = *usrc++ - 128;
233 cr = *vsrc++ - 128;
234
235 rv = RVFAC*cr;
236 guv = GUFAC*cb + GVFAC*cr;
237 bu = BUFAC*cb;
238
239 r = y + rv;
240 g = y + guv;
241 b = y + bu;
242
243 if ((unsigned)(r | g | b) > 64*256-1)
244 {
245 r = clamp(r, 0, 64*256-1);
246 g = clamp(g, 0, 64*256-1);
247 b = clamp(b, 0, 64*256-1);
248 }
249
250 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
251
252#if LCD_WIDTH >= LCD_HEIGHT
253 dst++;
254#else
255 dst += LCD_WIDTH;
256#endif
257
258 y = YFAC*(*ysrc++ - 16);
259 r = y + rv;
260 g = y + guv;
261 b = y + bu;
262
263 if ((unsigned)(r | g | b) > 64*256-1)
264 {
265 r = clamp(r, 0, 64*256-1);
266 g = clamp(g, 0, 64*256-1);
267 b = clamp(b, 0, 64*256-1);
268 }
269
270 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
271
272#if LCD_WIDTH >= LCD_HEIGHT
273 dst++;
274#else
275 dst += LCD_WIDTH;
276#endif
277 }
278 while (dst < row_end);
279
280 ysrc += stride;
281 usrc -= width >> 1;
282 vsrc -= width >> 1;
283
284#if LCD_WIDTH >= LCD_HEIGHT
285 row_end += LCD_WIDTH;
286 dst += LCD_WIDTH - width;
287#else
288 row_end -= 1;
289 dst -= LCD_WIDTH*width + 1;
290#endif
291
292 do
293 {
294 int y, cb, cr, rv, guv, bu, r, g, b;
295
296 y = YFAC*(*ysrc++ - 16);
297 cb = *usrc++ - 128;
298 cr = *vsrc++ - 128;
299
300 rv = RVFAC*cr;
301 guv = GUFAC*cb + GVFAC*cr;
302 bu = BUFAC*cb;
303
304 r = y + rv;
305 g = y + guv;
306 b = y + bu;
307
308 if ((unsigned)(r | g | b) > 64*256-1)
309 {
310 r = clamp(r, 0, 64*256-1);
311 g = clamp(g, 0, 64*256-1);
312 b = clamp(b, 0, 64*256-1);
313 }
314
315 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
316
317#if LCD_WIDTH >= LCD_HEIGHT
318 dst++;
319#else
320 dst += LCD_WIDTH;
321#endif
322
323 y = YFAC*(*ysrc++ - 16);
324 r = y + rv;
325 g = y + guv;
326 b = y + bu;
327
328 if ((unsigned)(r | g | b) > 64*256-1)
329 {
330 r = clamp(r, 0, 64*256-1);
331 g = clamp(g, 0, 64*256-1);
332 b = clamp(b, 0, 64*256-1);
333 }
334
335 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
336
337#if LCD_WIDTH >= LCD_HEIGHT
338 dst++;
339#else
340 dst += LCD_WIDTH;
341#endif
342 }
343 while (dst < row_end);
344
345 ysrc += stride;
346 usrc += stride >> 1;
347 vsrc += stride >> 1;
348
349#if LCD_WIDTH >= LCD_HEIGHT
350 row_end += LCD_WIDTH;
351 dst += LCD_WIDTH - width;
352#else
353 row_end -= 1;
354 dst -= LCD_WIDTH*width + 1;
355#endif
356 }
357 while (--linecounter > 0);
358
359#if LCD_WIDTH >= LCD_HEIGHT
360 lcd_update_rect(x, y, width, height);
361#else
362 lcd_update_rect(y, x, height, width);
363#endif
364}
365#endif /* HAVE_LCD_COLOR */