summaryrefslogtreecommitdiff
path: root/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/sandisk/sansa-e200/lcd-e200.c')
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/lcd-e200.c116
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. */
302void lcd_yuv_blit(unsigned char * const src[3], 318void 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