1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* user intereface of image viewer.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _IMAGE_VIEWER_H
#define _IMAGE_VIEWER_H
#include "plugin.h"
/* different graphics libraries */
#if LCD_DEPTH < 8
#define USEGSLIB
#include <lib/grey.h>
#else
#include <lib/xlcd.h>
#endif
#include <lib/mylcd.h>
#if defined(USEGSLIB) && defined(IMGDEC)
#undef mylcd_ub_
#undef myxlcd_ub_
#define mylcd_ub_(fn) iv->fn
#define myxlcd_ub_(fn) iv->fn
#endif
/* Min memory allowing us to use the plugin buffer
* and thus not stopping the music
* *Very* rough estimation:
* Max 10 000 dir entries * 4bytes/entry (char **) = 40000 bytes
* + 30k code size = 70 000
* + 50k min for image = 120 000
*/
#define MIN_MEM 120000
/* State code for output with return. */
enum {
PLUGIN_OTHER = 0x200,
PLUGIN_ABORT,
PLUGIN_OUTOFMEM,
PLUGIN_JPEG_PROGRESSIVE,
ZOOM_IN,
ZOOM_OUT,
NEXT_FRAME,
};
#if (CONFIG_PLATFORM & PLATFORM_NATIVE) && defined(HAVE_DISK_STORAGE)
#define DISK_SPINDOWN
#endif
#if PLUGIN_BUFFER_SIZE >= MIN_MEM
#define USE_PLUG_BUF
#endif
/* Settings. jpeg needs these */
struct imgview_settings
{
#ifdef HAVE_LCD_COLOR
int jpeg_colour_mode;
int jpeg_dither_mode;
#endif
int ss_timeout;
};
/* structure passed to image decoder. */
struct image_info {
int x_size, y_size; /* set size of loaded image in load_image(). */
int width, height; /* set size of resized image in get_image(). */
int x, y; /* display position */
int frames_count; /* number of subframes */
int delay; /* delay expressed in ticks between frames */
void *data; /* use freely in decoder. not touched in ui. */
};
struct imgdec_api {
const struct imgview_settings *settings;
bool slideshow_enabled; /* run slideshow */
bool running_slideshow; /* loading image because of slideshw */
#ifdef DISK_SPINDOWN
bool immediate_ata_off; /* power down disk after loading */
#endif
#ifdef USE_PLUG_BUF
bool plug_buf; /* are we using the plugin buffer or the audio buffer? */
#endif
/* callback updating a progress meter while image decoding */
void (*cb_progress)(int current, int total);
#ifdef USEGSLIB
void (*gray_bitmap_part)(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
#endif
};
/* functions need to be implemented in each image decoders. */
struct image_decoder {
/* set true if unscaled image can be always displayed even when there isn't
* enough memory for resized image. e.g. when using native format to store
* image. */
const bool unscaled_avail;
/* return needed size of buffer to store downscaled image by ds.
* this is used to calculate min downscale. */
int (*img_mem)(int ds);
/* load image from filename. use the passed buffer to store loaded, decoded
* or resized image later, so save it to local variables if needed.
* set width and height of info properly. also, set buf_size to remaining
* size of buf after load image. it is used to calculate min downscale.
* return PLUGIN_ERROR for error. ui will skip to next image. */
int (*load_image)(char *filename, struct image_info *info,
unsigned char *buf, ssize_t *buf_size);
/* downscale loaded image by ds. use the buffer passed to load_image to
* reszie image and/or store resized image.
* return PLUGIN_ERROR for error. ui will skip to next image. */
int (*get_image)(struct image_info *info, int frame, int ds);
/* draw part of image */
void (*draw_image_rect)(struct image_info *info,
int x, int y, int width, int height);
};
#define IMGDEC_API_VERSION 1
/* image decoder header */
struct imgdec_header {
struct lc_header lc_hdr; /* must be the first */
const struct image_decoder *decoder;
const struct plugin_api **api;
unsigned short plugin_api_version;
size_t plugin_api_size;
const struct imgdec_api **img_api;
size_t img_api_size;
};
#ifdef IMGDEC
extern const struct imgdec_api *iv;
extern const struct image_decoder image_decoder;
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
#define IMGDEC_HEADER \
const struct plugin_api *rb DATA_ATTR; \
const struct imgdec_api *iv DATA_ATTR; \
const struct imgdec_header __header \
__attribute__ ((section (".header")))= { \
{ PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \
plugin_start_addr, plugin_end_addr, }, &image_decoder, \
&rb, PLUGIN_API_VERSION, sizeof(struct plugin_api), \
&iv, sizeof(struct imgdec_api) };
#else /* PLATFORM_HOSTED */
#define IMGDEC_HEADER \
const struct plugin_api *rb DATA_ATTR; \
const struct imgdec_api *iv DATA_ATTR; \
const struct imgdec_header __header \
__attribute__((visibility("default"))) = { \
{ PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, NULL, NULL }, \
&image_decoder, &rb, PLUGIN_API_VERSION, sizeof(struct plugin_api), \
&iv, sizeof(struct imgdec_api), };
#endif /* CONFIG_PLATFORM */
#endif
#endif /* _IMAGE_VIEWER_H */
|