1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Marcus Boerger <helly@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: xbm.c 272374 2008-12-31 11:17:49Z sebastian $ */
20 :
21 : #include <stdio.h>
22 : #include <math.h>
23 : #include <string.h>
24 : #include <stdlib.h>
25 : #include "gd.h"
26 : #include "gdhelpers.h"
27 :
28 : #include "php.h"
29 :
30 : #define MAX_XBM_LINE_SIZE 255
31 :
32 : /* {{{ gdImagePtr gdImageCreateFromXbm */
33 : gdImagePtr gdImageCreateFromXbm(FILE * fd)
34 2 : {
35 : char fline[MAX_XBM_LINE_SIZE];
36 : char iname[MAX_XBM_LINE_SIZE];
37 : char *type;
38 : int value;
39 2 : unsigned int width = 0, height = 0;
40 2 : int fail = 0;
41 2 : int max_bit = 0;
42 :
43 : gdImagePtr im;
44 2 : int bytes = 0, i;
45 2 : int bit, x = 0, y = 0;
46 : int ch;
47 : char h[8];
48 : unsigned int b;
49 :
50 2 : rewind(fd);
51 9 : while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
52 6 : fline[MAX_XBM_LINE_SIZE-1] = '\0';
53 6 : if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
54 0 : return 0;
55 : }
56 6 : if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
57 4 : if (!(type = strrchr(iname, '_'))) {
58 2 : type = iname;
59 : } else {
60 2 : type++;
61 : }
62 :
63 4 : if (!strcmp("width", type)) {
64 2 : width = (unsigned int) value;
65 : }
66 4 : if (!strcmp("height", type)) {
67 2 : height = (unsigned int) value;
68 : }
69 : } else {
70 4 : if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
71 : || sscanf(fline, "static char %s = {", iname) == 1)
72 : {
73 2 : max_bit = 128;
74 0 : } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
75 : || sscanf(fline, "static short %s = {", iname) == 1)
76 : {
77 0 : max_bit = 32768;
78 : }
79 2 : if (max_bit) {
80 2 : bytes = (width * height / 8) + 1;
81 2 : if (!bytes) {
82 0 : return 0;
83 : }
84 2 : if (!(type = strrchr(iname, '_'))) {
85 1 : type = iname;
86 : } else {
87 1 : type++;
88 : }
89 2 : if (!strcmp("bits[]", type)) {
90 1 : break;
91 : }
92 : }
93 : }
94 : }
95 2 : if (!bytes || !max_bit) {
96 0 : return 0;
97 : }
98 :
99 2 : if(!(im = gdImageCreate(width, height))) {
100 1 : return 0;
101 : }
102 1 : gdImageColorAllocate(im, 255, 255, 255);
103 1 : gdImageColorAllocate(im, 0, 0, 0);
104 1 : h[2] = '\0';
105 1 : h[4] = '\0';
106 10 : for (i = 0; i < bytes; i++) {
107 : while (1) {
108 39 : if ((ch=getc(fd)) == EOF) {
109 0 : fail = 1;
110 0 : break;
111 : }
112 39 : if (ch == 'x') {
113 10 : break;
114 : }
115 29 : }
116 10 : if (fail) {
117 0 : break;
118 : }
119 : /* Get hex value */
120 10 : if ((ch=getc(fd)) == EOF) {
121 0 : break;
122 : }
123 10 : h[0] = ch;
124 10 : if ((ch=getc(fd)) == EOF) {
125 0 : break;
126 : }
127 10 : h[1] = ch;
128 10 : if (max_bit == 32768) {
129 0 : if ((ch=getc(fd)) == EOF) {
130 0 : break;
131 : }
132 0 : h[2] = ch;
133 0 : if ((ch=getc(fd)) == EOF) {
134 0 : break;
135 : }
136 0 : h[3] = ch;
137 : }
138 10 : sscanf(h, "%x", &b);
139 85 : for (bit = 1; bit <= max_bit; bit = bit << 1) {
140 80 : gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
141 80 : if (x == im->sx) {
142 5 : x = 0;
143 5 : y++;
144 5 : if (y == im->sy) {
145 1 : return im;
146 : }
147 4 : break;
148 : }
149 : }
150 : }
151 :
152 0 : php_gd_error("EOF before image was complete");
153 0 : gdImageDestroy(im);
154 0 : return 0;
155 : }
156 : /* }}} */
157 :
158 : /* {{{ gdCtxPrintf */
159 : void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
160 0 : {
161 : char *buf;
162 : int len;
163 : va_list args;
164 :
165 0 : va_start(args, format);
166 0 : len = vspprintf(&buf, 0, format, args);
167 0 : va_end(args);
168 0 : out->putBuf(out, buf, len);
169 0 : efree(buf);
170 0 : }
171 : /* }}} */
172 :
173 : /* {{{ gdImageXbmCtx */
174 : void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
175 0 : {
176 : int x, y, c, b, sx, sy, p;
177 : char *name, *f;
178 : size_t i, l;
179 :
180 0 : name = file_name;
181 0 : if ((f = strrchr(name, '/')) != NULL) name = f+1;
182 0 : if ((f = strrchr(name, '\\')) != NULL) name = f+1;
183 0 : name = estrdup(name);
184 0 : if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
185 0 : if ((l = strlen(name)) == 0) {
186 0 : efree(name);
187 0 : name = estrdup("image");
188 : } else {
189 0 : for (i=0; i<l; i++) {
190 : /* only in C-locale isalnum() would work */
191 0 : if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
192 0 : name[i] = '_';
193 : }
194 : }
195 : }
196 :
197 0 : gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
198 0 : gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
199 0 : gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n ", name);
200 :
201 0 : efree(name);
202 :
203 0 : b = 1;
204 0 : p = 0;
205 0 : c = 0;
206 0 : sx = gdImageSX(image);
207 0 : sy = gdImageSY(image);
208 0 : for (y = 0; y < sy; y++) {
209 0 : for (x = 0; x < sx; x++) {
210 0 : if (gdImageGetPixel(image, x, y) == fg) {
211 0 : c |= b;
212 : }
213 0 : if ((b == 128) || (x == sx && y == sy)) {
214 0 : b = 1;
215 0 : if (p) {
216 0 : gdCtxPrintf(out, ", ");
217 0 : if (!(p%12)) {
218 0 : gdCtxPrintf(out, "\n ");
219 0 : p = 12;
220 : }
221 : }
222 0 : p++;
223 0 : gdCtxPrintf(out, "0x%02X", c);
224 0 : c = 0;
225 : } else {
226 0 : b <<= 1;
227 : }
228 : }
229 : }
230 0 : gdCtxPrintf(out, "};\n");
231 0 : }
232 : /* }}} */
233 :
234 : /*
235 : * Local variables:
236 : * tab-width: 4
237 : * c-basic-offset: 4
238 : * End:
239 : * vim600: sw=4 ts=4 fdm=marker
240 : * vim<600: sw=4 ts=4
241 : */
|