diff options
Diffstat (limited to 'firmware/target/arm/sandisk/sansa-e200/lcd-e200.c')
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | 116 |
1 files changed, 106 insertions, 10 deletions
diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c index c2829d11da..25bb6f04aa 100644 --- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | |||
@@ -299,18 +299,114 @@ void lcd_blit(const fb_data* data, int x, int by, int width, | |||
299 | (void)stride; | 299 | (void)stride; |
300 | } | 300 | } |
301 | 301 | ||
302 | #define CSUB_X 2 | ||
303 | #define CSUB_Y 2 | ||
304 | |||
305 | #define RYFAC (31*257) | ||
306 | #define GYFAC (63*257) | ||
307 | #define BYFAC (31*257) | ||
308 | #define RVFAC 11170 /* 31 * 257 * 1.402 */ | ||
309 | #define GVFAC (-11563) /* 63 * 257 * -0.714136 */ | ||
310 | #define GUFAC (-5572) /* 63 * 257 * -0.344136 */ | ||
311 | #define BUFAC 14118 /* 31 * 257 * 1.772 */ | ||
312 | |||
313 | #define ROUNDOFFS (127*257) | ||
314 | |||
315 | /* Performance function to blit a YUV bitmap directly to the LCD | ||
316 | Actually this code is from gigabeat, because this target is also | ||
317 | writing direct to a buffer. */ | ||
302 | void lcd_yuv_blit(unsigned char * const src[3], | 318 | void lcd_yuv_blit(unsigned char * const src[3], |
303 | int src_x, int src_y, int stride, | 319 | int src_x, int src_y, int stride, |
304 | int x, int y, int width, int height) | 320 | int _x, int _y, int width, int height) |
305 | { | 321 | { |
306 | /* TODO: Implement lcd_blit() */ | 322 | const unsigned char *usrc; |
307 | (void)src; | 323 | const unsigned char *vsrc; |
308 | (void)src_x; | 324 | const unsigned char *ysrc; |
309 | (void)src_y; | 325 | int xphase; |
310 | (void)stride; | 326 | int rc, gc, bc; |
311 | (void)x; | 327 | int y, u, v; |
312 | (void)y; | 328 | int red, green, blue; |
313 | (void)width; | 329 | unsigned rbits, gbits, bbits; |
314 | (void)height; | 330 | int count; |
331 | fb_data *dst_row; | ||
332 | |||
333 | |||
334 | width = (width + 1) & ~1; | ||
335 | fb_data *dst = (fb_data*)lcd_framebuffer + _x * LCD_WIDTH + (LCD_WIDTH - _y) - 1; | ||
336 | fb_data *dst_last = dst - (height - 1); | ||
337 | |||
338 | do | ||
339 | { | ||
340 | dst_row = dst; | ||
341 | count = width; | ||
342 | ysrc = src[0] + stride * src_y + src_x; | ||
343 | |||
344 | /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ | ||
345 | usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y) | ||
346 | + (src_x/CSUB_X); | ||
347 | vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y) | ||
348 | + (src_x/CSUB_X); | ||
349 | xphase = src_x % CSUB_X; | ||
350 | |||
351 | u = *usrc++ - 128; | ||
352 | v = *vsrc++ - 128; | ||
353 | rc = RVFAC * v + ROUNDOFFS; | ||
354 | gc = GVFAC * v + GUFAC * u + ROUNDOFFS; | ||
355 | bc = BUFAC * u + ROUNDOFFS; | ||
356 | |||
357 | do | ||
358 | { | ||
359 | y = *ysrc++; | ||
360 | red = RYFAC * y + rc; | ||
361 | green = GYFAC * y + gc; | ||
362 | blue = BYFAC * y + bc; | ||
363 | |||
364 | if ((unsigned)red > (RYFAC*255+ROUNDOFFS)) | ||
365 | { | ||
366 | if (red < 0) | ||
367 | red = 0; | ||
368 | else | ||
369 | red = (RYFAC*255+ROUNDOFFS); | ||
370 | } | ||
371 | if ((unsigned)green > (GYFAC*255+ROUNDOFFS)) | ||
372 | { | ||
373 | if (green < 0) | ||
374 | green = 0; | ||
375 | else | ||
376 | green = (GYFAC*255+ROUNDOFFS); | ||
377 | } | ||
378 | if ((unsigned)blue > (BYFAC*255+ROUNDOFFS)) | ||
379 | { | ||
380 | if (blue < 0) | ||
381 | blue = 0; | ||
382 | else | ||
383 | blue = (BYFAC*255+ROUNDOFFS); | ||
384 | } | ||
385 | rbits = ((unsigned)red) >> 16 ; | ||
386 | gbits = ((unsigned)green) >> 16 ; | ||
387 | bbits = ((unsigned)blue) >> 16 ; | ||
388 | |||
389 | *dst_row = (rbits << 11) | (gbits << 5) | bbits; | ||
390 | |||
391 | /* next pixel - since rotated, add WIDTH */ | ||
392 | dst_row += LCD_WIDTH; | ||
393 | |||
394 | if (++xphase >= CSUB_X) | ||
395 | { | ||
396 | u = *usrc++ - 128; | ||
397 | v = *vsrc++ - 128; | ||
398 | rc = RVFAC * v + ROUNDOFFS; | ||
399 | gc = GVFAC * v + GUFAC * u + ROUNDOFFS; | ||
400 | bc = BUFAC * u + ROUNDOFFS; | ||
401 | xphase = 0; | ||
402 | } | ||
403 | } | ||
404 | while (--count); | ||
405 | |||
406 | if (dst == dst_last) break; | ||
407 | |||
408 | dst--; | ||
409 | src_y++; | ||
410 | } while( 1); | ||
315 | } | 411 | } |
316 | 412 | ||