summaryrefslogtreecommitdiff
path: root/apps/plugins/imageviewer/imageviewer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/imageviewer/imageviewer.c')
-rw-r--r--apps/plugins/imageviewer/imageviewer.c219
1 files changed, 131 insertions, 88 deletions
diff --git a/apps/plugins/imageviewer/imageviewer.c b/apps/plugins/imageviewer/imageviewer.c
index e3c72ae291..01b9f31be1 100644
--- a/apps/plugins/imageviewer/imageviewer.c
+++ b/apps/plugins/imageviewer/imageviewer.c
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * user intereface of image viewers (jpeg, png, etc.) 10 * user intereface of image viewer
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -19,11 +19,16 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22/*
23 * TODO:
24 * - check magick value in file header to determine image type.
25 */
22#include "plugin.h" 26#include "plugin.h"
23#include <lib/playback_control.h> 27#include <lib/playback_control.h>
24#include <lib/helper.h> 28#include <lib/helper.h>
25#include <lib/configfile.h> 29#include <lib/configfile.h>
26#include "imageviewer.h" 30#include "imageviewer.h"
31#include "image_decoder.h"
27 32
28 33
29 34
@@ -38,16 +43,6 @@ GREY_INFO_STRUCT
38 43
39/******************************* Globals ***********************************/ 44/******************************* Globals ***********************************/
40 45
41bool slideshow_enabled = false; /* run slideshow */
42bool running_slideshow = false; /* loading image because of slideshow */
43#ifdef DISK_SPINDOWN
44bool immediate_ata_off = false; /* power down disk after loading */
45#endif
46#ifdef USE_PLUG_BUF
47/* are we using the plugin buffer or the audio buffer? */
48bool plug_buf = true;
49#endif
50
51/* Persistent configuration */ 46/* Persistent configuration */
52#define IMGVIEW_CONFIGFILE "imageviewer.cfg" 47#define IMGVIEW_CONFIGFILE "imageviewer.cfg"
53#define IMGVIEW_SETTINGS_MINVERSION 1 48#define IMGVIEW_SETTINGS_MINVERSION 1
@@ -63,8 +58,7 @@ bool plug_buf = true;
63#include "jpeg/yuv2rgb.h" 58#include "jpeg/yuv2rgb.h"
64#endif 59#endif
65 60
66/* jpeg use this */ 61static struct imgview_settings settings =
67struct imgview_settings settings =
68{ 62{
69#ifdef HAVE_LCD_COLOR 63#ifdef HAVE_LCD_COLOR
70 COLOURMODE_COLOUR, 64 COLOURMODE_COLOUR,
@@ -86,17 +80,39 @@ static struct configdata config[] =
86 { .int_p = &settings.ss_timeout }, "Slideshow Time", NULL }, 80 { .int_p = &settings.ss_timeout }, "Slideshow Time", NULL },
87}; 81};
88 82
83static void cb_progress(int current, int total);
84
85static struct imgdec_api iv_api = {
86 .settings = &settings,
87 .slideshow_enabled = false,
88 .running_slideshow = false,
89#ifdef DISK_SPINDOWN
90 .immediate_ata_off = false,
91#endif
92#ifdef USE_PLUG_BUF
93 .plug_buf = true,
94#endif
95
96 .cb_progress = cb_progress,
97
98#ifdef USEGSLIB
99 .gray_bitmap_part = myxlcd_ub_(gray_bitmap_part),
100#endif
101};
102
89/**************** begin Application ********************/ 103/**************** begin Application ********************/
90 104
91 105
92/************************* Globals ***************************/ 106/************************* Globals ***************************/
93 107
94#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 108#ifdef HAVE_LCD_COLOR
95static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when 109static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when
96 DITHER_DIFFUSION is set */ 110 DITHER_DIFFUSION is set */
97#endif 111#endif
98 112
99/* my memory pool (from the mp3 buffer) */ 113/* buffer to load image decoder */
114static unsigned char* decoder_buf;
115static size_t decoder_buf_size;
100/* the remaining free part of the buffer for loaded+resized images */ 116/* the remaining free part of the buffer for loaded+resized images */
101static unsigned char* buf; 117static unsigned char* buf;
102static size_t buf_size; 118static size_t buf_size;
@@ -106,11 +122,14 @@ static struct image_info image_info;
106 122
107/* the current full file name */ 123/* the current full file name */
108static char np_file[MAX_PATH]; 124static char np_file[MAX_PATH];
109static int curfile = 0, direction = DIR_NEXT, entries = 0; 125static int curfile = -1, direction = DIR_NEXT, entries = 0;
110 126
111/* list of the supported image files */ 127/* list of the supported image files */
112static char **file_pt; 128static char **file_pt;
113 129
130static const struct image_decoder *imgdec = NULL;
131static enum image_type image_type = IMAGE_UNKNOWN;
132
114/************************* Implementation ***************************/ 133/************************* Implementation ***************************/
115 134
116/* Read directory contents for scrolling. */ 135/* Read directory contents for scrolling. */
@@ -130,7 +149,7 @@ static void get_pic_list(void)
130 for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++) 149 for (i = 0; i < tree->filesindir && buf_size > sizeof(char**); i++)
131 { 150 {
132 if (!(dircache[i].attr & ATTR_DIRECTORY) 151 if (!(dircache[i].attr & ATTR_DIRECTORY)
133 && img_ext(rb->strrchr(dircache[i].name,'.'))) 152 && get_image_type(dircache[i].name) != IMAGE_UNKNOWN)
134 { 153 {
135 file_pt[entries] = dircache[i].name; 154 file_pt[entries] = dircache[i].name;
136 /* Set Selected File. */ 155 /* Set Selected File. */
@@ -187,11 +206,11 @@ static void cleanup(void *parameter)
187#endif 206#endif
188} 207}
189 208
190#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 209#ifdef HAVE_LCD_COLOR
191static bool set_option_grayscale(void) 210static bool set_option_grayscale(void)
192{ 211{
193 bool gray = settings.jpeg_colour_mode == COLOURMODE_GRAY; 212 bool gray = settings.jpeg_colour_mode == COLOURMODE_GRAY;
194 rb->set_bool("Grayscale", &gray); 213 rb->set_bool("Grayscale (Jpeg)", &gray);
195 settings.jpeg_colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR; 214 settings.jpeg_colour_mode = gray ? COLOURMODE_GRAY : COLOURMODE_COLOUR;
196 return false; 215 return false;
197} 216}
@@ -204,14 +223,14 @@ static bool set_option_dithering(void)
204 [DITHER_DIFFUSION] = { "Diffusion", -1 }, 223 [DITHER_DIFFUSION] = { "Diffusion", -1 },
205 }; 224 };
206 225
207 rb->set_option("Dithering", &settings.jpeg_dither_mode, INT, 226 rb->set_option("Dithering (Jpeg)", &settings.jpeg_dither_mode, INT,
208 dithering, DITHER_NUM_MODES, NULL); 227 dithering, DITHER_NUM_MODES, NULL);
209 return false; 228 return false;
210} 229}
211 230
212MENUITEM_FUNCTION(grayscale_item, 0, "Greyscale", 231MENUITEM_FUNCTION(grayscale_item, 0, "Greyscale (Jpeg)",
213 set_option_grayscale, NULL, NULL, Icon_NOICON); 232 set_option_grayscale, NULL, NULL, Icon_NOICON);
214MENUITEM_FUNCTION(dithering_item, 0, "Dithering", 233MENUITEM_FUNCTION(dithering_item, 0, "Dithering (Jpeg)",
215 set_option_dithering, NULL, NULL, Icon_NOICON); 234 set_option_dithering, NULL, NULL, Icon_NOICON);
216MAKE_MENU(display_menu, "Display Options", NULL, Icon_NOICON, 235MAKE_MENU(display_menu, "Display Options", NULL, Icon_NOICON,
217 &grayscale_item, &dithering_item); 236 &grayscale_item, &dithering_item);
@@ -220,7 +239,7 @@ static void display_options(void)
220{ 239{
221 rb->do_menu(&display_menu, NULL, NULL, false); 240 rb->do_menu(&display_menu, NULL, NULL, false);
222} 241}
223#endif /* defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) */ 242#endif /* HAVE_LCD_COLOR */
224 243
225static int show_menu(void) /* return 1 to quit */ 244static int show_menu(void) /* return 1 to quit */
226{ 245{
@@ -234,19 +253,19 @@ static int show_menu(void) /* return 1 to quit */
234#ifdef USE_PLUG_BUF 253#ifdef USE_PLUG_BUF
235 MIID_SHOW_PLAYBACK_MENU, 254 MIID_SHOW_PLAYBACK_MENU,
236#endif 255#endif
237#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 256#ifdef HAVE_LCD_COLOR
238 MIID_DISPLAY_OPTIONS, 257 MIID_DISPLAY_OPTIONS,
239#endif 258#endif
240 MIID_QUIT, 259 MIID_QUIT,
241 }; 260 };
242 261
243 MENUITEM_STRINGLIST(menu, MENU_TITLE, NULL, 262 MENUITEM_STRINGLIST(menu, "Image Viewer Menu", NULL,
244 "Return", "Toggle Slideshow Mode", 263 "Return", "Toggle Slideshow Mode",
245 "Change Slideshow Time", 264 "Change Slideshow Time",
246#ifdef USE_PLUG_BUF 265#ifdef USE_PLUG_BUF
247 "Show Playback Menu", 266 "Show Playback Menu",
248#endif 267#endif
249#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 268#ifdef HAVE_LCD_COLOR
250 "Display Options", 269 "Display Options",
251#endif 270#endif
252 "Quit"); 271 "Quit");
@@ -263,7 +282,7 @@ static int show_menu(void) /* return 1 to quit */
263 case MIID_RETURN: 282 case MIID_RETURN:
264 break; 283 break;
265 case MIID_TOGGLE_SS_MODE: 284 case MIID_TOGGLE_SS_MODE:
266 rb->set_option("Toggle Slideshow", &slideshow_enabled, BOOL, 285 rb->set_option("Toggle Slideshow", &iv_api.slideshow_enabled, BOOL,
267 slideshow , 2, NULL); 286 slideshow , 2, NULL);
268 break; 287 break;
269 case MIID_CHANGE_SS_MODE: 288 case MIID_CHANGE_SS_MODE:
@@ -274,7 +293,7 @@ static int show_menu(void) /* return 1 to quit */
274 293
275#ifdef USE_PLUG_BUF 294#ifdef USE_PLUG_BUF
276 case MIID_SHOW_PLAYBACK_MENU: 295 case MIID_SHOW_PLAYBACK_MENU:
277 if (plug_buf) 296 if (iv_api.plug_buf)
278 { 297 {
279 playback_control(NULL); 298 playback_control(NULL);
280 } 299 }
@@ -284,7 +303,7 @@ static int show_menu(void) /* return 1 to quit */
284 } 303 }
285 break; 304 break;
286#endif 305#endif
287#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 306#ifdef HAVE_LCD_COLOR
288 case MIID_DISPLAY_OPTIONS: 307 case MIID_DISPLAY_OPTIONS:
289 display_options(); 308 display_options();
290 break; 309 break;
@@ -296,10 +315,10 @@ static int show_menu(void) /* return 1 to quit */
296 315
297#ifdef DISK_SPINDOWN 316#ifdef DISK_SPINDOWN
298 /* change ata spindown time based on slideshow time setting */ 317 /* change ata spindown time based on slideshow time setting */
299 immediate_ata_off = false; 318 iv_api.immediate_ata_off = false;
300 rb->storage_spindown(rb->global_settings->disk_spindown); 319 rb->storage_spindown(rb->global_settings->disk_spindown);
301 320
302 if (slideshow_enabled) 321 if (iv_api.slideshow_enabled)
303 { 322 {
304 if(settings.ss_timeout < 10) 323 if(settings.ss_timeout < 10)
305 { 324 {
@@ -309,7 +328,7 @@ static int show_menu(void) /* return 1 to quit */
309 else if (!rb->mp3_is_playing()) 328 else if (!rb->mp3_is_playing())
310 { 329 {
311 /* slideshow times > 10s and not playing: ata_off after load */ 330 /* slideshow times > 10s and not playing: ata_off after load */
312 immediate_ata_off = true; 331 iv_api.immediate_ata_off = true;
313 } 332 }
314 } 333 }
315#endif 334#endif
@@ -344,7 +363,7 @@ static int ask_and_get_audio_buffer(const char *filename)
344 switch(button) 363 switch(button)
345 { 364 {
346 case IMGVIEW_ZOOM_IN: 365 case IMGVIEW_ZOOM_IN:
347 plug_buf = false; 366 iv_api.plug_buf = false;
348 buf = rb->plugin_get_audio_buffer(&buf_size); 367 buf = rb->plugin_get_audio_buffer(&buf_size);
349 /*try again this file, now using the audio buffer */ 368 /*try again this file, now using the audio buffer */
350 return PLUGIN_OTHER; 369 return PLUGIN_OTHER;
@@ -382,15 +401,15 @@ static int ask_and_get_audio_buffer(const char *filename)
382#endif /* USE_PLUG_BUF */ 401#endif /* USE_PLUG_BUF */
383 402
384/* callback updating a progress meter while image decoding */ 403/* callback updating a progress meter while image decoding */
385void cb_progress(int current, int total) 404static void cb_progress(int current, int total)
386{ 405{
387 rb->yield(); /* be nice to the other threads */ 406 rb->yield(); /* be nice to the other threads */
388#ifndef USEGSLIB 407#ifndef USEGSLIB
389 /* in slideshow mode, keep gui interference to a minimum */ 408 /* in slideshow mode, keep gui interference to a minimum */
390 const int size = (!running_slideshow ? 8 : 4); 409 const int size = (!iv_api.running_slideshow ? 8 : 4);
391#else 410#else
392 const int size = 8; 411 const int size = 8;
393 if(!running_slideshow) 412 if(!iv_api.running_slideshow)
394#endif 413#endif
395 { 414 {
396 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], 415 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],
@@ -414,7 +433,8 @@ static void pan_view_right(struct image_info *info)
414 { 433 {
415 mylcd_ub_scroll_left(move); /* scroll left */ 434 mylcd_ub_scroll_left(move); /* scroll left */
416 info->x += move; 435 info->x += move;
417 draw_image_rect(info, LCD_WIDTH - move, 0, move, info->height-info->y); 436 imgdec->draw_image_rect(info, LCD_WIDTH - move, 0,
437 move, info->height-info->y);
418 mylcd_ub_update(); 438 mylcd_ub_update();
419 } 439 }
420} 440}
@@ -430,7 +450,7 @@ static void pan_view_left(struct image_info *info)
430 { 450 {
431 mylcd_ub_scroll_right(move); /* scroll right */ 451 mylcd_ub_scroll_right(move); /* scroll right */
432 info->x -= move; 452 info->x -= move;
433 draw_image_rect(info, 0, 0, move, info->height-info->y); 453 imgdec->draw_image_rect(info, 0, 0, move, info->height-info->y);
434 mylcd_ub_update(); 454 mylcd_ub_update();
435 } 455 }
436} 456}
@@ -446,15 +466,16 @@ static void pan_view_up(struct image_info *info)
446 { 466 {
447 mylcd_ub_scroll_down(move); /* scroll down */ 467 mylcd_ub_scroll_down(move); /* scroll down */
448 info->y -= move; 468 info->y -= move;
449#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 469#ifdef HAVE_LCD_COLOR
450 if (settings.jpeg_dither_mode == DITHER_DIFFUSION) 470 if (image_type == IMAGE_JPEG
471 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
451 { 472 {
452 /* Draw over the band at the top of the last update 473 /* Draw over the band at the top of the last update
453 caused by lack of error history on line zero. */ 474 caused by lack of error history on line zero. */
454 move = MIN(move + 1, info->y + info->height); 475 move = MIN(move + 1, info->y + info->height);
455 } 476 }
456#endif 477#endif
457 draw_image_rect(info, 0, 0, info->width-info->x, move); 478 imgdec->draw_image_rect(info, 0, 0, info->width-info->x, move);
458 mylcd_ub_update(); 479 mylcd_ub_update();
459 } 480 }
460} 481}
@@ -470,8 +491,9 @@ static void pan_view_down(struct image_info *info)
470 { 491 {
471 mylcd_ub_scroll_up(move); /* scroll up */ 492 mylcd_ub_scroll_up(move); /* scroll up */
472 info->y += move; 493 info->y += move;
473#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 494#ifdef HAVE_LCD_COLOR
474 if (settings.jpeg_dither_mode == DITHER_DIFFUSION) 495 if (image_type == IMAGE_JPEG
496 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
475 { 497 {
476 /* Save the line that was on the last line of the display 498 /* Save the line that was on the last line of the display
477 and draw one extra line above then recover the line with 499 and draw one extra line above then recover the line with
@@ -484,10 +506,12 @@ static void pan_view_down(struct image_info *info)
484 } 506 }
485#endif 507#endif
486 508
487 draw_image_rect(info, 0, LCD_HEIGHT - move, info->width-info->x, move); 509 imgdec->draw_image_rect(info, 0, LCD_HEIGHT - move,
510 info->width-info->x, move);
488 511
489#if defined(HAVE_LCD_COLOR) && defined(JPEG_VIEWER) 512#ifdef HAVE_LCD_COLOR
490 if (settings.jpeg_dither_mode == DITHER_DIFFUSION) 513 if (image_type == IMAGE_JPEG
514 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
491 { 515 {
492 /* Cover the first row drawn with previous image data. */ 516 /* Cover the first row drawn with previous image data. */
493 rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, 517 rb->memcpy(rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH,
@@ -507,12 +531,12 @@ static int scroll_bmp(struct image_info *info)
507 531
508 while (true) 532 while (true)
509 { 533 {
510 if (slideshow_enabled) 534 if (iv_api.slideshow_enabled)
511 button = rb->button_get_w_tmo(settings.ss_timeout * HZ); 535 button = rb->button_get_w_tmo(settings.ss_timeout * HZ);
512 else 536 else
513 button = rb->button_get(true); 537 button = rb->button_get(true);
514 538
515 running_slideshow = false; 539 iv_api.running_slideshow = false;
516 540
517 switch(button) 541 switch(button)
518 { 542 {
@@ -543,16 +567,16 @@ static int scroll_bmp(struct image_info *info)
543 break; 567 break;
544 568
545 case BUTTON_NONE: 569 case BUTTON_NONE:
546 if (slideshow_enabled && entries > 1) 570 if (iv_api.slideshow_enabled && entries > 1)
547 { 571 {
548 running_slideshow = true; 572 iv_api.running_slideshow = true;
549 return change_filename(DIR_NEXT); 573 return change_filename(DIR_NEXT);
550 } 574 }
551 break; 575 break;
552 576
553#ifdef IMGVIEW_SLIDE_SHOW 577#ifdef IMGVIEW_SLIDE_SHOW
554 case IMGVIEW_SLIDE_SHOW: 578 case IMGVIEW_SLIDE_SHOW:
555 slideshow_enabled = !slideshow_enabled; 579 iv_api.slideshow_enabled = !iv_api.slideshow_enabled;
556 break; 580 break;
557#endif 581#endif
558 582
@@ -605,7 +629,7 @@ static int scroll_bmp(struct image_info *info)
605#ifdef USEGSLIB 629#ifdef USEGSLIB
606 grey_show(true); /* switch on greyscale overlay */ 630 grey_show(true); /* switch on greyscale overlay */
607#else 631#else
608 draw_image_rect(info, 0, 0, 632 imgdec->draw_image_rect(info, 0, 0,
609 info->width-info->x, info->height-info->y); 633 info->width-info->x, info->height-info->y);
610 mylcd_ub_update(); 634 mylcd_ub_update();
611#endif 635#endif
@@ -637,10 +661,10 @@ static int min_downscale(int bufsize)
637{ 661{
638 int downscale = 8; 662 int downscale = 8;
639 663
640 if (img_mem(8) > bufsize) 664 if (imgdec->img_mem(8) > bufsize)
641 return 0; /* error, too large, even 1:8 doesn't fit */ 665 return 0; /* error, too large, even 1:8 doesn't fit */
642 666
643 while (downscale > 1 && img_mem(downscale/2) <= bufsize) 667 while (downscale > 1 && imgdec->img_mem(downscale/2) <= bufsize)
644 downscale /= 2; 668 downscale /= 2;
645 669
646 return downscale; 670 return downscale;
@@ -697,18 +721,39 @@ static int load_and_show(char* filename, struct image_info *info)
697 721
698 rb->lcd_clear_display(); 722 rb->lcd_clear_display();
699 723
724 status = get_image_type(filename);
725 if (image_type != status) /* type of image is changed, load decoder. */
726 {
727 struct loader_info loader_info = {
728 status, &iv_api, decoder_buf, decoder_buf_size,
729 };
730 image_type = status;
731 imgdec = load_decoder(&loader_info);
732 if (imgdec == NULL)
733 {
734 /* something is wrong */
735 return PLUGIN_ERROR;
736 }
737#ifdef USE_PLUG_BUF
738 if(iv_api.plug_buf)
739 {
740 buf = loader_info.buffer;
741 buf_size = loader_info.size;
742 }
743#endif
744 }
700 rb->memset(info, 0, sizeof(*info)); 745 rb->memset(info, 0, sizeof(*info));
701 remaining = buf_size; 746 remaining = buf_size;
702 747
703 if (rb->button_get(false) == IMGVIEW_MENU) 748 if (rb->button_get(false) == IMGVIEW_MENU)
704 status = PLUGIN_ABORT; 749 status = PLUGIN_ABORT;
705 else 750 else
706 status = load_image(filename, info, buf, &remaining); 751 status = imgdec->load_image(filename, info, buf, &remaining);
707 752
708 if (status == PLUGIN_OUTOFMEM) 753 if (status == PLUGIN_OUTOFMEM)
709 { 754 {
710#ifdef USE_PLUG_BUF 755#ifdef USE_PLUG_BUF
711 if(plug_buf) 756 if(iv_api.plug_buf)
712 { 757 {
713 return ask_and_get_audio_buffer(filename); 758 return ask_and_get_audio_buffer(filename);
714 } 759 }
@@ -734,13 +779,14 @@ static int load_and_show(char* filename, struct image_info *info)
734 ds_min = min_downscale(remaining); /* check memory constraint */ 779 ds_min = min_downscale(remaining); /* check memory constraint */
735 if (ds_min == 0) 780 if (ds_min == 0)
736 { 781 {
737#if UNSCALED_IS_AVAILABLE 782 if (imgdec->unscaled_avail)
738 /* Can not resize the image but original one is available, so use it. */ 783 {
739 ds_min = ds_max = 1; 784 /* Can not resize the image but original one is available, so use it. */
740#else 785 ds_min = ds_max = 1;
741 /* not enough memory to decode image. */ 786 }
787 else
742#ifdef USE_PLUG_BUF 788#ifdef USE_PLUG_BUF
743 if(plug_buf) 789 if (iv_api.plug_buf)
744 { 790 {
745 return ask_and_get_audio_buffer(filename); 791 return ask_and_get_audio_buffer(filename);
746 } 792 }
@@ -751,7 +797,6 @@ static int load_and_show(char* filename, struct image_info *info)
751 file_pt[curfile] = NULL; 797 file_pt[curfile] = NULL;
752 return change_filename(direction); 798 return change_filename(direction);
753 } 799 }
754#endif
755 } 800 }
756 else if (ds_max < ds_min) 801 else if (ds_max < ds_min)
757 ds_max = ds_min; 802 ds_max = ds_min;
@@ -762,7 +807,7 @@ static int load_and_show(char* filename, struct image_info *info)
762 807
763 do /* loop the image prepare and decoding when zoomed */ 808 do /* loop the image prepare and decoding when zoomed */
764 { 809 {
765 status = get_image(info, ds); /* decode or fetch from cache */ 810 status = imgdec->get_image(info, ds); /* decode or fetch from cache */
766 if (status == PLUGIN_ERROR) 811 if (status == PLUGIN_ERROR)
767 { 812 {
768 file_pt[curfile] = NULL; 813 file_pt[curfile] = NULL;
@@ -771,14 +816,14 @@ static int load_and_show(char* filename, struct image_info *info)
771 816
772 set_view(info, cx, cy); 817 set_view(info, cx, cy);
773 818
774 if(!running_slideshow) 819 if(!iv_api.running_slideshow)
775 { 820 {
776 rb->lcd_putsf(0, 3, "showing %dx%d", info->width, info->height); 821 rb->lcd_putsf(0, 3, "showing %dx%d", info->width, info->height);
777 rb->lcd_update(); 822 rb->lcd_update();
778 } 823 }
779 824
780 mylcd_ub_clear_display(); 825 mylcd_ub_clear_display();
781 draw_image_rect(info, 0, 0, 826 imgdec->draw_image_rect(info, 0, 0,
782 info->width-info->x, info->height-info->y); 827 info->width-info->x, info->height-info->y);
783 mylcd_ub_update(); 828 mylcd_ub_update();
784 829
@@ -794,18 +839,10 @@ static int load_and_show(char* filename, struct image_info *info)
794 status = scroll_bmp(info); 839 status = scroll_bmp(info);
795 if (status == ZOOM_IN) 840 if (status == ZOOM_IN)
796 { 841 {
797#if UNSCALED_IS_AVAILABLE 842 if (ds > ds_min || (imgdec->unscaled_avail && ds > 1))
798 if (ds > 1)
799#else
800 if (ds > ds_min)
801#endif
802 { 843 {
803#if UNSCALED_IS_AVAILABLE
804 /* if 1/1 is always available, jump ds from ds_min to 1. */ 844 /* if 1/1 is always available, jump ds from ds_min to 1. */
805 int zoom = (ds == ds_min)? ds_min: 2; 845 int zoom = (ds == ds_min)? ds_min: 2;
806#else
807 const int zoom = 2;
808#endif
809 ds /= zoom; /* reduce downscaling to zoom in */ 846 ds /= zoom; /* reduce downscaling to zoom in */
810 get_view(info, &cx, &cy); 847 get_view(info, &cx, &cy);
811 cx *= zoom; /* prepare the position in the new image */ 848 cx *= zoom; /* prepare the position in the new image */
@@ -819,12 +856,8 @@ static int load_and_show(char* filename, struct image_info *info)
819 { 856 {
820 if (ds < ds_max) 857 if (ds < ds_max)
821 { 858 {
822#if UNSCALED_IS_AVAILABLE
823 /* if ds is 1 and ds_min is > 1, jump ds to ds_min. */ 859 /* if ds is 1 and ds_min is > 1, jump ds to ds_min. */
824 int zoom = (ds < ds_min)? ds_min: 2; 860 int zoom = (ds < ds_min)? ds_min: 2;
825#else
826 const int zoom = 2;
827#endif
828 ds *= zoom; /* increase downscaling to zoom out */ 861 ds *= zoom; /* increase downscaling to zoom out */
829 get_view(info, &cx, &cy); 862 get_view(info, &cx, &cy);
830 cx /= zoom; /* prepare the position in the new image */ 863 cx /= zoom; /* prepare the position in the new image */
@@ -859,25 +892,24 @@ enum plugin_status plugin_start(const void* parameter)
859 892
860 if(!parameter) return PLUGIN_ERROR; 893 if(!parameter) return PLUGIN_ERROR;
861 894
895 rb->strcpy(np_file, parameter);
896 if (get_image_type(np_file) == IMAGE_UNKNOWN)
897 {
898 rb->splash(HZ*2, "Unsupported file");
899 return PLUGIN_ERROR;
900 }
901
862#ifdef USE_PLUG_BUF 902#ifdef USE_PLUG_BUF
863 buf = rb->plugin_get_buffer(&buf_size); 903 buf = rb->plugin_get_buffer(&buf_size);
864#else 904#else
905 decoder_buf = rb->plugin_get_buffer(&decoder_buf_size);
865 buf = rb->plugin_get_audio_buffer(&buf_size); 906 buf = rb->plugin_get_audio_buffer(&buf_size);
866#endif 907#endif
867 908
868 rb->strcpy(np_file, parameter);
869 get_pic_list(); 909 get_pic_list();
870 910
871 if(!entries) return PLUGIN_ERROR; 911 if(!entries) return PLUGIN_ERROR;
872 912
873#ifdef USE_PLUG_BUF
874 if(!rb->audio_status())
875 {
876 plug_buf = false;
877 buf = rb->plugin_get_audio_buffer(&buf_size);
878 }
879#endif
880
881#ifdef USEGSLIB 913#ifdef USEGSLIB
882 if (!grey_init(buf, buf_size, GREY_ON_COP, 914 if (!grey_init(buf, buf_size, GREY_ON_COP,
883 LCD_WIDTH, LCD_HEIGHT, &greysize)) 915 LCD_WIDTH, LCD_HEIGHT, &greysize))
@@ -889,6 +921,16 @@ enum plugin_status plugin_start(const void* parameter)
889 buf_size -= greysize; 921 buf_size -= greysize;
890#endif 922#endif
891 923
924#ifdef USE_PLUG_BUF
925 decoder_buf = buf;
926 decoder_buf_size = buf_size;
927 if(!rb->audio_status())
928 {
929 iv_api.plug_buf = false;
930 buf = rb->plugin_get_audio_buffer(&buf_size);
931 }
932#endif
933
892 /* should be ok to just load settings since the plugin itself has 934 /* should be ok to just load settings since the plugin itself has
893 just been loaded from disk and the drive should be spinning */ 935 just been loaded from disk and the drive should be spinning */
894 configfile_load(IMGVIEW_CONFIGFILE, config, 936 configfile_load(IMGVIEW_CONFIGFILE, config,
@@ -908,6 +950,7 @@ enum plugin_status plugin_start(const void* parameter)
908 { 950 {
909 condition = load_and_show(np_file, &image_info); 951 condition = load_and_show(np_file, &image_info);
910 } while (condition >= PLUGIN_OTHER); 952 } while (condition >= PLUGIN_OTHER);
953 release_decoder();
911 954
912 if (rb->memcmp(&settings, &old_settings, sizeof (settings))) 955 if (rb->memcmp(&settings, &old_settings, sizeof (settings)))
913 { 956 {