summaryrefslogtreecommitdiff
path: root/apps/plugins/imageviewer/ppm/ppm_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/imageviewer/ppm/ppm_decoder.c')
-rw-r--r--apps/plugins/imageviewer/ppm/ppm_decoder.c100
1 files changed, 51 insertions, 49 deletions
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
26static int ppm_read_magic_number(int fd) 27static 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
38static char ppm_getc(int fd) 39static 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
58static int ppm_getuint(int fd) 59static 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
158static void read_ppm_init(int fd, struct ppm_info *ppm) 157static 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 175static 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
184static 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 */
234int read_ppm(int fd, struct ppm_info *ppm) 235int 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}