xref: /PHP-7.4/ext/gd/libgd/gdxpm.c (revision 6de750ef)
1 
2 /*
3    add ability to load xpm files to gd, requires the xpm
4    library.
5    Caolan.McNamara@ul.ie
6    http://www.csn.ul.ie/~caolan
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "gd.h"
12 #include "gdhelpers.h"
13 
14 #ifdef HAVE_XPM
15 
16 #include <X11/xpm.h>
17 
gdImageCreateFromXpm(char * filename)18 gdImagePtr gdImageCreateFromXpm (char *filename)
19 {
20 	XpmInfo info = {0};
21 	XpmImage image;
22 	int i, j, k, number;
23 	char buf[5];
24 	gdImagePtr im = 0;
25 	int *pointer;
26 	int red = 0, green = 0, blue = 0;
27 	int *colors;
28 	int ret;
29 
30 	ret = XpmReadFileToXpmImage(filename, &image, &info);
31 	if (ret != XpmSuccess) {
32 		return 0;
33 	}
34 	number = image.ncolors;
35 	for(i = 0; i < number; i++) {
36 		if (!image.colorTable[i].c_color) {
37 			goto done;
38 		}
39 	}
40 
41 	if (!(im = gdImageCreate(image.width, image.height))) {
42 		goto done;
43 	}
44 
45 	colors = (int *) safe_emalloc(number, sizeof(int), 0);
46 	for (i = 0; i < number; i++) {
47 		switch (strlen (image.colorTable[i].c_color)) {
48 			case 4:
49 				buf[1] = '\0';
50 				buf[0] = image.colorTable[i].c_color[1];
51 				red = strtol(buf, NULL, 16);
52 
53 				buf[0] = image.colorTable[i].c_color[2];
54 				green = strtol(buf, NULL, 16);
55 
56 				buf[0] = image.colorTable[i].c_color[3];
57 				blue = strtol(buf, NULL, 16);
58 				break;
59 
60 			case 7:
61 				buf[2] = '\0';
62 				buf[0] = image.colorTable[i].c_color[1];
63 				buf[1] = image.colorTable[i].c_color[2];
64 				red = strtol(buf, NULL, 16);
65 
66 				buf[0] = image.colorTable[i].c_color[3];
67 				buf[1] = image.colorTable[i].c_color[4];
68 				green = strtol(buf, NULL, 16);
69 
70 				buf[0] = image.colorTable[i].c_color[5];
71 				buf[1] = image.colorTable[i].c_color[6];
72 				blue = strtol(buf, NULL, 16);
73 				break;
74 
75 			case 10:
76 				buf[3] = '\0';
77 				buf[0] = image.colorTable[i].c_color[1];
78 				buf[1] = image.colorTable[i].c_color[2];
79 				buf[2] = image.colorTable[i].c_color[3];
80 				red = strtol(buf, NULL, 16);
81 				red /= 64;
82 
83 				buf[0] = image.colorTable[i].c_color[4];
84 				buf[1] = image.colorTable[i].c_color[5];
85 				buf[2] = image.colorTable[i].c_color[6];
86 				green = strtol(buf, NULL, 16);
87 				green /= 64;
88 
89 				buf[0] = image.colorTable[i].c_color[7];
90 				buf[1] = image.colorTable[i].c_color[8];
91 				buf[2] = image.colorTable[i].c_color[9];
92 				blue = strtol(buf, NULL, 16);
93 				blue /= 64;
94 				break;
95 
96 			case 13:
97 				buf[4] = '\0';
98 				buf[0] = image.colorTable[i].c_color[1];
99 				buf[1] = image.colorTable[i].c_color[2];
100 				buf[2] = image.colorTable[i].c_color[3];
101 				buf[3] = image.colorTable[i].c_color[4];
102 				red = strtol(buf, NULL, 16);
103 				red /= 256;
104 
105 				buf[0] = image.colorTable[i].c_color[5];
106 				buf[1] = image.colorTable[i].c_color[6];
107 				buf[2] = image.colorTable[i].c_color[7];
108 				buf[3] = image.colorTable[i].c_color[8];
109 				green = strtol(buf, NULL, 16);
110 				green /= 256;
111 
112 				buf[0] = image.colorTable[i].c_color[9];
113 				buf[1] = image.colorTable[i].c_color[10];
114 				buf[2] = image.colorTable[i].c_color[11];
115 				buf[3] = image.colorTable[i].c_color[12];
116 				blue = strtol(buf, NULL, 16);
117 				blue /= 256;
118 				break;
119 		}
120 
121 
122 		colors[i] = gdImageColorResolve(im, red, green, blue);
123 	}
124 
125 	pointer = (int *) image.data;
126 	for (i = 0; i < image.height; i++) {
127 		for (j = 0; j < image.width; j++) {
128 			k = *pointer++;
129 			gdImageSetPixel(im, j, i, colors[k]);
130 		}
131 	}
132 
133 	gdFree(colors);
134  done:
135 	XpmFreeXpmImage(&image);
136 	XpmFreeXpmInfo(&info);
137 	return im;
138 }
139 #endif
140