aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c')
-rw-r--r--libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c590
1 files changed, 0 insertions, 590 deletions
diff --git a/libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c b/libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c
deleted file mode 100644
index 393e407..0000000
--- a/libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c
+++ /dev/null
@@ -1,590 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#ifdef HAVE_EVIL
6# include <Evil.h>
7#endif
8
9#include "evas_common.h"
10#include "evas_private.h"
11
12#define FILE_BUFFER_SIZE 1024 * 32
13#define FILE_BUFFER_UNREAD_SIZE 16
14
15static Eina_Bool evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
16static Eina_Bool evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
17
18Evas_Image_Load_Func evas_image_load_pmaps_func = {
19 EINA_TRUE,
20 evas_image_load_file_head_pmaps,
21 evas_image_load_file_data_pmaps,
22 NULL,
23 EINA_FALSE
24};
25
26/* The buffer to load pmaps images */
27typedef struct Pmaps_Buffer Pmaps_Buffer;
28
29struct Pmaps_Buffer
30{
31 Eina_File *file;
32 void *map;
33 size_t position;
34
35 /* the buffer */
36 DATA8 buffer[FILE_BUFFER_SIZE];
37 DATA8 unread[FILE_BUFFER_UNREAD_SIZE];
38 DATA8 *current;
39 DATA8 *end;
40 char type[3];
41 unsigned char unread_len:7;
42 unsigned char last_buffer:1;
43
44 /* image properties */
45 int w;
46 int h;
47 int max;
48
49 /* interface */
50 int (*int_get) (Pmaps_Buffer *b, int *val);
51 int (*color_get) (Pmaps_Buffer *b, DATA32 *color);
52};
53
54/* internal used functions */
55static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error);
56static void pmaps_buffer_close(Pmaps_Buffer *b);
57static Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error);
58static int pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val);
59static int pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val);
60static int pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val);
61static int pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color);
62static int pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color);
63static int pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *color);
64
65static size_t pmaps_buffer_plain_update(Pmaps_Buffer *b);
66static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b);
67static int pmaps_buffer_comment_skip(Pmaps_Buffer *b);
68
69static Eina_Bool
70evas_image_load_file_head_pmaps(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
71{
72 Pmaps_Buffer b;
73
74 if (!pmaps_buffer_open(&b, file, error))
75 {
76 pmaps_buffer_close(&b);
77 return EINA_FALSE;
78 }
79
80 if (!pmaps_buffer_header_parse(&b, error))
81 {
82 pmaps_buffer_close(&b);
83 return EINA_FALSE;
84 }
85
86 ie->w = b.w;
87 ie->h = b.h;
88
89 pmaps_buffer_close(&b);
90 *error = EVAS_LOAD_ERROR_NONE;
91 return EINA_TRUE;
92}
93
94static Eina_Bool
95evas_image_load_file_data_pmaps(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
96{
97 Pmaps_Buffer b;
98 int pixels;
99 DATA32 *ptr;
100
101 if (!pmaps_buffer_open(&b, file, error))
102 {
103 pmaps_buffer_close(&b);
104 return EINA_FALSE;
105 }
106
107 if (!pmaps_buffer_header_parse(&b, error))
108 {
109 pmaps_buffer_close(&b);
110 return EINA_FALSE;
111 }
112
113 pixels = b.w * b.h;
114
115 evas_cache_image_surface_alloc(ie, b.w, b.h);
116 ptr = evas_cache_image_pixels(ie);
117 if (!ptr)
118 {
119 pmaps_buffer_close(&b);
120 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
121 return EINA_FALSE;
122 }
123
124 if (b.type[1] != '4')
125 {
126 while (pixels > 0 && b.color_get(&b, ptr))
127 {
128 pixels--;
129 ptr++;
130 }
131 }
132 else
133 {
134 while (pixels > 0
135 && (b.current != b.end || pmaps_buffer_raw_update(&b)))
136 {
137 int i;
138
139 for (i = 7; i >= 0 && pixels > 0; i--)
140 {
141 if (*b.current & (1 << i))
142 *ptr = 0xff000000;
143 else
144 *ptr = 0xffffffff;
145 ptr++;
146 pixels--;
147 }
148 b.current++;
149 }
150 }
151
152 /* if there are some pix missing, give them a proper default */
153 memset(ptr, 0xff, 4 * pixels);
154 pmaps_buffer_close(&b);
155
156 *error = EVAS_LOAD_ERROR_NONE;
157 return EINA_TRUE;
158}
159
160/* internal used functions */
161static Eina_Bool
162pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error)
163{
164 size_t len;
165
166 b->file = eina_file_open(filename, EINA_FALSE);
167 if (!b->file)
168 {
169 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
170 return EINA_FALSE;
171 }
172
173 b->map = eina_file_map_all(b->file, EINA_FILE_SEQUENTIAL);
174 if (!b->map)
175 {
176 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
177 eina_file_close(b->file);
178 b->file = NULL;
179 return EINA_FALSE;
180 }
181
182 b->position = 0;
183 *b->buffer = 0;
184 *b->unread = 0;
185 b->last_buffer = 0;
186 b->unread_len = 0;
187
188 len = pmaps_buffer_plain_update(b);
189
190 if (len < 3)
191 {
192 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
193 eina_file_map_free(b->file, b->map);
194 eina_file_close(b->file);
195 b->map = NULL;
196 b->file = NULL;
197 return EINA_FALSE;
198 }
199
200 /* copy the type */
201 b->type[0] = b->buffer[0];
202 b->type[1] = b->buffer[1];
203 b->type[2] = 0;
204 /* skip the PX */
205 b->current = b->buffer + 2;
206
207 *error = EVAS_LOAD_ERROR_NONE;
208 return EINA_TRUE;
209}
210
211static void
212pmaps_buffer_close(Pmaps_Buffer *b)
213{
214 if (b->file)
215 {
216 if (b->map) eina_file_map_free(b->file, b->map);
217 b->map = NULL;
218 eina_file_close(b->file);
219 b->file = NULL;
220 }
221}
222
223static Eina_Bool
224pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error)
225{
226 /* if there is no P at the beginning it is not a file we can parse */
227 if (b->type[0] != 'P')
228 {
229 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
230 return EINA_FALSE;
231 }
232
233 /* get the width */
234 if (!pmaps_buffer_plain_int_get(b, &(b->w)) || b->w < 1)
235 {
236 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
237 return EINA_FALSE;
238 }
239
240 /* get the height */
241 if (!pmaps_buffer_plain_int_get(b, &(b->h)) || b->h < 1)
242 {
243 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
244 return EINA_FALSE;
245 }
246
247 /* get the maximum value. P1 and P4 don't have a maximum value. */
248 if (!(b->type[1] == '1' || b->type[1] == '4')
249 && (!pmaps_buffer_plain_int_get(b, &(b->max)) || b->max < 1))
250 {
251 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
252 return EINA_FALSE;
253 }
254
255 /* set up the color get callback */
256 switch (b->type[1])
257 {
258 /* Black and White */
259 case '1':
260 b->color_get = pmaps_buffer_plain_bw_get;
261 break;
262 case '4':
263 /* Binary black and white use another format */
264 b->color_get = NULL;
265 break;
266 case '2':
267 case '5':
268 b->color_get = pmaps_buffer_gray_get;
269 break;
270 case '3':
271 case '6':
272 b->color_get = pmaps_buffer_rgb_get;
273 break;
274 case '7':
275 /* XXX write me */
276 return 0;
277 break;
278 default:
279 return 0;
280 }
281 /* set up the int get callback */
282 switch (b->type[1])
283 {
284 /* RAW */
285 case '5':
286 case '6':
287 if (b->max < 256)
288 b->int_get = pmaps_buffer_1byte_int_get;
289 else
290 b->int_get = pmaps_buffer_2byte_int_get;
291
292 if (b->current == b->end && !pmaps_buffer_raw_update(b))
293 return 0;
294
295 b->current++;
296 break;
297 /* Plain */
298 case '2':
299 case '3':
300 b->int_get = pmaps_buffer_plain_int_get;
301 break;
302 /* Black and White Bitmaps don't use that callback */
303 case '1':
304 case '4':
305 b->int_get = NULL;
306 /* we need to skip the next character fpr P4 it
307 * doesn't hurt if we do it for the P1 as well */
308 b->current++;
309 break;
310 }
311 return 1;
312}
313
314static size_t
315pmaps_buffer_plain_update(Pmaps_Buffer *b)
316{
317 size_t r;
318 size_t max;
319
320 /* if we already are in the last buffer we can not update it */
321 if (b->last_buffer)
322 return 0;
323
324 /* if we have unread bytes we need to put them before the new read
325 * stuff */
326 if (b->unread_len)
327 memcpy(b->buffer, b->unread, b->unread_len);
328
329 max = FILE_BUFFER_SIZE - b->unread_len - 1;
330 if (b->position + max > eina_file_size_get(b->file))
331 max = eina_file_size_get(b->file) - b->position;
332
333 memcpy(&b->buffer[b->unread_len], b->map + b->position, max);
334 b->position += max;
335 r = max + b->unread_len;
336
337 /* we haven't read anything nor have we bytes in the unread buffer */
338 if (r == 0)
339 {
340 b->buffer[0] = '\0';
341 b->end = b->buffer;
342 b->last_buffer = 1;
343 return 0;
344 }
345
346 if (r < FILE_BUFFER_SIZE - 1)
347 {
348 /*we reached eof */ ;
349 b->last_buffer = 1;
350 }
351
352 b->buffer[r] = 0;
353
354 b->unread[0] = '\0';
355 b->unread_len = 0;
356
357 b->buffer[r] = '\0';
358 b->current = b->buffer;
359 b->end = b->buffer + r;
360
361 return r;
362}
363
364static size_t
365pmaps_buffer_raw_update(Pmaps_Buffer *b)
366{
367 size_t r;
368 size_t max;
369
370 if (b->last_buffer)
371 return 0;
372
373 if (b->unread_len)
374 memcpy(b->buffer, b->unread, b->unread_len);
375
376 max = FILE_BUFFER_SIZE - b->unread_len;
377 if (b->position + max > eina_file_size_get(b->file))
378 max = eina_file_size_get(b->file) - b->position;
379
380 memcpy(&b->buffer[b->unread_len], b->map + b->position, max);
381 b->position += max;
382 r = max + b->unread_len;
383
384 if (r < FILE_BUFFER_SIZE)
385 {
386 /*we reached eof */
387 b->last_buffer = 1;
388 }
389
390 b->end = b->buffer + r;
391 b->current = b->buffer;
392
393 if (b->unread_len)
394 {
395 /* the buffer is now read */
396 *b->unread = 0;
397 b->unread_len = 0;
398 }
399
400 return r;
401}
402
403static int
404pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val)
405{
406 char *start;
407 DATA8 lastc;
408
409 /* first skip all white space
410 * Note: we are skipping here actually every character than is not
411 * a digit */
412 while (!isdigit(*b->current))
413 {
414 if (*b->current == '\0')
415 {
416 if (!pmaps_buffer_plain_update(b))
417 return 0;
418
419 continue;
420 }
421 if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
422 return 0;
423 b->current++;
424 }
425
426 start = (char *)b->current;
427 /* now find the end of the number */
428 while (isdigit(*b->current))
429 b->current++;
430
431 lastc = *b->current;
432 *b->current = '\0';
433 *val = atoi(start);
434 *b->current = lastc;
435
436 return 1;
437}
438
439static int
440pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val)
441{
442 /* are we at the end of the buffer? */
443 if (b->current == b->end && !pmaps_buffer_raw_update(b))
444 return 0;
445
446 *val = *b->current;
447 b->current++;
448
449 return 1;
450}
451static int
452pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val)
453{
454 /* are we at the end of the buffer? */
455 if (b->current == b->end && !pmaps_buffer_raw_update(b))
456 return 0;
457
458 *val = (int)(*b->current << 8);
459 b->current++;
460
461 /* are we at the end of the buffer? */
462 if (b->current == b->end && !pmaps_buffer_raw_update(b))
463 return 0;
464
465 *val |= *b->current;
466 b->current++;
467
468 return 1;
469}
470
471static int
472pmaps_buffer_comment_skip(Pmaps_Buffer *b)
473{
474 while (*b->current != '\n')
475 {
476 if (*b->current == '\0')
477 {
478 if (!pmaps_buffer_plain_update(b))
479 return 0;
480
481 continue;
482 }
483 b->current++;
484 }
485 return 1;
486}
487
488static int
489pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color)
490{
491 int vr, vg, vb;
492
493 if (!b->int_get(b, &vr) || !b->int_get(b, &vg) || !b->int_get(b, &vb))
494 return 0;
495
496 if (b->max != 255)
497 {
498 vr = (vr * 255) / b->max;
499 vg = (vg * 255) / b->max;
500 vb = (vb * 255) / b->max;
501 }
502 if (vr > 255)
503 vr = 255;
504 if (vg > 255)
505 vg = 255;
506 if (vb > 255)
507 vb = 255;
508
509 *color = ARGB_JOIN(0xff, vr, vg, vb);
510
511 return 1;
512}
513
514static int
515pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color)
516{
517 int val;
518
519 if (!b->int_get(b, &val))
520 return 0;
521
522 if (b->max != 255)
523 val = (val * 255) / b->max;
524 if (val > 255)
525 val = 255;
526 *color = ARGB_JOIN(0xff, val, val, val);
527
528 return 1;
529}
530
531static int
532pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *val)
533{
534 /* first skip all white space
535 * Note: we are skipping here actually every character than is not
536 * a digit */
537 while (!isdigit(*b->current))
538 {
539 if (*b->current == '\0')
540 {
541 if (!pmaps_buffer_raw_update(b))
542 return 0;
543
544 continue;
545 }
546 if (*b->current == '#' && !pmaps_buffer_comment_skip(b))
547 return 0;
548 b->current++;
549 }
550
551 if (*b->current == '0')
552 *val = 0xffffffff;
553 else
554 *val = 0xff000000;
555
556 b->current++;
557
558 return 1;
559}
560
561/* external functions */
562static int
563module_open(Evas_Module *em)
564{
565 if (!em)
566 return 0;
567 em->functions = (void *)(&evas_image_load_pmaps_func);
568 return 1;
569}
570
571static void
572module_close(Evas_Module *em __UNUSED__)
573{
574}
575
576static Evas_Module_Api evas_modapi = {
577 EVAS_MODULE_API_VERSION,
578 "pmaps",
579 "none",
580 {
581 module_open,
582 module_close
583 }
584};
585
586EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, pmaps);
587
588#ifndef EVAS_STATIC_BUILD_PMAPS
589EVAS_EINA_MODULE_DEFINE(image_loader, pmaps);
590#endif