1 /* +-------------------------------------------------------------------+ */
2 /* | Copyright 1993, David Koblas (koblas@netcom.com) | */
3 /* | | */
4 /* | Permission to use, copy, modify, and to distribute this software | */
5 /* | and its documentation for any purpose is hereby granted without | */
6 /* | fee, provided that the above copyright notice appear in all | */
7 /* | copies and that both that copyright notice and this permission | */
8 /* | notice appear in supporting documentation. There is no | */
9 /* | representations about the suitability of this software for | */
10 /* | any purpose. this software is provided "as is" without express | */
11 /* | or implied warranty. | */
12 /* | | */
13 /* +-------------------------------------------------------------------+ */
14
15 /* $Id: readWriteXPM.c,v 1.21 2005/03/20 20:15:34 demailly Exp $ */
16
17 #include <stdio.h>
18
19 #include <X11/Intrinsic.h>
20 #include <X11/xpm.h>
21
22 #include "xpaint.h"
23 #include "messages.h"
24 #include "image.h"
25 #include "rwTable.h"
26
27 extern int file_transparent;
28 extern void Notice(Widget w,...);
29
AlphaWarning(char * format,int mode)30 void AlphaWarning(char *format, int mode)
31 {
32 Notice((Global.canvas)? Global.canvas : Global.toplevel,
33 msgText[WARNING_ALPHA_NO_SUPPORT+mode], format);
34 }
35
WriteXPM(char * file,Image * image)36 int WriteXPM(char *file, Image * image)
37 {
38 XpmAttributes attr;
39 Display *dpy = Global.display;
40
41 if (!image) return 1;
42
43 if (image->alpha) AlphaWarning("XPM", 1);
44
45 if (!image->sourcePixmap) return 1;
46 attr.valuemask = XpmColormap;
47 if (image->sourceColormap)
48 attr.colormap = (Colormap) image->sourceColormap;
49 else
50 attr.colormap = DefaultColormap(dpy, DefaultScreen(dpy));
51
52 return (XpmWriteFileFromPixmap(Global.display, file,
53 image->sourcePixmap, image->sourceMask, &attr) != XpmSuccess);
54 }
55
TestXPM(char * file)56 int TestXPM(char *file)
57 {
58 FILE *fd = fopen(file, "r");
59 char buf[40];
60 int i, n, ret = 0;
61 int cstart = False;
62
63 if (fd == NULL)
64 return 0;
65
66 n = fread(buf, sizeof(char), sizeof(buf), fd);
67
68 for (i = 0; i < n && ret == 0; i++) {
69 if (!cstart) {
70 if (buf[i] == '/' && buf[i + 1] == '*')
71 cstart = True;
72 } else {
73 if (buf[i] == 'X' && buf[i + 1] == 'P' && buf[i + 2] == 'M')
74 ret = 1;
75 }
76 }
77
78 fclose(fd);
79 return ret;
80 }
81
ReadXPM(char * file)82 Image * ReadXPM(char *file)
83 {
84 Display *dpy = Global.display;
85 XImage *xim, *mim = NULL;
86 int x, y, i;
87 Image *image;
88 XpmAttributes attr;
89 XpmColorSymbol bg;
90 XColor bgcolor;
91 XColor *col;
92 unsigned char *ucp, *ump = NULL;
93 unsigned short *usp;
94 Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy));
95 int status;
96
97 bgcolor.flags = DoRed | DoGreen | DoBlue;
98 bgcolor.red = Global.bg[0]*257;
99 bgcolor.green = Global.bg[1]*257;
100 bgcolor.blue = Global.bg[2]*257;
101 XAllocColor(dpy, cmap, &bgcolor);
102 attr.valuemask = XpmColormap | XpmReturnPixels | XpmColorSymbols;
103 attr.colormap = cmap;
104 attr.numsymbols = 1;
105 attr.colorsymbols = &bg;
106 bg.pixel = bgcolor.pixel;
107 bg.name = NULL;
108 bg.value = "None";
109
110 if ((status = XpmReadFileToImage(dpy, file, &xim, &mim, &attr)) != XpmSuccess) {
111 switch (status) {
112 case XpmColorError:
113 RWSetMsg("XPM Color Error");
114 break;
115 case XpmSuccess:
116 RWSetMsg("Success, shouldn't have error & success");
117 break;
118 case XpmOpenFailed:
119 RWSetMsg("XPM Open Failed");
120 break;
121 case XpmFileInvalid:
122 RWSetMsg("File Invalid");
123 break;
124 case XpmNoMemory:
125 RWSetMsg("Not enough memory");
126 break;
127 case XpmColorFailed:
128 RWSetMsg("Unable to allocate color");
129 break;
130 }
131 XpmFreeAttributes(&attr);
132 return NULL;
133 }
134
135 image = ImageNewCmap(attr.width, attr.height, attr.npixels);
136 ucp = (unsigned char *) image->data;
137 usp = (unsigned short *) image->data;
138
139 col = (XColor *) XtMalloc(sizeof(XColor) * attr.npixels);
140 for (i = 0; i < attr.npixels; i++) {
141 col[i].pixel = attr.pixels[i];
142 col[i].flags = DoRed | DoGreen | DoBlue;
143 }
144 XQueryColors(dpy, cmap, col, attr.npixels);
145
146 if (mim != NULL) {
147 file_transparent = 1;
148 ImageMakeMask(image);
149 ump = image->alpha;
150 }
151
152 for (i = 0; i < attr.npixels; i++)
153 ImageSetCmap(image, i, col[i].red>>8, col[i].green>>8, col[i].blue>>8);
154
155 for (y = 0; y < xim->height; y++) {
156 for (x = 0; x < xim->width; x++) {
157 Pixel p;
158
159 if (mim != NULL) {
160 Pixel f = XGetPixel(mim, x, y);
161
162 if (!(*ump++ = (f?255:0))) {
163 if (attr.npixels > 256)
164 *usp++ = 0;
165 else
166 *ucp++ = 0;
167 continue;
168 }
169 }
170 p = XGetPixel(xim, x, y);
171
172 for (i = 0; i < attr.npixels && col[i].pixel != p; i++);
173
174 if (attr.npixels > 256)
175 *usp++ = i;
176 else
177 *ucp++ = i;
178 }
179 }
180
181 XtFree((XtPointer) col);
182 XDestroyImage(xim);
183 XpmFreeAttributes(&attr);
184
185 return image;
186 }
187