diff options
-rw-r--r-- | apps/plugins/jpeg/jpeg.c | 267 |
1 files changed, 152 insertions, 115 deletions
diff --git a/apps/plugins/jpeg/jpeg.c b/apps/plugins/jpeg/jpeg.c index 9c580b7f34..ed1b181e92 100644 --- a/apps/plugins/jpeg/jpeg.c +++ b/apps/plugins/jpeg/jpeg.c | |||
@@ -463,16 +463,158 @@ int show_menu(void) /* return 1 to quit */ | |||
463 | menu_exit(m); | 463 | menu_exit(m); |
464 | return 0; | 464 | return 0; |
465 | } | 465 | } |
466 | |||
467 | /* Pan the viewing window right - move image to the left and fill in | ||
468 | the right-hand side */ | ||
469 | static void pan_view_right(struct t_disp* pdisp) | ||
470 | { | ||
471 | int move; | ||
472 | |||
473 | move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH); | ||
474 | if (move > 0) | ||
475 | { | ||
476 | MYXLCD(scroll_left)(move); /* scroll left */ | ||
477 | pdisp->x += move; | ||
478 | #ifdef HAVE_LCD_COLOR | ||
479 | yuv_bitmap_part( | ||
480 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, | ||
481 | pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride, | ||
482 | LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
483 | move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ | ||
484 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
485 | #else | ||
486 | MYXLCD(gray_bitmap_part)( | ||
487 | pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move, | ||
488 | pdisp->y, pdisp->stride, | ||
489 | LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
490 | move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ | ||
491 | #endif | ||
492 | MYLCD_UPDATE(); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | /* Pan the viewing window left - move image to the right and fill in | ||
497 | the left-hand side */ | ||
498 | static void pan_view_left(struct t_disp* pdisp) | ||
499 | { | ||
500 | int move; | ||
501 | |||
502 | move = MIN(HSCROLL, pdisp->x); | ||
503 | if (move > 0) | ||
504 | { | ||
505 | MYXLCD(scroll_right)(move); /* scroll right */ | ||
506 | pdisp->x -= move; | ||
507 | #ifdef HAVE_LCD_COLOR | ||
508 | yuv_bitmap_part( | ||
509 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, | ||
510 | pdisp->x, pdisp->y, pdisp->stride, | ||
511 | 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
512 | move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ | ||
513 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
514 | #else | ||
515 | MYXLCD(gray_bitmap_part)( | ||
516 | pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, | ||
517 | 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
518 | move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ | ||
519 | #endif | ||
520 | MYLCD_UPDATE(); | ||
521 | } | ||
522 | } | ||
523 | |||
524 | |||
525 | /* Pan the viewing window up - move image down and fill in | ||
526 | the top */ | ||
527 | static void pan_view_up(struct t_disp* pdisp) | ||
528 | { | ||
529 | int move; | ||
530 | |||
531 | move = MIN(VSCROLL, pdisp->y); | ||
532 | if (move > 0) | ||
533 | { | ||
534 | MYXLCD(scroll_down)(move); /* scroll down */ | ||
535 | pdisp->y -= move; | ||
536 | #ifdef HAVE_LCD_COLOR | ||
537 | if (jpeg_settings.dither_mode == DITHER_DIFFUSION) | ||
538 | { | ||
539 | /* Draw over the band at the top of the last update | ||
540 | caused by lack of error history on line zero. */ | ||
541 | move = MIN(move + 1, pdisp->y + pdisp->height); | ||
542 | } | ||
543 | |||
544 | yuv_bitmap_part( | ||
545 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, | ||
546 | pdisp->x, pdisp->y, pdisp->stride, | ||
547 | MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ | ||
548 | MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ | ||
549 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
550 | #else | ||
551 | MYXLCD(gray_bitmap_part)( | ||
552 | pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, | ||
553 | MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ | ||
554 | MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ | ||
555 | #endif | ||
556 | MYLCD_UPDATE(); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | /* Pan the viewing window down - move image up and fill in | ||
561 | the bottom */ | ||
562 | static void pan_view_down(struct t_disp* pdisp) | ||
563 | { | ||
564 | int move; | ||
565 | |||
566 | move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT); | ||
567 | if (move > 0) | ||
568 | { | ||
569 | MYXLCD(scroll_up)(move); /* scroll up */ | ||
570 | pdisp->y += move; | ||
571 | #ifdef HAVE_LCD_COLOR | ||
572 | if (jpeg_settings.dither_mode == DITHER_DIFFUSION) | ||
573 | { | ||
574 | /* Save the line that was on the last line of the display | ||
575 | and draw one extra line above then recover the line with | ||
576 | image data that had an error history when it was drawn. | ||
577 | */ | ||
578 | move++, pdisp->y--; | ||
579 | rb->memcpy(rgb_linebuf, | ||
580 | rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, | ||
581 | LCD_WIDTH*sizeof (fb_data)); | ||
582 | } | ||
583 | |||
584 | yuv_bitmap_part( | ||
585 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x, | ||
586 | pdisp->y + LCD_HEIGHT - move, pdisp->stride, | ||
587 | MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ | ||
588 | MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ | ||
589 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
590 | |||
591 | if (jpeg_settings.dither_mode == DITHER_DIFFUSION) | ||
592 | { | ||
593 | /* Cover the first row drawn with previous image data. */ | ||
594 | rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, | ||
595 | rgb_linebuf, | ||
596 | LCD_WIDTH*sizeof (fb_data)); | ||
597 | pdisp->y++; | ||
598 | } | ||
599 | #else | ||
600 | MYXLCD(gray_bitmap_part)( | ||
601 | pdisp->bitmap[0], pdisp->x, | ||
602 | pdisp->y + LCD_HEIGHT - move, pdisp->stride, | ||
603 | MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ | ||
604 | MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ | ||
605 | #endif | ||
606 | MYLCD_UPDATE(); | ||
607 | } | ||
608 | } | ||
609 | |||
466 | /* interactively scroll around the image */ | 610 | /* interactively scroll around the image */ |
467 | int scroll_bmp(struct t_disp* pdisp) | 611 | int scroll_bmp(struct t_disp* pdisp) |
468 | { | 612 | { |
613 | int button; | ||
469 | int lastbutton = 0; | 614 | int lastbutton = 0; |
470 | 615 | ||
471 | while (true) | 616 | while (true) |
472 | { | 617 | { |
473 | int button; | ||
474 | int move; | ||
475 | |||
476 | if (slideshow_enabled) | 618 | if (slideshow_enabled) |
477 | button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ); | 619 | button = rb->button_get_w_tmo(jpeg_settings.ss_timeout * HZ); |
478 | else button = rb->button_get(true); | 620 | else button = rb->button_get(true); |
@@ -485,131 +627,26 @@ int scroll_bmp(struct t_disp* pdisp) | |||
485 | if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) | 627 | if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) |
486 | return change_filename(DIR_PREV); | 628 | return change_filename(DIR_PREV); |
487 | case JPEG_LEFT | BUTTON_REPEAT: | 629 | case JPEG_LEFT | BUTTON_REPEAT: |
488 | move = MIN(HSCROLL, pdisp->x); | 630 | pan_view_left(pdisp); |
489 | if (move > 0) | ||
490 | { | ||
491 | MYXLCD(scroll_right)(move); /* scroll right */ | ||
492 | pdisp->x -= move; | ||
493 | #ifdef HAVE_LCD_COLOR | ||
494 | yuv_bitmap_part( | ||
495 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, | ||
496 | pdisp->x, pdisp->y, pdisp->stride, | ||
497 | 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
498 | move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ | ||
499 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
500 | #else | ||
501 | MYXLCD(gray_bitmap_part)( | ||
502 | pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, | ||
503 | 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
504 | move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ | ||
505 | #endif | ||
506 | MYLCD_UPDATE(); | ||
507 | } | ||
508 | break; | 631 | break; |
509 | 632 | ||
510 | case JPEG_RIGHT: | 633 | case JPEG_RIGHT: |
511 | if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) | 634 | if (!(ds < ds_max) && entries > 0 && jpg.x_size <= MAX_X_SIZE) |
512 | return change_filename(DIR_NEXT); | 635 | return change_filename(DIR_NEXT); |
513 | case JPEG_RIGHT | BUTTON_REPEAT: | 636 | case JPEG_RIGHT | BUTTON_REPEAT: |
514 | move = MIN(HSCROLL, pdisp->width - pdisp->x - LCD_WIDTH); | 637 | pan_view_right(pdisp); |
515 | if (move > 0) | ||
516 | { | ||
517 | MYXLCD(scroll_left)(move); /* scroll left */ | ||
518 | pdisp->x += move; | ||
519 | #ifdef HAVE_LCD_COLOR | ||
520 | yuv_bitmap_part( | ||
521 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, | ||
522 | pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride, | ||
523 | LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
524 | move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ | ||
525 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
526 | #else | ||
527 | MYXLCD(gray_bitmap_part)( | ||
528 | pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move, | ||
529 | pdisp->y, pdisp->stride, | ||
530 | LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ | ||
531 | move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ | ||
532 | #endif | ||
533 | MYLCD_UPDATE(); | ||
534 | } | ||
535 | break; | 638 | break; |
536 | 639 | ||
537 | case JPEG_UP: | 640 | case JPEG_UP: |
538 | case JPEG_UP | BUTTON_REPEAT: | 641 | case JPEG_UP | BUTTON_REPEAT: |
539 | move = MIN(VSCROLL, pdisp->y); | 642 | pan_view_up(pdisp); |
540 | if (move > 0) | ||
541 | { | ||
542 | MYXLCD(scroll_down)(move); /* scroll down */ | ||
543 | pdisp->y -= move; | ||
544 | #ifdef HAVE_LCD_COLOR | ||
545 | if (jpeg_settings.dither_mode == DITHER_DIFFUSION) | ||
546 | { | ||
547 | /* Draw over the band at the top of the last update | ||
548 | caused by lack of error history on line zero. */ | ||
549 | move = MIN(move + 1, pdisp->y + pdisp->height); | ||
550 | } | ||
551 | |||
552 | yuv_bitmap_part( | ||
553 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, | ||
554 | pdisp->x, pdisp->y, pdisp->stride, | ||
555 | MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ | ||
556 | MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ | ||
557 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
558 | #else | ||
559 | MYXLCD(gray_bitmap_part)( | ||
560 | pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride, | ||
561 | MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ | ||
562 | MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ | ||
563 | #endif | ||
564 | MYLCD_UPDATE(); | ||
565 | } | ||
566 | break; | 643 | break; |
567 | 644 | ||
568 | case JPEG_DOWN: | 645 | case JPEG_DOWN: |
569 | case JPEG_DOWN | BUTTON_REPEAT: | 646 | case JPEG_DOWN | BUTTON_REPEAT: |
570 | move = MIN(VSCROLL, pdisp->height - pdisp->y - LCD_HEIGHT); | 647 | pan_view_down(pdisp); |
571 | if (move > 0) | ||
572 | { | ||
573 | MYXLCD(scroll_up)(move); /* scroll up */ | ||
574 | pdisp->y += move; | ||
575 | #ifdef HAVE_LCD_COLOR | ||
576 | if (jpeg_settings.dither_mode == DITHER_DIFFUSION) | ||
577 | { | ||
578 | /* Save the line that was on the last line of the display | ||
579 | and draw one extra line above then recover the line with | ||
580 | image data that had an error history when it was drawn. | ||
581 | */ | ||
582 | move++, pdisp->y--; | ||
583 | rb->memcpy(rgb_linebuf, | ||
584 | rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, | ||
585 | LCD_WIDTH*sizeof (fb_data)); | ||
586 | } | ||
587 | |||
588 | yuv_bitmap_part( | ||
589 | pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x, | ||
590 | pdisp->y + LCD_HEIGHT - move, pdisp->stride, | ||
591 | MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ | ||
592 | MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ | ||
593 | jpeg_settings.colour_mode, jpeg_settings.dither_mode); | ||
594 | |||
595 | if (jpeg_settings.dither_mode == DITHER_DIFFUSION) | ||
596 | { | ||
597 | /* Cover the first row drawn with previous image data. */ | ||
598 | rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, | ||
599 | rgb_linebuf, | ||
600 | LCD_WIDTH*sizeof (fb_data)); | ||
601 | pdisp->y++; | ||
602 | } | ||
603 | #else | ||
604 | MYXLCD(gray_bitmap_part)( | ||
605 | pdisp->bitmap[0], pdisp->x, | ||
606 | pdisp->y + LCD_HEIGHT - move, pdisp->stride, | ||
607 | MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ | ||
608 | MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ | ||
609 | #endif | ||
610 | MYLCD_UPDATE(); | ||
611 | } | ||
612 | break; | 648 | break; |
649 | |||
613 | case BUTTON_NONE: | 650 | case BUTTON_NONE: |
614 | if (!slideshow_enabled) | 651 | if (!slideshow_enabled) |
615 | break; | 652 | break; |
@@ -1194,8 +1231,8 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame | |||
1194 | xlcd_init(rb); | 1231 | xlcd_init(rb); |
1195 | #endif | 1232 | #endif |
1196 | 1233 | ||
1197 | /* should be ok to just load settings since a parameter is present | 1234 | /* should be ok to just load settings since the plugin itself has |
1198 | here and the drive should be spinning */ | 1235 | just been loaded from disk and the drive should be spinning */ |
1199 | configfile_init(rb); | 1236 | configfile_init(rb); |
1200 | configfile_load(JPEG_CONFIGFILE, jpeg_config, | 1237 | configfile_load(JPEG_CONFIGFILE, jpeg_config, |
1201 | ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION); | 1238 | ARRAYLEN(jpeg_config), JPEG_SETTINGS_MINVERSION); |