diff options
Diffstat (limited to 'apps/plugins/imageviewer/imageviewer.c')
-rw-r--r-- | apps/plugins/imageviewer/imageviewer.c | 219 |
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 | ||
41 | bool slideshow_enabled = false; /* run slideshow */ | ||
42 | bool running_slideshow = false; /* loading image because of slideshow */ | ||
43 | #ifdef DISK_SPINDOWN | ||
44 | bool 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? */ | ||
48 | bool 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 */ | 61 | static struct imgview_settings settings = |
67 | struct 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 | ||
83 | static void cb_progress(int current, int total); | ||
84 | |||
85 | static 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 |
95 | static fb_data rgb_linebuf[LCD_WIDTH]; /* Line buffer for scrolling when | 109 | static 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 */ |
114 | static unsigned char* decoder_buf; | ||
115 | static 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 */ |
101 | static unsigned char* buf; | 117 | static unsigned char* buf; |
102 | static size_t buf_size; | 118 | static 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 */ |
108 | static char np_file[MAX_PATH]; | 124 | static char np_file[MAX_PATH]; |
109 | static int curfile = 0, direction = DIR_NEXT, entries = 0; | 125 | static int curfile = -1, direction = DIR_NEXT, entries = 0; |
110 | 126 | ||
111 | /* list of the supported image files */ | 127 | /* list of the supported image files */ |
112 | static char **file_pt; | 128 | static char **file_pt; |
113 | 129 | ||
130 | static const struct image_decoder *imgdec = NULL; | ||
131 | static 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 |
191 | static bool set_option_grayscale(void) | 210 | static 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 | ||
212 | MENUITEM_FUNCTION(grayscale_item, 0, "Greyscale", | 231 | MENUITEM_FUNCTION(grayscale_item, 0, "Greyscale (Jpeg)", |
213 | set_option_grayscale, NULL, NULL, Icon_NOICON); | 232 | set_option_grayscale, NULL, NULL, Icon_NOICON); |
214 | MENUITEM_FUNCTION(dithering_item, 0, "Dithering", | 233 | MENUITEM_FUNCTION(dithering_item, 0, "Dithering (Jpeg)", |
215 | set_option_dithering, NULL, NULL, Icon_NOICON); | 234 | set_option_dithering, NULL, NULL, Icon_NOICON); |
216 | MAKE_MENU(display_menu, "Display Options", NULL, Icon_NOICON, | 235 | MAKE_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 | ||
225 | static int show_menu(void) /* return 1 to quit */ | 244 | static 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 */ |
385 | void cb_progress(int current, int total) | 404 | static 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 | { |