diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/evas/src/modules/loaders/pmaps/evas_image_load_pmaps.c | 590 |
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 | |||
15 | static 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); | ||
16 | static 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 | |||
18 | Evas_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 */ | ||
27 | typedef struct Pmaps_Buffer Pmaps_Buffer; | ||
28 | |||
29 | struct 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 */ | ||
55 | static Eina_Bool pmaps_buffer_open(Pmaps_Buffer *b, const char *filename, int *error); | ||
56 | static void pmaps_buffer_close(Pmaps_Buffer *b); | ||
57 | static Eina_Bool pmaps_buffer_header_parse(Pmaps_Buffer *b, int *error); | ||
58 | static int pmaps_buffer_plain_int_get(Pmaps_Buffer *b, int *val); | ||
59 | static int pmaps_buffer_1byte_int_get(Pmaps_Buffer *b, int *val); | ||
60 | static int pmaps_buffer_2byte_int_get(Pmaps_Buffer *b, int *val); | ||
61 | static int pmaps_buffer_gray_get(Pmaps_Buffer *b, DATA32 *color); | ||
62 | static int pmaps_buffer_rgb_get(Pmaps_Buffer *b, DATA32 *color); | ||
63 | static int pmaps_buffer_plain_bw_get(Pmaps_Buffer *b, DATA32 *color); | ||
64 | |||
65 | static size_t pmaps_buffer_plain_update(Pmaps_Buffer *b); | ||
66 | static size_t pmaps_buffer_raw_update(Pmaps_Buffer *b); | ||
67 | static int pmaps_buffer_comment_skip(Pmaps_Buffer *b); | ||
68 | |||
69 | static Eina_Bool | ||
70 | evas_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 | |||
94 | static Eina_Bool | ||
95 | evas_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 */ | ||
161 | static Eina_Bool | ||
162 | pmaps_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 | |||
211 | static void | ||
212 | pmaps_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 | |||
223 | static Eina_Bool | ||
224 | pmaps_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 | |||
314 | static size_t | ||
315 | pmaps_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 | |||
364 | static size_t | ||
365 | pmaps_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 | |||
403 | static int | ||
404 | pmaps_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 | |||
439 | static int | ||
440 | pmaps_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 | } | ||
451 | static int | ||
452 | pmaps_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 | |||
471 | static int | ||
472 | pmaps_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 | |||
488 | static int | ||
489 | pmaps_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 | |||
514 | static int | ||
515 | pmaps_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 | |||
531 | static int | ||
532 | pmaps_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 */ | ||
562 | static int | ||
563 | module_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 | |||
571 | static void | ||
572 | module_close(Evas_Module *em __UNUSED__) | ||
573 | { | ||
574 | } | ||
575 | |||
576 | static Evas_Module_Api evas_modapi = { | ||
577 | EVAS_MODULE_API_VERSION, | ||
578 | "pmaps", | ||
579 | "none", | ||
580 | { | ||
581 | module_open, | ||
582 | module_close | ||
583 | } | ||
584 | }; | ||
585 | |||
586 | EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, pmaps); | ||
587 | |||
588 | #ifndef EVAS_STATIC_BUILD_PMAPS | ||
589 | EVAS_EINA_MODULE_DEFINE(image_loader, pmaps); | ||
590 | #endif | ||