5 #include "evas_common.h"
6 #include "evas_private.h"
8 #define FILE_BUFFER_SIZE 1024
9 #define FILE_BUFFER_UNREAD_SIZE 16
11 static int evas_image_load_file_head_pmaps(Image_Entry *ie,
12 const char *file, const char *key);
13 static int evas_image_load_file_data_pmaps(Image_Entry *ie,
14 const char *file, const char *key);
16 Evas_Image_Load_Func evas_image_load_pmaps_func = {
17 evas_image_load_file_head_pmaps,
18 evas_image_load_file_data_pmaps
21 /* The buffer to load pmaps images */
22 typedef struct Pmaps_Buffer Pmaps_Buffer;
29 DATA8 buffer[FILE_BUFFER_SIZE];
30 DATA8 unread[FILE_BUFFER_UNREAD_SIZE];
34 unsigned char unread_len:7;
35 unsigned char last_buffer:1;
37 /* image properties */
43 int (*int_get) (Pmaps_Buffer *b, int *val);
44 int (*color_get) (Pmaps_Buffer *b, DATA32 *color);
47 /* internal used functions */
48 static int pmaps_buffer_open(Pmaps_Buffer *b, const char *filename);
49 static void pmaps_buffer_close(Pmaps_Buffer *b);
50 static int pmaps_buffer_header_parse(Pmaps_Buffer *b);
51 static int pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val);
52 static int pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val);
53 static int pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val);
54 static int pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color);
55 static int pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color);
56 static int pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *color);
58 static size_t pmaps_buffer_plain_update(Pmaps_Buffer *b);
59 static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b);
60 static int pmaps_buffer_comment_skip(Pmaps_Buffer *b);
63 evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file,
71 if (!pmaps_buffer_open(&b, file))
73 pmaps_buffer_close(&b);
77 if (!pmaps_buffer_header_parse(&b))
79 pmaps_buffer_close(&b);
86 pmaps_buffer_close(&b);
88 /* we don't have a use for key, skip warnings */
93 evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file,
103 if (!pmaps_buffer_open(&b, file))
105 pmaps_buffer_close(&b);
109 if (!pmaps_buffer_header_parse(&b))
111 pmaps_buffer_close(&b);
117 evas_cache_image_surface_alloc(ie, b.w, b.h);
118 if (!evas_cache_image_pixels(ie))
120 pmaps_buffer_close(&b);
124 ptr = evas_cache_image_pixels(ie);
126 if (b.type[1] != '4')
128 while (pixels > 0 && b.color_get(&b, ptr))
137 && (b.current != b.end || pmaps_buffer_raw_update(&b)))
141 for (i = 7; i >= 0 && pixels > 0; i--)
143 if (*b.current & (1 << i))
154 /* if there are some pix missing, give them a proper default */
155 memset(ptr, 0xff, 4 * pixels);
156 pmaps_buffer_close(&b);
159 /* we don't have a use for key, skip warnings */
163 /* internal used functions */
165 pmaps_buffer_open(Pmaps_Buffer *b, const char *filename)
169 b->file = fopen(filename, "r");
178 len = pmaps_buffer_plain_update(b);
184 b->type[0] = b->buffer[0];
185 b->type[1] = b->buffer[1];
188 b->current = b->buffer + 2;
194 pmaps_buffer_close(Pmaps_Buffer *b)
201 pmaps_buffer_header_parse(Pmaps_Buffer *b)
203 /* if there is no P at the beginning it is not a file we can parse */
204 if (b->type[0] != 'P')
208 if (!pmaps_buffer_plain_int_get(b, &(b->w)) || b->w < 1)
212 if (!pmaps_buffer_plain_int_get(b, &(b->h)) || b->h < 1)
215 /* get the maximum value. P1 and P4 don't have a maximum value. */
216 if (!(b->type[1] == '1' || b->type[1] == '4')
217 && (!pmaps_buffer_plain_int_get(b, &(b->max)) || b->max < 1))
220 /* set up the color get callback */
223 /* Black and White */
225 b->color_get = pmaps_buffer_plain_bw_get;
228 /* Binary black and white use another format */
233 b->color_get = pmaps_buffer_gray_get;
237 b->color_get = pmaps_buffer_rgb_get;
246 /* set up the int get callback */
253 b->int_get = pmaps_buffer_1byte_int_get;
255 b->int_get = pmaps_buffer_2byte_int_get;
257 if (b->current == b->end && !pmaps_buffer_raw_update(b))
265 b->int_get = pmaps_buffer_plain_int_get;
267 /* Black and White Bitmaps don't use that callback */
271 /* we need to skip the next character fpr P4 it
272 * doesn't hurt if we do it for the P1 as well */
280 pmaps_buffer_plain_update(Pmaps_Buffer *b)
285 /* if we already are in the last buffer we can not update it */
289 /* if we have unread bytes we need to put them before the new read
292 memcpy(b->buffer, b->unread, b->unread_len);
294 r = fread(&b->buffer[b->unread_len], 1,
295 FILE_BUFFER_SIZE - b->unread_len - 1, b->file) + b->unread_len;
297 /* we haven't read anything nor have we bytes in the unread buffer */
306 if (r < FILE_BUFFER_SIZE - 1)
308 /*we reached eof */ ;
315 while (steps < (FILE_BUFFER_UNREAD_SIZE - 2)
316 && r > 1 && !isspace(b->buffer[r]))
324 memcpy(b->unread, &b->buffer[r], steps + 1);
325 b->unread_len = steps + 1;
334 b->current = b->buffer;
335 b->end = b->buffer + r;
341 pmaps_buffer_raw_update(Pmaps_Buffer *b)
349 memcpy(b->buffer, b->unread, b->unread_len);
351 r = fread(&b->buffer[b->unread_len], 1,
352 FILE_BUFFER_SIZE - b->unread_len - 1, b->file) + b->unread_len;
354 if (r < FILE_BUFFER_SIZE - 1)
356 /*we reached eof */ ;
361 b->end = b->buffer + r;
362 b->current = b->buffer;
366 /* the buffer is now read */
375 pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val)
380 /* first skip all white space
381 * Note: we are skipping here actually every character than is not
383 while (!isdigit(*b->current))
385 if (*b->current == '\0')
387 if (!pmaps_buffer_plain_update(b))
392 if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
397 start = (char *)b->current;
398 /* now find the end of the number */
399 while (isdigit(*b->current))
411 pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val)
413 /* are we at the end of the buffer? */
414 if (b->current == b->end && !pmaps_buffer_raw_update(b))
423 pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val)
425 /* are we at the end of the buffer? */
426 if (b->current == b->end && !pmaps_buffer_raw_update(b))
429 *val = (int)(*b->current << 8);
432 /* are we at the end of the buffer? */
433 if (b->current == b->end && !pmaps_buffer_raw_update(b))
443 pmaps_buffer_comment_skip(Pmaps_Buffer *b)
445 while (*b->current != '\n')
447 if (*b->current == '\0')
449 if (!pmaps_buffer_plain_update(b))
460 pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color)
464 if (!b->int_get(b, &vr) || !b->int_get(b, &vg) || !b->int_get(b, &vb))
469 vr = (vr * 255) / b->max;
470 vg = (vg * 255) / b->max;
471 vb = (vb * 255) / b->max;
480 *color = 0xff000000 | (vr << 16) | (vg << 8) | vb;
486 pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color)
490 if (!b->int_get(b, &val))
494 val = (val * 255) / b->max;
497 *color = 0xff000000 | (val << 16) | (val << 8) | val;
503 pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *val)
505 /* first skip all white space
506 * Note: we are skipping here actually every character than is not
508 while (!isdigit(*b->current))
510 if (*b->current == '\0')
512 if (!pmaps_buffer_raw_update(b))
517 if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
522 if (*b->current == '0')
532 /* external functions */
534 module_open(Evas_Module *em)
538 em->functions = (void *)(&evas_image_load_pmaps_func);
548 EAPI Evas_Module_Api evas_modapi = {
549 EVAS_MODULE_API_VERSION,
550 EVAS_MODULE_TYPE_IMAGE_LOADER,