1 /*
2  * Copyright (c) 2000,2001 Sasha Vasko <sasha at aftercode.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #ifdef _WIN32
20 #include "win32/config.h"
21 #else
22 #include "config.h"
23 #endif
24 
25 #undef LOCAL_DEBUG
26 #define DO_CLOCKING
27 
28 #ifdef DO_CLOCKING
29 #if TIME_WITH_SYS_TIME
30 # include <sys/time.h>
31 # include <time.h>
32 #else
33 # if HAVE_SYS_TIME_H
34 #  include <sys/time.h>
35 # else
36 #  include <time.h>
37 # endif
38 #endif
39 #endif
40 #ifdef HAVE_STDARG_H
41 #include <stdarg.h>
42 #endif
43 
44 #ifdef HAVE_GLX
45 # include <GL/gl.h>
46 # include <GL/glx.h>
47 /*# include <GL/glu.h> */
48 #endif
49 
50 
51 #ifdef _WIN32
52 # include "win32/afterbase.h"
53 #else
54 # include "afterbase.h"
55 #endif
56 #include "asvisual.h"
57 #include "blender.h"
58 #include "asimage.h"
59 #include "imencdec.h"
60 #include "ximage.h"
61 
62 
63 /* ***************************************************************************/
64 /* ASImage->XImage->pixmap->XImage->ASImage conversion						*/
65 /* ***************************************************************************/
66 
67 ASImage      *
picture_ximage2asimage(ASVisual * asv,XImage * xim,XImage * alpha_xim,unsigned int compression)68 picture_ximage2asimage (ASVisual *asv, XImage *xim, XImage *alpha_xim, unsigned int compression)
69 {
70 	ASImage      *im = NULL;
71 	unsigned char *xim_line;
72 	int           i, height, width, bpl;
73 	ASScanline    xim_buf;
74 #ifdef LOCAL_DEBUG
75 	CARD32       *tmp ;
76 #endif
77 #if 0
78   struct timeval stv;
79 	gettimeofday (&stv,NULL);
80 #define PRINT_BACKGROUND_OP_TIME do{ struct timeval tv;gettimeofday (&tv,NULL); tv.tv_sec-= stv.tv_sec;\
81                                      fprintf (stderr,__FILE__ "%d: elapsed  %ld usec\n",__LINE__,\
82                                               tv.tv_sec*1000000+tv.tv_usec-stv.tv_usec );}while(0)
83 #else
84 #define PRINT_BACKGROUND_OP_TIME do{}while(0)
85 #endif
86 
87 	if( xim && alpha_xim )
88 		if( xim->width != alpha_xim->width ||
89 		    xim->height != alpha_xim->height )
90 			return NULL ;
91 	if( xim == NULL && alpha_xim == NULL )
92 		return NULL ;
93 
94 	width = xim?xim->width:alpha_xim->width;
95 	height = xim?xim->height:alpha_xim->height;
96 
97 	im = create_asimage( width, height, compression);
98 	prepare_scanline( width, 0, &xim_buf, asv->BGR_mode );
99 #ifdef LOCAL_DEBUG
100 	tmp = safemalloc( width * sizeof(CARD32));
101 #endif
102 PRINT_BACKGROUND_OP_TIME;
103 	if( xim )
104 	{
105 		bpl 	 = xim->bytes_per_line;
106 		xim_line = (unsigned char *)xim->data;
107 
108 		for (i = 0; i < height; i++)
109 		{
110 #if 0
111 /* unfortunately this method does not seem to yield any better results performancewise: */
112 			if (asv->true_depth == 32 || asv->true_depth == 24)
113 			{
114 				if( asv->msb_first )
115 				{
116 				}else
117 					asimage_add_line_bgra (im, xim_line, i);
118 			}else
119 #endif
120 			if( xim->depth == (int)asv->true_depth )
121 			{
122 			    GET_SCANLINE(asv,xim,&xim_buf,i,xim_line);
123     		    asimage_add_line (im, IC_RED,   xim_buf.red, i);
124 			    asimage_add_line (im, IC_GREEN, xim_buf.green, i);
125 			    asimage_add_line (im, IC_BLUE,  xim_buf.blue, i);
126 				if( xim->depth == 32 && alpha_xim == NULL )
127 				    asimage_add_line (im, IC_ALPHA,  xim_buf.alpha, i);
128 #ifdef LOCAL_DEBUG
129 			    if( !asimage_compare_line( im, IC_RED,  xim_buf.red, tmp, i, True ) )
130 				exit(0);
131 			    if( !asimage_compare_line( im, IC_GREEN,  xim_buf.green, tmp, i, True ) )
132 				exit(0);
133 			    if( !asimage_compare_line( im, IC_BLUE,  xim_buf.blue, tmp, i, True ) )
134 				exit(0);
135 #endif
136 			}else if( xim->depth == 8 )
137 			{
138 			    register int x = width;
139 			    while(--x >= 0 )
140 	    		        xim_buf.blue[x] = (CARD32)(xim_line[x]);
141 	    		    asimage_add_line (im, IC_RED,   xim_buf.red, i);
142 			    asimage_add_line (im, IC_GREEN, xim_buf.red, i);
143 			    asimage_add_line (im, IC_BLUE,  xim_buf.red, i);
144 			}else if( xim->depth == 1 )
145 			{
146 			    register int x = width;
147 			    while(--x >= 0 )
148 			    {
149 #ifndef X_DISPLAY_MISSING
150 				xim_buf.red[x] = (XGetPixel(xim, x, i) == 0)?0x00:0xFF;
151 #else
152 				xim_buf.red[x] = 0xFF ;
153 #endif
154 			    }
155 	    		    asimage_add_line (im, IC_RED,   xim_buf.red, i);
156 			    asimage_add_line (im, IC_GREEN, xim_buf.red, i);
157 			    asimage_add_line (im, IC_BLUE,  xim_buf.red, i);
158 			}
159 
160 			xim_line += bpl;
161 		}
162 	}
163 PRINT_BACKGROUND_OP_TIME;
164 	if( alpha_xim )
165 	{
166 		CARD32 *dst = xim_buf.alpha ;
167 		bpl 	 = alpha_xim->bytes_per_line;
168 		xim_line = (unsigned char *)alpha_xim->data;
169 
170 		for (i = 0; i < height; i++)
171 		{
172 			register int x = width;
173 			if( alpha_xim->depth == 8 )
174 			{
175 				while(--x >= 0 ) dst[x] = (CARD32)(xim_line[x]);
176 			}else
177 			{
178 				while(--x >= 0 )
179 #ifndef X_DISPLAY_MISSING
180 					dst[x] = (XGetPixel(alpha_xim, x, i) == 0)?0x00:0xFF;
181 #else
182 					dst[x] = 0xFF ;
183 #endif
184 			}
185 			asimage_add_line (im, IC_ALPHA, xim_buf.alpha, i);
186 #ifdef LOCAL_DEBUG
187 			if( !asimage_compare_line( im, IC_ALPHA,  xim_buf.alpha, tmp, i, True ) )
188 				exit(0);
189 #endif
190 			xim_line += bpl;
191 		}
192 	}
193 	free_scanline(&xim_buf, True);
194 PRINT_BACKGROUND_OP_TIME;
195 
196 	return im;
197 }
198 
199 ASImage      *
ximage2asimage(ASVisual * asv,XImage * xim,unsigned int compression)200 ximage2asimage (ASVisual *asv, XImage * xim, unsigned int compression)
201 {
202 	return picture_ximage2asimage (asv, xim, NULL, compression);
203 }
204 
205 static inline int
xim_set_component(register CARD32 * src,register CARD32 value,int offset,int len)206 xim_set_component( register CARD32 *src, register CARD32 value, int offset, int len )
207 {
208 	register int i ;
209 	for( i = offset ; i < len ; ++i )
210 		src[i] = value;
211 	return len-offset;
212 }
213 
214 Bool
subimage2ximage(ASVisual * asv,ASImage * im,int x,int y,XImage * xim)215 subimage2ximage (ASVisual *asv, ASImage *im, int x, int y, XImage* xim)
216 {
217 	int            i, max_i;
218 	ASScanline     xim_buf;
219 	ASImageOutput *imout ;
220 /*#ifdef DO_CLOCKING
221 	clock_t       started = clock ();
222 #endif*/
223 	int width, height ;
224 	ASImage *scratch_im ;
225 
226 	if (im == NULL)
227 	{
228 LOCAL_DEBUG_OUT( "Attempt to convert NULL ASImage into XImage.", "" );
229 		return False;
230 	}
231 	if( x >= (int)im->width || y >= (int)im->height )
232 		return False;
233 	width = xim->width ;
234 	if( width > (int)im->width - x)
235 		width = (int)im->width - x;
236 	width = ( x > (int)im->width - width )?im->width - width:im->width - x ;
237 	height = xim->height ;
238 	if( height > (int)im->height - y )
239 		height = im->height - y ;
240 	scratch_im = create_asimage( width, height, 0);
241 	scratch_im->alt.ximage = xim ;
242 LOCAL_DEBUG_OUT( "target width = %d, height = %d", width, height );
243 	if( (imout = start_image_output( asv, scratch_im, ASA_ScratchXImage, 0, ASIMAGE_QUALITY_DEFAULT )) == NULL )
244 	{
245 LOCAL_DEBUG_OUT( "Failed to start ASImageOutput for ASImage %p and ASVisual %p", im, asv );
246 		return False;
247 	}
248 
249 	prepare_scanline( width, 0, &xim_buf, asv->BGR_mode );
250 /*#ifdef DO_CLOCKING
251 	started = clock ();
252 #endif*/
253 	set_flags( xim_buf.flags, SCL_DO_ALL );
254 	max_i = y + height ;
255 	for (i = y; i < max_i; i++)
256 	{
257 		int count ;
258 		if( (count = asimage_decode_line (im, IC_RED,   xim_buf.red, i, x, xim_buf.width)) < (int)xim_buf.width )
259 			xim_set_component( xim_buf.red, ARGB32_RED8(im->back_color), count, xim_buf.width );
260 		if( (count = asimage_decode_line (im, IC_GREEN, xim_buf.green, i, x, xim_buf.width))< (int)xim_buf.width )
261 			xim_set_component( xim_buf.green, ARGB32_GREEN8(im->back_color), count, xim_buf.width );
262 		if( (count = asimage_decode_line (im, IC_BLUE,  xim_buf.blue, i, x, xim_buf.width)) < (int)xim_buf.width )
263 			xim_set_component( xim_buf.blue, ARGB32_BLUE8(im->back_color), count, xim_buf.width );
264 		if( xim->depth == 32 )
265 			if( (count = asimage_decode_line (im, IC_ALPHA,  xim_buf.alpha, i, x, xim_buf.width)) < (int)xim_buf.width )
266 				xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
267 
268 		imout->output_image_scanline( imout, &xim_buf, 1 );
269 /*		LOCAL_DEBUG_OUT( "line %d, count = %d", i, count ); */
270 	}
271 /*#ifdef DO_CLOCKING
272 	fprintf (stderr, "asimage->ximage time (clocks): %lu\n", clock () - started);
273 #endif*/
274 	free_scanline(&xim_buf, True);
275 	stop_image_output(&imout);
276 
277 	scratch_im->alt.ximage = NULL ;
278 	destroy_asimage( &scratch_im );
279 	return True;
280 }
281 
282 
283 
284 static XImage*
asimage2ximage_ext(ASVisual * asv,ASImage * im,Bool scratch)285 asimage2ximage_ext (ASVisual *asv, ASImage *im, Bool scratch)
286 {
287 	XImage        *xim = NULL;
288 	int            i;
289 	ASImageOutput *imout ;
290 	ASImageDecoder *imdec;
291 /*#ifdef DO_CLOCKING
292 	clock_t       started = clock ();
293 #endif*/
294 
295 	if (im == NULL)
296 	{
297 LOCAL_DEBUG_OUT( "Attempt to convert NULL ASImage into XImage.", "" );
298 		return xim;
299 	}
300 	if( (imout = start_image_output( asv, im, scratch?ASA_ScratchXImage:ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT )) == NULL )
301 	{
302 LOCAL_DEBUG_OUT( "Failed to start ASImageOutput for ASImage %p and ASVisual %p", im, asv );
303 		return xim;
304 	}
305 	xim = im->alt.ximage ;
306 	/* no data in ximage yet */
307 	set_flags( im->flags, ASIM_XIMAGE_NOT_USEFUL);
308 /*#ifdef DO_CLOCKING
309 	started = clock ();
310 #endif*/
311 #if	1
312 	if ((imdec = start_image_decoding(  asv, im, (xim->depth >= 24)?SCL_DO_ALL:SCL_DO_COLOR,
313 										0, 0, im->width, im->height, NULL)) != NULL )
314 	{
315 		for (i = 0; i < (int)im->height; i++)
316 		{
317 			imdec->decode_image_scanline( imdec );
318 			imout->output_image_scanline( imout, &(imdec->buffer), 1);
319 		}
320 		stop_image_decoding( &imdec );
321 	}
322 #else
323 	{
324 		ASScanline     xim_buf;
325 		prepare_scanline( im->width, 0, &xim_buf, asv->BGR_mode );
326 		set_flags( xim_buf.flags, SCL_DO_ALL );
327 		for (i = 0; i < (int)im->height; i++)
328 		{
329 			int count ;
330 			if( (count = asimage_decode_line (im, IC_RED,   xim_buf.red, i, 0, xim_buf.width)) < (int)xim_buf.width )
331 				xim_set_component( xim_buf.red, ARGB32_RED8(im->back_color), count, xim_buf.width );
332 			if( (count = asimage_decode_line (im, IC_GREEN, xim_buf.green, i, 0, xim_buf.width))< (int)xim_buf.width )
333 				xim_set_component( xim_buf.green, ARGB32_GREEN8(im->back_color), count, xim_buf.width );
334 			if( (count = asimage_decode_line (im, IC_BLUE,  xim_buf.blue, i, 0, xim_buf.width)) < (int)xim_buf.width )
335 				xim_set_component( xim_buf.blue, ARGB32_BLUE8(im->back_color), count, xim_buf.width );
336 			if( xim->depth == 32 )
337 				if( (count = asimage_decode_line (im, IC_ALPHA,  xim_buf.alpha, i, 0, xim_buf.width)) < (int)xim_buf.width )
338 					xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
339 			imout->output_image_scanline( imout, &xim_buf, 1 );
340 		}
341 		free_scanline(&xim_buf, True);
342 	}
343 #endif
344 
345 /*#ifdef DO_CLOCKING
346 	fprintf (stderr, "asimage->ximage time (clocks): %lu\n", clock () - started);
347 #endif*/
348 
349 	stop_image_output(&imout);
350 	clear_flags( im->flags, ASIM_XIMAGE_NOT_USEFUL);
351 
352 	return xim;
353 }
354 
355 XImage*
asimage2ximage(ASVisual * asv,ASImage * im)356 asimage2ximage (ASVisual *asv, ASImage *im)
357 {
358 	return asimage2ximage_ext (asv, im, False);
359 }
360 
361 XImage*
asimage2alpha_ximage(ASVisual * asv,ASImage * im,Bool bitmap)362 asimage2alpha_ximage (ASVisual *asv, ASImage *im, Bool bitmap )
363 {
364 	XImage        *xim = NULL;
365 	int            i;
366 	ASScanline     xim_buf;
367 	ASImageOutput *imout ;
368 	ASFlagType flag = bitmap?0:ASIM_XIMAGE_8BIT_MASK;
369 
370 	if (im == NULL)
371 		return xim;
372 
373 	if( im->alt.mask_ximage )
374 		if( (im->flags & ASIM_XIMAGE_8BIT_MASK )^flag)
375 		{
376 #ifndef X_DISPLAY_MISSING
377 			XDestroyImage( im->alt.mask_ximage );
378 #endif
379 			im->alt.mask_ximage = NULL ;
380 		}
381     clear_flags( im->flags, ASIM_XIMAGE_8BIT_MASK );
382 	set_flags( im->flags, flag );
383 
384 	if( (imout = start_image_output( asv, im, ASA_MaskXImage, 0, ASIMAGE_QUALITY_POOR )) == NULL )
385 		return xim;
386 	xim = im->alt.mask_ximage ;
387 	prepare_scanline( xim->width, 0, &xim_buf, asv->BGR_mode );
388 	xim_buf.flags = SCL_DO_ALPHA ;
389 	for (i = 0; i < (int)im->height; i++)
390 	{
391 		int count = asimage_decode_line (im, IC_ALPHA, xim_buf.alpha, i, 0, xim_buf.width);
392 		if( count < (int)xim_buf.width )
393 			xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
394 		imout->output_image_scanline( imout, &xim_buf, 1 );
395 	}
396 	free_scanline(&xim_buf, True);
397 
398 	stop_image_output(&imout);
399 
400 	return xim;
401 }
402 
403 XImage*
asimage2mask_ximage(ASVisual * asv,ASImage * im)404 asimage2mask_ximage (ASVisual *asv, ASImage *im)
405 {
406 	return asimage2alpha_ximage (asv, im, True );
407 }
408 
409 ASImage      *
pixmap2ximage(ASVisual * asv,Pixmap p,int x,int y,unsigned int width,unsigned int height,unsigned long plane_mask,unsigned int compression)410 pixmap2ximage(ASVisual *asv, Pixmap p, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, unsigned int compression)
411 {
412 #ifndef X_DISPLAY_MISSING
413 	XImage       *xim = ASGetXImage (asv, p, x, y, width, height, plane_mask);
414 	ASImage      *im = NULL;
415 
416 	if (xim)
417 	{
418 		im = create_asimage( xim->width, xim->height, compression);
419 		im->flags = ASIM_DATA_NOT_USEFUL ;
420 		im->alt.ximage = xim ;
421 	}
422 	return im;
423 #else
424     return NULL ;
425 #endif
426 }
427 
428 ASImage      *
picture2asimage(ASVisual * asv,Pixmap rgb,Pixmap a,int x,int y,unsigned int width,unsigned int height,unsigned long plane_mask,Bool keep_cache,unsigned int compression)429 picture2asimage(ASVisual *asv, Pixmap rgb, Pixmap a , int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, Bool keep_cache, unsigned int compression)
430 {
431 #ifndef X_DISPLAY_MISSING
432 	XImage       *xim = ASGetXImage (asv, rgb, x, y, width, height, plane_mask);
433 	XImage       *alpha_xim = (a==None)?NULL:ASGetXImage (asv, a, x, y, width, height, 0xFFFFFFFF);
434 	ASImage      *im = NULL;
435 
436 	if (xim)
437 	{
438 		im = picture_ximage2asimage (asv, xim, alpha_xim, compression);
439 		if( keep_cache )
440 		{
441 			im->alt.ximage = xim ;
442 			if( alpha_xim )
443 			{
444 				im->alt.mask_ximage = alpha_xim ;
445 				if( alpha_xim->depth == 8 )
446 					set_flags( im->flags, ASIM_XIMAGE_8BIT_MASK );
447 			}
448 		}else
449 		{
450 			XDestroyImage (xim);
451 			if( alpha_xim )
452 				XDestroyImage (alpha_xim);
453 		}
454 	}
455 	return im;
456 #else
457     return NULL ;
458 #endif
459 }
460 
461 ASImage      *
pixmap2asimage(ASVisual * asv,Pixmap p,int x,int y,unsigned int width,unsigned int height,unsigned long plane_mask,Bool keep_cache,unsigned int compression)462 pixmap2asimage(ASVisual *asv, Pixmap p, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, Bool keep_cache, unsigned int compression)
463 {
464 	return picture2asimage(asv, p, None, x, y, width, height, plane_mask, keep_cache, compression);
465 }
466 
467 Bool
put_ximage(ASVisual * asv,XImage * xim,Drawable d,GC gc,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height)468 put_ximage( ASVisual *asv, XImage *xim, Drawable d, GC gc,
469             int src_x, int src_y, int dest_x, int dest_y,
470   		    unsigned int width, unsigned int height )
471 {
472 #ifndef X_DISPLAY_MISSING
473 	GC 			  my_gc = gc ;
474 
475 	if( src_x < 0 )
476 	{
477 		width += src_x ;
478 		src_x = 0;
479 	}else if( src_x > xim->width )
480 		return False;
481 	if( xim->width  > src_x+width )
482 		width = xim->width - src_x ;
483 	if( src_y < 0 )
484 	{
485 		height+= src_y ;
486 		src_y = 0;
487 	}else if( src_y > xim->height )
488 		return False;
489 	if( xim->height  > src_y+height )
490 		height = xim->height - src_y ;
491 
492 	if( my_gc == NULL )
493 	{
494 		XGCValues gcv ;
495 		my_gc = XCreateGC( asv->dpy, d, 0, &gcv );
496 	}
497 	ASPutXImage( asv, d, my_gc, xim, src_x, src_y, dest_x, dest_y, width, height );
498 	if( my_gc != gc )
499 		XFreeGC( asv->dpy, my_gc );
500 	return True ;
501 #else
502 	return False ;
503 #endif
504 }
505 
506 #define IS_POWER_OF2(i)  (((((i)>>16)&1)+(((i)>>15)&1)+(((i)>>14)&1)+(((i)>>13)&1)+(((i)>>12)&1)+(((i)>>11)&1)+(((i)>>10)&1)+(((i)>>9)&1)+(((i)>>8)&1) \
507                          +(((i)>>7)&1)+(((i)>>6)&1)+(((i)>>5)&1)+(((i)>>4)&1)+(((i)>>3)&1)+(((i)>>2)&1))==1)
508 
509 Bool
asimage2drawable_gl(ASVisual * asv,Drawable d,ASImage * im,int src_x,int src_y,int dest_x,int dest_y,int width,int height,int d_width,int d_height,Bool force_direct)510 asimage2drawable_gl(	ASVisual *asv, Drawable d, ASImage *im,
511                   		int src_x, int src_y, int dest_x, int dest_y,
512         		  		int width, int height, int d_width, int d_height,
513 						Bool force_direct )
514 {
515 	if( im != NULL && get_flags( asv->glx_support, ASGLX_Available ) && d != None )
516 	{
517 #ifdef HAVE_GLX
518 		int glbuf_size = (get_flags( asv->glx_support, ASGLX_RGBA )? 4 : 3 ) * width * height;
519 		CARD8 *glbuf = NULL;
520 		ASImageDecoder *imdec  = NULL ;
521 		GLXPixmap glxp = None;
522 
523 		if ((imdec = start_image_decoding( asv, im,
524 									   	get_flags( asv->glx_support, ASGLX_RGBA )?SCL_DO_ALL:SCL_DO_COLOR,
525 									   	src_x, src_y, width, height, NULL)) != NULL )
526 		{
527 			int i, l = glbuf_size;
528 			glbuf = safemalloc( glbuf_size );
529 			for (i = 0; i < (int)height; i++)
530 			{
531 				int k = width;
532 				imdec->decode_image_scanline( imdec );
533 				if( get_flags( asv->glx_support, ASGLX_RGBA ) )
534 				{
535 					while( --k >= 0 )
536 					{
537 						glbuf[--l] = imdec->buffer.alpha[k] ;
538 						glbuf[--l] = imdec->buffer.blue[k] ;
539 						glbuf[--l] = imdec->buffer.green[k] ;
540 						glbuf[--l] = imdec->buffer.red[k] ;
541 					}
542 				}else
543 				{
544 					while( --k >= 0 )
545 					{
546 						glbuf[--l] = imdec->buffer.blue[k] ;
547 						glbuf[--l] = imdec->buffer.green[k] ;
548 						glbuf[--l] = imdec->buffer.red[k] ;
549 					}
550 				}
551 			}
552 			stop_image_decoding( &imdec );
553 		}else
554 			return False;
555 
556 		if( !force_direct )
557 		{
558 			glxp = glXCreateGLXPixmap( asv->dpy, &(asv->visual_info), d);
559 			/* d is either invalid drawable or is a window */
560 			if( glxp == None )
561 				force_direct = True ;
562 		}
563 		if( glxp == None )
564 		{
565 			if( asv->glx_scratch_gc_direct	!= NULL )
566 				glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_direct);
567 			else
568 				glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_indirect);
569 		}else
570 			glXMakeCurrent (asv->dpy, glxp, asv->glx_scratch_gc_indirect);
571 
572 		if( glGetError() != 0 )
573 			return False;
574 
575   		if ( get_flags( asv->glx_support, ASGLX_DoubleBuffer ) )
576    			glDrawBuffer (GL_FRONT);
577 
578 		glDisable(GL_BLEND);		/* optimize pixel transfer rates */
579 	  	glDisable (GL_DEPTH_TEST);
580 	  	glDisable (GL_DITHER);
581 	  	glDisable (GL_FOG);
582 	  	glDisable (GL_LIGHTING);
583 
584 		glViewport( 0, 0, d_width, d_height);
585 		glMatrixMode (GL_PROJECTION);
586 		glLoadIdentity ();
587 		/* gluOrtho2D (0, d_width, 0, d_height); */
588 		glMatrixMode (GL_MODELVIEW);
589 		glLoadIdentity ();
590 		glTranslatef (0.375, 0.375, 0.0);
591 
592 
593 #if 1
594 		if( !IS_POWER_OF2(width) || !IS_POWER_OF2(height))
595 		{
596 			/* now put pixels on */
597 			glRasterPos2i( dest_x, d_height - (dest_y+height) );
598 			glDrawPixels(   width, height,
599 							get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB,
600 							GL_UNSIGNED_BYTE, glbuf );
601 		}else
602 #endif
603 		{ /* this stuff might be faster : */
604 			GLuint texture ;
605 
606 #define TARGET_TEXTURE_ID GL_TEXTURE_2D
607 
608 #if TARGET_TEXTURE_ID!=GL_TEXTURE_2D
609 			glEnable(GL_TEXTURE_2D);
610 #endif
611 			glEnable(TARGET_TEXTURE_ID);
612 			glGenTextures(1, &texture);
613 
614 			glBindTexture(TARGET_TEXTURE_ID, texture);
615 	    	glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
616 	     	glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
617 			glTexImage2D(TARGET_TEXTURE_ID, 0, get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB,
618 					      /* width and height must be the power of 2 !!! */
619 						  width, height,
620 						  0, GL_RGBA, GL_UNSIGNED_BYTE, glbuf);
621 
622 		 	glBegin(GL_QUADS);
623 			/* bottom-left */
624 		   	glTexCoord2d(0., 0.); glVertex2i(dest_x, d_height - (dest_y+height) );
625 			/* bottom-right */
626 		   	glTexCoord2d(1.0, 0.0); glVertex2i(dest_x+width, d_height - (dest_y+height));
627 			/* top-right */
628 		   	glTexCoord2d(1.0, 1.0); glVertex2i(dest_x+width, d_height - dest_y);
629 			/* top-left */
630 		   	glTexCoord2d(0.0, 1.0); glVertex2i(dest_x, d_height - dest_y);
631 		   	glEnd();
632 
633 			glBindTexture(TARGET_TEXTURE_ID, 0);
634 			glFinish();
635 		}
636 
637 		free( glbuf );
638 		glXMakeCurrent (asv->dpy, None, NULL);
639 		if( glxp )
640 			glXDestroyGLXPixmap( asv->dpy, glxp);
641 		glFinish();
642 		return True;
643 #endif /* #ifdef HAVE_GLX */
644 	}
645 	{
646 		static Bool warning_shown = False ;
647 		if( !warning_shown )
648 		{
649 			warning_shown = True ;
650 			show_warning( "Support for GLX is unavailable.");
651 		}
652 	}
653 	return False;
654 }
655 
656 Bool
asimage2drawable(ASVisual * asv,Drawable d,ASImage * im,GC gc,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height,Bool use_cached)657 asimage2drawable( ASVisual *asv, Drawable d, ASImage *im, GC gc,
658                   int src_x, int src_y, int dest_x, int dest_y,
659         		  unsigned int width, unsigned int height,
660 				  Bool use_cached)
661 {
662 #ifndef X_DISPLAY_MISSING
663 	if( im )
664 	{
665 		Bool 		  my_xim = False ;
666 		XImage       *xim ;
667 		Bool res = False;
668 		if ( !use_cached || im->alt.ximage == NULL )
669 		{
670             if( (xim = asimage2ximage_ext( asv, im, False )) == NULL )
671 			{
672 				show_error("cannot export image into XImage.");
673 				return None ;
674 			}
675 			 my_xim = True ;
676 		}else
677 			xim = im->alt.ximage ;
678 		if (xim != NULL )
679 		{
680             res = put_ximage( asv, xim, d, gc,  src_x, src_y, dest_x, dest_y, width, height );
681 			if( my_xim && xim == im->alt.ximage )
682 				im->alt.ximage = NULL ;
683 			if( xim != im->alt.ximage )
684 				XDestroyImage (xim);
685 		}
686 		return res;
687 	}
688 #endif
689 	return False ;
690 }
691 
692 Bool
asimage2alpha_drawable(ASVisual * asv,Drawable d,ASImage * im,GC gc,int src_x,int src_y,int dest_x,int dest_y,unsigned int width,unsigned int height,Bool use_cached)693 asimage2alpha_drawable( ASVisual *asv, Drawable d, ASImage *im, GC gc,
694             		    int src_x, int src_y, int dest_x, int dest_y,
695         				unsigned int width, unsigned int height,
696 						Bool use_cached)
697 {
698 #ifndef X_DISPLAY_MISSING
699 	if( im )
700 	{
701 		XImage       *xim ;
702 		unsigned int  alpha_depth = 1 ;
703 		int dumm; unsigned int udumm; Window root ;
704 		Bool res = False ;
705 
706 		XGetGeometry( asv->dpy, d, &root, &dumm, &dumm, &udumm, &udumm, &udumm, &alpha_depth );
707 
708 		if ( !use_cached || im->alt.mask_ximage == NULL || im->alt.mask_ximage->depth != alpha_depth )
709 		{
710 			if( (xim = asimage2alpha_ximage (asv, im, (alpha_depth == 1) )) == NULL )
711 			{
712 				show_error("cannot export image into alpha XImage.");
713 				return None ;
714 			}
715 		}else
716 			xim = im->alt.mask_ximage ;
717 		if (xim != NULL )
718 		{
719 			res = put_ximage( asv, xim, d, gc,	src_x, src_y, dest_x, dest_y, width, height );
720 			if( xim != im->alt.mask_ximage )
721 				XDestroyImage (xim);
722 		}
723 		return res;
724 	}
725 #endif
726 	return False ;
727 }
728 
729 
730 Pixmap
asimage2pixmap(ASVisual * asv,Window root,ASImage * im,GC gc,Bool use_cached)731 asimage2pixmap(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached)
732 {
733 #ifndef X_DISPLAY_MISSING
734 	if( im )
735 	{
736 		Pixmap        p = None;
737 
738 		p = create_visual_pixmap( asv, root, im->width, im->height, 0 );
739 
740 		if( !asimage2drawable( asv, p, im, gc, 0, 0, 0, 0, im->width, im->height, use_cached) )
741 		{
742 			XFreePixmap( asv->dpy, p );
743 			p = None ;
744 		}
745 		return p;
746 	}
747 #endif
748 	return None ;
749 }
750 
751 Pixmap
asimage2alpha(ASVisual * asv,Window root,ASImage * im,GC gc,Bool use_cached,Bool bitmap)752 asimage2alpha(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached, Bool bitmap)
753 {
754 #ifndef X_DISPLAY_MISSING
755 	XImage       *xim ;
756 	Pixmap        mask = None;
757 	GC 			  my_gc = gc ;
758 
759 	int target_depth = bitmap?1:8;
760 
761 	if ( !use_cached || im->alt.mask_ximage == NULL ||
762 	     im->alt.mask_ximage->depth != target_depth )
763 	{
764 		if( (xim = asimage2alpha_ximage( asv, im, bitmap )) == NULL )
765 		{
766 			show_error("cannot export image's mask into XImage.");
767 			return None ;
768 		}
769 	}else
770 		xim = im->alt.mask_ximage ;
771 	mask = create_visual_pixmap( asv, root, xim->width, xim->height, target_depth );
772 	if( my_gc == NULL )
773 	{
774 		XGCValues gcv ;
775 		my_gc = XCreateGC( asv->dpy, mask, 0, &gcv );
776 	}
777 	ASPutXImage( asv, mask, my_gc, xim, 0, 0, 0, 0, xim->width, xim->height );
778 	if( my_gc != gc )
779 		XFreeGC( asv->dpy, my_gc );
780 	if( xim != im->alt.mask_ximage )
781 		XDestroyImage (xim);
782 	return mask;
783 #else
784 	return None ;
785 #endif
786 }
787 
788 Pixmap
asimage2mask(ASVisual * asv,Window root,ASImage * im,GC gc,Bool use_cached)789 asimage2mask(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached)
790 {
791 	return asimage2alpha(asv, root, im, gc, use_cached, True);
792 }
793 /* ********************************************************************************/
794 /* The end !!!! 																 */
795 /* ********************************************************************************/
796 
797