ximage.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2000,2001 Sasha Vasko <sasha at aftercode.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #ifdef _WIN32
00020 #include "win32/config.h"
00021 #else
00022 #include "config.h"
00023 #endif
00024 
00025 #undef LOCAL_DEBUG
00026 #define DO_CLOCKING 
00027 
00028 #ifdef DO_CLOCKING
00029 #if TIME_WITH_SYS_TIME
00030 # include <sys/time.h>
00031 # include <time.h>
00032 #else
00033 # if HAVE_SYS_TIME_H
00034 #  include <sys/time.h>
00035 # else
00036 #  include <time.h>
00037 # endif
00038 #endif
00039 #endif
00040 #ifdef HAVE_STDARG_H
00041 #include <stdarg.h>
00042 #endif
00043 
00044 #ifdef HAVE_GLX
00045 # include <GL/gl.h>
00046 # include <GL/glx.h>
00047 /*# include <GL/glu.h> */
00048 #endif
00049 
00050 
00051 #ifdef _WIN32
00052 # include "win32/afterbase.h"
00053 #else
00054 # include "afterbase.h"
00055 #endif
00056 #include "asvisual.h"
00057 #include "blender.h"
00058 #include "asimage.h"
00059 #include "imencdec.h"
00060 #include "ximage.h"
00061 
00062 
00063 /* ***************************************************************************/
00064 /* ASImage->XImage->pixmap->XImage->ASImage conversion                                          */
00065 /* ***************************************************************************/
00066 
00067 ASImage      *
00068 picture_ximage2asimage (ASVisual *asv, XImage *xim, XImage *alpha_xim, unsigned int compression)
00069 {
00070         ASImage      *im = NULL;
00071         unsigned char *xim_line;
00072         int           i, height, width, bpl;
00073         ASScanline    xim_buf;
00074 #ifdef LOCAL_DEBUG
00075         CARD32       *tmp ;
00076 #endif
00077 #if 0
00078   struct timeval stv;
00079         gettimeofday (&stv,NULL);
00080 #define PRINT_BACKGROUND_OP_TIME do{ struct timeval tv;gettimeofday (&tv,NULL); tv.tv_sec-= stv.tv_sec;\
00081                                      fprintf (stderr,__FILE__ "%d: elapsed  %ld usec\n",__LINE__,\
00082                                               tv.tv_sec*1000000+tv.tv_usec-stv.tv_usec );}while(0)
00083 #else                                           
00084 #define PRINT_BACKGROUND_OP_TIME do{}while(0)                                          
00085 #endif
00086 
00087         if( xim && alpha_xim )
00088                 if( xim->width != alpha_xim->width ||
00089                     xim->height != alpha_xim->height )
00090                         return NULL ;
00091         if( xim == NULL && alpha_xim == NULL )
00092                 return NULL ;
00093 
00094         width = xim?xim->width:alpha_xim->width;
00095         height = xim?xim->height:alpha_xim->height;
00096 
00097         im = create_asimage( width, height, compression);
00098         prepare_scanline( width, 0, &xim_buf, asv->BGR_mode );
00099 #ifdef LOCAL_DEBUG
00100         tmp = safemalloc( width * sizeof(CARD32));
00101 #endif
00102 PRINT_BACKGROUND_OP_TIME;
00103         if( xim )
00104         {
00105                 bpl      = xim->bytes_per_line;
00106                 xim_line = (unsigned char *)xim->data;
00107 
00108                 for (i = 0; i < height; i++)
00109                 {
00110 #if 0
00111 /* unfortunately this method does not seem to yield any better results performancewise: */
00112                         if (asv->true_depth == 32 || asv->true_depth == 24)
00113                         {
00114                                 if( asv->msb_first ) 
00115                                 {
00116                                 }else
00117                                         asimage_add_line_bgra (im, xim_line, i);
00118                         }else 
00119 #endif                  
00120                         if( xim->depth == (int)asv->true_depth )
00121                         {
00122                             GET_SCANLINE(asv,xim,&xim_buf,i,xim_line);
00123                     asimage_add_line (im, IC_RED,   xim_buf.red, i);
00124                             asimage_add_line (im, IC_GREEN, xim_buf.green, i);
00125                             asimage_add_line (im, IC_BLUE,  xim_buf.blue, i);
00126                                 if( xim->depth == 32 && alpha_xim == NULL ) 
00127                                     asimage_add_line (im, IC_ALPHA,  xim_buf.alpha, i);
00128 #ifdef LOCAL_DEBUG
00129                             if( !asimage_compare_line( im, IC_RED,  xim_buf.red, tmp, i, True ) )
00130                                 exit(0);
00131                             if( !asimage_compare_line( im, IC_GREEN,  xim_buf.green, tmp, i, True ) )
00132                                 exit(0);
00133                             if( !asimage_compare_line( im, IC_BLUE,  xim_buf.blue, tmp, i, True ) )
00134                                 exit(0);
00135 #endif
00136                         }else if( xim->depth == 8 )
00137                         {
00138                             register int x = width;
00139                             while(--x >= 0 )
00140                                 xim_buf.blue[x] = (CARD32)(xim_line[x]);
00141                             asimage_add_line (im, IC_RED,   xim_buf.red, i);
00142                             asimage_add_line (im, IC_GREEN, xim_buf.red, i);
00143                             asimage_add_line (im, IC_BLUE,  xim_buf.red, i);
00144                         }else if( xim->depth == 1 )
00145                         {
00146                             register int x = width;
00147                             while(--x >= 0 )
00148                             {
00149 #ifndef X_DISPLAY_MISSING
00150                                 xim_buf.red[x] = (XGetPixel(xim, x, i) == 0)?0x00:0xFF;
00151 #else
00152                                 xim_buf.red[x] = 0xFF ;
00153 #endif
00154                             }
00155                             asimage_add_line (im, IC_RED,   xim_buf.red, i);
00156                             asimage_add_line (im, IC_GREEN, xim_buf.red, i);
00157                             asimage_add_line (im, IC_BLUE,  xim_buf.red, i);
00158                         }
00159 
00160                         xim_line += bpl;
00161                 }
00162         }
00163 PRINT_BACKGROUND_OP_TIME;
00164         if( alpha_xim )
00165         {
00166                 CARD32 *dst = xim_buf.alpha ;
00167                 bpl      = alpha_xim->bytes_per_line;
00168                 xim_line = (unsigned char *)alpha_xim->data;
00169 
00170                 for (i = 0; i < height; i++)
00171                 {
00172                         register int x = width;
00173                         if( alpha_xim->depth == 8 )
00174                         {
00175                                 while(--x >= 0 ) dst[x] = (CARD32)(xim_line[x]);
00176                         }else
00177                         {
00178                                 while(--x >= 0 )
00179 #ifndef X_DISPLAY_MISSING
00180                                         dst[x] = (XGetPixel(alpha_xim, x, i) == 0)?0x00:0xFF;
00181 #else
00182                                         dst[x] = 0xFF ;
00183 #endif
00184                         }
00185                         asimage_add_line (im, IC_ALPHA, xim_buf.alpha, i);
00186 #ifdef LOCAL_DEBUG
00187                         if( !asimage_compare_line( im, IC_ALPHA,  xim_buf.alpha, tmp, i, True ) )
00188                                 exit(0);
00189 #endif
00190                         xim_line += bpl;
00191                 }
00192         }
00193         free_scanline(&xim_buf, True);
00194 PRINT_BACKGROUND_OP_TIME;
00195 
00196         return im;
00197 }
00198 
00199 ASImage      *
00200 ximage2asimage (ASVisual *asv, XImage * xim, unsigned int compression)
00201 {
00202         return picture_ximage2asimage (asv, xim, NULL, compression);
00203 }
00204 
00205 static inline int
00206 xim_set_component( register CARD32 *src, register CARD32 value, int offset, int len )
00207 {
00208         register int i ;
00209         for( i = offset ; i < len ; ++i )
00210                 src[i] = value;
00211         return len-offset;
00212 }
00213 
00214 Bool
00215 subimage2ximage (ASVisual *asv, ASImage *im, int x, int y, XImage* xim)
00216 {
00217         int            i, max_i;
00218         ASScanline     xim_buf;
00219         ASImageOutput *imout ;
00220 /*#ifdef DO_CLOCKING
00221         clock_t       started = clock ();
00222 #endif*/
00223         int width, height ;
00224         ASImage *scratch_im ;
00225 
00226         if (im == NULL)
00227         {
00228 LOCAL_DEBUG_OUT( "Attempt to convert NULL ASImage into XImage.", "" );
00229                 return False;
00230         }
00231         if( x >= (int)im->width || y >= (int)im->height ) 
00232                 return False;
00233         width = xim->width ;
00234         if( width > (int)im->width - x) 
00235                 width = (int)im->width - x;                
00236         width = ( x > (int)im->width - width )?im->width - width:im->width - x ;
00237         height = xim->height ;
00238         if( height > (int)im->height - y ) 
00239                 height = im->height - y ;               
00240         scratch_im = create_asimage( width, height, 0);
00241         scratch_im->alt.ximage = xim ;
00242 LOCAL_DEBUG_OUT( "target width = %d, height = %d", width, height );
00243         if( (imout = start_image_output( asv, scratch_im, ASA_ScratchXImage, 0, ASIMAGE_QUALITY_DEFAULT )) == NULL )
00244         {
00245 LOCAL_DEBUG_OUT( "Failed to start ASImageOutput for ASImage %p and ASVisual %p", im, asv );
00246                 return False;
00247         }
00248 
00249         prepare_scanline( width, 0, &xim_buf, asv->BGR_mode );
00250 /*#ifdef DO_CLOCKING
00251         started = clock ();
00252 #endif*/
00253         set_flags( xim_buf.flags, SCL_DO_ALL );
00254         max_i = y + height ;
00255         for (i = y; i < max_i; i++)
00256         {
00257                 int count ;
00258                 if( (count = asimage_decode_line (im, IC_RED,   xim_buf.red, i, x, xim_buf.width)) < (int)xim_buf.width )
00259                         xim_set_component( xim_buf.red, ARGB32_RED8(im->back_color), count, xim_buf.width );
00260                 if( (count = asimage_decode_line (im, IC_GREEN, xim_buf.green, i, x, xim_buf.width))< (int)xim_buf.width )
00261                         xim_set_component( xim_buf.green, ARGB32_GREEN8(im->back_color), count, xim_buf.width );
00262                 if( (count = asimage_decode_line (im, IC_BLUE,  xim_buf.blue, i, x, xim_buf.width)) < (int)xim_buf.width )
00263                         xim_set_component( xim_buf.blue, ARGB32_BLUE8(im->back_color), count, xim_buf.width );
00264                 if( xim->depth == 32 ) 
00265                         if( (count = asimage_decode_line (im, IC_ALPHA,  xim_buf.alpha, i, x, xim_buf.width)) < (int)xim_buf.width )
00266                                 xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
00267                         
00268                 imout->output_image_scanline( imout, &xim_buf, 1 );
00269 /*              LOCAL_DEBUG_OUT( "line %d, count = %d", i, count ); */
00270         }
00271 /*#ifdef DO_CLOCKING
00272         fprintf (stderr, "asimage->ximage time (clocks): %lu\n", clock () - started);
00273 #endif*/
00274         free_scanline(&xim_buf, True);
00275         stop_image_output(&imout);
00276 
00277         scratch_im->alt.ximage = NULL ;
00278         destroy_asimage( &scratch_im );
00279         return True;
00280 }
00281 
00282 
00283 
00284 static XImage*
00285 asimage2ximage_ext (ASVisual *asv, ASImage *im, Bool scratch)
00286 {
00287         XImage        *xim = NULL;
00288         int            i;
00289         ASImageOutput *imout ;
00290         ASImageDecoder *imdec;
00291 /*#ifdef DO_CLOCKING
00292         clock_t       started = clock ();
00293 #endif*/
00294 
00295         if (im == NULL)
00296         {
00297 LOCAL_DEBUG_OUT( "Attempt to convert NULL ASImage into XImage.", "" );
00298                 return xim;
00299         }
00300         if( (imout = start_image_output( asv, im, scratch?ASA_ScratchXImage:ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT )) == NULL )
00301         {
00302 LOCAL_DEBUG_OUT( "Failed to start ASImageOutput for ASImage %p and ASVisual %p", im, asv );
00303                 return xim;
00304         }
00305         xim = im->alt.ximage ;
00306         /* no data in ximage yet */
00307         set_flags( im->flags, ASIM_XIMAGE_NOT_USEFUL);
00308 /*#ifdef DO_CLOCKING
00309         started = clock ();
00310 #endif*/
00311 #if     1
00312         if ((imdec = start_image_decoding(  asv, im, (xim->depth >= 24)?SCL_DO_ALL:SCL_DO_COLOR, 
00313                                                                                 0, 0, im->width, im->height, NULL)) != NULL )
00314         {        
00315                 for (i = 0; i < (int)im->height; i++)
00316                 {       
00317                         imdec->decode_image_scanline( imdec ); 
00318                         imout->output_image_scanline( imout, &(imdec->buffer), 1);
00319                 }
00320                 stop_image_decoding( &imdec );
00321         }
00322 #else     
00323         {       
00324                 ASScanline     xim_buf;
00325                 prepare_scanline( im->width, 0, &xim_buf, asv->BGR_mode );
00326                 set_flags( xim_buf.flags, SCL_DO_ALL );
00327                 for (i = 0; i < (int)im->height; i++)
00328                 {
00329                         int count ;
00330                         if( (count = asimage_decode_line (im, IC_RED,   xim_buf.red, i, 0, xim_buf.width)) < (int)xim_buf.width )
00331                                 xim_set_component( xim_buf.red, ARGB32_RED8(im->back_color), count, xim_buf.width );
00332                         if( (count = asimage_decode_line (im, IC_GREEN, xim_buf.green, i, 0, xim_buf.width))< (int)xim_buf.width )
00333                                 xim_set_component( xim_buf.green, ARGB32_GREEN8(im->back_color), count, xim_buf.width );
00334                         if( (count = asimage_decode_line (im, IC_BLUE,  xim_buf.blue, i, 0, xim_buf.width)) < (int)xim_buf.width )
00335                                 xim_set_component( xim_buf.blue, ARGB32_BLUE8(im->back_color), count, xim_buf.width );
00336                         if( xim->depth == 32 ) 
00337                                 if( (count = asimage_decode_line (im, IC_ALPHA,  xim_buf.alpha, i, 0, xim_buf.width)) < (int)xim_buf.width )
00338                                         xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
00339                         imout->output_image_scanline( imout, &xim_buf, 1 );
00340                 }
00341                 free_scanline(&xim_buf, True);
00342         }
00343 #endif
00344 
00345 /*#ifdef DO_CLOCKING
00346         fprintf (stderr, "asimage->ximage time (clocks): %lu\n", clock () - started);
00347 #endif*/
00348 
00349         stop_image_output(&imout);
00350         clear_flags( im->flags, ASIM_XIMAGE_NOT_USEFUL);
00351 
00352         return xim;
00353 }
00354 
00355 XImage*
00356 asimage2ximage (ASVisual *asv, ASImage *im)
00357 {
00358         return asimage2ximage_ext (asv, im, False);     
00359 }
00360 
00361 XImage*
00362 asimage2alpha_ximage (ASVisual *asv, ASImage *im, Bool bitmap )
00363 {
00364         XImage        *xim = NULL;
00365         int            i;
00366         ASScanline     xim_buf;
00367         ASImageOutput *imout ;
00368         ASFlagType flag = bitmap?0:ASIM_XIMAGE_8BIT_MASK;
00369 
00370         if (im == NULL)
00371                 return xim;
00372 
00373         if( im->alt.mask_ximage )
00374                 if( (im->flags & ASIM_XIMAGE_8BIT_MASK )^flag)
00375                 {
00376 #ifndef X_DISPLAY_MISSING
00377                         XDestroyImage( im->alt.mask_ximage );
00378 #endif
00379                         im->alt.mask_ximage = NULL ;
00380                 }
00381     clear_flags( im->flags, ASIM_XIMAGE_8BIT_MASK );
00382         set_flags( im->flags, flag );
00383 
00384         if( (imout = start_image_output( asv, im, ASA_MaskXImage, 0, ASIMAGE_QUALITY_POOR )) == NULL )
00385                 return xim;
00386         xim = im->alt.mask_ximage ;
00387         prepare_scanline( xim->width, 0, &xim_buf, asv->BGR_mode );
00388         xim_buf.flags = SCL_DO_ALPHA ;
00389         for (i = 0; i < (int)im->height; i++)
00390         {
00391                 int count = asimage_decode_line (im, IC_ALPHA, xim_buf.alpha, i, 0, xim_buf.width);
00392                 if( count < (int)xim_buf.width )
00393                         xim_set_component( xim_buf.alpha, ARGB32_ALPHA8(im->back_color), count, xim_buf.width );
00394                 imout->output_image_scanline( imout, &xim_buf, 1 );
00395         }
00396         free_scanline(&xim_buf, True);
00397 
00398         stop_image_output(&imout);
00399 
00400         return xim;
00401 }
00402 
00403 XImage*
00404 asimage2mask_ximage (ASVisual *asv, ASImage *im)
00405 {
00406         return asimage2alpha_ximage (asv, im, True );
00407 }
00408 
00409 ASImage      *
00410 pixmap2ximage(ASVisual *asv, Pixmap p, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, unsigned int compression)
00411 {
00412 #ifndef X_DISPLAY_MISSING
00413         XImage       *xim = ASGetXImage (asv, p, x, y, width, height, plane_mask);
00414         ASImage      *im = NULL;
00415 
00416         if (xim)
00417         {
00418                 im = create_asimage( xim->width, xim->height, compression);
00419                 im->flags = ASIM_DATA_NOT_USEFUL ;
00420                 im->alt.ximage = xim ;
00421         }
00422         return im;
00423 #else
00424     return NULL ;
00425 #endif
00426 }
00427 
00428 ASImage      *
00429 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)
00430 {
00431 #ifndef X_DISPLAY_MISSING
00432         XImage       *xim = ASGetXImage (asv, rgb, x, y, width, height, plane_mask);
00433         XImage       *alpha_xim = (a==None)?NULL:ASGetXImage (asv, a, x, y, width, height, 0xFFFFFFFF);
00434         ASImage      *im = NULL;
00435 
00436         if (xim)
00437         {
00438                 im = picture_ximage2asimage (asv, xim, alpha_xim, compression);
00439                 if( keep_cache )
00440                 {
00441                         im->alt.ximage = xim ;
00442                         if( alpha_xim )
00443                         {
00444                                 im->alt.mask_ximage = alpha_xim ;
00445                                 if( alpha_xim->depth == 8 )
00446                                         set_flags( im->flags, ASIM_XIMAGE_8BIT_MASK );
00447                         }
00448                 }else
00449                 {
00450                         XDestroyImage (xim);
00451                         if( alpha_xim )
00452                                 XDestroyImage (alpha_xim);
00453                 }
00454         }
00455         return im;
00456 #else
00457     return NULL ;
00458 #endif
00459 }
00460 
00461 ASImage      *
00462 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)
00463 {
00464         return picture2asimage(asv, p, None, x, y, width, height, plane_mask, keep_cache, compression);
00465 }
00466 
00467 Bool
00468 put_ximage( ASVisual *asv, XImage *xim, Drawable d, GC gc,
00469             int src_x, int src_y, int dest_x, int dest_y,
00470                     unsigned int width, unsigned int height )
00471 {
00472 #ifndef X_DISPLAY_MISSING
00473         GC                        my_gc = gc ;
00474 
00475         if( src_x < 0 )
00476         {
00477                 width += src_x ;
00478                 src_x = 0;
00479         }else if( src_x > xim->width )
00480                 return False;
00481         if( xim->width  > src_x+width )
00482                 width = xim->width - src_x ;
00483         if( src_y < 0 )
00484         {
00485                 height+= src_y ;
00486                 src_y = 0;
00487         }else if( src_y > xim->height )
00488                 return False;
00489         if( xim->height  > src_y+height )
00490                 height = xim->height - src_y ;
00491 
00492         if( my_gc == NULL )
00493         {
00494                 XGCValues gcv ;
00495                 my_gc = XCreateGC( asv->dpy, d, 0, &gcv );
00496         }
00497         ASPutXImage( asv, d, my_gc, xim, src_x, src_y, dest_x, dest_y, width, height );
00498         if( my_gc != gc )
00499                 XFreeGC( asv->dpy, my_gc );
00500         return True ;
00501 #else
00502         return False ;
00503 #endif
00504 }
00505 
00506 #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) \
00507                          +(((i)>>7)&1)+(((i)>>6)&1)+(((i)>>5)&1)+(((i)>>4)&1)+(((i)>>3)&1)+(((i)>>2)&1))==1)
00508 
00509 Bool
00510 asimage2drawable_gl(    ASVisual *asv, Drawable d, ASImage *im,
00511                                 int src_x, int src_y, int dest_x, int dest_y,
00512                                         int width, int height, int d_width, int d_height, 
00513                                                 Bool force_direct )
00514 {
00515         if( im != NULL && get_flags( asv->glx_support, ASGLX_Available ) && d != None )
00516         {
00517 #ifdef HAVE_GLX
00518                 int glbuf_size = (get_flags( asv->glx_support, ASGLX_RGBA )? 4 : 3 ) * width * height;
00519                 CARD8 *glbuf = NULL;
00520                 ASImageDecoder *imdec  = NULL ;
00521                 GLXPixmap glxp = None;
00522                 
00523                 if ((imdec = start_image_decoding( asv, im, 
00524                                                                                 get_flags( asv->glx_support, ASGLX_RGBA )?SCL_DO_ALL:SCL_DO_COLOR, 
00525                                                                                 src_x, src_y, width, height, NULL)) != NULL )
00526                 {        
00527                         int i, l = glbuf_size;
00528                         glbuf = safemalloc( glbuf_size );
00529                         for (i = 0; i < (int)height; i++)
00530                         {       
00531                                 int k = width;
00532                                 imdec->decode_image_scanline( imdec ); 
00533                                 if( get_flags( asv->glx_support, ASGLX_RGBA ) ) 
00534                                 {         
00535                                         while( --k >= 0 ) 
00536                                         {
00537                                                 glbuf[--l] = imdec->buffer.alpha[k] ;
00538                                                 glbuf[--l] = imdec->buffer.blue[k] ;
00539                                                 glbuf[--l] = imdec->buffer.green[k] ;
00540                                                 glbuf[--l] = imdec->buffer.red[k] ;
00541                                         }        
00542                                 }else
00543                                 {       
00544                                         while( --k >= 0 ) 
00545                                         {
00546                                                 glbuf[--l] = imdec->buffer.blue[k] ;
00547                                                 glbuf[--l] = imdec->buffer.green[k] ;
00548                                                 glbuf[--l] = imdec->buffer.red[k] ;
00549                                         }        
00550                                 }
00551                         }
00552                         stop_image_decoding( &imdec );
00553                 }else
00554                         return False;
00555 
00556                 if( !force_direct ) 
00557                 {       
00558                         glxp = glXCreateGLXPixmap( asv->dpy, &(asv->visual_info), d);
00559                         /* d is either invalid drawable or is a window */
00560                         if( glxp == None ) 
00561                                 force_direct = True ; 
00562                 }                      
00563                 if( glxp == None ) 
00564                 {
00565                         if( asv->glx_scratch_gc_direct  != NULL )
00566                                 glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_direct);
00567                         else
00568                                 glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_indirect);
00569                 }else
00570                         glXMakeCurrent (asv->dpy, glxp, asv->glx_scratch_gc_indirect);
00571                 
00572                 if( glGetError() != 0 ) 
00573                         return False;
00574 
00575                 if ( get_flags( asv->glx_support, ASGLX_DoubleBuffer ) ) 
00576                         glDrawBuffer (GL_FRONT);
00577 
00578                 glDisable(GL_BLEND);            /* optimize pixel transfer rates */
00579                 glDisable (GL_DEPTH_TEST);
00580                 glDisable (GL_DITHER);
00581                 glDisable (GL_FOG);
00582                 glDisable (GL_LIGHTING);
00583 
00584                 glViewport( 0, 0, d_width, d_height);
00585                 glMatrixMode (GL_PROJECTION);
00586                 glLoadIdentity ();
00587                 /* gluOrtho2D (0, d_width, 0, d_height); */
00588                 glMatrixMode (GL_MODELVIEW);
00589                 glLoadIdentity ();
00590                 glTranslatef (0.375, 0.375, 0.0);
00591 
00592 
00593 #if 1
00594                 if( !IS_POWER_OF2(width) || !IS_POWER_OF2(height))
00595                 {
00596                         /* now put pixels on */
00597                         glRasterPos2i( dest_x, d_height - (dest_y+height) );
00598                         glDrawPixels(   width, height, 
00599                                                         get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB, 
00600                                                         GL_UNSIGNED_BYTE, glbuf );
00601                 }else
00602 #endif          
00603                 { /* this stuff might be faster : */
00604                         GLuint texture ;
00605 
00606 #define TARGET_TEXTURE_ID GL_TEXTURE_2D
00607 
00608 #if TARGET_TEXTURE_ID!=GL_TEXTURE_2D
00609                         glEnable(GL_TEXTURE_2D);
00610 #endif                  
00611                         glEnable(TARGET_TEXTURE_ID);
00612                         glGenTextures(1, &texture);
00613 
00614                         glBindTexture(TARGET_TEXTURE_ID, texture);
00615                 glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00616                 glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00617                         glTexImage2D(TARGET_TEXTURE_ID, 0, get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB, 
00618                                               /* width and height must be the power of 2 !!! */
00619                                                   width, height, 
00620                                                   0, GL_RGBA, GL_UNSIGNED_BYTE, glbuf);
00621 
00622                         glBegin(GL_QUADS);
00623                         /* bottom-left */
00624                         glTexCoord2d(0., 0.); glVertex2i(dest_x, d_height - (dest_y+height) );
00625                         /* bottom-right */
00626                         glTexCoord2d(1.0, 0.0); glVertex2i(dest_x+width, d_height - (dest_y+height));
00627                         /* top-right */
00628                         glTexCoord2d(1.0, 1.0); glVertex2i(dest_x+width, d_height - dest_y);    
00629                         /* top-left */ 
00630                         glTexCoord2d(0.0, 1.0); glVertex2i(dest_x, d_height - dest_y);
00631                         glEnd();
00632 
00633                         glBindTexture(TARGET_TEXTURE_ID, 0);
00634                         glFinish();
00635                 }                                                       
00636 
00637                 free( glbuf );
00638                 glXMakeCurrent (asv->dpy, None, NULL);    
00639                 if( glxp ) 
00640                         glXDestroyGLXPixmap( asv->dpy, glxp);
00641                 glFinish();                                
00642                 return True;
00643 #endif /* #ifdef HAVE_GLX */
00644         }
00645         {
00646                 static Bool warning_shown = False ; 
00647                 if( !warning_shown ) 
00648                 {
00649                         warning_shown = True ;
00650                         show_warning( "Support for GLX is unavailable.");
00651                 }
00652         }
00653         return False;
00654 }
00655 
00656 Bool
00657 asimage2drawable( ASVisual *asv, Drawable d, ASImage *im, GC gc,
00658                   int src_x, int src_y, int dest_x, int dest_y,
00659                           unsigned int width, unsigned int height,
00660                                   Bool use_cached)
00661 {
00662 #ifndef X_DISPLAY_MISSING
00663         if( im )
00664         {
00665                 Bool              my_xim = False ;
00666                 XImage       *xim ;
00667                 Bool res = False;
00668                 if ( !use_cached || im->alt.ximage == NULL )
00669                 {
00670             if( (xim = asimage2ximage_ext( asv, im, False )) == NULL )
00671                         {
00672                                 show_error("cannot export image into XImage.");
00673                                 return None ;
00674                         }
00675                          my_xim = True ;
00676                 }else
00677                         xim = im->alt.ximage ;
00678                 if (xim != NULL )
00679                 {
00680             res = put_ximage( asv, xim, d, gc,  src_x, src_y, dest_x, dest_y, width, height );
00681                         if( my_xim && xim == im->alt.ximage ) 
00682                                 im->alt.ximage = NULL ;
00683                         if( xim != im->alt.ximage )
00684                                 XDestroyImage (xim);
00685                 }
00686                 return res;
00687         }
00688 #endif
00689         return False ;
00690 }
00691 
00692 Bool
00693 asimage2alpha_drawable( ASVisual *asv, Drawable d, ASImage *im, GC gc,
00694                             int src_x, int src_y, int dest_x, int dest_y,
00695                                         unsigned int width, unsigned int height,
00696                                                 Bool use_cached)
00697 {
00698 #ifndef X_DISPLAY_MISSING
00699         if( im )
00700         {
00701                 XImage       *xim ;
00702                 unsigned int  alpha_depth = 1 ;
00703                 int dumm; unsigned int udumm; Window root ;
00704                 Bool res = False ;
00705 
00706                 XGetGeometry( asv->dpy, d, &root, &dumm, &dumm, &udumm, &udumm, &udumm, &alpha_depth );
00707 
00708                 if ( !use_cached || im->alt.mask_ximage == NULL || im->alt.mask_ximage->depth != alpha_depth )
00709                 {
00710                         if( (xim = asimage2alpha_ximage (asv, im, (alpha_depth == 1) )) == NULL )
00711                         {
00712                                 show_error("cannot export image into alpha XImage.");
00713                                 return None ;
00714                         }
00715                 }else
00716                         xim = im->alt.mask_ximage ;
00717                 if (xim != NULL )
00718                 {
00719                         res = put_ximage( asv, xim, d, gc,      src_x, src_y, dest_x, dest_y, width, height );
00720                         if( xim != im->alt.mask_ximage )
00721                                 XDestroyImage (xim);
00722                 }
00723                 return res;
00724         }
00725 #endif
00726         return False ;
00727 }
00728 
00729 
00730 Pixmap
00731 asimage2pixmap(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached)
00732 {
00733 #ifndef X_DISPLAY_MISSING
00734         if( im )
00735         {
00736                 Pixmap        p = None;
00737 
00738                 p = create_visual_pixmap( asv, root, im->width, im->height, 0 );
00739 
00740                 if( !asimage2drawable( asv, p, im, gc, 0, 0, 0, 0, im->width, im->height, use_cached) )
00741                 {
00742                         XFreePixmap( asv->dpy, p );
00743                         p = None ;
00744                 }
00745                 return p;
00746         }
00747 #endif
00748         return None ;
00749 }
00750 
00751 Pixmap
00752 asimage2alpha(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached, Bool bitmap)
00753 {
00754 #ifndef X_DISPLAY_MISSING
00755         XImage       *xim ;
00756         Pixmap        mask = None;
00757         GC                        my_gc = gc ;
00758 
00759         int target_depth = bitmap?1:8;
00760 
00761         if ( !use_cached || im->alt.mask_ximage == NULL ||
00762              im->alt.mask_ximage->depth != target_depth )
00763         {
00764                 if( (xim = asimage2alpha_ximage( asv, im, bitmap )) == NULL )
00765                 {
00766                         show_error("cannot export image's mask into XImage.");
00767                         return None ;
00768                 }
00769         }else
00770                 xim = im->alt.mask_ximage ;
00771         mask = create_visual_pixmap( asv, root, xim->width, xim->height, target_depth );
00772         if( my_gc == NULL )
00773         {
00774                 XGCValues gcv ;
00775                 my_gc = XCreateGC( asv->dpy, mask, 0, &gcv );
00776         }
00777         ASPutXImage( asv, mask, my_gc, xim, 0, 0, 0, 0, xim->width, xim->height );
00778         if( my_gc != gc )
00779                 XFreeGC( asv->dpy, my_gc );
00780         if( xim != im->alt.mask_ximage )
00781                 XDestroyImage (xim);
00782         return mask;
00783 #else
00784         return None ;
00785 #endif
00786 }
00787 
00788 Pixmap
00789 asimage2mask(ASVisual *asv, Window root, ASImage *im, GC gc, Bool use_cached)
00790 {
00791         return asimage2alpha(asv, root, im, gc, use_cached, True);
00792 }
00793 /* ********************************************************************************/
00794 /* The end !!!!                                                                                                                                  */
00795 /* ********************************************************************************/
00796 

Generated on Tue Jul 5 14:13:33 2011 for ROOT_528-00b_version by  doxygen 1.5.1