fix bug with alpha transparent xpm
[wmaker-crm.git] / wrlib / xpm.c
blob79cffe50d3644fe464f2b904d1bca199d2473955
1 /* xpm.c - load XPM image from file
2 *
3 * Raster graphics library
4 *
5 * Copyright (c) 1997 Alfredo K. Kojima
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.
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.
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.
22 #include <config.h>
25 #ifdef USE_XPM
27 #include <X11/Xlib.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <X11/xpm.h>
33 #include "wraster.h"
35 RImage*
36 RGetImageFromXPMData(RContext *context, char **data)
38 Display *dpy = context->dpy;
39 Colormap cmap = context->cmap;
40 RImage *image;
41 XpmImage xpm;
42 unsigned char *color_table[3];
43 unsigned char *r, *g, *b, *a;
44 int *p;
45 int i;
46 int transp=-1;
48 i = XpmCreateXpmImageFromData(data, &xpm, (XpmInfo *)NULL);
49 if (i!=XpmSuccess) {
50 switch (i) {
51 case XpmOpenFailed:
52 RErrorCode = RERR_OPEN;
53 break;
54 case XpmFileInvalid:
55 RErrorCode = RERR_BADIMAGEFILE;
56 break;
57 case XpmNoMemory:
58 RErrorCode = RERR_NOMEMORY;
59 break;
60 default:
61 RErrorCode = RERR_BADIMAGEFILE;
62 break;
64 return NULL;
66 if (xpm.height<1 || xpm.width < 1) {
67 RErrorCode = RERR_BADIMAGEFILE;
68 XpmFreeXpmImage(&xpm);
69 return NULL;
72 if (xpm.colorTable==NULL) {
73 RErrorCode = RERR_BADIMAGEFILE;
74 XpmFreeXpmImage(&xpm);
75 return NULL;
77 image = RCreateImage(xpm.width, xpm.height, True);
78 if (!image) {
79 XpmFreeXpmImage(&xpm);
80 return NULL;
83 /* make color table */
84 for (i=0; i<3; i++) {
85 color_table[i] = malloc(xpm.ncolors*sizeof(char));
86 if (!color_table[i]) {
87 for (i=i-1;i>=0; i--) {
88 if (color_table[i])
89 free(color_table[i]);
91 RDestroyImage(image);
92 RErrorCode = RERR_NOMEMORY;
93 XpmFreeXpmImage(&xpm);
94 return NULL;
98 for (i=0; i<xpm.ncolors; i++) {
99 XColor xcolor;
101 if (strncmp(xpm.colorTable[i].c_color,"None",4)==0) {
102 color_table[0][i]=0;
103 color_table[1][i]=0;
104 color_table[2][i]=0;
105 transp = i;
106 continue;
108 if (XParseColor(dpy, cmap, xpm.colorTable[i].c_color, &xcolor)) {
109 color_table[0][i] = xcolor.red>>8;
110 color_table[1][i] = xcolor.green>>8;
111 color_table[2][i] = xcolor.blue>>8;
112 } else {
113 color_table[0][i]=0xbe;
114 color_table[1][i]=0xbe;
115 color_table[2][i]=0xbe;
118 memset(image->data[3], 255, xpm.width*xpm.height);
119 /* convert pixmap to RImage */
120 p = (int*)xpm.data;
121 r = image->data[0];
122 g = image->data[1];
123 b = image->data[2];
124 a = image->data[3];
125 for (i=0; i<xpm.width*xpm.height; i++) {
126 if (*p==transp)
127 *a=0;
128 a++;
129 *(r++)=color_table[0][*p];
130 *(g++)=color_table[1][*p];
131 *(b++)=color_table[2][*p];
132 p++;
134 for(i=0; i<3; i++) {
135 free(color_table[i]);
137 XpmFreeXpmImage(&xpm);
138 return image;
143 RImage*
144 RLoadXPM(RContext *context, char *file, int index)
146 Display *dpy = context->dpy;
147 Colormap cmap = context->cmap;
148 RImage *image;
149 XpmImage xpm;
150 unsigned char *color_table[3];
151 unsigned char *r, *g, *b, *a;
152 int *p;
153 int i;
154 int transp=-1;
156 i = XpmReadFileToXpmImage(file, &xpm, (XpmInfo *)NULL);
157 if (i!=XpmSuccess) {
158 switch (i) {
159 case XpmOpenFailed:
160 RErrorCode = RERR_OPEN;
161 break;
162 case XpmFileInvalid:
163 RErrorCode = RERR_BADIMAGEFILE;
164 break;
165 case XpmNoMemory:
166 RErrorCode = RERR_NOMEMORY;
167 break;
168 default:
169 RErrorCode = RERR_BADIMAGEFILE;
170 break;
172 return NULL;
174 if (xpm.height<1 || xpm.width < 1) {
175 RErrorCode = RERR_BADIMAGEFILE;
176 XpmFreeXpmImage(&xpm);
177 return NULL;
180 if (xpm.colorTable==NULL) {
181 RErrorCode = RERR_BADIMAGEFILE;
182 XpmFreeXpmImage(&xpm);
183 return NULL;
185 image = RCreateImage(xpm.width, xpm.height, True);
186 if (!image) {
187 XpmFreeXpmImage(&xpm);
188 return NULL;
191 /* make color table */
192 for (i=0; i<3; i++) {
193 color_table[i] = malloc(xpm.ncolors*sizeof(char));
194 if (!color_table[i]) {
195 for (i=i-1;i>=0; i--) {
196 if (color_table[i])
197 free(color_table[i]);
199 RDestroyImage(image);
200 RErrorCode = RERR_NOMEMORY;
201 XpmFreeXpmImage(&xpm);
202 return NULL;
206 for (i=0; i<xpm.ncolors; i++) {
207 XColor xcolor;
209 if (strncmp(xpm.colorTable[i].c_color,"None",4)==0) {
210 color_table[0][i]=0;
211 color_table[1][i]=0;
212 color_table[2][i]=0;
213 transp = i;
214 continue;
216 if (XParseColor(dpy, cmap, xpm.colorTable[i].c_color, &xcolor)) {
217 color_table[0][i] = xcolor.red>>8;
218 color_table[1][i] = xcolor.green>>8;
219 color_table[2][i] = xcolor.blue>>8;
220 } else {
221 color_table[0][i]=0xbe;
222 color_table[1][i]=0xbe;
223 color_table[2][i]=0xbe;
226 memset(image->data[3], 255, xpm.width*xpm.height);
227 /* convert pixmap to RImage */
228 p = (int*)xpm.data;
229 r = image->data[0];
230 g = image->data[1];
231 b = image->data[2];
232 a = image->data[3];
233 for (i=0; i<xpm.width*xpm.height; i++) {
234 if (*p==transp)
235 *a=0;
236 a++;
237 *(r++)=color_table[0][*p];
238 *(g++)=color_table[1][*p];
239 *(b++)=color_table[2][*p];
240 p++;
242 for(i=0; i<3; i++) {
243 free(color_table[i]);
245 XpmFreeXpmImage(&xpm);
246 return image;
249 #endif /* USE_XPM */