]> git.saurik.com Git - wxWidgets.git/blob - src/gdk_imlib/load.c
Initial revision
[wxWidgets.git] / src / gdk_imlib / load.c
1
2 #define _GNU_SOURCE
3 #include <config.h>
4
5 #include "gdk_imlib.h"
6 #include "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 transp = 0;
499 done = 0;
500
501 file = fopen(f, "r");
502 if (!file)
503 return NULL;
504
505 *w = 10;
506 *h = 10;
507
508 ptr = NULL;
509 data = NULL;
510 c = ' ';
511 comment = 0;
512 quote = 0;
513 context = 0;
514
515 while (!done)
516 {
517 pc = c;
518 c = fgetc(file);
519 if (c == EOF)
520 break;
521 if (!quote)
522 {
523 if (pc == '/' && c == '*')
524 comment = 1;
525 else if (pc == '*' && c == '/' && comment)
526 comment = 0;
527 }
528 if (!comment)
529 {
530 if (!quote && c == '"')
531 {
532 quote = 1;
533 i = 0;
534 }
535 else if (quote && c == '"')
536 {
537 line[i] = 0;
538 quote = 0;
539 if (context == 0)
540 {
541 /* Header */
542 sscanf(line, "%i %i %i %i", w, h, &ncolors, &cpp);
543 if (cpp > 7)
544 {
545 fprintf(stderr, "gdk_imlib ERROR: XPM files with characters per pixel > 7 not supported\n");
546 return NULL;
547 }
548 if (*w > 32767)
549 {
550 fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
551 return NULL;
552 }
553 if (*h > 32767)
554 {
555 fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
556 return NULL;
557 }
558 cmap = malloc(sizeof(struct _cmap) * ncolors);
559
560 if (!cmap)
561 return NULL;
562 data = malloc(*w ** h * 3);
563 if (!data)
564 {
565 free(cmap);
566 return NULL;
567 }
568 ptr = data;
569 j = 0;
570 context++;
571 }
572 else if (context == 1)
573 {
574 /* Color Table */
575 if (j < ncolors)
576 {
577 int colptr = 0;
578 int slen;
579
580 tok[0] = 0;
581 col[0] = 0;
582 s[0] = 0;
583 len = strlen(line);
584 strncpy(cmap[j].str, line, cpp);
585 cmap[j].str[cpp] = 0;
586 cmap[j].r = -1;
587 cmap[j].transp = 0;
588 for (k = cpp; k < len; k++)
589 {
590 if (line[k] != ' ')
591 {
592 s[0] = 0;
593 sscanf(&line[k], "%65535s", s);
594 slen = strlen(s);
595 k += slen;
596 if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
597 (!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
598 (!strcmp(s, "c")) || (k >= len))
599 {
600 if (k >= len)
601 {
602 if (col[0])
603 strcat(col, " ");
604 strcat(col, s);
605 }
606 if (col[0])
607 {
608 if (!strcasecmp(col, "none"))
609 {
610 transp = 1;
611 cmap[j].transp = 1;
612 }
613 else
614 {
615 if ((cmap[j].r < 0) ||
616 (!strcmp(tok, "c")))
617 {
618 XParseColor(id->x.disp,
619 id->x.root_cmap,
620 col, &xcol);
621 cmap[j].r = xcol.red >> 8;
622 cmap[j].g = xcol.green >> 8;
623 cmap[j].b = xcol.blue >> 8;
624 if ((cmap[j].r == 255) &&
625 (cmap[j].g == 0) &&
626 (cmap[j].b == 255))
627 cmap[j].r = 254;
628 }
629 }
630 }
631 strcpy(tok, s);
632 col[0] = 0;
633 }
634 else
635 {
636 if (col[0])
637 strcat(col, " ");
638 strcat(col, s);
639 }
640 }
641 }
642 }
643 j++;
644 if (j >= ncolors)
645 {
646 if (cpp == 1)
647 for (i = 0; i < ncolors; i++)
648 lookup[cmap[i].str[0]][cmap[i].str[1]] = i;
649 if (cpp == 2)
650 for (i = 0; i < ncolors; i++)
651 lookup[cmap[i].str[0]][cmap[i].str[1]] = i;
652 context++;
653 }
654 }
655 else
656 {
657 /* Image Data */
658 i = 0;
659 if (cpp == 0)
660 {
661 /* Chars per pixel = 0? well u never know */
662 }
663 if (cpp == 1)
664 {
665 if (transp)
666 {
667 for (i = 0; ((i < 65536) && (line[i])); i++)
668 {
669 col[0] = line[i];
670 if (cmap[lookup[col[0]][0]].transp)
671 {
672 *ptr++ = 255;
673 *ptr++ = 0;
674 *ptr++ = 255;
675 }
676 else
677 {
678 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].r;
679 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].g;
680 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].b;
681 }
682 }
683 }
684 else
685 {
686 for (i = 0; ((i < 65536) && (line[i])); i++)
687 {
688 col[0] = line[i];
689 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].r;
690 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].g;
691 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].b;
692 }
693 }
694 }
695 else if (cpp == 2)
696 {
697 if (transp)
698 {
699 for (i = 0; ((i < 65536) && (line[i])); i++)
700 {
701 col[0] = line[i++];
702 col[1] = line[i];
703 if (cmap[lookup[col[0]][col[1]]].transp)
704 {
705 *ptr++ = 255;
706 *ptr++ = 0;
707 *ptr++ = 255;
708 }
709 else
710 {
711 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].r;
712 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].g;
713 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].b;
714 }
715 }
716 }
717 else
718 {
719 for (i = 0; ((i < 65536) && (line[i])); i++)
720 {
721 col[0] = line[i++];
722 col[1] = line[i];
723 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].r;
724 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].g;
725 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].b;
726 }
727 }
728 }
729 else
730 {
731 if (transp)
732 {
733 for (i = 0; ((i < 65536) && (line[i])); i++)
734 {
735 for (j = 0; j < cpp; j++, i++)
736 {
737 col[j] = line[i];
738 }
739 col[j] = 0;
740 i--;
741 for (j = 0; j < ncolors; j++)
742 {
743 if (!strcmp(col, cmap[j].str))
744 {
745 if (cmap[j].transp)
746 {
747 *ptr++ = 255;
748 *ptr++ = 0;
749 *ptr++ = 255;
750 }
751 else
752 {
753 *ptr++ = (unsigned char)cmap[j].r;
754 *ptr++ = (unsigned char)cmap[j].g;
755 *ptr++ = (unsigned char)cmap[j].b;
756 }
757 j = ncolors;
758 }
759 }
760 }
761 }
762 else
763 {
764 for (i = 0; ((i < 65536) && (line[i])); i++)
765 {
766 for (j = 0; j < cpp; j++, i++)
767 {
768 col[j] = line[i];
769 }
770 col[j] = 0;
771 i--;
772 for (j = 0; j < ncolors; j++)
773 {
774 if (!strcmp(col, cmap[j].str))
775 {
776 *ptr++ = (unsigned char)cmap[j].r;
777 *ptr++ = (unsigned char)cmap[j].g;
778 *ptr++ = (unsigned char)cmap[j].b;
779 j = ncolors;
780 }
781 }
782 }
783 }
784 }
785 }
786 }
787 }
788 /* Scan in line from XPM file (limit line length 65k) */
789 if (i < 65536)
790 {
791 if ((!comment) && (quote) && (c != '"'))
792 {
793 line[i++] = c;
794 }
795 }
796 if ((ptr) && ((ptr - data) >= *w ** h * 3))
797 done = 1;
798 }
799 fclose(file);
800 if (transp)
801 *t = 1;
802 else
803 *t = 0;
804 free(cmap);
805 return data;
806 }
807
808 unsigned char *
809 g_LoadPPM(FILE * f, int *w, int *h)
810 {
811 int done;
812 unsigned char *ptr;
813 unsigned char chr;
814 char s[256];
815 int a, b;
816 int color, scale;
817
818 a = b = scale = 0;
819 fgets(s, 256, f);
820 s[strlen(s) - 1] = 0;
821
822 if (!strcmp(s, "P6"))
823 color = 1;
824 else if (!strcmp(s, "P5"))
825 color = 0;
826 else
827 return NULL;
828
829 done = 1;
830 ptr = NULL;
831 while (done)
832 {
833 if (fgets(s, 256, f) == NULL)
834 break;
835
836 s[strlen(s) - 1] = 0;
837 if (s[0] != '#')
838 {
839 done = 0;
840 sscanf(s, "%i %i", w, h);
841 a = *w;
842 b = *h;
843 if (a > 32767)
844 {
845 fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
846 return NULL;
847 }
848 if (b > 32767)
849 {
850 fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
851 return NULL;
852 }
853 fgets(s, 256, f);
854 sscanf(s, "%i", &scale);
855 s[strlen(s) - 1] = 0;
856 ptr = (unsigned char *)malloc(a * b * 3);
857 if (!ptr)
858 {
859 fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for RGB data in file");
860 return ptr;
861 }
862 if (color)
863 {
864 if (!fread(ptr, a * b * 3, 1, f))
865 {
866 free(ptr);
867 return NULL;
868 }
869 }
870 else
871 {
872 b = (a * b * 3);
873 a = 0;
874 while ((fread(&chr, 1, 1, f)) && (a < b))
875 {
876 ptr[a++] = chr;
877 ptr[a++] = chr;
878 ptr[a++] = chr;
879 }
880 }
881 }
882 }
883 if (scale == 0)
884 {
885 free(ptr);
886 return NULL;
887 }
888 if (scale < 255)
889 {
890 int rot;
891 unsigned char *po;
892
893 if (scale <= 1)
894 rot = 7;
895 else if (scale <= 3)
896 rot = 6;
897 else if (scale <= 7)
898 rot = 5;
899 else if (scale <= 15)
900 rot = 4;
901 else if (scale <= 31)
902 rot = 3;
903 else if (scale <= 63)
904 rot = 2;
905 else
906 rot = 1;
907
908 if (rot > 0)
909 {
910 po = ptr;
911 while (po < (ptr + (*w ** h * 3)))
912 {
913 *po++ <<= rot;
914 *po++ <<= rot;
915 *po++ <<= rot;
916 }
917 }
918 }
919 return ptr;
920 }
921
922 static int
923 gispnm(char *file)
924 {
925 FILE *f;
926 char buf[8];
927
928 f = fopen(file, "rb");
929 if (!f)
930 return 0;
931 fgets(buf, 8, f);
932 fclose(f);
933 if (!strcmp("P6\n", buf))
934 return 1;
935 if (!strcmp("P5\n", buf))
936 return 1;
937 return 0;
938 }
939
940 static int
941 gisjpeg(char *file)
942 {
943 FILE *f;
944 unsigned char buf[8];
945
946 f = fopen(file, "rb");
947 if (!f)
948 return 0;
949 fread(buf, 1, 2, f);
950 fclose(f);
951 if ((buf[0] == 0xff) && (buf[1] == 0xd8))
952 return 1;
953 return 0;
954 }
955
956 static int
957 gispng(char *file)
958 {
959 #ifdef HAVE_LIBPNG
960 FILE *f;
961 unsigned char buf[8];
962
963 f = fopen(file, "rb");
964 if (!f)
965 return 0;
966 fread(buf, 1, 8, f);
967 fclose(f);
968 return (int)png_check_sig(buf, 8);
969 #else
970 return 0;
971 #endif
972 }
973
974 static int
975 gistiff(char *file)
976 {
977 FILE *f;
978 char buf[8];
979
980 f = fopen(file, "rb");
981 if (!f)
982 return 0;
983 fgets(buf, 5, f);
984 fclose(f);
985 if ((buf[0] == 'M') && (buf[1] == 'M') && (buf[2] == 0x00) && (buf[3] == 0x2a))
986 return 1;
987 if ((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == 0x2a) && (buf[3] == 0x00))
988 return 1;
989 return 0;
990 }
991
992 static int
993 giseim(char *file)
994 {
995 FILE *f;
996 char buf[8];
997
998 f = fopen(file, "rb");
999 if (!f)
1000 return 0;
1001 fread(buf, 1, 4, f);
1002 fclose(f);
1003 if (!strncmp("EIM ", buf, 4))
1004 return 1;
1005 return 0;
1006 }
1007
1008 static int
1009 gisgif(char *file)
1010 {
1011 FILE *f;
1012 char buf[8];
1013
1014 f = fopen(file, "rb");
1015 if (!f)
1016 return 0;
1017 fread(buf, 1, 4, f);
1018 fclose(f);
1019 buf[4] = 0;
1020 if (!strcmp("GIF8", buf))
1021 return 1;
1022 return 0;
1023 }
1024
1025 static int
1026 gisxpm(char *file)
1027 {
1028 FILE *f;
1029 char buf[11];
1030
1031 f = fopen(file, "rb");
1032 if (!f)
1033 return 0;
1034 fread(buf, 1, 9, f);
1035 fclose(f);
1036 buf[9] = 0;
1037 if (!strcmp("/* XPM */", buf))
1038 return 1;
1039 return 0;
1040 }
1041
1042 GdkImlibImage *
1043 gdk_imlib_load_image(char *file)
1044 {
1045 int w, h;
1046 int needs_conv = 1;
1047 unsigned char *data;
1048 GdkImlibImage *im;
1049 char s[4096];
1050 char fil[4096];
1051 char *iden;
1052 char *e;
1053 char cmd[4096];
1054 FILE *p;
1055 int eim;
1056 int fmt;
1057 int trans;
1058
1059 eim = 0;
1060 fmt = 0;
1061 p = NULL;
1062 data = NULL;
1063
1064 if (!file)
1065 return NULL;
1066 if (id->cache.on_image)
1067 if ((im = gfind_image(file)))
1068 return im;
1069
1070 strncpy(fil, file, sizeof(fil));
1071 iden = g_SplitID(fil);
1072 e = g_GetExtension(fil);
1073
1074 if (gispnm(fil))
1075 {
1076 needs_conv = 0;
1077 fmt = 0;
1078 }
1079 else if (gisjpeg(fil))
1080 {
1081 #ifdef HAVE_LIBJPEG
1082 needs_conv = 0;
1083 fmt = 2;
1084 #else
1085 needs_conv = 1;
1086 fmt = 0;
1087 #endif
1088 }
1089 else if (gistiff(fil))
1090 {
1091 #ifdef HAVE_LIBTIFF
1092 needs_conv = 0;
1093 fmt = 3;
1094 #else
1095 needs_conv = 1;
1096 fmt = 0;
1097 #endif
1098 }
1099 else if (giseim(fil))
1100 {
1101 needs_conv = 0;
1102 eim = 1;
1103 fmt = 9999;
1104 }
1105 else if (gisxpm(fil))
1106 {
1107 needs_conv = 0;
1108 fmt = 5;
1109 }
1110 else if (gispng(fil))
1111 {
1112 #ifdef HAVE_LIBPNG
1113 needs_conv = 0;
1114 fmt = 1;
1115 #else
1116 needs_conv = 1;
1117 fmt = 0;
1118 #endif
1119 }
1120 else if (gisgif(fil))
1121 {
1122 #ifdef HAVE_LIBGIF
1123 needs_conv = 0;
1124 fmt = 4;
1125 #else
1126 needs_conv = 1;
1127 fmt = 0;
1128 #endif
1129 }
1130 if (needs_conv && id->fallback)
1131 {
1132 p = open_helper("%C/convert %s pnm:-", fil, "rb");
1133 }
1134 else if ((fmt == 2) || (fmt == 1) || (fmt == 0))
1135 p = fopen(fil, "rb");
1136
1137 trans = 0;
1138 if (!eim && !data)
1139 {
1140 switch (fmt)
1141 {
1142 case 5:
1143 data = g_LoadXPM(fil, &w, &h, &trans);
1144 break;
1145 #ifdef HAVE_LIBGIF
1146 case 4:
1147 data = g_LoadGIF(fil, &w, &h, &trans);
1148 break;
1149 #endif
1150 #ifdef HAVE_LIBTIFF
1151 case 3:
1152 data = g_LoadTIFF(fil, &w, &h, &trans);
1153 break;
1154 #endif
1155 #ifdef HAVE_LIBJPEG
1156 case 2:
1157 if (p)
1158 data = g_LoadJPEG(p, &w, &h);
1159 break;
1160 #endif
1161 #ifdef HAVE_LIBPNG
1162 case 1:
1163 if (p)
1164 data = g_LoadPNG(p, &w, &h, &trans);
1165 break;
1166 #endif
1167 default:
1168 if (p)
1169 data = g_LoadPPM(p, &w, &h);
1170 break;
1171 }
1172 }
1173
1174 if (p && !needs_conv)
1175 fclose(p);
1176 else if (p)
1177 close_helper(p);
1178
1179 if ((!data) && (id->fallback))
1180 {
1181 p = open_helper("%C/convert %s pnm:-", fil, "rb");
1182 if (p)
1183 {
1184 data = g_LoadPPM(p, &w, &h);
1185 close_helper(p);
1186 }
1187 }
1188 if ((!eim) && (!data) && (id->fallback))
1189 {
1190 if (!strcasecmp(s, "jpeg"))
1191 strcpy(cmd, "%J %s");
1192 else if (!strcasecmp(s, "jpg"))
1193 strcpy(cmd, "%J %s");
1194 else if (!strcasecmp(s, "bmp"))
1195 strcpy(cmd, "%P/bmptoppm %s");
1196 else if (!strcasecmp(s, "ilbm"))
1197 strcpy(cmd, "%P/ilbmtoppm %s");
1198 else if (!strcasecmp(s, "ilb"))
1199 strcpy(cmd, "%P/ilbmtoppm %s");
1200 else if (!strcasecmp(s, "iff"))
1201 strcpy(cmd, "%P/ilbmtoppm %s");
1202 else if (!strcasecmp(s, "img"))
1203 strcpy(cmd, "%P/imgtoppm %s");
1204 else if (!strcasecmp(s, "mtv"))
1205 strcpy(cmd, "%P/mtvtoppm %s");
1206 else if (!strcasecmp(s, "pcx"))
1207 strcpy(cmd, "%P/pcxtoppm %s");
1208 else if (!strcasecmp(s, "pgm"))
1209 strcpy(cmd, "%P/pgmtoppm rgb:ffff/ffff/ffff %s");
1210 else if (!strcasecmp(s, "pi1"))
1211 strcpy(cmd, "%P/pi1toppm %s");
1212 else if (!strcasecmp(s, "pict"))
1213 strcpy(cmd, "%P/picttoppm %s");
1214 else if (!strcasecmp(s, "pic"))
1215 strcpy(cmd, "%P/picttoppm %s");
1216 else if (!strcasecmp(s, "pj"))
1217 strcpy(cmd, "%P/pjtoppm %s");
1218 else if (!strcasecmp(s, "qrt"))
1219 strcpy(cmd, "%P/qrttoppm %s");
1220 else if (!strcasecmp(s, "sld"))
1221 strcpy(cmd, "%P/sldtoppm %s");
1222 else if (!strcasecmp(s, "spc"))
1223 strcpy(cmd, "%P/spctoppm %s");
1224 else if (!strcasecmp(s, "spu"))
1225 strcpy(cmd, "%P/sputoppm %s");
1226 else if (!strcasecmp(s, "tga"))
1227 strcpy(cmd, "%P/tgatoppm %s");
1228 else if (!strcasecmp(s, "xim"))
1229 strcpy(cmd, "%P/ximtoppm %s");
1230 else if (!strcasecmp(s, "xpm"))
1231 strcpy(cmd, "%P/xpmtoppm %s");
1232 else if (!strcasecmp(s, "gif"))
1233 strcpy(cmd, "%P/giftopnm %s");
1234 else if (!strcasecmp(s, "rast"))
1235 strcpy(cmd, "%P/rasttopnm %s");
1236 else if (!strcasecmp(s, "ras"))
1237 strcpy(cmd, "%P/rasttopnm %s");
1238 else if (!strcasecmp(s, "sgi"))
1239 strcpy(cmd, "%P/sgitopnm %s");
1240 else if (!strcasecmp(s, "sir"))
1241 strcpy(cmd, "%P/sirtopnm %s");
1242 else if (!strcasecmp(s, "tiff"))
1243 strcpy(cmd, "%P/tifftopnm %s");
1244 else if (!strcasecmp(s, "tif"))
1245 strcpy(cmd, "%P/tifftopnm %s");
1246 else if (!strcasecmp(s, "wxd"))
1247 strcpy(cmd, "%P/wxdtopnm %s");
1248 else if (!strcasecmp(s, "zeiss"))
1249 strcpy(cmd, "%P/zeisstopnm -ppm %s");
1250 else if (!strcasecmp(s, "zei"))
1251 strcpy(cmd, "%P/zeisstopnm -ppm %s");
1252 else if (!strcasecmp(s, "zis"))
1253 strcpy(cmd, "%P/zeisstopnm -ppm %s");
1254 else
1255 strcpy(cmd, "%P/anytopnm %s");
1256 p = open_helper(cmd, fil, "rb");
1257 if (p)
1258 {
1259 data = g_LoadPPM(p, &w, &h);
1260 close_helper(p);
1261 }
1262 }
1263
1264 if (!eim && !data)
1265 {
1266 fprintf(stderr, "gdk_imlib ERROR: Cannot load image: %s\nAll fallbacks failed.\n", fil);
1267 return NULL;
1268 }
1269
1270 im = (GdkImlibImage *) malloc(sizeof(GdkImlibImage));
1271 if (!im)
1272 {
1273 fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for image data\n");
1274 if (data)
1275 free(data);
1276 return NULL;
1277 }
1278 im->alpha_data = NULL;
1279 if (trans)
1280 {
1281 im->shape_color.r = 255;
1282 im->shape_color.g = 0;
1283 im->shape_color.b = 255;
1284 }
1285 else
1286 {
1287 im->shape_color.r = -1;
1288 im->shape_color.g = -1;
1289 im->shape_color.b = -1;
1290 }
1291 im->border.left = 0;
1292 im->border.right = 0;
1293 im->border.top = 0;
1294 im->border.bottom = 0;
1295 im->cache = 1;
1296 im->rgb_data = data;
1297 im->rgb_width = w;
1298 im->rgb_height = h;
1299 im->pixmap = NULL;
1300 im->shape_mask = NULL;
1301 if (eim)
1302 {
1303 char s1[256], s2[256];
1304 int num, size;
1305 int r, g, b;
1306 int br, bl, bt, bb;
1307
1308 /* Load Native-as-can-be EIM format (Enlightenment IMlib format) */
1309 p = fopen(fil, "r");
1310 if (!p)
1311 {
1312 free(im);
1313 return NULL;
1314 }
1315 fgets(s, 4096, p);
1316 if ((s[0] != 'E') && (s[1] != 'I') && (s[2] != 'M') && (s[3] != ' '))
1317 {
1318 fclose(p);
1319 free(im);
1320 return NULL;
1321 }
1322 sscanf(s, "%256s %i", s1, &num);
1323 if (num <= 0)
1324 {
1325 fclose(p);
1326 free(im);
1327 return NULL;
1328 }
1329 while (fgets(s, 4096, p))
1330 {
1331 sscanf(s, "%256s", s1);
1332 if (!strcmp("IMAGE", s1))
1333 {
1334 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);
1335 if (!iden[0])
1336 break;
1337 else if (!strcmp(iden, s2))
1338 break;
1339 if (size > 0)
1340 fseek(p, size, SEEK_CUR);
1341 }
1342 }
1343 im->rgb_data = malloc(w * h * 3);
1344 if (!im->rgb_data)
1345 {
1346 fclose(p);
1347 free(im);
1348 return NULL;
1349 }
1350 im->shape_color.r = r;
1351 im->shape_color.g = g;
1352 im->shape_color.b = b;
1353 im->rgb_width = w;
1354 im->rgb_height = h;
1355 im->border.left = bl;
1356 im->border.right = br;
1357 im->border.top = bt;
1358 im->border.bottom = bb;
1359 fread(im->rgb_data, 1, w * h * 3, p);
1360 fclose(p);
1361 if (iden[0])
1362 {
1363 strncat(fil, ":", sizeof(fil) - strlen(fil));
1364 strncat(fil, iden, sizeof(fil) - strlen(fil));
1365 }
1366 }
1367 im->mod.gamma = id->mod.gamma;
1368 im->mod.brightness = id->mod.brightness;
1369 im->mod.contrast = id->mod.contrast;
1370 im->rmod.gamma = id->rmod.gamma;
1371 im->rmod.brightness = id->rmod.brightness;
1372 im->rmod.contrast = id->rmod.contrast;
1373 im->gmod.gamma = id->gmod.gamma;
1374 im->gmod.brightness = id->gmod.brightness;
1375 im->gmod.contrast = id->gmod.contrast;
1376 im->bmod.gamma = id->bmod.gamma;
1377 im->bmod.brightness = id->bmod.brightness;
1378 im->bmod.contrast = id->bmod.contrast;
1379 im->filename = malloc(strlen(file) + 1);
1380 if (im->filename)
1381 strcpy(im->filename, file);
1382 if ((id->cache.on_image && im))
1383 gadd_image(im, fil);
1384 gcalc_map_tables(im);
1385 return im;
1386 }
1387
1388 gint
1389 gdk_imlib_save_image_to_eim(GdkImlibImage * im, char *file)
1390 {
1391 char fil[4096];
1392 char *iden;
1393 FILE *f;
1394 int size;
1395
1396 if ((!id) || (!im) || (!file))
1397 return 0;
1398 strncpy(fil, file, sizeof(fil));
1399 iden = g_SplitID(fil);
1400 if (!iden[0])
1401 iden = "default";
1402 f = fopen(fil, "w");
1403 if (!f)
1404 return 0;
1405
1406 size = im->rgb_width * im->rgb_height * 3;
1407 fprintf(f, "EIM 1\n");
1408 fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n",
1409 size,
1410 iden,
1411 im->rgb_width,
1412 im->rgb_height,
1413 im->shape_color.r,
1414 im->shape_color.g,
1415 im->shape_color.b,
1416 im->border.left,
1417 im->border.right,
1418 im->border.top,
1419 im->border.bottom);
1420 if (fwrite(im->rgb_data, size, 1, f) != 1)
1421 {
1422 fclose(f);
1423 return 0;
1424 }
1425 fclose(f);
1426 return 1;
1427 }
1428
1429 gint
1430 gdk_imlib_add_image_to_eim(GdkImlibImage * im, char *file)
1431 {
1432 char fil[4096];
1433 char *iden;
1434 FILE *f;
1435 int size;
1436
1437 if ((!id) || (!im) || (!file))
1438 return 0;
1439 strncpy(fil, file, sizeof(fil));
1440
1441 iden = g_SplitID(file);
1442 if (!iden[0])
1443 strcpy(iden, "default");
1444
1445 f = fopen(fil, "a");
1446 if (!f)
1447 return 0;
1448
1449 size = im->rgb_width * im->rgb_height * 3;
1450 fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n",
1451 size,
1452 iden,
1453 im->rgb_width,
1454 im->rgb_height,
1455 im->shape_color.r,
1456 im->shape_color.g,
1457 im->shape_color.b,
1458 im->border.left,
1459 im->border.right,
1460 im->border.top,
1461 im->border.bottom);
1462
1463 if (fwrite(im->rgb_data, size, 1, f) != 1)
1464 {
1465 fclose(f);
1466 return 0;
1467 }
1468 fclose(f);
1469 return 1;
1470 }
1471
1472 gint
1473 gdk_imlib_save_image_to_ppm(GdkImlibImage * im, char *file)
1474 {
1475 FILE *f;
1476
1477 if ((!id) || (!im) || (!file))
1478 return 0;
1479 f = fopen(file, "w");
1480 if (!f)
1481 return 0;
1482
1483 fprintf(f, "P6\n");
1484 fprintf(f, "%i %i\n255\n",
1485 im->rgb_width,
1486 im->rgb_height);
1487 if (fwrite(im->rgb_data, im->rgb_width * im->rgb_height * 3, 1, f) != 1)
1488 {
1489 fclose(f);
1490 return 0;
1491 }
1492 fclose(f);
1493 return 1;
1494 }