]> git.saurik.com Git - wxWidgets.git/blob - src/xpm/crbuffri.c
*** empty log message ***
[wxWidgets.git] / src / xpm / crbuffri.c
1 /*
2 * Copyright (C) 1989-94 GROUPE BULL
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
24 */
25
26 /*****************************************************************************\
27 * XpmCrBufFrI.c: *
28 * *
29 * XPM library *
30 * Scan an image and possibly its mask and create an XPM buffer *
31 * *
32 * Developed by Arnaud Le Hors *
33 \*****************************************************************************/
34
35 #include "xpm34p.h"
36 #ifdef VMS
37 #include "sys$library:string.h"
38 #else
39 #if defined(SYSV) || defined(SVR4)
40 #include <string.h>
41 #else
42 #include <strings.h>
43 #endif
44 #endif
45
46 LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
47 unsigned int *used_size, XpmColor *colors,
48 unsigned int ncolors, unsigned int cpp));
49
50 LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size,
51 unsigned int width, unsigned int height,
52 unsigned int cpp, unsigned int *pixels,
53 XpmColor *colors));
54
55 LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
56 XpmExtension *ext, unsigned int num));
57
58 LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
59 LFUNC(CommentsSize, int, (XpmInfo *info));
60
61 int
62 XpmCreateBufferFromImage(Display *display, char **buffer_return, XImage *image,
63 XImage *shapeimage, XpmAttributes *attributes)
64 {
65 XpmImage xpmimage;
66 XpmInfo info;
67 int ErrorStatus;
68
69 /* initialize return value */
70 if (buffer_return)
71 *buffer_return = NULL;
72
73 /* create an XpmImage from the image */
74 ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
75 &xpmimage, attributes);
76 if (ErrorStatus != XpmSuccess)
77 return (ErrorStatus);
78
79 /* create the buffer from the XpmImage */
80 if (attributes) {
81 xpmSetInfo(&info, attributes);
82 ErrorStatus =
83 XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
84 } else
85 ErrorStatus =
86 XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
87
88 /* free the XpmImage */
89 XpmFreeXpmImage(&xpmimage);
90
91 return (ErrorStatus);
92 }
93
94
95 #undef RETURN
96 #define RETURN(status) \
97 { \
98 if (ptr) \
99 XpmFree(ptr); \
100 return(status); \
101 }
102
103 int
104 XpmCreateBufferFromXpmImage(char **buffer_return, XpmImage *image, XpmInfo *info)
105 {
106 /* calculation variables */
107 int ErrorStatus;
108 char buf[BUFSIZ];
109 unsigned int cmts, extensions, ext_size = 0;
110 unsigned int l, cmt_size = 0;
111 char *ptr = NULL, *p;
112 unsigned int ptr_size, used_size;
113
114 *buffer_return = NULL;
115
116 cmts = info && (info->valuemask & XpmComments);
117 extensions = info && (info->valuemask & XpmExtensions)
118 && info->nextensions;
119
120 /* compute the extensions and comments size */
121 if (extensions)
122 ext_size = ExtensionsSize(info->extensions, info->nextensions);
123 if (cmts)
124 cmt_size = CommentsSize(info);
125
126 /* write the header line */
127 sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
128 used_size = strlen(buf);
129 ptr_size = used_size + ext_size + cmt_size + 1;
130 ptr = (char *) XpmMalloc(ptr_size);
131 if (!ptr)
132 return XpmNoMemory;
133 strcpy(ptr, buf);
134
135 /* write the values line */
136 if (cmts && info->hints_cmt) {
137 sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
138 used_size += strlen(info->hints_cmt) + 5;
139 }
140 sprintf(buf, "\"%d %d %d %d", image->width, image->height,
141 image->ncolors, image->cpp);
142 l = strlen(buf);
143
144 if (info && (info->valuemask & XpmHotspot)) {
145 sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
146 l = strlen(buf);
147 }
148 if (extensions) {
149 sprintf(buf + l, " XPMEXT");
150 l = strlen(buf);
151 }
152 sprintf(buf + l, "\",\n");
153 l = strlen(buf);
154 ptr_size += l;
155 p = (char *) XpmRealloc(ptr, ptr_size);
156 if (!p)
157 RETURN(XpmNoMemory);
158 ptr = p;
159 strcpy(ptr + used_size, buf);
160 used_size += l;
161
162 /* write colors */
163 if (cmts && info->colors_cmt) {
164 sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
165 used_size += strlen(info->colors_cmt) + 5;
166 }
167 ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
168 image->colorTable, image->ncolors, image->cpp);
169
170 if (ErrorStatus != XpmSuccess)
171 RETURN(ErrorStatus);
172
173 /*
174 * now we know the exact size we needed, realloc the data 4 = 1 (for
175 * '"') + 3 (for '",\n') 1 = - 2 is because the last line does not end
176 * with ',\n' + 3 (for '};\n')
177 */
178 ptr_size += image->height * (image->width * image->cpp + 4) + 1;
179
180 p = (char *) XpmRealloc(ptr, ptr_size);
181 if (!p)
182 RETURN(XpmNoMemory);
183 ptr = p;
184
185 /* print pixels */
186 if (cmts && info->pixels_cmt) {
187 sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
188 used_size += strlen(info->pixels_cmt) + 5;
189 }
190 WritePixels(ptr + used_size, &used_size, image->width, image->height,
191 image->cpp, image->data, image->colorTable);
192
193 /* print extensions */
194 if (extensions)
195 WriteExtensions(ptr + used_size, &used_size,
196 info->extensions, info->nextensions);
197
198 /* close the array */
199 sprintf(ptr + used_size, "};\n");
200
201 *buffer_return = ptr;
202
203 return (XpmSuccess);
204 }
205
206 static int
207 WriteColors(char **dataptr, unsigned int *data_size, unsigned int *used_size,
208 XpmColor *colors, unsigned int ncolors, unsigned int cpp)
209 {
210 char buf[BUFSIZ];
211 unsigned int a, key, l;
212 char *s, *s2;
213 char **defaults;
214
215 *buf = '"';
216 for (a = 0; a < ncolors; a++, colors++) {
217
218 defaults = (char **) colors;
219 s = buf + 1;
220 strncpy(s, *defaults++, cpp);
221 s += cpp;
222
223 for (key = 1; key <= NKEYS; key++, defaults++) {
224 if (s2 = *defaults) {
225 sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
226 s += strlen(s);
227 }
228 }
229 strcpy(s, "\",\n");
230 l = strlen(buf);
231 s = (char *) XpmRealloc(*dataptr, *data_size + l);
232 if (!s)
233 return (XpmNoMemory);
234 *data_size += l;
235 strcpy(s + *used_size, buf);
236 *used_size += l;
237 *dataptr = s;
238 }
239 return (XpmSuccess);
240 }
241
242 static void
243 WritePixels(char *dataptr, unsigned int *used_size, unsigned int width, unsigned int height,
244 unsigned int cpp, unsigned int *pixels, XpmColor *colors)
245 {
246 char *s = dataptr;
247 unsigned int x, y, h;
248
249 h = height - 1;
250 for (y = 0; y < h; y++) {
251 *s++ = '"';
252 for (x = 0; x < width; x++, pixels++) {
253 strncpy(s, colors[*pixels].string, cpp);
254 s += cpp;
255 }
256 strcpy(s, "\",\n");
257 s += 3;
258 }
259 /* duplicate some code to avoid a test in the loop */
260 *s++ = '"';
261 for (x = 0; x < width; x++, pixels++) {
262 strncpy(s, colors[*pixels].string, cpp);
263 s += cpp;
264 }
265 *s++ = '"';
266 *used_size += s - dataptr;
267 }
268
269 static int
270 ExtensionsSize(XpmExtension *ext, unsigned int num)
271 {
272 unsigned int x, y, a, size;
273 char **line;
274
275 size = 0;
276 for (x = 0; x < num; x++, ext++) {
277 /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
278 size += strlen(ext->name) + 11;
279 a = ext->nlines;
280 for (y = 0, line = ext->lines; y < a; y++, line++)
281 /* 4 = 3 (for ',\n"') + 1 (for '"') */
282 size += strlen(*line) + 4;
283 }
284 /* 13 is for ',\n"XPMENDEXT"' */
285 return size + 13;
286 }
287
288 static void
289 WriteExtensions(char *dataptr, unsigned int *used_size, XpmExtension *ext, unsigned int num)
290 {
291 unsigned int x, y, a;
292 char **line;
293 char *s = dataptr;
294
295 for (x = 0; x < num; x++, ext++) {
296 sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
297 s += strlen(ext->name) + 11;
298 a = ext->nlines;
299 for (y = 0, line = ext->lines; y < a; y++, line++) {
300 sprintf(s, ",\n\"%s\"", *line);
301 s += strlen(*line) + 4;
302 }
303 }
304 strcpy(s, ",\n\"XPMENDEXT\"");
305 *used_size += s - dataptr + 13;
306 }
307
308 static int
309 CommentsSize(XpmInfo *info)
310 {
311 int size = 0;
312
313 /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
314 if (info->hints_cmt)
315 size += 5 + strlen(info->hints_cmt);
316
317 if (info->colors_cmt)
318 size += 5 + strlen(info->colors_cmt);
319
320 if (info->pixels_cmt)
321 size += 5 + strlen(info->pixels_cmt);
322
323 return size;
324 }