]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/misc.c
added an error message if a bitmap can't be addedto the image list
[wxWidgets.git] / src / xpm / misc.c
CommitLineData
cfbe03c9
JS
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* misc.c: *
28* *
29* XPM library *
30* Miscellaneous utilities *
31* *
32* Developed by Arnaud Le Hors *
33\*****************************************************************************/
34
35/*
36 * The code related to FOR_MSW has been added by
37 * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
38 */
39
40#include "xpm34p.h"
41#ifdef VMS
42#include "sys$library:stat.h"
43#include "sys$library:fcntl.h"
44#else
45#include <sys/types.h>
46#include <sys/stat.h>
47#include <fcntl.h>
48#include <stdio.h>
49#ifdef FOR_MSW
50#include <io.h>
51#else
52#include <unistd.h>
53#endif
54#endif
55
56/* 3.2 backward compatibility code */
57LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors,
58 XpmColor ***oldct));
59
60LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors));
61
62/*
63 * Create a colortable compatible with the old style colortable
64 */
65static int
66CreateOldColorTable(XpmColor *ct, int ncolors, XpmColor ***oldct)
67{
68 XpmColor **colorTable, **color;
69 int a;
70
71 colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
72 if (!colorTable) {
73 *oldct = NULL;
74 return (XpmNoMemory);
75 }
76 for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++)
77 *color = ct;
78 *oldct = colorTable;
79 return (XpmSuccess);
80}
81
82static void
83FreeOldColorTable(XpmColor **colorTable, int ncolors)
84{
85 int a, b;
86 XpmColor **color;
87 char **sptr;
88
89 if (colorTable) {
90 for (a = 0, color = colorTable; a < ncolors; a++, color++) {
91 for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++)
92 if (*sptr)
93 XpmFree(*sptr);
94 }
95 XpmFree(*colorTable);
96 XpmFree(colorTable);
97 }
98}
99
100/* end 3.2 bc */
101
102
103/*
104 * Free the computed color table
105 */
106void
107xpmFreeColorTable(XpmColor *colorTable, int ncolors)
108{
109 int a, b;
110 XpmColor *color;
111 char **sptr;
112
113 if (colorTable) {
114 for (a = 0, color = colorTable; a < ncolors; a++, color++) {
115 for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++)
116 if (*sptr)
117 XpmFree(*sptr);
118 }
119 XpmFree(colorTable);
120 }
121}
122
123/*
124 * Free array of extensions
125 */
126void
127XpmFreeExtensions(XpmExtension *extensions, int nextensions)
128{
129 unsigned int i, j, nlines;
130 XpmExtension *ext;
131 char **sptr;
132
133 if (extensions) {
134 for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
135 if (ext->name)
136 XpmFree(ext->name);
137 nlines = ext->nlines;
138 for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++)
139 if (*sptr)
140 XpmFree(*sptr);
141 if (ext->lines)
142 XpmFree(ext->lines);
143 }
144 XpmFree(extensions);
145 }
146}
147
148
149/*
150 * Return the XpmAttributes structure size
151 */
152
153int
154XpmAttributesSize()
155{
156 return sizeof(XpmAttributes);
157}
158
159/*
160 * Init returned data to free safely later on
161 */
162void
163xpmInitAttributes(XpmAttributes *attributes)
164{
165 if (attributes) {
166 attributes->pixels = NULL;
167 attributes->npixels = 0;
168 attributes->colorTable = NULL;
169 attributes->ncolors = 0;
170/* 3.2 backward compatibility code */
171 attributes->hints_cmt = NULL;
172 attributes->colors_cmt = NULL;
173 attributes->pixels_cmt = NULL;
174/* end 3.2 bc */
175 attributes->extensions = NULL;
176 attributes->nextensions = 0;
177 }
178}
179
180/*
181 * Fill in the XpmAttributes with the XpmImage and the XpmInfo
182 */
183void
184xpmSetAttributes(XpmAttributes *attributes, XpmImage *image, XpmInfo *info)
185{
186 if (attributes->valuemask & XpmReturnColorTable) {
187 attributes->colorTable = image->colorTable;
188 attributes->ncolors = image->ncolors;
189
190 /* avoid deletion of copied data */
191 image->ncolors = 0;
192 image->colorTable = NULL;
193 }
194/* 3.2 backward compatibility code */
195 else if (attributes->valuemask & XpmReturnInfos) {
196 int ErrorStatus;
197
198 ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors,
199 (XpmColor ***)
200 &attributes->colorTable);
201
202 /* if error just say we can't return requested data */
203 if (ErrorStatus != XpmSuccess) {
204 attributes->valuemask &= ~XpmReturnInfos;
205 if (!(attributes->valuemask & XpmReturnPixels)) {
206 XpmFree(attributes->pixels);
207 attributes->pixels = NULL;
208 attributes->npixels = 0;
209 }
210 attributes->ncolors = 0;
211 } else {
212 attributes->ncolors = image->ncolors;
213 attributes->hints_cmt = info->hints_cmt;
214 attributes->colors_cmt = info->colors_cmt;
215 attributes->pixels_cmt = info->pixels_cmt;
216
217 /* avoid deletion of copied data */
218 image->ncolors = 0;
219 image->colorTable = NULL;
220 info->hints_cmt = NULL;
221 info->colors_cmt = NULL;
222 info->pixels_cmt = NULL;
223 }
224 }
225/* end 3.2 bc */
226 if (attributes->valuemask & XpmReturnExtensions) {
227 attributes->extensions = info->extensions;
228 attributes->nextensions = info->nextensions;
229
230 /* avoid deletion of copied data */
231 info->extensions = NULL;
232 info->nextensions = 0;
233 }
234 if (info->valuemask & XpmHotspot) {
235 attributes->valuemask |= XpmHotspot;
236 attributes->x_hotspot = info->x_hotspot;
237 attributes->y_hotspot = info->y_hotspot;
238 }
239 attributes->valuemask |= XpmCharsPerPixel;
240 attributes->cpp = image->cpp;
241 attributes->valuemask |= XpmSize;
242 attributes->width = image->width;
243 attributes->height = image->height;
244}
245
246/*
247 * Free the XpmAttributes structure members
248 * but the structure itself
249 */
250void
251XpmFreeAttributes(XpmAttributes *attributes)
252{
253 if (attributes->valuemask & XpmReturnPixels && attributes->npixels) {
254 XpmFree(attributes->pixels);
255 attributes->pixels = NULL;
256 attributes->npixels = 0;
257 }
258 if (attributes->valuemask & XpmReturnColorTable) {
259 xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
260 attributes->colorTable = NULL;
261 attributes->ncolors = 0;
262 }
263/* 3.2 backward compatibility code */
264 else if (attributes->valuemask & XpmInfos) {
265 if (attributes->colorTable) {
266 FreeOldColorTable((XpmColor **) attributes->colorTable,
267 attributes->ncolors);
268 attributes->colorTable = NULL;
269 attributes->ncolors = 0;
270 }
271 if (attributes->hints_cmt) {
272 XpmFree(attributes->hints_cmt);
273 attributes->hints_cmt = NULL;
274 }
275 if (attributes->colors_cmt) {
276 XpmFree(attributes->colors_cmt);
277 attributes->colors_cmt = NULL;
278 }
279 if (attributes->pixels_cmt) {
280 XpmFree(attributes->pixels_cmt);
281 attributes->pixels_cmt = NULL;
282 }
283 if (attributes->pixels) {
284 XpmFree(attributes->pixels);
285 attributes->pixels = NULL;
286 attributes->npixels = 0;
287 }
288 }
289/* end 3.2 bc */
290 if (attributes->valuemask & XpmReturnExtensions
291 && attributes->nextensions) {
292 XpmFreeExtensions(attributes->extensions, attributes->nextensions);
293 attributes->extensions = NULL;
294 attributes->nextensions = 0;
295 }
296 attributes->valuemask = 0;
297}
298
299/*
300 * Init returned data to free safely later on
301 */
302void
303xpmInitXpmImage(XpmImage *image)
304{
305 image->ncolors = 0;
306 image->colorTable = NULL;
307 image->data = NULL;
308}
309
310/*
311 * Free the XpmImage data which have been allocated
312 */
313void
314XpmFreeXpmImage(XpmImage *image)
315{
316 if (image->colorTable)
317 xpmFreeColorTable(image->colorTable, image->ncolors);
318 XpmFree(image->data);
319 image->data = NULL;
320}
321
322/*
323 * Init returned data to free safely later on
324 */
325void
326xpmInitXpmInfo(XpmInfo *info)
327{
328 if (info) {
329 info->hints_cmt = NULL;
330 info->colors_cmt = NULL;
331 info->pixels_cmt = NULL;
332 info->extensions = NULL;
333 info->nextensions = 0;
334 }
335}
336
337/*
338 * Free the XpmInfo data which have been allocated
339 */
340void
341XpmFreeXpmInfo(XpmInfo *info)
342{
343 if (info) {
344 if (info->valuemask & XpmComments) {
345 if (info->hints_cmt) {
346 XpmFree(info->hints_cmt);
347 info->hints_cmt = NULL;
348 }
349 if (info->colors_cmt) {
350 XpmFree(info->colors_cmt);
351 info->colors_cmt = NULL;
352 }
353 if (info->pixels_cmt) {
354 XpmFree(info->pixels_cmt);
355 info->pixels_cmt = NULL;
356 }
357 }
358 if (info->valuemask & XpmReturnExtensions && info->nextensions) {
359 XpmFreeExtensions(info->extensions, info->nextensions);
360 info->extensions = NULL;
361 info->nextensions = 0;
362 }
363 info->valuemask = 0;
364 }
365}
366
367/*
368 * Set the XpmInfo valuemask to retrieve required info
369 */
370void
371xpmSetInfoMask(XpmInfo *info, XpmAttributes *attributes)
372{
373 info->valuemask = 0;
374 if (attributes->valuemask & XpmReturnInfos)
375 info->valuemask |= XpmReturnComments;
376 if (attributes->valuemask & XpmReturnExtensions)
377 info->valuemask |= XpmReturnExtensions;
378}
379
380/*
381 * Fill in the XpmInfo with the XpmAttributes
382 */
383void
384xpmSetInfo(XpmInfo *info, XpmAttributes *attributes)
385{
386 info->valuemask = 0;
387 if (attributes->valuemask & XpmInfos) {
388 info->valuemask |= XpmComments | XpmColorTable;
389 info->hints_cmt = attributes->hints_cmt;
390 info->colors_cmt = attributes->colors_cmt;
391 info->pixels_cmt = attributes->pixels_cmt;
392 }
393 if (attributes->valuemask & XpmExtensions) {
394 info->valuemask |= XpmExtensions;
395 info->extensions = attributes->extensions;
396 info->nextensions = attributes->nextensions;
397 }
398 if (attributes->valuemask & XpmHotspot) {
399 info->valuemask |= XpmHotspot;
400 info->x_hotspot = attributes->x_hotspot;
401 info->y_hotspot = attributes->y_hotspot;
402 }
403}
404
405
406#ifdef NEED_STRDUP
407/*
408 * in case strdup is not provided by the system here is one
409 * which does the trick
410 */
411char *
412strdup(char *s1)
413{
414 char *s2;
415 int l = strlen(s1) + 1;
416
417 if (s2 = (char *) XpmMalloc(l))
418 strncpy(s2, s1, l);
419 return s2;
420}
421
422#endif
423
424unsigned int
425atoui(register char *p, unsigned int l, unsigned int *ui_return)
426{
427 register unsigned int n, i;
428
429 n = 0;
430 for (i = 0; i < l; i++)
431 if (*p >= '0' && *p <= '9')
432 n = n * 10 + *p++ - '0';
433 else
434 break;
435
436 if (i != 0 && i == l) {
437 *ui_return = n;
438 return 1;
439 } else
440 return 0;
441}
442
443
444/*
445 * File / Buffer utilities
446 */
447int
448XpmReadFileToBuffer(char *filename, char **buffer_return)
449{
450 int fd, fcheck, len;
451 char *ptr;
452 struct stat stats;
453 FILE *fp;
454
455 *buffer_return = NULL;
456
457 fd = open(filename, O_RDONLY);
458 if (fd < 0)
459 return XpmOpenFailed;
460
461 if (fstat(fd, &stats)) {
462 close(fd);
463 return XpmOpenFailed;
464 }
465 fp = fdopen(fd, "r");
466 if (!fp) {
467 close(fd);
468 return XpmOpenFailed;
469 }
470 len = (int) stats.st_size;
471 ptr = (char *) XpmMalloc(len + 1);
472 if (!ptr) {
473 fclose(fp);
474 return XpmNoMemory;
475 }
476 fcheck = fread(ptr, len, 1, fp);
477 fclose(fp);
478 if (fcheck != 1) {
479 XpmFree(ptr);
480 return XpmOpenFailed;
481 }
482 ptr[len] = '\0';
483 *buffer_return = ptr;
484 return XpmSuccess;
485}
486
487int
488XpmWriteFileFromBuffer(char *filename, char *buffer)
489{
490 int fcheck, len;
491 FILE *fp = fopen(filename, "w");
492
493 if (!fp)
494 return XpmOpenFailed;
495
496 len = strlen(buffer);
497 fcheck = fwrite(buffer, len, 1, fp);
498 fclose(fp);
499 if (fcheck != 1)
500 return XpmOpenFailed;
501
502 return XpmSuccess;
503}
504
505
506/*
507 * Small utility function
508 */
509char *
510XpmGetErrorString(int errcode)
511{
512 switch (errcode) {
513 case XpmColorError:
514 return ("XpmColorError");
515 case XpmSuccess:
516 return ("XpmSuccess");
517 case XpmOpenFailed:
518 return ("XpmOpenFailed");
519 case XpmFileInvalid:
520 return ("XpmFileInvalid");
521 case XpmNoMemory:
522 return ("XpmNoMemory");
523 case XpmColorFailed:
524 return ("XpmColorFailed");
525 default:
526 return ("Invalid XpmError");
527 }
528}
529
530/*
531 * The following function provides a way to figure out if the linked library is
532 * newer or older than the one with which a program has been first compiled.
533 */
534int
535XpmLibraryVersion()
536{
537 return XpmIncludeVersion;
538}
539
540
541#ifndef FOR_MSW
542void
543xpmCreatePixmapFromImage(Display *display, Drawable d, XImage *ximage, Pixmap *pixmap_return)
544{
545 GC gc;
546
547 *pixmap_return = XCreatePixmap(display, d, ximage->width,
548 ximage->height, ximage->depth);
549 gc = XCreateGC(display, *pixmap_return, 0, NULL);
550
551 XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0,
552 ximage->width, ximage->height);
553
554 XFreeGC(display, gc);
555}
556
557void
558xpmCreateImageFromPixmap(Display *display, Pixmap pixmap, XImage **ximage_return, unsigned int *width, unsigned int *height)
559{
560 unsigned int dum;
561 int dummy;
562 Window win;
563
564 if (*width == 0 && *height == 0)
565 XGetGeometry(display, pixmap, &win, &dummy, &dummy,
566 width, height, &dum, &dum);
567
568 *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height,
569 AllPlanes, ZPixmap);
570}
571
572#endif /* FOR_MSW */