]> git.saurik.com Git - wxWidgets.git/blob - src/gdk_imlib/load.c
One that got away
[wxWidgets.git] / src / gdk_imlib / load.c
1
2 #define _GNU_SOURCE
3 #include "../gdk_imlib/config.h"
4
5 #include "../gdk_imlib/gdk_imlib.h"
6 #include "../gdk_imlib/gdk_imlib_private.h"
7
8 /* Split the ID - damages input */
9
10 static char *
11 g_SplitID(char *file)
12 {
13 char *p = strrchr(file, ':');
14
15 if (p == NULL)
16 return "";
17 else
18 {
19 *p++ = 0;
20 return p;
21 }
22 }
23
24 /*
25 * Doesn't damage the input
26 */
27
28 char *
29 g_GetExtension(char *file)
30 {
31 char *p = strrchr(file, '.');
32
33 if (p == NULL)
34 return "";
35 else
36 return p + 1;
37 }
38
39 #ifdef HAVE_LIBJPEG
40 unsigned char *
41 g_LoadJPEG(FILE * f, int *w, int *h)
42 {
43 struct jpeg_decompress_struct cinfo;
44 struct jpeg_error_mgr jerr;
45 unsigned char *data, *line[16], *ptr;
46 int x, y, i;
47
48 cinfo.err = jpeg_std_error(&jerr);
49 jpeg_create_decompress(&cinfo);
50 jpeg_stdio_src(&cinfo, f);
51 jpeg_read_header(&cinfo, TRUE);
52 cinfo.do_fancy_upsampling = FALSE;
53 cinfo.do_block_smoothing = FALSE;
54 jpeg_start_decompress(&cinfo);
55 *w = cinfo.output_width;
56 *h = cinfo.output_height;
57 data = malloc(*w ** h * 3);
58 if (!data)
59 {
60 jpeg_destroy_decompress(&cinfo);
61 return NULL;
62 }
63 ptr = data;
64
65 if (cinfo.rec_outbuf_height > 16)
66 {
67 fprintf(stderr, "gdk_imlib ERROR: JPEG uses line buffers > 16. Cannot load.\n");
68 return NULL;
69 }
70 if (cinfo.output_components == 3)
71 {
72 for (y = 0; y < *h; y += cinfo.rec_outbuf_height)
73 {
74 for (i = 0; i < cinfo.rec_outbuf_height; i++)
75 {
76 line[i] = ptr;
77 ptr += *w * 3;
78 }
79 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
80 }
81 }
82 else if (cinfo.output_components == 1)
83 {
84 for (i = 0; i < cinfo.rec_outbuf_height; i++)
85 {
86 if ((line[i] = malloc(*w)) == NULL)
87 {
88 int t = 0;
89
90 for (t = 0; t < i; t++)
91 free(line[t]);
92 jpeg_destroy_decompress(&cinfo);
93 return NULL;
94 }
95 }
96 for (y = 0; y < *h; y += cinfo.rec_outbuf_height)
97 {
98 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
99 for (i = 0; i < cinfo.rec_outbuf_height; i++)
100 {
101 for (x = 0; x < *w; x++)
102 {
103 *ptr++ = line[i][x];
104 *ptr++ = line[i][x];
105 *ptr++ = line[i][x];
106 }
107 }
108 }
109 for (i = 0; i < cinfo.rec_outbuf_height; i++)
110 free(line[i]);
111 }
112 jpeg_finish_decompress(&cinfo);
113 jpeg_destroy_decompress(&cinfo);
114 return data;
115 }
116 #endif /* HAVE_LIBJPEG */
117
118 #ifdef HAVE_LIBPNG
119 unsigned char *
120 g_LoadPNG(FILE * f, int *w, int *h, int *t)
121 {
122 png_structp png_ptr;
123 png_infop info_ptr;
124 unsigned char *data, *ptr, **lines, *ptr2, r, g, b, a;
125 int i, x, y, transp, bit_depth, color_type, interlace_type;
126 png_uint_32 *ww, *hh;
127
128 /* Init PNG Reader */
129 transp = 0;
130 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
131 if (!png_ptr)
132 return NULL;
133
134 info_ptr = png_create_info_struct(png_ptr);
135 if (!info_ptr)
136 {
137 png_destroy_read_struct(&png_ptr, NULL, NULL);
138 return NULL;
139 }
140
141 if (setjmp(png_ptr->jmpbuf))
142 {
143 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
144 return NULL;
145 }
146
147 if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
148 {
149 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
150 return NULL;
151 }
152 png_init_io(png_ptr, f);
153 /* Read Header */
154 png_read_info(png_ptr, info_ptr);
155 ww = (png_uint_32 *) w;
156 hh = (png_uint_32 *) h;
157 png_get_IHDR(png_ptr, info_ptr, ww, hh, &bit_depth, &color_type, &interlace_type,
158 NULL, NULL);
159 /* Setup Translators */
160 if (color_type == PNG_COLOR_TYPE_PALETTE)
161 png_set_expand(png_ptr);
162 png_set_strip_16(png_ptr);
163 png_set_packing(png_ptr);
164 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
165 png_set_expand(png_ptr);
166 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
167 *w = info_ptr->width;
168 *h = info_ptr->height;
169 data = malloc(*w ** h * 3);
170 if (!data)
171 {
172 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
173 return NULL;
174 }
175 lines = (unsigned char **)malloc(*h * sizeof(unsigned char *));
176
177 if (lines == NULL)
178 {
179 free(data);
180 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
181 return NULL;
182 }
183 for (i = 0; i < *h; i++)
184 {
185 if ((lines[i] = malloc(*w * (sizeof(unsigned char) * 4))) == NULL)
186 {
187 int n;
188
189 free(data);
190 for (n = 0; n < i; n++)
191 free(lines[n]);
192 free(lines);
193 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
194 return NULL;
195 }
196 }
197 png_read_image(png_ptr, lines);
198 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
199 ptr = data;
200 if (color_type == PNG_COLOR_TYPE_GRAY)
201 {
202 for (y = 0; y < *h; y++)
203 {
204 ptr2 = lines[y];
205 for (x = 0; x < *w; x++)
206 {
207 r = *ptr2++;
208 *ptr++ = r;
209 *ptr++ = r;
210 *ptr++ = r;
211 }
212 }
213 }
214 else
215 {
216 for (y = 0; y < *h; y++)
217 {
218 ptr2 = lines[y];
219 for (x = 0; x < *w; x++)
220 {
221 r = *ptr2++;
222 g = *ptr2++;
223 b = *ptr2++;
224 a = *ptr2++;
225 if (a < 128)
226 {
227 *ptr++ = 255;
228 *ptr++ = 0;
229 *ptr++ = 255;
230 transp = 1;
231 }
232 else
233 {
234 if ((r == 255) && (g == 0) && (b == 255))
235 r = 254;
236 *ptr++ = r;
237 *ptr++ = g;
238 *ptr++ = b;
239 }
240 }
241 }
242 }
243 for (i = 0; i < *h; i++)
244 free(lines[i]);
245 free(lines);
246 *t = transp;
247 return data;
248 }
249 #endif /* HAVE_LIBPNG */
250
251 #ifdef HAVE_LIBTIFF
252 unsigned char *
253 g_LoadTIFF(char *f, int *w, int *h, int *t)
254 {
255 TIFF *tif;
256 unsigned char *data, *ptr, r, g, b, a;
257 int x, y;
258 uint32 ww, hh, *rast, *tptr;
259 size_t npix;
260 int istransp;
261
262 istransp = 0;
263 if (!f)
264 return NULL;
265
266 tif = TIFFOpen(f, "r");
267 if (!tif)
268 return NULL;
269
270 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &ww);
271 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &hh);
272 npix = ww * hh;
273 *w = (int)ww;
274 *h = (int)hh;
275 rast = (uint32 *) _TIFFmalloc(npix * sizeof(uint32));
276 if (!rast)
277 {
278 TIFFClose(tif);
279 return NULL;
280 }
281 data = NULL;
282 if (TIFFReadRGBAImage(tif, ww, hh, rast, 0))
283 {
284 data = (unsigned char *)malloc(*w ** h * 3);
285 if (!data)
286 {
287 _TIFFfree(rast);
288 TIFFClose(tif);
289 return NULL;
290 }
291 ptr = data;
292 for (y = 0; y < *h; y++)
293 {
294 tptr = rast;
295 tptr += ((*h - y - 1) ** w);
296 for (x = 0; x < *w; x++)
297 {
298 a = TIFFGetA(*tptr);
299 b = TIFFGetB(*tptr);
300 g = TIFFGetG(*tptr);
301 r = TIFFGetR(*tptr);
302 tptr++;
303 if (a < 128)
304 {
305 *ptr++ = 255;
306 *ptr++ = 0;
307 *ptr++ = 255;
308 istransp = 1;
309 }
310 else
311 {
312 if ((r == 255) && (g == 0) && (b == 255))
313 r = 254;
314 *ptr++ = r;
315 *ptr++ = g;
316 *ptr++ = b;
317 }
318 }
319 }
320 }
321 _TIFFfree(rast);
322 TIFFClose(tif);
323 *t = istransp;
324 return data;
325 }
326
327 #endif /* HAVE_LIBTIFF */
328
329 #ifdef HAVE_LIBGIF
330 unsigned char *
331 g_LoadGIF(char *f, int *w, int *h, int *t)
332 {
333 unsigned char *data, *ptr;
334 GifFileType *gif;
335 GifRowType *rows;
336 GifRecordType rec;
337 ColorMapObject *cmap;
338 int i, j, done, bg, csize, r, g, b;
339 int intoffset[] =
340 {0, 4, 2, 1};
341 int intjump[] =
342 {8, 8, 4, 2};
343 int istransp, transp;
344
345 done = 0;
346 istransp = 0;
347 gif = DGifOpenFileName(f);
348 if (!gif)
349 return NULL;
350
351 do
352 {
353 DGifGetRecordType(gif, &rec);
354 if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
355 {
356 DGifGetImageDesc(gif);
357 *w = gif->Image.Width;
358 *h = gif->Image.Height;
359 rows = malloc(*h * sizeof(GifRowType *));
360 if (!rows)
361 {
362 DGifCloseFile(gif);
363 return NULL;
364 }
365 data = malloc(*w ** h * 3);
366 if (!data)
367 {
368 DGifCloseFile(gif);
369 free(rows);
370 return NULL;
371 }
372 for (i = 0; i < *h; i++)
373 rows[i] = NULL;
374 for (i = 0; i < *h; i++)
375 {
376 rows[i] = malloc(*w * sizeof(GifPixelType));
377 if (!rows[i])
378 {
379 DGifCloseFile(gif);
380 for (i = 0; i < *h; i++)
381 if (rows[i])
382 free(rows[i]);
383 free(rows);
384 free(data);
385 return NULL;
386 }
387 }
388 if (gif->Image.Interlace)
389 {
390 for (i = 0; i < 4; i++)
391 {
392 for (j = intoffset[i]; j < *h; j += intjump[i])
393 DGifGetLine(gif, rows[j], *w);
394 }
395 }
396 else
397 {
398 for (i = 0; i < *h; i++)
399 DGifGetLine(gif, rows[i], *w);
400 }
401 done = 1;
402 }
403 else if (rec == EXTENSION_RECORD_TYPE)
404 {
405 int ext_code;
406 GifByteType *ext;
407
408 DGifGetExtension(gif, &ext_code, &ext);
409 if (ext)
410 {
411 if ((ext[1] & 1))
412 {
413 istransp = 1;
414 transp = (int)ext[4];
415 }
416 }
417 do
418 {
419 DGifGetExtensionNext(gif, &ext);
420 }
421 while (ext);
422 }
423 }
424 while (rec != TERMINATE_RECORD_TYPE);
425 bg = gif->SBackGroundColor;
426 cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
427 csize = cmap->ColorCount;
428 ptr = data;
429 if (!istransp)
430 {
431 for (i = 0; i < *h; i++)
432 {
433 for (j = 0; j < *w; j++)
434 {
435 r = cmap->Colors[rows[i][j]].Red;
436 g = cmap->Colors[rows[i][j]].Green;
437 b = cmap->Colors[rows[i][j]].Blue;
438 *ptr++ = r;
439 *ptr++ = g;
440 *ptr++ = b;
441 }
442 }
443 }
444 else
445 {
446 for (i = 0; i < *h; i++)
447 {
448 for (j = 0; j < *w; j++)
449 {
450 if (rows[i][j] == transp)
451 {
452 *ptr++ = 255;
453 *ptr++ = 0;
454 *ptr++ = 255;
455 }
456 else
457 {
458 r = cmap->Colors[rows[i][j]].Red;
459 g = cmap->Colors[rows[i][j]].Green;
460 b = cmap->Colors[rows[i][j]].Blue;
461 if (r == 255 && g == 0 && b == 255)
462 r = 254;
463 *ptr++ = r;
464 *ptr++ = g;
465 *ptr++ = b;
466 }
467 }
468 }
469 }
470 DGifCloseFile(gif);
471 for (i = 0; i < *h; i++)
472 free(rows[i]);
473 free(rows);
474 *t = istransp;
475 return data;
476 }
477
478 #endif /* HAVE_LIBGIF */
479
480 unsigned char *
481 g_LoadXPM(char *f, int *w, int *h, int *t)
482 {
483 FILE *file;
484 unsigned char *data, *ptr;
485 int pc, c, i, j, k, ncolors, cpp, comment, transp, quote,
486 context, len, /*token,*/ done;
487 char line[65536], s[65536], tok[65536], col[65536];
488 XColor xcol;
489 struct _cmap
490 {
491 char str[8];
492 char transp;
493 int r, g, b;
494 }
495 *cmap;
496 int lookup[128][128];
497
498 i = 0;
499 j = 0;
500
501 transp = 0;
502 done = 0;
503 cmap = NULL;
504
505 file = fopen(f, "r");
506 if (!file)
507 return NULL;
508
509 *w = 10;
510 *h = 10;
511
512 ptr = NULL;
513 data = NULL;
514 c = ' ';
515 comment = 0;
516 quote = 0;
517 context = 0;
518
519 while (!done)
520 {
521 pc = c;
522 c = fgetc(file);
523 if (c == EOF)
524 break;
525 if (!quote)
526 {
527 if (pc == '/' && c == '*')
528 comment = 1;
529 else if (pc == '*' && c == '/' && comment)
530 comment = 0;
531 }
532 if (!comment)
533 {
534 if (!quote && c == '"')
535 {
536 quote = 1;
537 i = 0;
538 }
539 else if (quote && c == '"')
540 {
541 line[i] = 0;
542 quote = 0;
543 if (context == 0)
544 {
545 /* Header */
546 sscanf(line, "%i %i %i %i", w, h, &ncolors, &cpp);
547 if (cpp > 7)
548 {
549 fprintf(stderr, "gdk_imlib ERROR: XPM files with characters per pixel > 7 not supported\n");
550 return NULL;
551 }
552 if (*w > 32767)
553 {
554 fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
555 return NULL;
556 }
557 if (*h > 32767)
558 {
559 fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
560 return NULL;
561 }
562 cmap = malloc(sizeof(struct _cmap) * ncolors);
563
564 if (!cmap)
565 return NULL;
566 data = malloc(*w ** h * 3);
567 if (!data)
568 {
569 free(cmap);
570 return NULL;
571 }
572 ptr = data;
573 j = 0;
574 context++;
575 }
576 else if (context == 1)
577 {
578 /* Color Table */
579 if (j < ncolors)
580 {
581 /* int colptr = 0; not used */
582 int slen;
583
584 tok[0] = 0;
585 col[0] = 0;
586 s[0] = 0;
587 len = strlen(line);
588 strncpy(cmap[j].str, line, cpp);
589 cmap[j].str[cpp] = 0;
590 cmap[j].r = -1;
591 cmap[j].transp = 0;
592 for (k = cpp; k < len; k++)
593 {
594 if (line[k] != ' ')
595 {
596 s[0] = 0;
597 sscanf(&line[k], "%65535s", s);
598 slen = strlen(s);
599 k += slen;
600 if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
601 (!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
602 (!strcmp(s, "c")) || (k >= len))
603 {
604 if (k >= len)
605 {
606 if (col[0])
607 strcat(col, " ");
608 strcat(col, s);
609 }
610 if (col[0])
611 {
612 if (!strcasecmp(col, "none"))
613 {
614 transp = 1;
615 cmap[j].transp = 1;
616 }
617 else
618 {
619 if ((cmap[j].r < 0) ||
620 (!strcmp(tok, "c")))
621 {
622 XParseColor(id->x.disp,
623 id->x.root_cmap,
624 col, &xcol);
625 cmap[j].r = xcol.red >> 8;
626 cmap[j].g = xcol.green >> 8;
627 cmap[j].b = xcol.blue >> 8;
628 if ((cmap[j].r == 255) &&
629 (cmap[j].g == 0) &&
630 (cmap[j].b == 255))
631 cmap[j].r = 254;
632 }
633 }
634 }
635 strcpy(tok, s);
636 col[0] = 0;
637 }
638 else
639 {
640 if (col[0])
641 strcat(col, " ");
642 strcat(col, s);
643 }
644 }
645 }
646 }
647 j++;
648 if (j >= ncolors)
649 {
650 if (cpp == 1)
651 for (i = 0; i < ncolors; i++)
652 lookup[(int)cmap[i].str[0]][(int)cmap[i].str[1]] = i;
653 if (cpp == 2)
654 for (i = 0; i < ncolors; i++)
655 lookup[(int)cmap[i].str[0]][(int)cmap[i].str[1]] = i;
656 context++;
657 }
658 }
659 else
660 {
661 /* Image Data */
662 i = 0;
663 if (cpp == 0)
664 {
665 /* Chars per pixel = 0? well u never know */
666 }
667 if (cpp == 1)
668 {
669 if (transp)
670 {
671 for (i = 0; ((i < 65536) && (line[i])); i++)
672 {
673 col[0] = line[i];
674 if (cmap[lookup[(int)col[0]][0]].transp)
675 {
676 *ptr++ = 255;
677 *ptr++ = 0;
678 *ptr++ = 255;
679 }
680 else
681 {
682 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].r;
683 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].g;
684 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].b;
685 }
686 }
687 }
688 else
689 {
690 for (i = 0; ((i < 65536) && (line[i])); i++)
691 {
692 col[0] = line[i];
693 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].r;
694 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].g;
695 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][0]].b;
696 }
697 }
698 }
699 else if (cpp == 2)
700 {
701 if (transp)
702 {
703 for (i = 0; ((i < 65536) && (line[i])); i++)
704 {
705 col[0] = line[i++];
706 col[1] = line[i];
707 if (cmap[lookup[(int)col[0]][(int)col[1]]].transp)
708 {
709 *ptr++ = 255;
710 *ptr++ = 0;
711 *ptr++ = 255;
712 }
713 else
714 {
715 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].r;
716 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].g;
717 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].b;
718 }
719 }
720 }
721 else
722 {
723 for (i = 0; ((i < 65536) && (line[i])); i++)
724 {
725 col[0] = line[i++];
726 col[1] = line[i];
727 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].r;
728 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].g;
729 *ptr++ = (unsigned char)cmap[lookup[(int)col[0]][(int)col[1]]].b;
730 }
731 }
732 }
733 else
734 {
735 if (transp)
736 {
737 for (i = 0; ((i < 65536) && (line[i])); i++)
738 {
739 for (j = 0; j < cpp; j++, i++)
740 {
741 col[j] = line[i];
742 }
743 col[j] = 0;
744 i--;
745 for (j = 0; j < ncolors; j++)
746 {
747 if (!strcmp(col, cmap[j].str))
748 {
749 if (cmap[j].transp)
750 {
751 *ptr++ = 255;
752 *ptr++ = 0;
753 *ptr++ = 255;
754 }
755 else
756 {
757 *ptr++ = (unsigned char)cmap[j].r;
758 *ptr++ = (unsigned char)cmap[j].g;
759 *ptr++ = (unsigned char)cmap[j].b;
760 }
761 j = ncolors;
762 }
763 }
764 }
765 }
766 else
767 {
768 for (i = 0; ((i < 65536) && (line[i])); i++)
769 {
770 for (j = 0; j < cpp; j++, i++)
771 {
772 col[j] = line[i];
773 }
774 col[j] = 0;
775 i--;
776 for (j = 0; j < ncolors; j++)
777 {
778 if (!strcmp(col, cmap[j].str))
779 {
780 *ptr++ = (unsigned char)cmap[j].r;
781 *ptr++ = (unsigned char)cmap[j].g;
782 *ptr++ = (unsigned char)cmap[j].b;
783 j = ncolors;
784 }
785 }
786 }
787 }
788 }
789 }
790 }
791 }
792 /* Scan in line from XPM file (limit line length 65k) */
793 if (i < 65536)
794 {
795 if ((!comment) && (quote) && (c != '"'))
796 {
797 line[i++] = c;
798 }
799 }
800 if ((ptr) && ((ptr - data) >= *w ** h * 3))
801 done = 1;
802 }
803 fclose(file);
804 if (transp)
805 *t = 1;
806 else
807 *t = 0;
808 free(cmap);
809 return data;
810 }
811
812 unsigned char *
813 g_LoadPPM(FILE * f, int *w, int *h)
814 {
815 int done;
816 unsigned char *ptr;
817 unsigned char chr;
818 char s[256];
819 int a, b;
820 int color, scale;
821
822 a = b = scale = 0;
823 fgets(s, 256, f);
824 s[strlen(s) - 1] = 0;
825
826 if (!strcmp(s, "P6"))
827 color = 1;
828 else if (!strcmp(s, "P5"))
829 color = 0;
830 else
831 return NULL;
832
833 done = 1;
834 ptr = NULL;
835 while (done)
836 {
837 if (fgets(s, 256, f) == NULL)
838 break;
839
840 s[strlen(s) - 1] = 0;
841 if (s[0] != '#')
842 {
843 done = 0;
844 sscanf(s, "%i %i", w, h);
845 a = *w;
846 b = *h;
847 if (a > 32767)
848 {
849 fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
850 return NULL;
851 }
852 if (b > 32767)
853 {
854 fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
855 return NULL;
856 }
857 fgets(s, 256, f);
858 sscanf(s, "%i", &scale);
859 s[strlen(s) - 1] = 0;
860 ptr = (unsigned char *)malloc(a * b * 3);
861 if (!ptr)
862 {
863 fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for RGB data in file");
864 return ptr;
865 }
866 if (color)
867 {
868 if (!fread(ptr, a * b * 3, 1, f))
869 {
870 free(ptr);
871 return NULL;
872 }
873 }
874 else
875 {
876 b = (a * b * 3);
877 a = 0;
878 while ((fread(&chr, 1, 1, f)) && (a < b))
879 {
880 ptr[a++] = chr;
881 ptr[a++] = chr;
882 ptr[a++] = chr;
883 }
884 }
885 }
886 }
887 if (scale == 0)
888 {
889 free(ptr);
890 return NULL;
891 }
892 if (scale < 255)
893 {
894 int rot;
895 unsigned char *po;
896
897 if (scale <= 1)
898 rot = 7;
899 else if (scale <= 3)
900 rot = 6;
901 else if (scale <= 7)
902 rot = 5;
903 else if (scale <= 15)
904 rot = 4;
905 else if (scale <= 31)
906 rot = 3;
907 else if (scale <= 63)
908 rot = 2;
909 else
910 rot = 1;
911
912 if (rot > 0)
913 {
914 po = ptr;
915 while (po < (ptr + (*w ** h * 3)))
916 {
917 *po++ <<= rot;
918 *po++ <<= rot;
919 *po++ <<= rot;
920 }
921 }
922 }
923 return ptr;
924 }
925
926 static int
927 gispnm(char *file)
928 {
929 FILE *f;
930 char buf[8];
931
932 f = fopen(file, "rb");
933 if (!f)
934 return 0;
935 fgets(buf, 8, f);
936 fclose(f);
937 if (!strcmp("P6\n", buf))
938 return 1;
939 if (!strcmp("P5\n", buf))
940 return 1;
941 return 0;
942 }
943
944 static int
945 gisjpeg(char *file)
946 {
947 FILE *f;
948 unsigned char buf[8];
949
950 f = fopen(file, "rb");
951 if (!f)
952 return 0;
953 fread(buf, 1, 2, f);
954 fclose(f);
955 if ((buf[0] == 0xff) && (buf[1] == 0xd8))
956 return 1;
957 return 0;
958 }
959
960 static int
961 gispng(char *file)
962 {
963 #ifdef HAVE_LIBPNG
964 FILE *f;
965 unsigned char buf[8];
966
967 f = fopen(file, "rb");
968 if (!f)
969 return 0;
970 fread(buf, 1, 8, f);
971 fclose(f);
972 return (int)png_check_sig(buf, 8);
973 #else
974 return 0;
975 #endif
976 }
977
978 static int
979 gistiff(char *file)
980 {
981 FILE *f;
982 char buf[8];
983
984 f = fopen(file, "rb");
985 if (!f)
986 return 0;
987 fgets(buf, 5, f);
988 fclose(f);
989 if ((buf[0] == 'M') && (buf[1] == 'M') && (buf[2] == 0x00) && (buf[3] == 0x2a))
990 return 1;
991 if ((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == 0x2a) && (buf[3] == 0x00))
992 return 1;
993 return 0;
994 }
995
996 static int
997 giseim(char *file)
998 {
999 FILE *f;
1000 char buf[8];
1001
1002 f = fopen(file, "rb");
1003 if (!f)
1004 return 0;
1005 fread(buf, 1, 4, f);
1006 fclose(f);
1007 if (!strncmp("EIM ", buf, 4))
1008 return 1;
1009 return 0;
1010 }
1011
1012 static int
1013 gisgif(char *file)
1014 {
1015 FILE *f;
1016 char buf[8];
1017
1018 f = fopen(file, "rb");
1019 if (!f)
1020 return 0;
1021 fread(buf, 1, 4, f);
1022 fclose(f);
1023 buf[4] = 0;
1024 if (!strcmp("GIF8", buf))
1025 return 1;
1026 return 0;
1027 }
1028
1029 static int
1030 gisxpm(char *file)
1031 {
1032 FILE *f;
1033 char buf[11];
1034
1035 f = fopen(file, "rb");
1036 if (!f)
1037 return 0;
1038 fread(buf, 1, 9, f);
1039 fclose(f);
1040 buf[9] = 0;
1041 if (!strcmp("/* XPM */", buf))
1042 return 1;
1043 return 0;
1044 }
1045
1046 GdkImlibImage *
1047 gdk_imlib_load_image(char *file)
1048 {
1049 int w, h;
1050 int needs_conv = 1;
1051 unsigned char *data;
1052 GdkImlibImage *im;
1053 char s[4096];
1054 char fil[4096];
1055 char *iden;
1056 char *e;
1057 char cmd[4096];
1058 FILE *p;
1059 int eim;
1060 int fmt;
1061 int trans;
1062
1063 eim = 0;
1064 fmt = 0;
1065 p = NULL;
1066 data = NULL;
1067
1068 if (!file)
1069 return NULL;
1070 if (id->cache.on_image)
1071 if ((im = gfind_image(file)))
1072 return im;
1073
1074 strncpy(fil, file, sizeof(fil));
1075 iden = g_SplitID(fil);
1076 e = g_GetExtension(fil);
1077
1078 if (gispnm(fil))
1079 {
1080 needs_conv = 0;
1081 fmt = 0;
1082 }
1083 else if (gisjpeg(fil))
1084 {
1085 #ifdef HAVE_LIBJPEG
1086 needs_conv = 0;
1087 fmt = 2;
1088 #else
1089 needs_conv = 1;
1090 fmt = 0;
1091 #endif
1092 }
1093 else if (gistiff(fil))
1094 {
1095 #ifdef HAVE_LIBTIFF
1096 needs_conv = 0;
1097 fmt = 3;
1098 #else
1099 needs_conv = 1;
1100 fmt = 0;
1101 #endif
1102 }
1103 else if (giseim(fil))
1104 {
1105 needs_conv = 0;
1106 eim = 1;
1107 fmt = 9999;
1108 }
1109 else if (gisxpm(fil))
1110 {
1111 needs_conv = 0;
1112 fmt = 5;
1113 }
1114 else if (gispng(fil))
1115 {
1116 #ifdef HAVE_LIBPNG
1117 needs_conv = 0;
1118 fmt = 1;
1119 #else
1120 needs_conv = 1;
1121 fmt = 0;
1122 #endif
1123 }
1124 else if (gisgif(fil))
1125 {
1126 #ifdef HAVE_LIBGIF
1127 needs_conv = 0;
1128 fmt = 4;
1129 #else
1130 needs_conv = 1;
1131 fmt = 0;
1132 #endif
1133 }
1134 if (needs_conv && id->fallback)
1135 {
1136 p = open_helper("%C/convert %s pnm:-", fil, "rb");
1137 }
1138 else if ((fmt == 2) || (fmt == 1) || (fmt == 0))
1139 p = fopen(fil, "rb");
1140
1141 trans = 0;
1142 if (!eim && !data)
1143 {
1144 switch (fmt)
1145 {
1146 case 5:
1147 data = g_LoadXPM(fil, &w, &h, &trans);
1148 break;
1149 #ifdef HAVE_LIBGIF
1150 case 4:
1151 data = g_LoadGIF(fil, &w, &h, &trans);
1152 break;
1153 #endif
1154 #ifdef HAVE_LIBTIFF
1155 case 3:
1156 data = g_LoadTIFF(fil, &w, &h, &trans);
1157 break;
1158 #endif
1159 #ifdef HAVE_LIBJPEG
1160 case 2:
1161 if (p)
1162 data = g_LoadJPEG(p, &w, &h);
1163 break;
1164 #endif
1165 #ifdef HAVE_LIBPNG
1166 case 1:
1167 if (p)
1168 data = g_LoadPNG(p, &w, &h, &trans);
1169 break;
1170 #endif
1171 default:
1172 if (p)
1173 data = g_LoadPPM(p, &w, &h);
1174 break;
1175 }
1176 }
1177
1178 if (p && !needs_conv)
1179 fclose(p);
1180 else if (p)
1181 close_helper(p);
1182
1183 if ((!data) && (id->fallback))
1184 {
1185 p = open_helper("%C/convert %s pnm:-", fil, "rb");
1186 if (p)
1187 {
1188 data = g_LoadPPM(p, &w, &h);
1189 close_helper(p);
1190 }
1191 }
1192 if ((!eim) && (!data) && (id->fallback))
1193 {
1194 if (!strcasecmp(s, "jpeg"))
1195 strcpy(cmd, "%J %s");
1196 else if (!strcasecmp(s, "jpg"))
1197 strcpy(cmd, "%J %s");
1198 else if (!strcasecmp(s, "bmp"))
1199 strcpy(cmd, "%P/bmptoppm %s");
1200 else if (!strcasecmp(s, "ilbm"))
1201 strcpy(cmd, "%P/ilbmtoppm %s");
1202 else if (!strcasecmp(s, "ilb"))
1203 strcpy(cmd, "%P/ilbmtoppm %s");
1204 else if (!strcasecmp(s, "iff"))
1205 strcpy(cmd, "%P/ilbmtoppm %s");
1206 else if (!strcasecmp(s, "img"))
1207 strcpy(cmd, "%P/imgtoppm %s");
1208 else if (!strcasecmp(s, "mtv"))
1209 strcpy(cmd, "%P/mtvtoppm %s");
1210 else if (!strcasecmp(s, "pcx"))
1211 strcpy(cmd, "%P/pcxtoppm %s");
1212 else if (!strcasecmp(s, "pgm"))
1213 strcpy(cmd, "%P/pgmtoppm rgb:ffff/ffff/ffff %s");
1214 else if (!strcasecmp(s, "pi1"))
1215 strcpy(cmd, "%P/pi1toppm %s");
1216 else if (!strcasecmp(s, "pict"))
1217 strcpy(cmd, "%P/picttoppm %s");
1218 else if (!strcasecmp(s, "pic"))
1219 strcpy(cmd, "%P/picttoppm %s");
1220 else if (!strcasecmp(s, "pj"))
1221 strcpy(cmd, "%P/pjtoppm %s");
1222 else if (!strcasecmp(s, "qrt"))
1223 strcpy(cmd, "%P/qrttoppm %s");
1224 else if (!strcasecmp(s, "sld"))
1225 strcpy(cmd, "%P/sldtoppm %s");
1226 else if (!strcasecmp(s, "spc"))
1227 strcpy(cmd, "%P/spctoppm %s");
1228 else if (!strcasecmp(s, "spu"))
1229 strcpy(cmd, "%P/sputoppm %s");
1230 else if (!strcasecmp(s, "tga"))
1231 strcpy(cmd, "%P/tgatoppm %s");
1232 else if (!strcasecmp(s, "xim"))
1233 strcpy(cmd, "%P/ximtoppm %s");
1234 else if (!strcasecmp(s, "xpm"))
1235 strcpy(cmd, "%P/xpmtoppm %s");
1236 else if (!strcasecmp(s, "gif"))
1237 strcpy(cmd, "%P/giftopnm %s");
1238 else if (!strcasecmp(s, "rast"))
1239 strcpy(cmd, "%P/rasttopnm %s");
1240 else if (!strcasecmp(s, "ras"))
1241 strcpy(cmd, "%P/rasttopnm %s");
1242 else if (!strcasecmp(s, "sgi"))
1243 strcpy(cmd, "%P/sgitopnm %s");
1244 else if (!strcasecmp(s, "sir"))
1245 strcpy(cmd, "%P/sirtopnm %s");
1246 else if (!strcasecmp(s, "tiff"))
1247 strcpy(cmd, "%P/tifftopnm %s");
1248 else if (!strcasecmp(s, "tif"))
1249 strcpy(cmd, "%P/tifftopnm %s");
1250 else if (!strcasecmp(s, "wxd"))
1251 strcpy(cmd, "%P/wxdtopnm %s");
1252 else if (!strcasecmp(s, "zeiss"))
1253 strcpy(cmd, "%P/zeisstopnm -ppm %s");
1254 else if (!strcasecmp(s, "zei"))
1255 strcpy(cmd, "%P/zeisstopnm -ppm %s");
1256 else if (!strcasecmp(s, "zis"))
1257 strcpy(cmd, "%P/zeisstopnm -ppm %s");
1258 else
1259 strcpy(cmd, "%P/anytopnm %s");
1260 p = open_helper(cmd, fil, "rb");
1261 if (p)
1262 {
1263 data = g_LoadPPM(p, &w, &h);
1264 close_helper(p);
1265 }
1266 }
1267
1268 if (!eim && !data)
1269 {
1270 fprintf(stderr, "gdk_imlib ERROR: Cannot load image: %s\nAll fallbacks failed.\n", fil);
1271 return NULL;
1272 }
1273
1274 im = (GdkImlibImage *) malloc(sizeof(GdkImlibImage));
1275 if (!im)
1276 {
1277 fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for image data\n");
1278 if (data)
1279 free(data);
1280 return NULL;
1281 }
1282 im->alpha_data = NULL;
1283 if (trans)
1284 {
1285 im->shape_color.r = 255;
1286 im->shape_color.g = 0;
1287 im->shape_color.b = 255;
1288 }
1289 else
1290 {
1291 im->shape_color.r = -1;
1292 im->shape_color.g = -1;
1293 im->shape_color.b = -1;
1294 }
1295 im->border.left = 0;
1296 im->border.right = 0;
1297 im->border.top = 0;
1298 im->border.bottom = 0;
1299 im->cache = 1;
1300 im->rgb_data = data;
1301 im->rgb_width = w;
1302 im->rgb_height = h;
1303 im->pixmap = NULL;
1304 im->shape_mask = NULL;
1305 if (eim)
1306 {
1307 char s1[256], s2[256];
1308 int num, size;
1309 int r, g, b;
1310 int br, bl, bt, bb;
1311
1312 /* Load Native-as-can-be EIM format (Enlightenment IMlib format) */
1313 p = fopen(fil, "r");
1314 if (!p)
1315 {
1316 free(im);
1317 return NULL;
1318 }
1319 fgets(s, 4096, p);
1320 if ((s[0] != 'E') && (s[1] != 'I') && (s[2] != 'M') && (s[3] != ' '))
1321 {
1322 fclose(p);
1323 free(im);
1324 return NULL;
1325 }
1326 sscanf(s, "%256s %i", s1, &num);
1327 if (num <= 0)
1328 {
1329 fclose(p);
1330 free(im);
1331 return NULL;
1332 }
1333 while (fgets(s, 4096, p))
1334 {
1335 sscanf(s, "%256s", s1);
1336 if (!strcmp("IMAGE", s1))
1337 {
1338 sscanf(s, "%256s %i %256s %i %i %i %i %i %i %i %i %i", s1, &size, s2, &w, &h, &r, &g, &b, &bl, &br, &bt, &bb);
1339 if (!iden[0])
1340 break;
1341 else if (!strcmp(iden, s2))
1342 break;
1343 if (size > 0)
1344 fseek(p, size, SEEK_CUR);
1345 }
1346 }
1347 im->rgb_data = malloc(w * h * 3);
1348 if (!im->rgb_data)
1349 {
1350 fclose(p);
1351 free(im);
1352 return NULL;
1353 }
1354 im->shape_color.r = r;
1355 im->shape_color.g = g;
1356 im->shape_color.b = b;
1357 im->rgb_width = w;
1358 im->rgb_height = h;
1359 im->border.left = bl;
1360 im->border.right = br;
1361 im->border.top = bt;
1362 im->border.bottom = bb;
1363 fread(im->rgb_data, 1, w * h * 3, p);
1364 fclose(p);
1365 if (iden[0])
1366 {
1367 strncat(fil, ":", sizeof(fil) - strlen(fil));
1368 strncat(fil, iden, sizeof(fil) - strlen(fil));
1369 }
1370 }
1371 im->mod.gamma = id->mod.gamma;
1372 im->mod.brightness = id->mod.brightness;
1373 im->mod.contrast = id->mod.contrast;
1374 im->rmod.gamma = id->rmod.gamma;
1375 im->rmod.brightness = id->rmod.brightness;
1376 im->rmod.contrast = id->rmod.contrast;
1377 im->gmod.gamma = id->gmod.gamma;
1378 im->gmod.brightness = id->gmod.brightness;
1379 im->gmod.contrast = id->gmod.contrast;
1380 im->bmod.gamma = id->bmod.gamma;
1381 im->bmod.brightness = id->bmod.brightness;
1382 im->bmod.contrast = id->bmod.contrast;
1383 im->filename = malloc(strlen(file) + 1);
1384 if (im->filename)
1385 strcpy(im->filename, file);
1386 if ((id->cache.on_image && im))
1387 gadd_image(im, fil);
1388 gcalc_map_tables(im);
1389 return im;
1390 }
1391
1392 gint
1393 gdk_imlib_save_image_to_eim(GdkImlibImage * im, char *file)
1394 {
1395 char fil[4096];
1396 char *iden;
1397 FILE *f;
1398 int size;
1399
1400 if ((!id) || (!im) || (!file))
1401 return 0;
1402 strncpy(fil, file, sizeof(fil));
1403 iden = g_SplitID(fil);
1404 if (!iden[0])
1405 iden = "default";
1406 f = fopen(fil, "w");
1407 if (!f)
1408 return 0;
1409
1410 size = im->rgb_width * im->rgb_height * 3;
1411 fprintf(f, "EIM 1\n");
1412 fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n",
1413 size,
1414 iden,
1415 im->rgb_width,
1416 im->rgb_height,
1417 im->shape_color.r,
1418 im->shape_color.g,
1419 im->shape_color.b,
1420 im->border.left,
1421 im->border.right,
1422 im->border.top,
1423 im->border.bottom);
1424 if (fwrite(im->rgb_data, size, 1, f) != 1)
1425 {
1426 fclose(f);
1427 return 0;
1428 }
1429 fclose(f);
1430 return 1;
1431 }
1432
1433 gint
1434 gdk_imlib_add_image_to_eim(GdkImlibImage * im, char *file)
1435 {
1436 char fil[4096];
1437 char *iden;
1438 FILE *f;
1439 int size;
1440
1441 if ((!id) || (!im) || (!file))
1442 return 0;
1443 strncpy(fil, file, sizeof(fil));
1444
1445 iden = g_SplitID(file);
1446 if (!iden[0])
1447 strcpy(iden, "default");
1448
1449 f = fopen(fil, "a");
1450 if (!f)
1451 return 0;
1452
1453 size = im->rgb_width * im->rgb_height * 3;
1454 fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n",
1455 size,
1456 iden,
1457 im->rgb_width,
1458 im->rgb_height,
1459 im->shape_color.r,
1460 im->shape_color.g,
1461 im->shape_color.b,
1462 im->border.left,
1463 im->border.right,
1464 im->border.top,
1465 im->border.bottom);
1466
1467 if (fwrite(im->rgb_data, size, 1, f) != 1)
1468 {
1469 fclose(f);
1470 return 0;
1471 }
1472 fclose(f);
1473 return 1;
1474 }
1475
1476 gint
1477 gdk_imlib_save_image_to_ppm(GdkImlibImage * im, char *file)
1478 {
1479 FILE *f;
1480
1481 if ((!id) || (!im) || (!file))
1482 return 0;
1483 f = fopen(file, "w");
1484 if (!f)
1485 return 0;
1486
1487 fprintf(f, "P6\n");
1488 fprintf(f, "%i %i\n255\n",
1489 im->rgb_width,
1490 im->rgb_height);
1491 if (fwrite(im->rgb_data, im->rgb_width * im->rgb_height * 3, 1, f) != 1)
1492 {
1493 fclose(f);
1494 return 0;
1495 }
1496 fclose(f);
1497 return 1;
1498 }