Change to the linux kernel coding style
[wmaker-crm.git] / wrlib / xpm.c
1 /* xpm.c - load XPM image from file
2  *
3  * Raster graphics library
4  *
5  * Copyright (c) 1997-2003 Alfredo K. Kojima
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Library General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Library General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <config.h>
23
24 #ifdef USE_XPM
25
26 #include <X11/Xlib.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <X11/xpm.h>
31
32 #include "wraster.h"
33
34 RImage *RGetImageFromXPMData(RContext * context, char **xpmData)
35 {
36         Display *dpy = context->dpy;
37         Colormap cmap = context->cmap;
38         RImage *image;
39         XpmImage xpm;
40         unsigned char *color_table[4];
41         unsigned char *data;
42         int *p;
43         int i;
44
45         i = XpmCreateXpmImageFromData(xpmData, &xpm, (XpmInfo *) NULL);
46         if (i != XpmSuccess) {
47                 switch (i) {
48                 case XpmOpenFailed:
49                         RErrorCode = RERR_OPEN;
50                         break;
51                 case XpmFileInvalid:
52                         RErrorCode = RERR_BADIMAGEFILE;
53                         break;
54                 case XpmNoMemory:
55                         RErrorCode = RERR_NOMEMORY;
56                         break;
57                 default:
58                         RErrorCode = RERR_BADIMAGEFILE;
59                         break;
60                 }
61                 return NULL;
62         }
63         if (xpm.height < 1 || xpm.width < 1) {
64                 RErrorCode = RERR_BADIMAGEFILE;
65                 XpmFreeXpmImage(&xpm);
66                 return NULL;
67         }
68
69         if (xpm.colorTable == NULL) {
70                 RErrorCode = RERR_BADIMAGEFILE;
71                 XpmFreeXpmImage(&xpm);
72                 return NULL;
73         }
74         image = RCreateImage(xpm.width, xpm.height, True);
75         if (!image) {
76                 XpmFreeXpmImage(&xpm);
77                 return NULL;
78         }
79
80         /* make color table */
81         for (i = 0; i < 4; i++) {
82                 color_table[i] = malloc(xpm.ncolors * sizeof(char));
83                 if (!color_table[i]) {
84                         for (i = i - 1; i >= 0; i--) {
85                                 if (color_table[i])
86                                         free(color_table[i]);
87                         }
88                         RReleaseImage(image);
89                         RErrorCode = RERR_NOMEMORY;
90                         XpmFreeXpmImage(&xpm);
91                         return NULL;
92                 }
93         }
94
95         for (i = 0; i < xpm.ncolors; i++) {
96                 XColor xcolor;
97                 char *color = NULL;
98
99                 if (xpm.colorTable[i].c_color)
100                         color = xpm.colorTable[i].c_color;
101                 else if (xpm.colorTable[i].g_color)
102                         color = xpm.colorTable[i].g_color;
103                 else if (xpm.colorTable[i].g4_color)
104                         color = xpm.colorTable[i].g4_color;
105                 else if (xpm.colorTable[i].m_color)
106                         color = xpm.colorTable[i].m_color;
107                 else if (xpm.colorTable[i].symbolic)
108                         color = xpm.colorTable[i].symbolic;
109
110                 if (!color) {
111                         color_table[0][i] = 0xbe;
112                         color_table[1][i] = 0xbe;
113                         color_table[2][i] = 0xbe;
114                         color_table[3][i] = 0xff;
115                         continue;
116                 }
117
118                 if (strncmp(color, "None", 4) == 0) {
119                         color_table[0][i] = 0;
120                         color_table[1][i] = 0;
121                         color_table[2][i] = 0;
122                         color_table[3][i] = 0;
123                         continue;
124                 }
125                 if (XParseColor(dpy, cmap, color, &xcolor)) {
126                         color_table[0][i] = xcolor.red >> 8;
127                         color_table[1][i] = xcolor.green >> 8;
128                         color_table[2][i] = xcolor.blue >> 8;
129                         color_table[3][i] = 0xff;
130                 } else {
131                         color_table[0][i] = 0xbe;
132                         color_table[1][i] = 0xbe;
133                         color_table[2][i] = 0xbe;
134                         color_table[3][i] = 0xff;
135                 }
136         }
137         /* convert pixmap to RImage */
138         p = (int *)xpm.data;
139         data = image->data;
140         for (i = 0; i < xpm.width * xpm.height; i++) {
141                 *(data++) = color_table[0][*p];
142                 *(data++) = color_table[1][*p];
143                 *(data++) = color_table[2][*p];
144                 *(data++) = color_table[3][*p];
145                 p++;
146         }
147         for (i = 0; i < 4; i++) {
148                 free(color_table[i]);
149         }
150         XpmFreeXpmImage(&xpm);
151         return image;
152 }
153
154 RImage *RLoadXPM(RContext * context, char *file, int index)
155 {
156         Display *dpy = context->dpy;
157         Colormap cmap = context->cmap;
158         RImage *image;
159         XpmImage xpm;
160         unsigned char *color_table[4];
161         unsigned char *data;
162         int *p;
163         int i;
164
165         i = XpmReadFileToXpmImage(file, &xpm, (XpmInfo *) NULL);
166         if (i != XpmSuccess) {
167                 switch (i) {
168                 case XpmOpenFailed:
169                         RErrorCode = RERR_OPEN;
170                         break;
171                 case XpmFileInvalid:
172                         RErrorCode = RERR_BADIMAGEFILE;
173                         break;
174                 case XpmNoMemory:
175                         RErrorCode = RERR_NOMEMORY;
176                         break;
177                 default:
178                         RErrorCode = RERR_BADIMAGEFILE;
179                         break;
180                 }
181                 return NULL;
182         }
183         if (xpm.height < 1 || xpm.width < 1) {
184                 RErrorCode = RERR_BADIMAGEFILE;
185                 XpmFreeXpmImage(&xpm);
186                 return NULL;
187         }
188
189         if (xpm.colorTable == NULL) {
190                 RErrorCode = RERR_BADIMAGEFILE;
191                 XpmFreeXpmImage(&xpm);
192                 return NULL;
193         }
194         image = RCreateImage(xpm.width, xpm.height, True);
195         if (!image) {
196                 XpmFreeXpmImage(&xpm);
197                 return NULL;
198         }
199
200         /* make color table */
201         for (i = 0; i < 4; i++) {
202                 color_table[i] = malloc(xpm.ncolors * sizeof(char));
203                 if (!color_table[i]) {
204                         for (i = i - 1; i >= 0; i--) {
205                                 if (color_table[i])
206                                         free(color_table[i]);
207                         }
208                         RReleaseImage(image);
209                         RErrorCode = RERR_NOMEMORY;
210                         XpmFreeXpmImage(&xpm);
211                         return NULL;
212                 }
213         }
214
215         for (i = 0; i < xpm.ncolors; i++) {
216                 XColor xcolor;
217                 char *color = NULL;
218
219                 if (xpm.colorTable[i].c_color)
220                         color = xpm.colorTable[i].c_color;
221                 else if (xpm.colorTable[i].g_color)
222                         color = xpm.colorTable[i].g_color;
223                 else if (xpm.colorTable[i].g4_color)
224                         color = xpm.colorTable[i].g4_color;
225                 else if (xpm.colorTable[i].m_color)
226                         color = xpm.colorTable[i].m_color;
227                 else if (xpm.colorTable[i].symbolic)
228                         color = xpm.colorTable[i].symbolic;
229
230                 if (!color) {
231                         color_table[0][i] = 0xbe;
232                         color_table[1][i] = 0xbe;
233                         color_table[2][i] = 0xbe;
234                         color_table[3][i] = 0xff;
235                         continue;
236                 }
237
238                 if (strncmp(color, "None", 4) == 0) {
239                         color_table[0][i] = 0;
240                         color_table[1][i] = 0;
241                         color_table[2][i] = 0;
242                         color_table[3][i] = 0;
243                         continue;
244                 }
245                 if (XParseColor(dpy, cmap, color, &xcolor)) {
246                         color_table[0][i] = xcolor.red >> 8;
247                         color_table[1][i] = xcolor.green >> 8;
248                         color_table[2][i] = xcolor.blue >> 8;
249                         color_table[3][i] = 0xff;
250                 } else {
251                         color_table[0][i] = 0xbe;
252                         color_table[1][i] = 0xbe;
253                         color_table[2][i] = 0xbe;
254                         color_table[3][i] = 0xff;
255                 }
256         }
257         /* convert pixmap to RImage */
258         p = (int *)xpm.data;
259         data = image->data;
260         for (i = 0; i < xpm.width * xpm.height; i++, p++) {
261                 *(data++) = color_table[0][*p];
262                 *(data++) = color_table[1][*p];
263                 *(data++) = color_table[2][*p];
264                 *(data++) = color_table[3][*p];
265         }
266         for (i = 0; i < 4; i++) {
267                 free(color_table[i]);
268         }
269         XpmFreeXpmImage(&xpm);
270         return image;
271 }
272
273 #endif                          /* USE_XPM */