diff options
Diffstat (limited to 'libraries/evas/src/modules/loaders/tga/evas_image_load_tga.c')
-rw-r--r-- | libraries/evas/src/modules/loaders/tga/evas_image_load_tga.c | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/loaders/tga/evas_image_load_tga.c b/libraries/evas/src/modules/loaders/tga/evas_image_load_tga.c new file mode 100644 index 0000000..61b99f6 --- /dev/null +++ b/libraries/evas/src/modules/loaders/tga/evas_image_load_tga.c | |||
@@ -0,0 +1,596 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <sys/types.h> | ||
7 | #include <fcntl.h> | ||
8 | |||
9 | #ifdef HAVE_EVIL | ||
10 | # include <Evil.h> | ||
11 | #endif | ||
12 | |||
13 | #include "evas_common.h" | ||
14 | #include "evas_private.h" | ||
15 | |||
16 | /* TGA pixel formats */ | ||
17 | #define TGA_TYPE_MAPPED 1 // handle | ||
18 | #define TGA_TYPE_COLOR 2 | ||
19 | #define TGA_TYPE_GRAY 3 | ||
20 | #define TGA_TYPE_MAPPED_RLE 9 // handle | ||
21 | #define TGA_TYPE_COLOR_RLE 10 | ||
22 | #define TGA_TYPE_GRAY_RLE 11 | ||
23 | |||
24 | /* TGA header flags */ | ||
25 | #define TGA_DESC_ABITS 0x0f | ||
26 | #define TGA_DESC_HORIZONTAL 0x10 | ||
27 | #define TGA_DESC_VERTICAL 0x20 | ||
28 | |||
29 | #define TGA_SIGNATURE "TRUEVISION-XFILE" | ||
30 | |||
31 | typedef struct _tga_header tga_header; | ||
32 | typedef struct _tga_footer tga_footer; | ||
33 | |||
34 | struct _tga_header | ||
35 | { | ||
36 | unsigned char idLength; | ||
37 | unsigned char colorMapType; | ||
38 | unsigned char imageType; | ||
39 | unsigned char colorMapIndexLo, colorMapIndexHi; | ||
40 | unsigned char colorMapLengthLo, colorMapLengthHi; | ||
41 | unsigned char colorMapSize; | ||
42 | unsigned char xOriginLo, xOriginHi; | ||
43 | unsigned char yOriginLo, yOriginHi; | ||
44 | unsigned char widthLo, widthHi; | ||
45 | unsigned char heightLo, heightHi; | ||
46 | unsigned char bpp; | ||
47 | unsigned char descriptor; | ||
48 | } __attribute__((packed)); | ||
49 | |||
50 | struct _tga_footer | ||
51 | { | ||
52 | unsigned int extensionAreaOffset; | ||
53 | unsigned int developerDirectoryOffset; | ||
54 | char signature[16]; | ||
55 | char dot; | ||
56 | char null; | ||
57 | } __attribute__((packed)); | ||
58 | |||
59 | |||
60 | static Eina_Bool evas_image_load_file_head_tga(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); | ||
61 | static Eina_Bool evas_image_load_file_data_tga(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4); | ||
62 | |||
63 | static Evas_Image_Load_Func evas_image_load_tga_func = | ||
64 | { | ||
65 | EINA_TRUE, | ||
66 | evas_image_load_file_head_tga, | ||
67 | evas_image_load_file_data_tga, | ||
68 | NULL | ||
69 | }; | ||
70 | |||
71 | static Eina_Bool | ||
72 | evas_image_load_file_head_tga(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error) | ||
73 | { | ||
74 | Eina_File *f; | ||
75 | unsigned char *seg = NULL, *filedata; | ||
76 | tga_header *header; | ||
77 | tga_footer *footer, tfooter; | ||
78 | char hasa = 0, footer_present = 0, vinverted = 0; | ||
79 | int w = 0, h = 0, bpp; | ||
80 | int x, y; | ||
81 | int abits; | ||
82 | |||
83 | f = eina_file_open(file, EINA_FALSE); | ||
84 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; | ||
85 | if (f == NULL) return EINA_FALSE; | ||
86 | |||
87 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | ||
88 | if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer))) | ||
89 | goto close_file; | ||
90 | seg = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); | ||
91 | if (seg == NULL) goto close_file; | ||
92 | filedata = seg; | ||
93 | |||
94 | header = (tga_header *)filedata; | ||
95 | // no unaligned data accessed, so ok | ||
96 | footer = (tga_footer *)(filedata + (eina_file_size_get(f) - sizeof(tga_footer))); | ||
97 | memcpy((unsigned char *)(&tfooter), | ||
98 | (unsigned char *)footer, | ||
99 | sizeof(tga_footer)); | ||
100 | printf("0\n"); | ||
101 | if (!memcmp(tfooter.signature, TGA_SIGNATURE, sizeof(tfooter.signature))) | ||
102 | { | ||
103 | if ((tfooter.dot == '.') && (tfooter.null == 0)) | ||
104 | { | ||
105 | // footer is there and matches. this is a tga file - any problems now | ||
106 | // are a corrupt file | ||
107 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | ||
108 | footer_present = 1; | ||
109 | } | ||
110 | } | ||
111 | // else goto close_file; | ||
112 | printf("1\n"); | ||
113 | |||
114 | filedata = (unsigned char *)filedata + sizeof(tga_header); | ||
115 | vinverted = !(header->descriptor & TGA_DESC_VERTICAL); | ||
116 | switch (header->imageType) | ||
117 | { | ||
118 | case TGA_TYPE_COLOR_RLE: | ||
119 | case TGA_TYPE_GRAY_RLE: | ||
120 | // rle = 1; | ||
121 | break; | ||
122 | case TGA_TYPE_COLOR: | ||
123 | case TGA_TYPE_GRAY: | ||
124 | // rle = 0; | ||
125 | break; | ||
126 | default: | ||
127 | goto close_file; | ||
128 | } | ||
129 | bpp = header->bpp; | ||
130 | if (!((bpp == 32) || (bpp == 24) || (bpp == 16) || (bpp == 8))) | ||
131 | goto close_file; | ||
132 | if ((bpp == 32) && (header->descriptor & TGA_DESC_ABITS)) hasa = 1; | ||
133 | abits = header->descriptor & TGA_DESC_ABITS; | ||
134 | // don't handle colormapped images | ||
135 | if ((header->colorMapType) != 0) | ||
136 | goto close_file; | ||
137 | // if colormap size is anything other than legal sizes or 0 - not real tga | ||
138 | if (!((header->colorMapSize == 0) || | ||
139 | (header->colorMapSize == 15) || | ||
140 | (header->colorMapSize == 16) || | ||
141 | (header->colorMapSize == 24) || | ||
142 | (header->colorMapSize == 32))) | ||
143 | goto close_file; | ||
144 | x = (header->xOriginHi << 8) | (header->xOriginLo); | ||
145 | y = (header->yOriginHi << 8) | (header->yOriginLo); | ||
146 | w = (header->widthHi << 8) | header->widthLo; | ||
147 | h = (header->heightHi << 8) | header->heightLo; | ||
148 | // x origin gerater that width, y origin greater than height - wrong file | ||
149 | if ((x >= w) || (y >= h)) | ||
150 | goto close_file; | ||
151 | // if descriptor has either of the top 2 bits set... not tga | ||
152 | if (header->descriptor & 0xc0) | ||
153 | goto close_file; | ||
154 | |||
155 | if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || | ||
156 | IMG_TOO_BIG(w, h)) | ||
157 | goto close_file; | ||
158 | |||
159 | ie->w = w; | ||
160 | ie->h = h; | ||
161 | if (hasa) ie->flags.alpha = 1; | ||
162 | |||
163 | eina_file_map_free(f, seg); | ||
164 | eina_file_close(f); | ||
165 | *error = EVAS_LOAD_ERROR_NONE; | ||
166 | return EINA_TRUE; | ||
167 | |||
168 | close_file: | ||
169 | if (seg != NULL) eina_file_map_free(f, seg); | ||
170 | eina_file_close(f); | ||
171 | return EINA_FALSE; | ||
172 | } | ||
173 | |||
174 | static Eina_Bool | ||
175 | evas_image_load_file_data_tga(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error) | ||
176 | { | ||
177 | Eina_File *f; | ||
178 | unsigned char *seg = NULL, *filedata; | ||
179 | tga_header *header; | ||
180 | tga_footer *footer, tfooter; | ||
181 | char hasa = 0, footer_present = 0, vinverted = 0, rle = 0; | ||
182 | int w = 0, h = 0, x, y, bpp; | ||
183 | off_t size; | ||
184 | unsigned int *surface, *dataptr; | ||
185 | unsigned int datasize; | ||
186 | unsigned char *bufptr, *bufend; | ||
187 | int abits; | ||
188 | |||
189 | f = eina_file_open(file, EINA_FALSE); | ||
190 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; | ||
191 | if (f == NULL) return EINA_FALSE; | ||
192 | |||
193 | *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | ||
194 | if (eina_file_size_get(f) < (off_t)(sizeof(tga_header) + sizeof(tga_footer))) | ||
195 | goto close_file; | ||
196 | seg = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); | ||
197 | if (seg == NULL) goto close_file; | ||
198 | filedata = seg; | ||
199 | size = eina_file_size_get(f); | ||
200 | |||
201 | header = (tga_header *)filedata; | ||
202 | // no unaligned data accessed, so ok | ||
203 | footer = (tga_footer *)(filedata + (size - sizeof(tga_footer))); | ||
204 | memcpy((unsigned char *)&tfooter, | ||
205 | (unsigned char *)footer, | ||
206 | sizeof(tga_footer)); | ||
207 | if (!memcmp(tfooter.signature, TGA_SIGNATURE, sizeof(tfooter.signature))) | ||
208 | { | ||
209 | if ((tfooter.dot == '.') && (tfooter.null == 0)) | ||
210 | { | ||
211 | // footer is there and matches. this is a tga file - any problems now | ||
212 | // are a corrupt file | ||
213 | *error = EVAS_LOAD_ERROR_CORRUPT_FILE; | ||
214 | footer_present = 1; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | filedata = (unsigned char *)filedata + sizeof(tga_header); | ||
219 | vinverted = !(header->descriptor & TGA_DESC_VERTICAL); | ||
220 | switch (header->imageType) | ||
221 | { | ||
222 | case TGA_TYPE_COLOR_RLE: | ||
223 | case TGA_TYPE_GRAY_RLE: | ||
224 | rle = 1; | ||
225 | break; | ||
226 | case TGA_TYPE_COLOR: | ||
227 | case TGA_TYPE_GRAY: | ||
228 | rle = 0; | ||
229 | break; | ||
230 | default: | ||
231 | goto close_file; | ||
232 | } | ||
233 | bpp = header->bpp; | ||
234 | if (!((bpp == 32) || (bpp == 24) || (bpp == 16) || (bpp == 8))) | ||
235 | goto close_file; | ||
236 | if ((bpp == 32) && (header->descriptor & TGA_DESC_ABITS)) hasa = 1; | ||
237 | abits = header->descriptor & TGA_DESC_ABITS; | ||
238 | // don't handle colormapped images | ||
239 | if ((header->colorMapType) != 0) | ||
240 | goto close_file; | ||
241 | // if colormap size is anything other than legal sizes or 0 - not real tga | ||
242 | if (!((header->colorMapSize == 0) || | ||
243 | (header->colorMapSize == 15) || | ||
244 | (header->colorMapSize == 16) || | ||
245 | (header->colorMapSize == 24) || | ||
246 | (header->colorMapSize == 32))) | ||
247 | goto close_file; | ||
248 | x = (header->xOriginHi << 8) | (header->xOriginLo); | ||
249 | y = (header->yOriginHi << 8) | (header->yOriginLo); | ||
250 | w = (header->widthHi << 8) | header->widthLo; | ||
251 | h = (header->heightHi << 8) | header->heightLo; | ||
252 | // x origin gerater that width, y origin greater than height - wrong file | ||
253 | if ((x >= w) || (y >= h)) | ||
254 | goto close_file; | ||
255 | // if descriptor has either of the top 2 bits set... not tga | ||
256 | if (header->descriptor & 0xc0) | ||
257 | goto close_file; | ||
258 | |||
259 | if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || | ||
260 | IMG_TOO_BIG(w, h)) | ||
261 | goto close_file; | ||
262 | |||
263 | if ((w != (int)ie->w) || (h != (int)ie->h)) | ||
264 | { | ||
265 | *error = EVAS_LOAD_ERROR_GENERIC; | ||
266 | goto close_file; | ||
267 | } | ||
268 | evas_cache_image_surface_alloc(ie, w, h); | ||
269 | surface = evas_cache_image_pixels(ie); | ||
270 | if (!surface) | ||
271 | { | ||
272 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | ||
273 | goto close_file; | ||
274 | } | ||
275 | |||
276 | datasize = size - sizeof(tga_header) - header->idLength; | ||
277 | if (footer_present) | ||
278 | datasize = size - sizeof(tga_header) - header->idLength - | ||
279 | sizeof(tga_footer); | ||
280 | |||
281 | bufptr = filedata + header->idLength; | ||
282 | bufend = filedata + datasize; | ||
283 | |||
284 | if (!rle) | ||
285 | { | ||
286 | for (y = 0; y < h; y++) | ||
287 | { | ||
288 | if (vinverted) | ||
289 | /* some TGA's are stored upside-down! */ | ||
290 | dataptr = surface + ((h - y - 1) * w); | ||
291 | else | ||
292 | dataptr = surface + (y * w); | ||
293 | switch (bpp) | ||
294 | { | ||
295 | case 32: | ||
296 | for (x = 0; (x < w) && ((bufptr + 4) <= bufend); x++) | ||
297 | { | ||
298 | if (hasa) | ||
299 | { | ||
300 | int a = bufptr[3]; | ||
301 | |||
302 | switch (abits) | ||
303 | { | ||
304 | case 1: | ||
305 | a = (a << 7) | (a << 6) | (a << 5) | (a << 4) | (a << 3) | (a << 2) | (a << 1) | (a); | ||
306 | case 2: | ||
307 | a = (a << 6) | (a << 4) | (a << 2) | (a); | ||
308 | case 3: | ||
309 | a = (a << 5) | (a << 2) | (a >> 1); | ||
310 | case 4: | ||
311 | a = (a << 4) | (a); | ||
312 | case 5: | ||
313 | a = (a << 3) | (a >> 2); | ||
314 | case 6: | ||
315 | a = (a << 2) | (a >> 4); | ||
316 | case 7: | ||
317 | a = (a << 1) | (a >> 6); | ||
318 | default: | ||
319 | break; | ||
320 | } | ||
321 | *dataptr = ARGB_JOIN(a, bufptr[2], bufptr[1], bufptr[0]); | ||
322 | } | ||
323 | else | ||
324 | *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]); | ||
325 | dataptr++; | ||
326 | bufptr += 4; | ||
327 | } | ||
328 | break; | ||
329 | case 24: | ||
330 | for (x = 0; (x < w) && ((bufptr + 3) <= bufend); x++) | ||
331 | { | ||
332 | *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]); | ||
333 | dataptr++; | ||
334 | bufptr += 3; | ||
335 | } | ||
336 | break; | ||
337 | case 16: | ||
338 | for (x = 0; (x < w) && ((bufptr + 3) <= bufend); x++) | ||
339 | { | ||
340 | unsigned char r, g, b, a; | ||
341 | unsigned short tmp; | ||
342 | |||
343 | tmp = | ||
344 | (((unsigned short)bufptr[1]) << 8) | | ||
345 | (((unsigned short)bufptr[0])); | ||
346 | r = (tmp >> 7) & 0xf8; r |= r >> 5; | ||
347 | g = (tmp >> 2) & 0xf8; g |= g >> 5; | ||
348 | b = (tmp << 3) & 0xf8; b |= b >> 5; | ||
349 | a = 0xff; | ||
350 | if ((hasa) && (tmp & 0x8000)) a = 0; | ||
351 | *dataptr = ARGB_JOIN(a, r, g, b); | ||
352 | dataptr++; | ||
353 | bufptr += 2; | ||
354 | } | ||
355 | break; | ||
356 | case 8: | ||
357 | for (x = 0; (x < w) && ((bufptr + 1) <= bufend); x++) | ||
358 | { | ||
359 | *dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[0], bufptr[0]); | ||
360 | dataptr++; | ||
361 | bufptr += 1; | ||
362 | } | ||
363 | break; | ||
364 | default: | ||
365 | break; | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | else | ||
370 | { | ||
371 | int count, i; | ||
372 | unsigned char val; | ||
373 | unsigned int *dataend; | ||
374 | |||
375 | dataptr = surface; | ||
376 | dataend = dataptr + (w * h); | ||
377 | while ((bufptr < bufend) && (dataptr < dataend)) | ||
378 | { | ||
379 | val = *bufptr; | ||
380 | bufptr++; | ||
381 | count = (val & 0x7f) + 1; | ||
382 | if (val & 0x80) // rel packet | ||
383 | { | ||
384 | switch (bpp) | ||
385 | { | ||
386 | case 32: | ||
387 | if (bufptr < (bufend - 4)) | ||
388 | { | ||
389 | unsigned char r, g, b; | ||
390 | int a = bufptr[3]; | ||
391 | |||
392 | switch (abits) | ||
393 | { | ||
394 | case 1: | ||
395 | a = (a << 7) | (a << 6) | (a << 5) | (a << 4) | (a << 3) | (a << 2) | (a << 1) | (a); | ||
396 | case 2: | ||
397 | a = (a << 6) | (a << 4) | (a << 2) | (a); | ||
398 | case 3: | ||
399 | a = (a << 5) | (a << 2) | (a >> 1); | ||
400 | case 4: | ||
401 | a = (a << 4) | (a); | ||
402 | case 5: | ||
403 | a = (a << 3) | (a >> 2); | ||
404 | case 6: | ||
405 | a = (a << 2) | (a >> 4); | ||
406 | case 7: | ||
407 | a = (a << 1) | (a >> 6); | ||
408 | default: | ||
409 | break; | ||
410 | } | ||
411 | r = bufptr[2]; | ||
412 | g = bufptr[1]; | ||
413 | b = bufptr[0]; | ||
414 | if (!hasa) a = 0xff; | ||
415 | bufptr += 4; | ||
416 | for (i = 0; (i < count) && (dataptr < dataend); i++) | ||
417 | { | ||
418 | *dataptr = ARGB_JOIN(a, r, g, b); | ||
419 | dataptr++; | ||
420 | } | ||
421 | } | ||
422 | break; | ||
423 | case 24: | ||
424 | if (bufptr < (bufend - 3)) | ||
425 | { | ||
426 | unsigned char r, g, b; | ||
427 | |||
428 | r = bufptr[2]; | ||
429 | g = bufptr[1]; | ||
430 | b = bufptr[0]; | ||
431 | bufptr += 3; | ||
432 | for (i = 0; (i < count) && (dataptr < dataend); i++) | ||
433 | { | ||
434 | *dataptr = ARGB_JOIN(0xff, r, g, b); | ||
435 | dataptr++; | ||
436 | } | ||
437 | } | ||
438 | break; | ||
439 | case 16: | ||
440 | if (bufptr < (bufend - 2)) | ||
441 | { | ||
442 | unsigned char r, g, b, a; | ||
443 | unsigned short tmp; | ||
444 | |||
445 | tmp = | ||
446 | (((unsigned short)bufptr[1]) << 8) | | ||
447 | (((unsigned short)bufptr[0])); | ||
448 | r = (tmp >> 7) & 0xf8; r |= r >> 5; | ||
449 | g = (tmp >> 2) & 0xf8; g |= g >> 5; | ||
450 | b = (tmp << 3) & 0xf8; b |= b >> 5; | ||
451 | a = 0xff; | ||
452 | if ((hasa) && (tmp & 0x8000)) a = 0; | ||
453 | bufptr += 2; | ||
454 | for (i = 0; (i < count) && (dataptr < dataend); i++) | ||
455 | { | ||
456 | *dataptr = ARGB_JOIN(a, r, g, b); | ||
457 | dataptr++; | ||
458 | } | ||
459 | } | ||
460 | break; | ||
461 | case 8: | ||
462 | if (bufptr < (bufend - 1)) | ||
463 | { | ||
464 | unsigned char g; | ||
465 | |||
466 | g = bufptr[0]; | ||
467 | bufptr += 1; | ||
468 | for (i = 0; (i < count) && (dataptr < dataend); i++) | ||
469 | { | ||
470 | *dataptr = ARGB_JOIN(0xff, g, g, g); | ||
471 | dataptr++; | ||
472 | } | ||
473 | } | ||
474 | break; | ||
475 | default: | ||
476 | break; | ||
477 | } | ||
478 | } | ||
479 | else // raw | ||
480 | { | ||
481 | switch (bpp) | ||
482 | { | ||
483 | case 32: | ||
484 | for (i = 0; (i < count) && (bufptr < (bufend - 4)) && (dataptr < dataend); i++) | ||
485 | { | ||
486 | if (hasa) | ||
487 | // *dataptr = ARGB_JOIN(255 - bufptr[3], bufptr[2], bufptr[1], bufptr[0]); | ||
488 | *dataptr = ARGB_JOIN(bufptr[3], bufptr[2], bufptr[1], bufptr[0]); | ||
489 | else | ||
490 | *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]); | ||
491 | dataptr++; | ||
492 | bufptr += 4; | ||
493 | } | ||
494 | break; | ||
495 | case 24: | ||
496 | for (i = 0; (i < count) && (bufptr < (bufend - 3)) && (dataptr < dataend); i++) | ||
497 | { | ||
498 | *dataptr = ARGB_JOIN(0xff, bufptr[2], bufptr[1], bufptr[0]); | ||
499 | dataptr++; | ||
500 | bufptr += 3; | ||
501 | } | ||
502 | break; | ||
503 | case 16: | ||
504 | for (i = 0; (i < count) && (bufptr < (bufend - 2)) && (dataptr < dataend); i++) | ||
505 | { | ||
506 | unsigned char r, g, b, a; | ||
507 | unsigned short tmp; | ||
508 | |||
509 | tmp = | ||
510 | (((unsigned short)bufptr[1]) << 8) | | ||
511 | (((unsigned short)bufptr[0])); | ||
512 | r = (tmp >> 7) & 0xf8; r |= r >> 5; | ||
513 | g = (tmp >> 2) & 0xf8; g |= g >> 5; | ||
514 | b = (tmp << 3) & 0xf8; b |= b >> 5; | ||
515 | a = 0xff; | ||
516 | if ((hasa) && (tmp & 0x8000)) a = 0; | ||
517 | *dataptr = ARGB_JOIN(a, r, g, b); | ||
518 | dataptr++; | ||
519 | bufptr += 2; | ||
520 | } | ||
521 | break; | ||
522 | case 8: | ||
523 | for (i = 0; (i < count) && (bufptr < (bufend - 1)) && (dataptr < dataend); i++) | ||
524 | { | ||
525 | *dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[0], bufptr[0]); | ||
526 | dataptr++; | ||
527 | bufptr += 1; | ||
528 | } | ||
529 | break; | ||
530 | default: | ||
531 | break; | ||
532 | } | ||
533 | } | ||
534 | } | ||
535 | if (vinverted) | ||
536 | { | ||
537 | unsigned int *adv, *adv2, tmp; | ||
538 | |||
539 | adv = surface; | ||
540 | adv2 = surface + (w * (h - 1)); | ||
541 | for (y = 0; y < (h / 2); y++) | ||
542 | { | ||
543 | for (x = 0; x < w; x++) | ||
544 | { | ||
545 | tmp = adv[x]; | ||
546 | adv[x] = adv2[x]; | ||
547 | adv2[x] = tmp; | ||
548 | } | ||
549 | adv2 -= w; | ||
550 | adv += w; | ||
551 | } | ||
552 | } | ||
553 | } | ||
554 | |||
555 | evas_common_image_premul(ie); | ||
556 | |||
557 | eina_file_map_free(f, seg); | ||
558 | eina_file_close(f); | ||
559 | *error = EVAS_LOAD_ERROR_NONE; | ||
560 | return EINA_TRUE; | ||
561 | |||
562 | close_file: | ||
563 | if (seg != NULL) eina_file_map_free(f, seg); | ||
564 | eina_file_close(f); | ||
565 | return EINA_FALSE; | ||
566 | } | ||
567 | |||
568 | static int | ||
569 | module_open(Evas_Module *em) | ||
570 | { | ||
571 | if (!em) return 0; | ||
572 | em->functions = (void *)(&evas_image_load_tga_func); | ||
573 | return 1; | ||
574 | } | ||
575 | |||
576 | static void | ||
577 | module_close(Evas_Module *em __UNUSED__) | ||
578 | { | ||
579 | } | ||
580 | |||
581 | static Evas_Module_Api evas_modapi = | ||
582 | { | ||
583 | EVAS_MODULE_API_VERSION, | ||
584 | "tga", | ||
585 | "none", | ||
586 | { | ||
587 | module_open, | ||
588 | module_close | ||
589 | } | ||
590 | }; | ||
591 | |||
592 | EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, tga); | ||
593 | |||
594 | #ifndef EVAS_STATIC_BUILD_TGA | ||
595 | EVAS_EINA_MODULE_DEFINE(image_loader, tga); | ||
596 | #endif | ||