1 #ifndef production
2 static char rcsId[]="$Header$";
3 #endif
4 /*****
5 * readXPM.c : XmHTML XPM image loading routines
6 *
7 * This file Version	$Revision$
8 *
9 * Creation date:		Wed Feb 19 03:19:23 GMT+0100 1997
10 * Last modification: 	$Date$
11 * By:					$Author$
12 * Current State:		$State$
13 *
14 * Author:				newt
15 *
16 * Copyright (C) 1994-1997 by Ripley Software Development
17 * All Rights Reserved
18 *
19 * This file is part of the XmHTML Widget Library.
20 *
21 * This library is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU Library General Public
23 * License as published by the Free Software Foundation; either
24 * version 2 of the License, or (at your option) any later version.
25 *
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29 * Library General Public License for more details.
30 *
31 * You should have received a copy of the GNU Library General Public
32 * License along with this library; if not, write to the Free
33 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 *
35 *****/
36 /*****
37 * ChangeLog
38 * $Log$
39 * Revision 1.1  2011/06/30 16:10:38  rwcox
40 * Cadd
41 *
42 * Revision 1.11  1998/04/27 07:03:20  newt
43 * tka stuff
44 *
45 * Revision 1.10  1998/04/04 06:28:36  newt
46 * XmHTML Beta 1.1.3
47 *
48 * Revision 1.9  1997/10/23 00:25:26  newt
49 * XmHTML Beta 1.1.0 release
50 *
51 * Revision 1.8  1997/08/30 01:34:07  newt
52 * Extended the check for transparent pixel names to include mask and background.
53 *
54 * Revision 1.7  1997/08/01 13:12:43  newt
55 * Much more readable: eliminated duplicate code.
56 *
57 * Revision 1.6  1997/05/28 01:56:09  newt
58 * Image depth support.
59 *
60 * Revision 1.5  1997/04/29 14:31:15  newt
61 * Header files modifications.
62 *
63 * Revision 1.4  1997/03/20 08:16:03  newt
64 * Transparency color bugfix: pixel is now index instead of background pixel
65 *
66 * Revision 1.3  1997/03/11 19:59:03  newt
67 * ImageBuffer changes
68 *
69 * Revision 1.2  1997/03/04 18:49:55  newt
70 * Removed dependency on work_area field of XmHTMLWidget
71 *
72 * Revision 1.1  1997/03/02 23:03:00  newt
73 * Initial Revision
74 *
75 *****/
76 #ifdef HAVE_CONFIG_H
77 #include "config.h"
78 #endif
79 
80 #include <stdio.h>
81 #include <stdlib.h>
82 
83 /* prevent Byte re-declaration */
84 #if defined(HAVE_LIBPNG) || defined(HAVE_LIBZ)
85 #include <zlib.h>
86 #endif
87 
88 #include "toolkit.h"
89 #include XmHTMLPrivateHeader
90 #include "plc.h"
91 
92 /* xpm checks whether Pixel has already been defined. IntrinsicP doesn't */
93 #include <X11/xpm.h>
94 
95 /*** External Function Prototype Declarations ***/
96 
97 /*** Public Variable Declarations ***/
98 
99 /*** Private Datatype Declarations ****/
100 
101 /*** Private Function Prototype Declarations ****/
102 static XmHTMLRawImageData *doXpm(Widget html, ImageBuffer *ib,
103 	XpmImage *xpm_image);
104 
105 /*** Private Variable Declarations ***/
106 
107 /*****
108 * Name: 		doXpm
109 * Return Type: 	XmHTMLRawImageData*
110 * Description: 	converts the given xpm data to our own format
111 * In:
112 *	html:		widget id;
113 *	ib:			current image buffer;
114 *	xpm_image:	xpm image data;
115 * Returns:
116 *
117 *****/
118 static XmHTMLRawImageData*
doXpm(Widget html,ImageBuffer * ib,XpmImage * xpm_image)119 doXpm(Widget html, ImageBuffer *ib, XpmImage *xpm_image)
120 {
121 	int i, is_gray = 0;
122 	XColor tmpcolr;
123 	String col_name;
124 	Colormap cmap;
125 	static XmHTMLRawImageData *img_data;
126 	ToolkitAbstraction *tka;
127 	register Byte *bptr;
128 	register unsigned int *ptr;
129 
130 	if(XmIsHTML(html))
131 		tka = HTML_ATTR(tka);
132 	else if(_xmimage_cfg == NULL || (tka = _xmimage_cfg->tka) == NULL)
133 	{
134 		_XmHTMLWarning(__WFUNC__(html, "doXpm"),
135 			"XmImage(XPM): Unable to find a valid ToolkitAbstraction.");
136 		return(NULL);
137 	}
138 
139 	/*
140 	* get colormap. We need one to obtain the RGB components of the
141 	* selected colors, pixmaps define their colors using a symbolic name
142 	* instead of defining the wanted RGB components.
143 	*/
144 	cmap = TkaGetColormap(html);
145 
146 	/* allocate raw image */
147 	AllocRawImageWithCmap(img_data, (int)xpm_image->width,
148 		(int)xpm_image->height, (int)xpm_image->ncolors);
149 
150 	/* little trick to compute image depth */
151 	if(ib != NULL)
152 	{
153 		ib->depth = 2;
154 		while((ib->depth << 2) < img_data->cmapsize && ib->depth < 12)
155 			ib->depth++;
156 	}
157 
158 	/* fill colormap for this image */
159 	for(i = 0; i < img_data->cmapsize; i++)
160 	{
161 		/* pick up the name of the current color */
162 		col_name = xpm_image->colorTable[i].c_color;
163 
164 		/* transparancy, these can *all* name a transparent color. */
165 		if(!(strcasecmp(col_name, "none")) ||
166 			!(strcasecmp(col_name, "mask")) ||
167 			!(strcasecmp(col_name, "background")))
168 		{
169 			Pixel bg_pixel;
170 
171 			/*
172 			* Get current background index: use the given background pixel
173 			* index if we have one. Else get the current background color of
174 			* the given widget.
175 			*/
176 			if(XmIsHTML(html))
177 				bg_pixel = HTML_ATTR(body_bg);
178 			else
179 			{
180 				if(_xmimage_cfg->flags & ImageBackground)
181 					bg_pixel = _xmimage_cfg->bg_color;
182 				else
183 					bg_pixel = 0;
184 			}
185 
186 			/* get RGB components for this color. */
187 			GETP(tmpcolr) = bg_pixel;
188 			tka->QueryColor(tka->dpy, cmap, &tmpcolr);
189 
190 			/* store background pixel index */
191 			img_data->bg = i;
192 		}
193 		else /* get RGB components for this color */
194 			(void)tka->ParseColor(tka->dpy, cmap, col_name, &tmpcolr);
195 
196 		/* 16bit RGB values */
197 		GETR(img_data->cmap[i]) = GETR(tmpcolr);
198 		GETG(img_data->cmap[i]) = GETG(tmpcolr);
199 		GETB(img_data->cmap[i]) = GETB(tmpcolr);
200 		is_gray &= (GETR(tmpcolr) == GETG(tmpcolr)) &&
201 					(GETG(tmpcolr) == GETB(tmpcolr));
202 	}
203 	/* no need to fill in remainder of colormap, gets done by AllocRawImage */
204 	img_data->color_class = (is_gray != 0 ? XmIMAGE_COLORSPACE_INDEXED :
205 		XmIMAGE_COLORSPACE_GRAYSCALE);
206 
207 	/*****
208 	* convert xpm image data to our own internal format: array of indices
209 	* in the colormap for this image. First pixel at upper-left corner.
210 	* The XpmImage data is actually already in this format but as the
211 	* XpmImage data is unsigned int we need to check if the indices don't
212 	* exceed 255 (or we would get an out-of-bounds indexing leading to a
213 	* segmentation fault eventually).
214 	*****/
215 	ptr  = xpm_image->data;
216 	bptr = img_data->data;
217 	for(i = 0; i < (img_data->width * img_data->height); i++)
218 	{
219 		int pix;
220 		pix = (int)*ptr;
221 		if (pix > (XmHTML_MAX_IMAGE_COLORS - 1))
222 			pix = 0;
223 		*bptr++ = (Byte)pix;
224 		ptr++;
225 	}
226 	XpmFreeXpmImage(xpm_image);
227 	return(img_data);
228 }
229 
230 /*****
231 * Name: 		_XmHTMLReadXPM
232 * Return Type: 	XmHTMLRawImageData*
233 * Description: 	reads an xpm image of any type from xpm data read from a file.
234 * In:
235 *	html:		widget id;
236 *	ib:			image data;
237 * Returns:
238 *	allocated image upon success. NULL on failure.
239 *****/
240 XmHTMLRawImageData*
_XmHTMLReadXPM(Widget html,ImageBuffer * ib)241 _XmHTMLReadXPM(Widget html, ImageBuffer *ib)
242 {
243 	XpmImage xpm_image;
244 	XpmInfo foo;
245 	int i;
246 
247 	(void)memset(&xpm_image, 0, sizeof(xpm_image));
248 	(void)memset(&foo, 0, sizeof(foo));
249 
250 	if((i = XpmCreateXpmImageFromBuffer((String)ib->buffer, &xpm_image,
251 		&foo)) != XpmSuccess)
252 	{
253 		/* spit out appropriate error message */
254 		_XmHTMLWarning(__WFUNC__(html, "_XmHTMLReadXPM"),
255 			XMHTML_MSG_121, "Xpm", ib->file, XpmGetErrorString(i));
256 
257 		/* release everything */
258 		XpmFreeXpmInfo(&foo);
259 		XpmFreeXpmImage(&xpm_image);
260 		return(NULL);
261 	}
262 	/* we don't use the returned info so free it */
263 	XpmFreeXpmInfo(&foo);
264 
265 	/* convert xpm data to raw image data */
266 	return(doXpm(html, ib, &xpm_image));
267 }
268 
269 /*****
270 * Name: 		_XmHTMLCreateXpmFromData
271 * Return Type: 	XmHTMLRawImageData*
272 * Description: 	reads an xpm image of any type from raw xpm data
273 * In:
274 *	html:		widget id;
275 *	data:		xpm data
276 * Returns:
277 *	allocated image upon success. NULL on failure.
278 *****/
279 XmHTMLRawImageData*
_XmHTMLCreateXpmFromData(Widget html,char ** data,String src)280 _XmHTMLCreateXpmFromData(Widget html, char **data, String src)
281 {
282 	XpmImage xpm_image;
283 	XpmInfo foo;
284 	int i;
285 
286 	(void)memset(&xpm_image, 0, sizeof(xpm_image));
287 	(void)memset(&foo, 0, sizeof(foo));
288 
289 	if((i = XpmCreateXpmImageFromData(data, &xpm_image, &foo)) != XpmSuccess)
290 	{
291 		/* spit out appropriate error message */
292 		_XmHTMLWarning(__WFUNC__(html, "_XmHTMLCreateXpmFromData"),
293 			XMHTML_MSG_121, "Xpm", "(builtin)", XpmGetErrorString(i));
294 
295 		/* release everything */
296 		XpmFreeXpmInfo(&foo);
297 		XpmFreeXpmImage(&xpm_image);
298 		return(NULL);
299 	}
300 	/* we don't use the returned info so free it */
301 	XpmFreeXpmInfo(&foo);
302 
303 	/* convert xpm data to raw image data */
304 	return(doXpm(html, NULL, &xpm_image));
305 }
306 
307 /*****
308 * Progressive Pixmap loading routines
309 *****/
310 
311 void
_PLC_XPM_Init(PLC * plc)312 _PLC_XPM_Init(PLC *plc)
313 {
314 	plc->plc_status = PLC_ABORT;
315 }
316 
317 void
_PLC_XPM_ScanlineProc(PLC * plc)318 _PLC_XPM_ScanlineProc(PLC *plc)
319 {
320 	plc->plc_status = PLC_ABORT;
321 }
322 
323 void
_PLC_XPM_Destructor(PLC * plc)324 _PLC_XPM_Destructor(PLC *plc)
325 {
326 	plc->plc_status = PLC_ABORT;
327 }
328 
329