diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-06-28 15:50:05 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-06-28 15:50:05 +0000 |
commit | 17ce42cdec5236ab0c97eea1cf12c9b0684c004a (patch) | |
tree | c89374b5a26714da78b6b3c1fc20e4e178eaf878 /apps/plugins | |
parent | 063b8e7c6a5f39c48aa0e45056ae165265af9719 (diff) | |
download | rockbox-17ce42cdec5236ab0c97eea1cf12c9b0684c004a.tar.gz rockbox-17ce42cdec5236ab0c97eea1cf12c9b0684c004a.zip |
Add ppm and rppm viewer by Alexander Papst
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17835 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/CATEGORIES | 1 | ||||
-rw-r--r-- | apps/plugins/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/ppmviewer.c | 334 | ||||
-rw-r--r-- | apps/plugins/viewers.config | 1 |
4 files changed, 337 insertions, 0 deletions
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES index b8ed0af75b..029bcfd164 100644 --- a/apps/plugins/CATEGORIES +++ b/apps/plugins/CATEGORIES | |||
@@ -54,6 +54,7 @@ pegbox,games | |||
54 | pictureflow,demos | 54 | pictureflow,demos |
55 | plasma,demos | 55 | plasma,demos |
56 | pong,games | 56 | pong,games |
57 | ppmviewer,viewers | ||
57 | properties,viewers | 58 | properties,viewers |
58 | random_folder_advance_config,apps | 59 | random_folder_advance_config,apps |
59 | reversi,games | 60 | reversi,games |
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index 260a357c39..7eabed6e00 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES | |||
@@ -60,6 +60,7 @@ fire.c | |||
60 | jpeg.c | 60 | jpeg.c |
61 | mandelbrot.c | 61 | mandelbrot.c |
62 | plasma.c | 62 | plasma.c |
63 | ppmviewer.c | ||
63 | 64 | ||
64 | blackjack.c | 65 | blackjack.c |
65 | bounce.c | 66 | bounce.c |
diff --git a/apps/plugins/ppmviewer.c b/apps/plugins/ppmviewer.c new file mode 100644 index 0000000000..4bb43e50da --- /dev/null +++ b/apps/plugins/ppmviewer.c | |||
@@ -0,0 +1,334 @@ | |||
1 | /***************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ / | ||
5 | * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) ( | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 Alexander Papst | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "plugin.h" | ||
21 | #include "bmp.h" | ||
22 | |||
23 | #if defined(HAVE_LCD_COLOR) | ||
24 | |||
25 | PLUGIN_HEADER | ||
26 | |||
27 | /* Magic constants. */ | ||
28 | #define PPM_MAGIC1 'P' | ||
29 | #define PPM_MAGIC2 '3' | ||
30 | #define RPPM_MAGIC2 '6' | ||
31 | #define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2) | ||
32 | #define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2) | ||
33 | |||
34 | #define PPM_OVERALLMAXVAL 65535 | ||
35 | #define PPM_MAXSIZE (300*1024)/sizeof(fb_data) | ||
36 | |||
37 | #define ppm_error(...) rb->splash(HZ*2, __VA_ARGS__ ) | ||
38 | |||
39 | static fb_data buffer[PPM_MAXSIZE]; | ||
40 | static fb_data lcd_buf[LCD_WIDTH * LCD_HEIGHT]; | ||
41 | |||
42 | static const struct plugin_api* rb; /* global api struct pointer */ | ||
43 | |||
44 | int ppm_read_magic_number(int fd) | ||
45 | { | ||
46 | char i1, i2; | ||
47 | if(!rb->read(fd, &i1, 1) || !rb->read(fd, &i2, 1)) | ||
48 | { | ||
49 | ppm_error( "Error reading magic number from ppm image stream. "\ | ||
50 | "Most often, this means your input file is empty." ); | ||
51 | return PLUGIN_ERROR; | ||
52 | } | ||
53 | return i1 * 256 + i2; | ||
54 | } | ||
55 | |||
56 | char ppm_getc(int fd) | ||
57 | { | ||
58 | char ch; | ||
59 | |||
60 | if (!rb->read(fd, &ch, 1)) { | ||
61 | ppm_error("EOF. Read error reading a byte"); | ||
62 | return PLUGIN_ERROR; | ||
63 | } | ||
64 | |||
65 | if (ch == '#') { | ||
66 | do { | ||
67 | if (!rb->read(fd, &ch, 1)) { | ||
68 | ppm_error("EOF. Read error reading a byte"); | ||
69 | return PLUGIN_ERROR; | ||
70 | } | ||
71 | } while (ch != '\n' && ch != '\r'); | ||
72 | } | ||
73 | return ch; | ||
74 | } | ||
75 | |||
76 | int ppm_getuint(int fd) | ||
77 | { | ||
78 | char ch; | ||
79 | int i; | ||
80 | int digitVal; | ||
81 | |||
82 | do { | ||
83 | ch = ppm_getc(fd); | ||
84 | } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); | ||
85 | |||
86 | if (ch < '0' || ch > '9') { | ||
87 | ppm_error("Junk (%c) in file where an integer should be.", ch); | ||
88 | return PLUGIN_ERROR; | ||
89 | } | ||
90 | |||
91 | i = 0; | ||
92 | |||
93 | do { | ||
94 | digitVal = ch - '0'; | ||
95 | |||
96 | if (i > INT_MAX/10 - digitVal) { | ||
97 | ppm_error("ASCII decimal integer in file is "\ | ||
98 | "too large to be processed."); | ||
99 | return PLUGIN_ERROR; | ||
100 | } | ||
101 | |||
102 | i = i * 10 + digitVal; | ||
103 | ch = ppm_getc(fd); | ||
104 | |||
105 | } while (ch >= '0' && ch <= '9'); | ||
106 | |||
107 | return i; | ||
108 | } | ||
109 | |||
110 | int ppm_getrawbyte(int fd) | ||
111 | { | ||
112 | unsigned char by; | ||
113 | |||
114 | if (!rb->read(fd, &by, 1)) { | ||
115 | ppm_error("EOF. Read error while reading a one-byte sample."); | ||
116 | return PLUGIN_ERROR; | ||
117 | } | ||
118 | |||
119 | return (int)by; | ||
120 | } | ||
121 | |||
122 | int ppm_getrawsample(int fd, int const maxval) | ||
123 | { | ||
124 | if (maxval < 256) { | ||
125 | /* The sample is just one byte. Read it. */ | ||
126 | return(ppm_getrawbyte(fd)); | ||
127 | } else { | ||
128 | /* The sample is two bytes. Read both. */ | ||
129 | unsigned char byte_pair[2]; | ||
130 | |||
131 | if (!rb->read(fd, byte_pair, 2)) { | ||
132 | ppm_error("EOF. Read error while reading a long sample."); | ||
133 | return PLUGIN_ERROR; | ||
134 | } | ||
135 | return((byte_pair[0]<<8) | byte_pair[1]); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | int read_ppm_init_rest(int fd, | ||
140 | int * const cols, | ||
141 | int * const rows, | ||
142 | int * const maxval) | ||
143 | { | ||
144 | /* Read size. */ | ||
145 | *cols = ppm_getuint(fd); | ||
146 | *rows = ppm_getuint(fd); | ||
147 | |||
148 | if ((long unsigned int)(*cols * *rows) > PPM_MAXSIZE) { | ||
149 | ppm_error("Imagesize (%ld pixels) is too large. "\ | ||
150 | "The maximum allowed is %ld.", | ||
151 | (long unsigned int)(*cols * *rows), | ||
152 | (long unsigned int)PPM_MAXSIZE); | ||
153 | return PLUGIN_ERROR; | ||
154 | } | ||
155 | |||
156 | /* Read maxval. */ | ||
157 | *maxval = ppm_getuint(fd); | ||
158 | |||
159 | if (*maxval > PPM_OVERALLMAXVAL) { | ||
160 | ppm_error("maxval of input image (%u) is too large. "\ | ||
161 | "The maximum allowed by the PPM is %u.", | ||
162 | *maxval, PPM_OVERALLMAXVAL); | ||
163 | return PLUGIN_ERROR; | ||
164 | } | ||
165 | if (*maxval == 0) { | ||
166 | ppm_error("maxval of input image is zero."); | ||
167 | return PLUGIN_ERROR; | ||
168 | } | ||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | void read_ppm_init(int fd, | ||
173 | int * const cols, | ||
174 | int * const rows, | ||
175 | int * const maxval, | ||
176 | int * const format) | ||
177 | { | ||
178 | /* Check magic number. */ | ||
179 | *format = ppm_read_magic_number( fd ); | ||
180 | |||
181 | if (*format == PLUGIN_ERROR) return; | ||
182 | switch (*format) { | ||
183 | case PPM_FORMAT: | ||
184 | case RPPM_FORMAT: | ||
185 | if(read_ppm_init_rest(fd, cols, rows, maxval) == PLUGIN_ERROR) { | ||
186 | *format = PLUGIN_ERROR; | ||
187 | } | ||
188 | break; | ||
189 | |||
190 | default: | ||
191 | ppm_error( "Bad magic number - not a ppm or rppm file." ); | ||
192 | *format = PLUGIN_ERROR; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | int read_ppm_row(int fd, | ||
197 | int const row, | ||
198 | int const cols, | ||
199 | int const maxval, | ||
200 | int const format) | ||
201 | { | ||
202 | int col; | ||
203 | int r, g, b; | ||
204 | switch (format) { | ||
205 | case PPM_FORMAT: | ||
206 | for (col = 0; col < cols; ++col) { | ||
207 | r = ppm_getuint(fd); | ||
208 | g = ppm_getuint(fd); | ||
209 | b = ppm_getuint(fd); | ||
210 | |||
211 | if (r == PLUGIN_ERROR || g == PLUGIN_ERROR || | ||
212 | b == PLUGIN_ERROR) | ||
213 | { | ||
214 | return PLUGIN_ERROR; | ||
215 | } | ||
216 | buffer[(cols * row) + col] = LCD_RGBPACK( | ||
217 | (255 / maxval) * r, | ||
218 | (255 / maxval) * g, | ||
219 | (255 / maxval) * b); | ||
220 | } | ||
221 | break; | ||
222 | |||
223 | case RPPM_FORMAT: | ||
224 | for (col = 0; col < cols; ++col) { | ||
225 | r = ppm_getrawsample(fd, maxval); | ||
226 | g = ppm_getrawsample(fd, maxval); | ||
227 | b = ppm_getrawsample(fd, maxval); | ||
228 | |||
229 | if (r == PLUGIN_ERROR || g == PLUGIN_ERROR || | ||
230 | b == PLUGIN_ERROR) | ||
231 | { | ||
232 | return PLUGIN_ERROR; | ||
233 | } | ||
234 | buffer[(cols * row) + col] = LCD_RGBPACK( | ||
235 | (255 / maxval) * r, | ||
236 | (255 / maxval) * g, | ||
237 | (255 / maxval) * b); | ||
238 | } | ||
239 | break; | ||
240 | |||
241 | default: | ||
242 | ppm_error("What?!"); | ||
243 | return PLUGIN_ERROR; | ||
244 | } | ||
245 | return 1; | ||
246 | } | ||
247 | |||
248 | int read_ppm(int fd, | ||
249 | int * const cols, | ||
250 | int * const rows, | ||
251 | int * const maxval) | ||
252 | { | ||
253 | int row; | ||
254 | int format; | ||
255 | |||
256 | read_ppm_init(fd, cols, rows, maxval, &format); | ||
257 | |||
258 | if(format == PLUGIN_ERROR) { | ||
259 | return PLUGIN_ERROR; | ||
260 | } | ||
261 | |||
262 | for (row = 0; row < *rows; ++row) { | ||
263 | if( read_ppm_row(fd, row, *cols, *maxval, format) == PLUGIN_ERROR) { | ||
264 | return PLUGIN_ERROR; | ||
265 | } | ||
266 | } | ||
267 | return 1; | ||
268 | } | ||
269 | |||
270 | /* this is the plugin entry point */ | ||
271 | enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter) | ||
272 | { | ||
273 | static char filename[MAX_PATH]; | ||
274 | int fd; | ||
275 | |||
276 | int cols; | ||
277 | int rows; | ||
278 | int maxval; | ||
279 | |||
280 | int result; | ||
281 | |||
282 | struct bitmap small_bitmap, orig_bitmap; | ||
283 | |||
284 | if(!parameter) return PLUGIN_ERROR; | ||
285 | |||
286 | rb = api; | ||
287 | |||
288 | rb->strcpy(filename, parameter); | ||
289 | |||
290 | fd = rb->open(filename, O_RDONLY); | ||
291 | if (fd < 0) | ||
292 | { | ||
293 | ppm_error("Couldnt open file: %s, %d", filename, fd); | ||
294 | return PLUGIN_ERROR; | ||
295 | } | ||
296 | |||
297 | result = read_ppm(fd, &cols, &rows, &maxval); | ||
298 | |||
299 | rb->close(fd); | ||
300 | if(result == PLUGIN_ERROR) return PLUGIN_ERROR; | ||
301 | |||
302 | orig_bitmap.width = cols; | ||
303 | orig_bitmap.height = rows; | ||
304 | orig_bitmap.data = (char*)buffer; | ||
305 | |||
306 | if (cols > LCD_WIDTH || rows > LCD_HEIGHT) | ||
307 | { | ||
308 | if (cols > LCD_WIDTH) { | ||
309 | small_bitmap.width = LCD_WIDTH; | ||
310 | small_bitmap.height = | ||
311 | (int)(((float)LCD_WIDTH / (float)cols) * (float)rows); | ||
312 | |||
313 | } else { /* rows > LCD_HEIGHT */ | ||
314 | |||
315 | small_bitmap.width = | ||
316 | (int)(((float)LCD_HEIGHT / (float)rows) * (float)cols); | ||
317 | small_bitmap.height = LCD_HEIGHT; | ||
318 | } | ||
319 | small_bitmap.data = (char*)lcd_buf; | ||
320 | |||
321 | smooth_resize_bitmap( &orig_bitmap, &small_bitmap ); | ||
322 | |||
323 | rb->lcd_bitmap((fb_data*)small_bitmap.data, 0, 0, | ||
324 | small_bitmap.width, small_bitmap.height); | ||
325 | } else { | ||
326 | rb->lcd_bitmap((fb_data*)orig_bitmap.data, 0, 0, cols, rows); | ||
327 | } | ||
328 | rb->lcd_update(); | ||
329 | rb->button_get(true); | ||
330 | |||
331 | return PLUGIN_OK; | ||
332 | } | ||
333 | |||
334 | #endif | ||
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index c1df1b2e71..49ade79144 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config | |||
@@ -36,6 +36,7 @@ tap,viewers/zxbox,12 | |||
36 | sna,viewers/zxbox,12 | 36 | sna,viewers/zxbox,12 |
37 | tzx,viewers/zxbox,12 | 37 | tzx,viewers/zxbox,12 |
38 | z80,viewers/zxbox,12 | 38 | z80,viewers/zxbox,12 |
39 | ppm,viewers/ppmviewer,2 | ||
39 | *,viewers/properties,- | 40 | *,viewers/properties,- |
40 | colours,apps/text_editor,11 | 41 | colours,apps/text_editor,11 |
41 | ssg,games/superdom,- | 42 | ssg,games/superdom,- |