diff options
author | Teruaki Kawashima <teru@rockbox.org> | 2011-01-19 12:51:57 +0000 |
---|---|---|
committer | Teruaki Kawashima <teru@rockbox.org> | 2011-01-19 12:51:57 +0000 |
commit | 622be891b3fbf251c1a8f8c53a134a1092747bec (patch) | |
tree | d443db819f74ad3d5b626238100fe04c54410241 | |
parent | d1ff23779821dc18f11256d51c397995496aa51c (diff) | |
download | rockbox-622be891b3fbf251c1a8f8c53a134a1092747bec.tar.gz rockbox-622be891b3fbf251c1a8f8c53a134a1092747bec.zip |
image viewer: ppm:
* return proper error code when image is too large.
* check return value of read() properly.
* display progressbar.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29090 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/imageviewer/ppm/ppm.c | 12 | ||||
-rw-r--r-- | apps/plugins/imageviewer/ppm/ppm.make | 8 | ||||
-rw-r--r-- | apps/plugins/imageviewer/ppm/ppm_decoder.c | 100 |
3 files changed, 56 insertions, 64 deletions
diff --git a/apps/plugins/imageviewer/ppm/ppm.c b/apps/plugins/imageviewer/ppm/ppm.c index 100a00ac84..20200d812e 100644 --- a/apps/plugins/imageviewer/ppm/ppm.c +++ b/apps/plugins/imageviewer/ppm/ppm.c | |||
@@ -106,11 +106,6 @@ static int load_image(char *filename, struct image_info *info, | |||
106 | if (!iv->running_slideshow) | 106 | if (!iv->running_slideshow) |
107 | { | 107 | { |
108 | rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1); | 108 | rb->lcd_puts(0, 0, rb->strrchr(filename,'/')+1); |
109 | rb->lcd_update(); | ||
110 | } | ||
111 | |||
112 | if (!iv->running_slideshow) | ||
113 | { | ||
114 | rb->lcd_putsf(0, 1, "loading %zu bytes", file_size); | 109 | rb->lcd_putsf(0, 1, "loading %zu bytes", file_size); |
115 | rb->lcd_update(); | 110 | rb->lcd_update(); |
116 | } | 111 | } |
@@ -130,14 +125,11 @@ static int load_image(char *filename, struct image_info *info, | |||
130 | #endif /*HAVE_ADJUSTABLE_CPU_FREQ*/ | 125 | #endif /*HAVE_ADJUSTABLE_CPU_FREQ*/ |
131 | time = *rb->current_tick - time; | 126 | time = *rb->current_tick - time; |
132 | 127 | ||
133 | /* close file descriptor */ | ||
134 | rb->close(fd); | 128 | rb->close(fd); |
135 | 129 | ||
136 | /* check return value from decoder */ | 130 | if (rc != PLUGIN_OK) |
137 | if ( rc == PLUGIN_ERROR ) | ||
138 | { | 131 | { |
139 | rb->splashf(HZ, "ppm decoder error"); | 132 | return rc; |
140 | return PLUGIN_ERROR; | ||
141 | } | 133 | } |
142 | 134 | ||
143 | if (!iv->running_slideshow) | 135 | if (!iv->running_slideshow) |
diff --git a/apps/plugins/imageviewer/ppm/ppm.make b/apps/plugins/imageviewer/ppm/ppm.make index e77f282723..b98ee62832 100644 --- a/apps/plugins/imageviewer/ppm/ppm.make +++ b/apps/plugins/imageviewer/ppm/ppm.make | |||
@@ -18,12 +18,10 @@ OTHER_SRC += $(PPM_SRC) | |||
18 | ROCKS += $(PPMBUILDDIR)/ppm.ovl | 18 | ROCKS += $(PPMBUILDDIR)/ppm.ovl |
19 | 19 | ||
20 | $(PPMBUILDDIR)/ppm.refmap: $(PPM_OBJ) | 20 | $(PPMBUILDDIR)/ppm.refmap: $(PPM_OBJ) |
21 | $(PPMBUILDDIR)/ppm.link: $(PPM_OBJ) $(PPMBUILDDIR)/ppm.refmap | 21 | $(PPMBUILDDIR)/ppm.link: $(PLUGIN_LDS) $(PPMBUILDDIR)/ppm.refmap |
22 | $(PPMBUILDDIR)/ppm.ovl: $(PPM_OBJ) | 22 | $(PPMBUILDDIR)/ppm.ovl: $(PPM_OBJ) |
23 | 23 | ||
24 | PPMFLAGS = $(IMGDECFLAGS) -Os | 24 | # special pattern rule for compiling image decoder with extra flags |
25 | |||
26 | # Compile PPM plugin with extra flags (adapted from ZXBox) | ||
27 | $(PPMBUILDDIR)/%.o: $(PPMSRCDIR)/%.c $(PPMSRCDIR)/ppm.make | 25 | $(PPMBUILDDIR)/%.o: $(PPMSRCDIR)/%.c $(PPMSRCDIR)/ppm.make |
28 | $(SILENT)mkdir -p $(dir $@) | 26 | $(SILENT)mkdir -p $(dir $@) |
29 | $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(PPMFLAGS) -c $< -o $@ | 27 | $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(IMGDECFLAGS) -c $< -o $@ |
diff --git a/apps/plugins/imageviewer/ppm/ppm_decoder.c b/apps/plugins/imageviewer/ppm/ppm_decoder.c index 44c4f9232e..be459293fe 100644 --- a/apps/plugins/imageviewer/ppm/ppm_decoder.c +++ b/apps/plugins/imageviewer/ppm/ppm_decoder.c | |||
@@ -22,42 +22,43 @@ | |||
22 | #include "plugin.h" | 22 | #include "plugin.h" |
23 | #include "lib/pluginlib_bmp.h" | 23 | #include "lib/pluginlib_bmp.h" |
24 | #include "ppm_decoder.h" | 24 | #include "ppm_decoder.h" |
25 | #include "../imageviewer.h" | ||
25 | 26 | ||
26 | static int ppm_read_magic_number(int fd) | 27 | static int ppm_read_magic_number(int fd) |
27 | { | 28 | { |
28 | char i1, i2; | 29 | unsigned char i1, i2; |
29 | if(!rb->read(fd, &i1, 1) || !rb->read(fd, &i2, 1)) | 30 | if(rb->read(fd, &i1, 1) < 1 || rb->read(fd, &i2, 1) < 1) |
30 | { | 31 | { |
31 | ppm_error( "Error reading magic number from ppm image stream. "\ | 32 | ppm_error( "Error reading magic number from ppm image stream. "\ |
32 | "Most often, this means your input file is empty." ); | 33 | "Most often, this means your input file is empty." ); |
33 | return PLUGIN_ERROR; | 34 | return PLUGIN_ERROR; |
34 | } | 35 | } |
35 | return i1 * 256 + i2; | 36 | return i1 * 256 + i2; |
36 | } | 37 | } |
37 | 38 | ||
38 | static char ppm_getc(int fd) | 39 | static int ppm_getc(int fd) |
39 | { | 40 | { |
40 | char ch; | 41 | unsigned char ch; |
41 | 42 | ||
42 | if (!rb->read(fd, &ch, 1)) { | 43 | if (rb->read(fd, &ch, 1) < 1) { |
43 | ppm_error("EOF. Read error reading a byte"); | 44 | ppm_error("EOF. Read error reading a byte"); |
44 | return PLUGIN_ERROR; | 45 | return PLUGIN_ERROR; |
45 | } | 46 | } |
46 | 47 | ||
47 | if (ch == '#') { | 48 | if (ch == '#') { |
48 | do { | 49 | do { |
49 | if (!rb->read(fd, &ch, 1)) { | 50 | if (rb->read(fd, &ch, 1) < 1) { |
50 | ppm_error("EOF. Read error reading a byte"); | 51 | ppm_error("EOF. Read error reading a byte"); |
51 | return PLUGIN_ERROR; | 52 | return PLUGIN_ERROR; |
52 | } | 53 | } |
53 | } while (ch != '\n' && ch != '\r'); | 54 | } while (ch != '\n' && ch != '\r'); |
54 | } | 55 | } |
55 | return ch; | 56 | return (int)ch; |
56 | } | 57 | } |
57 | 58 | ||
58 | static int ppm_getuint(int fd) | 59 | static int ppm_getuint(int fd) |
59 | { | 60 | { |
60 | char ch; | 61 | int ch; |
61 | int i; | 62 | int i; |
62 | int digitVal; | 63 | int digitVal; |
63 | 64 | ||
@@ -65,6 +66,7 @@ static int ppm_getuint(int fd) | |||
65 | ch = ppm_getc(fd); | 66 | ch = ppm_getc(fd); |
66 | } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); | 67 | } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); |
67 | 68 | ||
69 | if (ch == PLUGIN_ERROR) return PLUGIN_ERROR; | ||
68 | if (ch < '0' || ch > '9') { | 70 | if (ch < '0' || ch > '9') { |
69 | ppm_error("Junk (%c) in file where an integer should be.", ch); | 71 | ppm_error("Junk (%c) in file where an integer should be.", ch); |
70 | return PLUGIN_ERROR; | 72 | return PLUGIN_ERROR; |
@@ -83,8 +85,9 @@ static int ppm_getuint(int fd) | |||
83 | 85 | ||
84 | i = i * 10 + digitVal; | 86 | i = i * 10 + digitVal; |
85 | ch = ppm_getc(fd); | 87 | ch = ppm_getc(fd); |
86 | 88 | ||
87 | } while (ch >= '0' && ch <= '9'); | 89 | } while (ch >= '0' && ch <= '9'); |
90 | if (ch == PLUGIN_ERROR) return PLUGIN_ERROR; | ||
88 | 91 | ||
89 | return i; | 92 | return i; |
90 | } | 93 | } |
@@ -93,7 +96,7 @@ static int ppm_getrawbyte(int fd) | |||
93 | { | 96 | { |
94 | unsigned char by; | 97 | unsigned char by; |
95 | 98 | ||
96 | if (!rb->read(fd, &by, 1)) { | 99 | if (rb->read(fd, &by, 1) < 1) { |
97 | ppm_error("EOF. Read error while reading a one-byte sample."); | 100 | ppm_error("EOF. Read error while reading a one-byte sample."); |
98 | return PLUGIN_ERROR; | 101 | return PLUGIN_ERROR; |
99 | } | 102 | } |
@@ -110,7 +113,7 @@ static int ppm_getrawsample(int fd, int const maxval) | |||
110 | /* The sample is two bytes. Read both. */ | 113 | /* The sample is two bytes. Read both. */ |
111 | unsigned char byte_pair[2]; | 114 | unsigned char byte_pair[2]; |
112 | 115 | ||
113 | if (!rb->read(fd, byte_pair, 2)) { | 116 | if (rb->read(fd, byte_pair, 2) < 2) { |
114 | ppm_error("EOF. Read error while reading a long sample."); | 117 | ppm_error("EOF. Read error while reading a long sample."); |
115 | return PLUGIN_ERROR; | 118 | return PLUGIN_ERROR; |
116 | } | 119 | } |
@@ -132,16 +135,12 @@ static int read_ppm_init_rest(int fd, struct ppm_info *ppm) | |||
132 | #endif | 135 | #endif |
133 | 136 | ||
134 | if (ppm->native_img_size > ppm->buf_size) { | 137 | if (ppm->native_img_size > ppm->buf_size) { |
135 | ppm_error("Imagesize (%ld pixels) is too large. "\ | 138 | return PLUGIN_OUTOFMEM; |
136 | "The maximum allowed is %ld.", | ||
137 | (long)ppm->native_img_size, | ||
138 | (long)ppm->buf_size); | ||
139 | return PLUGIN_ERROR; | ||
140 | } | 139 | } |
141 | 140 | ||
142 | /* Read maxval. */ | 141 | /* Read maxval. */ |
143 | ppm->maxval = ppm_getuint(fd); | 142 | ppm->maxval = ppm_getuint(fd); |
144 | 143 | ||
145 | if (ppm->maxval > PPM_OVERALLMAXVAL) { | 144 | if (ppm->maxval > PPM_OVERALLMAXVAL) { |
146 | ppm_error("maxval of input image (%u) is too large. "\ | 145 | ppm_error("maxval of input image (%u) is too large. "\ |
147 | "The maximum allowed by the PPM is %u.", | 146 | "The maximum allowed by the PPM is %u.", |
@@ -152,40 +151,40 @@ static int read_ppm_init_rest(int fd, struct ppm_info *ppm) | |||
152 | ppm_error("maxval of input image is zero."); | 151 | ppm_error("maxval of input image is zero."); |
153 | return PLUGIN_ERROR; | 152 | return PLUGIN_ERROR; |
154 | } | 153 | } |
155 | return 1; | 154 | return PLUGIN_OK; |
156 | } | 155 | } |
157 | 156 | ||
158 | static void read_ppm_init(int fd, struct ppm_info *ppm) | 157 | static int read_ppm_init(int fd, struct ppm_info *ppm) |
159 | { | 158 | { |
160 | /* Check magic number. */ | 159 | /* Check magic number. */ |
161 | ppm->format = ppm_read_magic_number( fd ); | 160 | ppm->format = ppm_read_magic_number( fd ); |
162 | 161 | ||
163 | if (ppm->format == PLUGIN_ERROR) return; | 162 | if (ppm->format == PLUGIN_ERROR) return PLUGIN_ERROR; |
164 | switch (ppm->format) { | 163 | switch (ppm->format) { |
165 | case PPM_FORMAT: | 164 | case PPM_FORMAT: |
166 | case RPPM_FORMAT: | 165 | case RPPM_FORMAT: |
167 | if(read_ppm_init_rest(fd, ppm) == PLUGIN_ERROR) { | 166 | return read_ppm_init_rest(fd, ppm); |
168 | ppm->format = PLUGIN_ERROR; | ||
169 | } | ||
170 | break; | ||
171 | 167 | ||
172 | default: | 168 | default: |
173 | ppm_error( "Bad magic number - not a ppm or rppm file." ); | 169 | ppm_error( "Bad magic number - not a ppm or rppm file." ); |
174 | ppm->format = PLUGIN_ERROR; | 170 | return PLUGIN_ERROR; |
175 | } | 171 | } |
172 | return PLUGIN_OK; | ||
176 | } | 173 | } |
177 | 174 | ||
178 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | 175 | static int read_ppm_row(int fd, struct ppm_info *ppm, int row) |
179 | #define BUFADDR(x, y, width, height) ( ppm->buf + (height*(x) + (y))*FB_DATA_SZ) | ||
180 | #else | ||
181 | #define BUFADDR(x, y, width, height) ( ppm->buf + (width*(y) + (x))*FB_DATA_SZ) | ||
182 | #endif | ||
183 | |||
184 | static int read_ppm_row(int fd, struct ppm_info *ppm, int row) | ||
185 | { | 176 | { |
186 | |||
187 | int col; | 177 | int col; |
188 | int r, g, b; | 178 | int r, g, b; |
179 | #ifdef HAVE_LCD_COLOR | ||
180 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
181 | fb_data *dst = (fb_data *) ppm->buf + row; | ||
182 | const int stride = ppm->x; | ||
183 | #else | ||
184 | fb_data *dst = (fb_data *) ppm->buf + ppm->x*row; | ||
185 | const int stride = 1; | ||
186 | #endif | ||
187 | #endif /* HAVE_LCD_COLOR */ | ||
189 | switch (ppm->format) { | 188 | switch (ppm->format) { |
190 | case PPM_FORMAT: | 189 | case PPM_FORMAT: |
191 | for (col = 0; col < ppm->x; ++col) { | 190 | for (col = 0; col < ppm->x; ++col) { |
@@ -197,11 +196,12 @@ static int read_ppm_row(int fd, struct ppm_info *ppm, int row) | |||
197 | b == PLUGIN_ERROR) | 196 | b == PLUGIN_ERROR) |
198 | { | 197 | { |
199 | return PLUGIN_ERROR; | 198 | return PLUGIN_ERROR; |
200 | } | 199 | } |
201 | *(fb_data *)BUFADDR(col, row, ppm->x, ppm->y) = LCD_RGBPACK( | 200 | *dst = LCD_RGBPACK( |
202 | (255 * r)/ppm->maxval, | 201 | (255 * r)/ppm->maxval, |
203 | (255 * g)/ppm->maxval, | 202 | (255 * g)/ppm->maxval, |
204 | (255 * b)/ppm->maxval); | 203 | (255 * b)/ppm->maxval); |
204 | dst += stride; | ||
205 | } | 205 | } |
206 | break; | 206 | break; |
207 | 207 | ||
@@ -216,10 +216,11 @@ static int read_ppm_row(int fd, struct ppm_info *ppm, int row) | |||
216 | { | 216 | { |
217 | return PLUGIN_ERROR; | 217 | return PLUGIN_ERROR; |
218 | } | 218 | } |
219 | *(fb_data *)BUFADDR(col, row, ppm->x, ppm->y) = LCD_RGBPACK( | 219 | *dst = LCD_RGBPACK( |
220 | (255 * r)/ppm->maxval, | 220 | (255 * r)/ppm->maxval, |
221 | (255 * g)/ppm->maxval, | 221 | (255 * g)/ppm->maxval, |
222 | (255 * b)/ppm->maxval); | 222 | (255 * b)/ppm->maxval); |
223 | dst += stride; | ||
223 | } | 224 | } |
224 | break; | 225 | break; |
225 | 226 | ||
@@ -227,24 +228,25 @@ static int read_ppm_row(int fd, struct ppm_info *ppm, int row) | |||
227 | ppm_error("What?!"); | 228 | ppm_error("What?!"); |
228 | return PLUGIN_ERROR; | 229 | return PLUGIN_ERROR; |
229 | } | 230 | } |
230 | return 1; | 231 | return PLUGIN_OK; |
231 | } | 232 | } |
232 | 233 | ||
233 | /* public */ | 234 | /* public */ |
234 | int read_ppm(int fd, struct ppm_info *ppm) | 235 | int read_ppm(int fd, struct ppm_info *ppm) |
235 | { | 236 | { |
236 | int row; | 237 | int row, ret; |
237 | 238 | ||
238 | read_ppm_init(fd, ppm); | 239 | ret = read_ppm_init(fd, ppm); |
239 | 240 | if(ret != PLUGIN_OK) { | |
240 | if(ppm->format == PLUGIN_ERROR) { | 241 | return ret; |
241 | return PLUGIN_ERROR; | ||
242 | } | 242 | } |
243 | 243 | ||
244 | for (row = 0; row < ppm->y; ++row) { | 244 | for (row = 0; row < ppm->y; ++row) { |
245 | if( read_ppm_row(fd, ppm, row) == PLUGIN_ERROR) { | 245 | ret = read_ppm_row(fd, ppm, row); |
246 | return PLUGIN_ERROR; | 246 | if(ret != PLUGIN_OK) { |
247 | return ret; | ||
247 | } | 248 | } |
249 | iv->cb_progress(row, ppm->y); | ||
248 | } | 250 | } |
249 | return 1; | 251 | return PLUGIN_OK; |
250 | } | 252 | } |