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.c138
1 files changed, 34 insertions, 104 deletions
diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
index 6b51531056..3e8246b367 100644
--- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
+++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
@@ -329,115 +329,45 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
329 (void)stride; 329 (void)stride;
330} 330}
331 331
332#define CSUB_X 2 332/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
333#define CSUB_Y 2 333extern void lcd_write_yuv420_lines(fb_data *dst,
334 334 unsigned char chroma_buf[LCD_HEIGHT/2*3],
335#define RYFAC (31*257) 335 unsigned char const * const src[3],
336#define GYFAC (63*257) 336 int width,
337#define BYFAC (31*257) 337 int stride);
338#define RVFAC 11170 /* 31 * 257 * 1.402 */ 338/* Performance function to blit a YUV bitmap directly to the LCD */
339#define GVFAC (-11563) /* 63 * 257 * -0.714136 */ 339/* For the e200 - show it rotated */
340#define GUFAC (-5572) /* 63 * 257 * -0.344136 */ 340/* So the LCD_WIDTH is now the height */
341#define BUFAC 14118 /* 31 * 257 * 1.772 */
342
343#define ROUNDOFFS (127*257)
344
345/* Performance function to blit a YUV bitmap directly to the LCD
346 Actually this code is from gigabeat, because this target is also
347 writing direct to a buffer. */
348void lcd_yuv_blit(unsigned char * const src[3], 341void lcd_yuv_blit(unsigned char * const src[3],
349 int src_x, int src_y, int stride, 342 int src_x, int src_y, int stride,
350 int _x, int _y, int width, int height) 343 int x, int y, int width, int height)
351{ 344{
352 const unsigned char *usrc; 345 /* Caches for chroma data so it only need be recaculated every other
353 const unsigned char *vsrc; 346 line */
354 const unsigned char *ysrc; 347 unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */
355 int xphase; 348 unsigned char const * yuv_src[3];
356 int rc, gc, bc; 349 off_t z;
357 int y, u, v; 350
358 int red, green, blue; 351 /* Sorry, but width and height must be >= 2 or else */
359 unsigned rbits, gbits, bbits; 352 width &= ~1;
360 int count; 353 height >>= 1;
361 fb_data *dst_row; 354
362
363
364 width = (width + 1) & ~1;
365 fb_data *dst = (fb_data*)lcd_driver_framebuffer + 355 fb_data *dst = (fb_data*)lcd_driver_framebuffer +
366 _x * LCD_WIDTH + (LCD_WIDTH - _y) - 1; 356 x * LCD_WIDTH + (LCD_WIDTH - y) - 1;
367 fb_data *dst_last = dst - (height - 1); 357
358 z = stride*src_y;
359 yuv_src[0] = src[0] + z + src_x;
360 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
361 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
368 362
369 do 363 do
370 { 364 {
371 dst_row = dst; 365 lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width,
372 count = width; 366 stride);
373 ysrc = src[0] + stride * src_y + src_x; 367 yuv_src[0] += stride << 1; /* Skip down two luma lines */
374 368 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
375 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ 369 yuv_src[2] += stride >> 1;
376 usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y) 370 dst -= 2;
377 + (src_x/CSUB_X); 371 }
378 vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y) 372 while (--height > 0);
379 + (src_x/CSUB_X);
380 xphase = src_x % CSUB_X;
381
382 u = *usrc++ - 128;
383 v = *vsrc++ - 128;
384 rc = RVFAC * v + ROUNDOFFS;
385 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
386 bc = BUFAC * u + ROUNDOFFS;
387
388 do
389 {
390 y = *ysrc++;
391 red = RYFAC * y + rc;
392 green = GYFAC * y + gc;
393 blue = BYFAC * y + bc;
394
395 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
396 {
397 if (red < 0)
398 red = 0;
399 else
400 red = (RYFAC*255+ROUNDOFFS);
401 }
402 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
403 {
404 if (green < 0)
405 green = 0;
406 else
407 green = (GYFAC*255+ROUNDOFFS);
408 }
409 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
410 {
411 if (blue < 0)
412 blue = 0;
413 else
414 blue = (BYFAC*255+ROUNDOFFS);
415 }
416 rbits = ((unsigned)red) >> 16 ;
417 gbits = ((unsigned)green) >> 16 ;
418 bbits = ((unsigned)blue) >> 16 ;
419
420 *dst_row = (rbits << 11) | (gbits << 5) | bbits;
421
422 /* next pixel - since rotated, add WIDTH */
423 dst_row += LCD_WIDTH;
424
425 if (++xphase >= CSUB_X)
426 {
427 u = *usrc++ - 128;
428 v = *vsrc++ - 128;
429 rc = RVFAC * v + ROUNDOFFS;
430 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
431 bc = BUFAC * u + ROUNDOFFS;
432 xphase = 0;
433 }
434 }
435 while (--count);
436
437 if (dst == dst_last) break;
438
439 dst--;
440 src_y++;
441 } while( 1);
442} 373}
443