Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

xim.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "xim.h"
00008 #include "xutil.h"
00009 
00010 /*********************************************************************/
00011 /***** 22 Aug 1998: modified to allow for 3 and 4 byte visuals,  *****/
00012 /*****              and for either possible byte order -- RW Cox *****/
00013 /*****                                                           *****/
00014 /***** 11 Feb 1999: added ability to deal with MRI_rgb images    *****/
00015 /*********************************************************************/
00016 
00017 /*------------------------------------------------------------------------*/
00018 /*! Free an XImage created by mri_to_XImage() or its kin.
00019 --------------------------------------------------------------------------*/
00020 
00021 void MCW_kill_XImage( XImage *image )
00022 {
00023 ENTRY("MCW_kill_XImage") ;
00024    if( image != NULL ){
00025       if( image->data != NULL ){
00026          XtFree( image->data ) ; image->data = NULL ;
00027       }
00028       XDestroyImage( image ) ;
00029    }
00030    EXRETURN ;
00031 }
00032 
00033 /*-------------------------------------------------------------------------*/
00034 /*! Create an XImage from an MRI_IMAGE of shorts or rgbs:
00035     - values >= 0 draw from the "image" palette
00036     - values <  0 draw from the "overlay" palette (stored in dc)
00037 ---------------------------------------------------------------------------*/
00038 
00039 XImage * mri_to_XImage( MCW_DC *dc , MRI_IMAGE *im )
00040 {
00041    int  w2, width, height ;
00042    unsigned char *Image;
00043    XImage        *ximage;
00044    int  border ;        /* 22 Aug 1998 */
00045 
00046    register int     i , hw , sk , k ;
00047    register short *sar ;
00048    register Pixel *ppix , *npix ;
00049    register unsigned char *ptr;
00050 
00051 ENTRY("mri_to_XImage") ;
00052 
00053    if( im->kind == MRI_rgb ) RETURN( rgb_to_XImage(dc,im) ) ;  /* 11 Feb 1999 */
00054 
00055    if( im->kind != MRI_short ){
00056       fprintf(stderr,"\n*** ILLEGAL image input to mri_to_XImage\n") ;
00057       EXIT(1) ;
00058    }
00059    sar  = MRI_SHORT_PTR(im) ;
00060    ppix = dc->pix_im ;       /* array for positive pixels */
00061    npix = dc->ovc->pix_ov ;  /* array for negative pixels */
00062 
00063    width  = im->nx ;
00064    height = im->ny ;
00065 
00066    w2 = width * dc->byper ;  /* rowlength in bytes */
00067 
00068    Image = (unsigned char *) XtMalloc( (size_t) (w2*height) );
00069 
00070    ximage = XCreateImage( dc->display , dc->visual , dc->depth ,
00071                           ZPixmap , 0 , Image , width,height , 8 , w2 ) ;
00072 
00073    if( ximage == NULL ){
00074       fprintf(stderr,"\n*** CANNOT create new XImage for display\n") ;
00075       EXIT(1) ;
00076    }
00077 
00078    border = ximage->byte_order ;          /* 22 Aug 1998 */
00079 
00080    ptr = Image;
00081    k   = 0;
00082    hw  = height * width ;
00083 
00084    switch( dc->byper ){
00085 
00086       case 1:                             /* 1 byte data goes into Image */
00087          for( i=0 ; i < hw ; i++ ){
00088             sk = sar[k++] ;
00089             *ptr++ = (sk >= 0) ? (ppix[sk]  & 0xff)
00090                                : (npix[-sk] & 0xff) ;
00091          }
00092       break ;
00093 
00094       case 2:                             /* 2 byte data goes into Image */
00095          if( border == MSBFirst ){        /* 22 Aug 1998 */
00096             for( i=0 ; i < hw ; i++ ){
00097                sk = sar[k++] ;
00098                if( sk >= 0 ){
00099                   *ptr++ = (ppix[sk] >> 8) & 0xff ;  /* MSB */
00100                   *ptr++ = (ppix[sk])      & 0xff ;  /* LSB */
00101                } else {
00102                   *ptr++ = (npix[-sk] >> 8) & 0xff ;
00103                   *ptr++ = (npix[-sk])      & 0xff ;
00104                }
00105             }
00106          } else {                          /* LSBFirst */
00107             for( i=0 ; i < hw ; i++ ){
00108                sk = sar[k++] ;
00109                if( sk >= 0 ){
00110                   *ptr++ = (ppix[sk])      & 0xff ;  /* LSB */
00111                   *ptr++ = (ppix[sk] >> 8) & 0xff ;  /* MSB */
00112                } else {
00113                   *ptr++ = (npix[-sk])      & 0xff ;
00114                   *ptr++ = (npix[-sk] >> 8) & 0xff ;
00115                }
00116             }
00117          }
00118       break ;
00119 
00120       case 3:                            /* 3 & 4 byte data: 22 Aug 1998 */
00121          if( border == MSBFirst ){
00122             for( i=0 ; i < hw ; i++ ){
00123                sk = sar[k++] ;
00124                if( sk >= 0 ){
00125                   *ptr++ = (ppix[sk] >> 16) & 0xff ;  /* MSB */
00126                   *ptr++ = (ppix[sk] >>  8) & 0xff ;
00127                   *ptr++ = (ppix[sk])       & 0xff ;  /* LSB */
00128                } else {
00129                   *ptr++ = (npix[-sk] >> 16) & 0xff ;
00130                   *ptr++ = (npix[-sk] >>  8) & 0xff ;
00131                   *ptr++ = (npix[-sk])       & 0xff ;
00132                }
00133             }
00134          } else {                          /* LSBFirst */
00135             for( i=0 ; i < hw ; i++ ){
00136                sk = sar[k++] ;
00137                if( sk >= 0 ){
00138                   *ptr++ = (ppix[sk])       & 0xff ;  /* LSB */
00139                   *ptr++ = (ppix[sk] >>  8) & 0xff ;
00140                   *ptr++ = (ppix[sk] >> 16) & 0xff ;  /* MSB */
00141                } else {
00142                   *ptr++ = (npix[-sk])       & 0xff ;
00143                   *ptr++ = (npix[-sk] >>  8) & 0xff ;
00144                   *ptr++ = (npix[-sk] >> 16) & 0xff ;
00145                }
00146             }
00147          }
00148       break ;
00149 
00150       case 4:
00151          if( border == MSBFirst ){
00152             for( i=0 ; i < hw ; i++ ){
00153                sk = sar[k++] ;
00154                if( sk >= 0 ){
00155                   *ptr++ = (ppix[sk] >> 24) & 0xff ;  /* MSB */
00156                   *ptr++ = (ppix[sk] >> 16) & 0xff ;
00157                   *ptr++ = (ppix[sk] >>  8) & 0xff ;
00158                   *ptr++ = (ppix[sk])       & 0xff ;  /* LSB */
00159                } else {
00160                   *ptr++ = (npix[-sk] >> 24) & 0xff ;
00161                   *ptr++ = (npix[-sk] >> 16) & 0xff ;
00162                   *ptr++ = (npix[-sk] >>  8) & 0xff ;
00163                   *ptr++ = (npix[-sk])       & 0xff ;
00164                }
00165             }
00166          } else {                          /* LSBFirst */
00167             for( i=0 ; i < hw ; i++ ){
00168                sk = sar[k++] ;
00169                if( sk >= 0 ){
00170                   *ptr++ = (ppix[sk])       & 0xff ;  /* LSB */
00171                   *ptr++ = (ppix[sk] >>  8) & 0xff ;
00172                   *ptr++ = (ppix[sk] >> 16) & 0xff ;
00173                   *ptr++ = (ppix[sk] >> 24) & 0xff ;  /* MSB */
00174                } else {
00175                   *ptr++ = (npix[-sk])       & 0xff ;
00176                   *ptr++ = (npix[-sk] >>  8) & 0xff ;
00177                   *ptr++ = (npix[-sk] >> 16) & 0xff ;
00178                   *ptr++ = (npix[-sk] >> 24) & 0xff ;
00179                }
00180             }
00181          }
00182       break ;
00183 
00184       default:
00185          fprintf(stderr,
00186                  "\n*** ILLEGAL value of display bytes/pix=%d in mri_to_XImage\n",
00187                  dc->byper);
00188          EXIT(1) ;
00189    }
00190 
00191    RETURN( ximage ) ;
00192 }
00193 
00194 /*--------------------------------------------------------------------------*/
00195 /*! - Input:  an XImage of one size
00196     - Output: an XImage of another size
00197     - method: nearest neighbor resampling
00198 ----------------------------------------------------------------------------*/
00199 
00200 XImage * resize_XImage( MCW_DC *dc , XImage *image ,
00201                         int new_width , int new_height )
00202 {
00203    static int *lt = NULL ;       /* lookup table stuff */
00204    static int old_width = -1 ;
00205 
00206    register int iy, ex, ey, iW, iH, w2 ;
00207    char         *ximag;
00208    char         *Ep, *El, *Ip, *Il, *Id , *Ed ; /* d=data, l=row, p=pixel */
00209    int          Erow , Irow ;
00210 
00211    XImage *emage ;  /* to be output image */
00212 
00213    /*** sanity check ***/
00214 
00215 ENTRY("resize_XImage") ;
00216 
00217    if( new_width <= 0 || new_height <= 0 ){
00218       fprintf(stderr ,
00219               "\n***ILLEGAL new width %d or height %d in resize\n",
00220               new_width , new_height ) ;
00221       EXIT(1) ;
00222    }
00223 
00224    /*** data about input image ***/
00225 
00226    iW = image->width ;                /* input width and height */
00227    iH = image->height ;
00228 
00229    if( iW == new_width && iH == new_height ){ /* very special case */
00230         RETURN( image ) ;
00231    }
00232 
00233    /*** create emage of the appropriate size ***/
00234 
00235    w2    = new_width * dc->byper ;
00236    ximag = (char *) XtMalloc( (size_t) (w2 * new_height) );
00237 
00238    if( ximag == NULL ){
00239       fprintf(stderr,"\n***CANNOT allocate memory for resizing XImage\n") ;
00240       EXIT(1) ;
00241    }
00242 
00243    emage = XCreateImage( dc->display , dc->visual , dc->depth ,
00244                          ZPixmap, 0, ximag, new_width,new_height, 8, w2 ) ;
00245 
00246    if( emage == NULL ){
00247       fprintf(stderr,"\n*** CANNOT create new XImage for resizing\n") ;
00248       EXIT(1) ;
00249    }
00250 
00251    /*** make lookup table for xnew -> xold ***/
00252 
00253    /*** Notice that this table will never be de-allocated or shrink;
00254         it will grow larger when the images grow larger, as needed. ***/
00255 
00256    if( new_width > old_width ){
00257       lt = (int *) XtRealloc( (char *)lt,(size_t)(new_width * sizeof(int)) );
00258       old_width = new_width ;
00259    }
00260 
00261    for( ex=0 ; ex < new_width ; ex++ )
00262       lt[ex] = MAP_XY(ex,new_width,iW) * dc->byper ;
00263 
00264    /*** get ready to go ***/
00265 
00266    Ed = (char *) emage->data ; Erow = emage->bytes_per_line ;
00267    Id = (char *) image->data ; Irow = image->bytes_per_line ;
00268 
00269    switch( dc->byper ){
00270 
00271       case 1:                                 /* 1 byte per pixel */
00272          for( ey=0 ; ey < new_height ; ey++ ){
00273 
00274             iy = MAP_XY(ey,new_height,iH) ;   /* row index in input image */
00275             Il = Id + Irow * iy ;             /* start of that row */
00276             El = Ed + Erow * ey ;             /* start of row in output */
00277             Ep = El ;
00278             for( ex=0 ; ex < new_width ; ex++ ){
00279                Ip = Il + lt[ex] ;             /* data pointer in input */
00280                *Ep++ = *Ip ;
00281             }
00282          }
00283       break ;
00284 
00285       case 2:                                 /* 2 bytes per pixel */
00286          for( ey=0 ; ey < new_height ; ey++ ){
00287 
00288             iy = MAP_XY(ey,new_height,iH) ;   /* row index in input image */
00289             Il = Id + Irow * iy ;             /* start of that row */
00290             El = Ed + Erow * ey ;             /* start of row in output */
00291             Ep = El ;
00292             for( ex=0 ; ex < new_width ; ex++ ){
00293                Ip = Il + lt[ex] ;             /* data pointer in input */
00294                *Ep++ = *Ip ;
00295                *Ep++ = *(Ip+1) ;
00296             }
00297          }
00298       break ;
00299 
00300       case 3:                                 /* 3 & 4 added 22 Aug 1998 */
00301          for( ey=0 ; ey < new_height ; ey++ ){
00302 
00303             iy = MAP_XY(ey,new_height,iH) ;   /* row index in input image */
00304             Il = Id + Irow * iy ;             /* start of that row */
00305             El = Ed + Erow * ey ;             /* start of row in output */
00306             Ep = El ;
00307             for( ex=0 ; ex < new_width ; ex++ ){
00308                Ip = Il + lt[ex] ;             /* data pointer in input */
00309                *Ep++ = *Ip ;
00310                *Ep++ = *(Ip+1) ;
00311                *Ep++ = *(Ip+2) ;
00312             }
00313          }
00314       break ;
00315 
00316       case 4:
00317          for( ey=0 ; ey < new_height ; ey++ ){
00318 
00319             iy = MAP_XY(ey,new_height,iH) ;   /* row index in input image */
00320             Il = Id + Irow * iy ;             /* start of that row */
00321             El = Ed + Erow * ey ;             /* start of row in output */
00322             Ep = El ;
00323             for( ex=0 ; ex < new_width ; ex++ ){
00324                Ip = Il + lt[ex] ;             /* data pointer in input */
00325                *Ep++ = *Ip ;
00326                *Ep++ = *(Ip+1) ;
00327                *Ep++ = *(Ip+2) ;
00328                *Ep++ = *(Ip+3) ;
00329             }
00330          }
00331       break ;
00332 
00333       default:
00334          fprintf(stderr,"\n***ILLEGAL bytes/pix=%d for resizing\n",dc->byper) ;
00335          EXIT(1) ;
00336    }
00337 
00338    RETURN( emage ) ;
00339 }
00340 
00341 /*---------------------------------------------------------------------------*/
00342 /*! - input  = XImage (with Pixel values from dc)
00343     - output = RGB or Grayscale image
00344     - code   = mask of values indicating optional processing:
00345 
00346           - (code & X2M_USE_CMAP) != 0 means use the entire colormap
00347                                   == 0 means use only Pixels in dc
00348 
00349           - (code & X2M_FORCE_RGB)!= 0 means output is always RGB format
00350                                   == 0 means output might be byte format
00351                                        (grayscale) if all pixels are gray
00352 -----------------------------------------------------------------------------*/
00353 
00354 MRI_IMAGE * XImage_to_mri( MCW_DC *dc , XImage *ximage , int code )
00355 {
00356    int nx , ny , npix , ii,jj , kk , allgray , lsize ;
00357    Pixel pp ;
00358    byte *rgb , *gray ;
00359    byte rr,gg,bb ;
00360    byte *ptr ;
00361    XColor *xc ;
00362    MRI_IMAGE *outim ;
00363    int  border ;        /* 22 Aug 1998 */
00364 
00365    int use_cmap  = ((code & X2M_USE_CMAP ) != 0) ;  /* 03 Apr 2001 */
00366    int force_rgb = ((code & X2M_FORCE_RGB) != 0) ;
00367 
00368 ENTRY("XImage_to_mri") ;
00369 
00370    if( ximage == NULL || ximage->data == NULL ) RETURN( NULL ) ;
00371 
00372 #if 0
00373 fprintf(stderr,
00374         "XImage bitmap_unit   =%3d  bitmap_pad=%3d  depth =%3d\n"
00375         "       bytes_per_line=%3d  width     =%3d  height=%3d\n"
00376         "       bits_per_pixel=%3d  xoffset   =%3d\n" ,
00377  ximage->bitmap_unit    , ximage->bitmap_pad , ximage->depth ,
00378  ximage->bytes_per_line , ximage->width      , ximage->height ,
00379  ximage->bits_per_pixel , ximage->xoffset ) ;
00380 #endif
00381 
00382    nx = ximage->width ; ny = ximage->height ; npix = nx * ny ;
00383 
00384    lsize = ximage->bytes_per_line ;
00385 
00386    ptr = (byte *) ximage->data ;        /* pointer to pixels */
00387 
00388    rgb = (byte *) malloc( sizeof(byte) * 3*npix ) ;
00389    if( rgb == NULL ){
00390       fprintf(stderr,"\n*** malloc failure in XImage_to_mri\n") ;
00391       EXIT(1) ;
00392    }
00393 
00394    border = ximage->byte_order ;           /* 22 Aug 1998 */
00395 
00396    switch( dc->byper ){
00397 
00398       case 1:                              /* 1 byte per pixel */
00399          kk = 0 ; allgray = !force_rgb ;
00400          for( jj=0 ; jj < ny ; jj++ ){
00401             for( ii=0 ; ii < nx ; ii++ ){
00402                pp = ptr[ii+jj*lsize] ;                       /* pixel value */
00403                xc = DCpix_to_XColor( dc , pp , use_cmap ) ;  /* XColor */
00404                rr = rgb[kk++] = INTEN_TO_BYTE( xc->red ) ;
00405                gg = rgb[kk++] = INTEN_TO_BYTE( xc->green ) ;
00406                bb = rgb[kk++] = INTEN_TO_BYTE( xc->blue ) ;
00407                allgray = allgray && (rr==gg) && (gg=bb) ;
00408             }
00409          }
00410       break ;
00411 
00412       case 2:                               /* 2 bytes per pixel */
00413          kk = 0 ; allgray = !force_rgb ;
00414          for( jj=0 ; jj < ny ; jj++ ){
00415             for( ii=0 ; ii < nx ; ii++ ){
00416                if( border == MSBFirst )
00417                   pp = (ptr[2*ii+jj*lsize]   << 8) | ptr[2*ii+jj*lsize+1] ;
00418                else
00419                   pp = (ptr[2*ii+jj*lsize+1] << 8) | ptr[2*ii+jj*lsize] ;
00420 
00421                xc = DCpix_to_XColor( dc , pp , use_cmap ) ;
00422                rr = rgb[kk++] = INTEN_TO_BYTE( xc->red ) ;
00423                gg = rgb[kk++] = INTEN_TO_BYTE( xc->green ) ;
00424                bb = rgb[kk++] = INTEN_TO_BYTE( xc->blue ) ;
00425                allgray = allgray && (rr==gg) && (gg=bb) ;
00426             }
00427          }
00428       break ;
00429 
00430       case 3:                               /* 3 & 4 added 22 Aug 1998 */
00431          kk = 0 ; allgray = !force_rgb ;
00432          for( jj=0 ; jj < ny ; jj++ ){
00433             for( ii=0 ; ii < nx ; ii++ ){
00434                if( border == MSBFirst )
00435                   pp = (ptr[3*ii+jj*lsize]   << 16) |
00436                        (ptr[3*ii+jj*lsize+1] <<  8) | ptr[3*ii+jj*lsize+2] ;
00437                else
00438                   pp = (ptr[3*ii+jj*lsize+2] << 16) |
00439                        (ptr[3*ii+jj*lsize+1] <<  8) | ptr[3*ii+jj*lsize] ;
00440 
00441                xc = DCpix_to_XColor( dc , pp , use_cmap ) ;
00442                rr = rgb[kk++] = INTEN_TO_BYTE( xc->red ) ;
00443                gg = rgb[kk++] = INTEN_TO_BYTE( xc->green ) ;
00444                bb = rgb[kk++] = INTEN_TO_BYTE( xc->blue ) ;
00445                allgray = allgray && (rr==gg) && (gg=bb) ;
00446             }
00447          }
00448       break ;
00449 
00450       case 4:
00451          kk = 0 ; allgray = !force_rgb ;
00452          for( jj=0 ; jj < ny ; jj++ ){
00453             for( ii=0 ; ii < nx ; ii++ ){
00454                if( border == MSBFirst )
00455                   pp = (ptr[4*ii+jj*lsize]   << 24) | (ptr[4*ii+jj*lsize+1] << 16) |
00456                        (ptr[4*ii+jj*lsize+2] <<  8) |  ptr[4*ii+jj*lsize+3] ;
00457                else
00458                   pp = (ptr[4*ii+jj*lsize+3] << 24) | (ptr[4*ii+jj*lsize+2] << 16) |
00459                        (ptr[4*ii+jj*lsize+1] <<  8) |  ptr[4*ii+jj*lsize] ;
00460 
00461                xc = DCpix_to_XColor( dc , pp , use_cmap ) ;
00462                rr = rgb[kk++] = INTEN_TO_BYTE( xc->red ) ;
00463                gg = rgb[kk++] = INTEN_TO_BYTE( xc->green ) ;
00464                bb = rgb[kk++] = INTEN_TO_BYTE( xc->blue ) ;
00465                allgray = allgray && (rr==gg) && (gg=bb) ;
00466             }
00467          }
00468       break ;
00469 
00470       default:
00471          fprintf(stderr,
00472                  "\n*** ILLEGAL value of bytes/pix=%d in XImage_to_mri\n",
00473                  dc->byper);
00474          EXIT(1) ;
00475    }
00476 
00477    /*** if all pixels are gray, return a grayscale image ***/
00478 
00479    if( allgray ){
00480 
00481       gray = (byte *) malloc( sizeof(byte) * npix ) ;
00482       if( gray == NULL ){
00483          fprintf(stderr,"\n*** malloc failure in XImage_to_mri\n") ;
00484          EXIT(1) ;
00485       }
00486       for( ii=0 , kk=0 ; ii < npix ; ii++ , kk+=3) gray[ii] = rgb[kk] ;
00487       free(rgb) ;
00488       outim = mri_new_vol_empty( nx , ny , 1 , MRI_byte ) ;
00489       mri_fix_data_pointer( gray , outim ) ;
00490 
00491    } else {
00492 
00493    /*** not all gray --> return color RGB image ***/
00494 
00495       outim = mri_new_vol_empty( nx , ny , 1 , MRI_rgb ) ;
00496       mri_fix_data_pointer( rgb , outim ) ;
00497    }
00498 
00499    RETURN( outim ) ;
00500 }
00501 
00502 /*-----------------------------------------------------------------------*/
00503 /*  Convert an array of X11 Pixel values to an XImage for display.
00504     Adapted from mri_to_XImage by RWCox -- 11 Feb 1999
00505 -------------------------------------------------------------------------*/
00506 
00507 XImage * pixar_to_XImage( MCW_DC *dc, int nx, int ny, Pixel *par )
00508 {
00509    int  w2, width, height , border ;
00510    unsigned char *Image ;
00511    XImage        *ximage ;
00512    register int i , hw  ;
00513    register unsigned char *ptr;
00514 
00515    /*-- sanity checks --*/
00516 
00517 ENTRY("pixar_to_XImage") ;
00518 
00519    if( dc == NULL || nx < 1 || ny < 1 || par == NULL ) RETURN( NULL ) ;
00520 
00521    width = nx ; height = ny ;
00522 
00523    w2 = width * dc->byper ;  /* rowlength in bytes */
00524 
00525    Image = (unsigned char *) XtMalloc( (size_t) (w2*height) );
00526    if( Image == NULL ) RETURN( NULL ) ;
00527 
00528    ximage = XCreateImage( dc->display , dc->visual , dc->depth ,
00529                           ZPixmap , 0 , Image , width,height , 8 , w2 ) ;
00530    if( ximage == NULL ){ XtFree((char *)Image) ; RETURN( NULL ) ; }
00531 
00532    border = ximage->byte_order ;  /* byte order */
00533 
00534    ptr = Image ;                  /* pointer to image bytes */
00535    hw  = height * width ;         /* total number of pixels */
00536 
00537    switch( dc->byper ){           /* load data into Image */
00538 
00539       case 1:                             /* 1 byte data goes into Image */
00540          for( i=0 ; i < hw ; i++ ){
00541             *ptr++ = par[i] & 0xff ;
00542          }
00543       break ;
00544 
00545       case 2:                             /* 2 byte data goes into Image */
00546          if( border == MSBFirst ){
00547             for( i=0 ; i < hw ; i++ ){
00548                *ptr++ = (par[i] >> 8) & 0xff ;  /* MSB */
00549                *ptr++ = (par[i]     ) & 0xff ;  /* LSB */
00550             }
00551          } else {                          /* LSBFirst */
00552             for( i=0 ; i < hw ; i++ ){
00553                *ptr++ = (par[i]     ) & 0xff ;  /* LSB */
00554                *ptr++ = (par[i] >> 8) & 0xff ;  /* MSB */
00555             }
00556          }
00557       break ;
00558 
00559       case 3:                            /* 3 byte data */
00560          if( border == MSBFirst ){
00561             for( i=0 ; i < hw ; i++ ){
00562                *ptr++ = (par[i] >> 16) & 0xff ;  /* MSB */
00563                *ptr++ = (par[i] >>  8) & 0xff ;
00564                *ptr++ = (par[i]      ) & 0xff ;  /* LSB */
00565             }
00566          } else {                           /* LSBFirst */
00567             for( i=0 ; i < hw ; i++ ){
00568                *ptr++ = (par[i]      ) & 0xff ;  /* LSB */
00569                *ptr++ = (par[i] >>  8) & 0xff ;
00570                *ptr++ = (par[i] >> 16) & 0xff ;  /* MSB */
00571             }
00572          }
00573       break ;
00574 
00575       case 4:                            /* 4 byte data */
00576          if( border == MSBFirst ){
00577             for( i=0 ; i < hw ; i++ ){
00578                *ptr++ = (par[i] >> 24) & 0xff ;  /* MSB */
00579                *ptr++ = (par[i] >> 16) & 0xff ;
00580                *ptr++ = (par[i] >>  8) & 0xff ;
00581                *ptr++ = (par[i]      ) & 0xff ;  /* LSB */
00582             }
00583          } else {                           /* LSBFirst */
00584             for( i=0 ; i < hw ; i++ ){
00585                *ptr++ = (par[i]      ) & 0xff ;  /* LSB */
00586                *ptr++ = (par[i] >>  8) & 0xff ;
00587                *ptr++ = (par[i] >> 16) & 0xff ;
00588                *ptr++ = (par[i] >> 24) & 0xff ;  /* MSB */
00589             }
00590          }
00591       break ;
00592 
00593       default:
00594          fprintf(stderr,
00595                  "\n*** ILLEGAL value of display bytes/pix=%d in pixar_to_XImage\n",
00596                  dc->byper);
00597          EXIT(1) ;
00598    }
00599 
00600    RETURN( ximage ) ;
00601 }
00602 
00603 /*-------------------------------------------------------------------*/
00604 #undef INLINE
00605 #ifdef __GNUC__
00606 # define INLINE inline
00607 #else
00608 # define INLINE /*nada*/
00609 #endif
00610 /*-------------------------------------------------------------------*/
00611 /*! Local copy of function from display.c, hopefully for speed.
00612 ---------------------------------------------------------------------*/
00613 
00614 static INLINE Pixel tc_rgb_to_pixel( MCW_DC *dc, byte rr, byte gg, byte bb )
00615 {
00616    static MCW_DC *dcold=NULL ;
00617    DC_colordef *cd = dc->cdef ;
00618    static unsigned long pold=0 ;
00619    static byte rold=0 , gold=0 , bold=0 ;
00620    unsigned long r , g , b ;
00621 
00622    if( cd == NULL ){ reload_DC_colordef(dc) ; cd = dc->cdef ; }
00623 
00624    if( rr == 0   && gg == 0   && bb == 0   ) return 0 ;          /* common */
00625    if( rr == 255 && gg == 255 && bb == 255 ) return cd->whpix ;  /* cases  */
00626 
00627    if( dc == dcold && rr == rold && gg == gold && bb == bold ) /* Remembrance of Things Past? */
00628      return (Pixel) pold ;
00629 
00630    rold = rr ; gold = gg ; bold = bb ; dcold = dc ;            /* OK, remember for next time */
00631 
00632    r = (cd->rrshift<0) ? (rr<<(-cd->rrshift))
00633                        : (rr>>cd->rrshift)   ; r = r & cd->rrmask ;
00634 
00635    g = (cd->ggshift<0) ? (gg<<(-cd->ggshift))
00636                        : (gg>>cd->ggshift)   ; g = g & cd->ggmask ;
00637 
00638    b = (cd->bbshift<0) ? (bb<<(-cd->bbshift))
00639                        : (bb>>cd->bbshift)   ; b = b & cd->bbmask ;
00640 
00641    pold = r | g | b ;  /* assemble color from components */
00642    return (Pixel) pold ;
00643 }
00644 
00645 /*----------------------------------------------------------------------------*/
00646 
00647 static XImage * rgb_to_XImage_simple( MCW_DC *, MRI_IMAGE * ) ;
00648 static XImage * rgb_to_XImage_clever( MCW_DC *, MRI_IMAGE * ) ;
00649 
00650 /*----------------------------------------------------------------------------*/
00651 /*! Convert an MRI_IMAGE of rgb values to an XImage for display.
00652 ------------------------------------------------------------------------------*/
00653 
00654 XImage * rgb_to_XImage( MCW_DC *dc , MRI_IMAGE *im )
00655 {
00656    switch( dc->visual_class ){
00657     case TrueColor:   return rgb_to_XImage_simple(dc,im) ;
00658     case PseudoColor: return rgb_to_XImage_clever(dc,im) ;
00659    }
00660    return NULL ;
00661 }
00662 
00663 /*----------------------------------------------------------------------------*/
00664 /*! Convert an MRI_IMAGE of rgb bytes to an XImage (TrueColor visual only)
00665 ------------------------------------------------------------------------------*/
00666 
00667 static XImage * rgb_to_XImage_simple( MCW_DC *dc , MRI_IMAGE *im )
00668 {
00669    int nxy , ii ;
00670    byte *rgb ;
00671    Pixel *par ;
00672    XImage *xim ;
00673 
00674 ENTRY("rgb_to_XImage_simple") ;
00675 
00676    /*-- sanity check --*/
00677 
00678    if( dc == NULL || im == NULL || im->kind != MRI_rgb ) RETURN( NULL ) ;
00679 
00680    nxy = im->nx * im->ny ;
00681    rgb = MRI_RGB_PTR(im) ;
00682 
00683    par = (Pixel *) malloc(sizeof(Pixel)*nxy); if( par == NULL ) RETURN(NULL) ;
00684 
00685    for( ii=0 ; ii < nxy ; ii++ )
00686      par[ii] = tc_rgb_to_pixel( dc , rgb[3*ii], rgb[3*ii+1], rgb[3*ii+2] ) ;
00687 
00688    xim = pixar_to_XImage( dc , im->nx , im->ny , par ) ;
00689 
00690    free(par) ; RETURN( xim ) ;
00691 }
00692 
00693 /*-----------------------------------------------------------------------*/
00694 /*! Convert an MRI_IMAGE of rgb bytes to an XImage (general visual)
00695 -------------------------------------------------------------------------*/
00696 
00697 static XImage * rgb_to_XImage_clever( MCW_DC *dc , MRI_IMAGE *im )
00698 {
00699    int nxy , ii , c ;
00700    byte *rgb , r,g,b ;
00701    Pixel *par , p=0 ;
00702    XImage *xim ;
00703    int *col_ar , *ii_ar ;
00704 
00705 ENTRY("rgb_to_XImage_clever") ;
00706 
00707    /*-- sanity check --*/
00708 
00709    if( dc == NULL || im == NULL || im->kind != MRI_rgb ) RETURN( NULL ) ;
00710 
00711    nxy = im->nx * im->ny ;
00712    rgb = MRI_RGB_PTR(im) ;
00713 
00714    col_ar = (int *)  malloc( sizeof(int)   * nxy ) ;
00715    ii_ar  = (int *)  malloc( sizeof(int)   * nxy ) ;
00716    par    = (Pixel *)malloc( sizeof(Pixel) * nxy ) ;
00717 
00718    if( col_ar == NULL )                             RETURN( NULL );
00719    if( ii_ar  == NULL ){ free(col_ar);              RETURN( NULL ); }
00720    if( par    == NULL ){ free(col_ar); free(ii_ar); RETURN( NULL ); }
00721 
00722    for( ii=0 ; ii < nxy ; ii++ ){  /* convert RGB triples to ints */
00723       ii_ar[ii]  = ii ;            /* and save original location  */
00724       col_ar[ii] = rgb[3*ii] << 16 | rgb[3*ii+1] << 8 | rgb[3*ii+2] ;
00725    }
00726 
00727    qsort_intint( nxy , col_ar , ii_ar ) ; /* sort to bring like colors together */
00728 
00729    c = -1 ; /* a color that can't occur */
00730 
00731    for( ii=0 ; ii < nxy ; ii++ ){
00732       if( col_ar[ii] != c ){         /* have a new color, so compute its pixel */
00733          c = col_ar[ii] ;
00734          r = (c >> 16) & 0xff ; g = (c >> 8) & 0xff ; b = c & 0xff ;
00735          p = DC_rgb_to_pixel( dc , r,g,b ) ;
00736       }
00737       par[ii_ar[ii]] = p ;           /* store it where it came from */
00738    }
00739 
00740    free(col_ar) ; free(ii_ar) ;      /* toss some trash */
00741 
00742    xim = pixar_to_XImage( dc , im->nx , im->ny , par ) ;
00743 
00744    free(par) ; RETURN( xim ) ;
00745 }
00746 
00747 /**************************************************************************/
00748 /********** 26 Jun 2003: stuff for snapping a Widget to an image **********/
00749 
00750 static int     badsnap = 0 ;
00751 static MCW_DC *snap_dc = NULL ;
00752 
00753 /*! X11 error handler for when XGetImage fails. */
00754 
00755 static int SNAP_errhandler( Display *d , XErrorEvent *x )
00756 {
00757   fprintf(stderr,"** X11 error trying to snapshot window!\n");
00758   badsnap = 1 ; return 0 ;
00759 }
00760 
00761 /*--------------------------------------------------------------*/
00762 /*! Grab the image from a widget's window.  [20 Jun 2003]
00763 ----------------------------------------------------------------*/
00764 
00765 MRI_IMAGE * SNAP_grab_image( Widget w , MCW_DC *dc )
00766 {
00767    XImage * xim ;
00768    MRI_IMAGE * tim ;
00769    Window win ;
00770    Widget wpar=w ;
00771    XWindowAttributes wa ;
00772    int (*old_handler)(Display *, XErrorEvent *) ;
00773 
00774 ENTRY("SNAP_grab_image") ;
00775 
00776    if( dc == NULL )                          RETURN(NULL) ;
00777 
00778    if( w == NULL ){
00779      win = RootWindow( dc->display , dc->screen_num ) ;
00780    } else {
00781      if( !XtIsWidget(w)   ||
00782          !XtIsRealized(w) ||
00783          !XtIsManaged(w)    )                RETURN(NULL) ;
00784      win = XtWindow(w) ;
00785      if( win == (Window)0 )                  RETURN(NULL) ;
00786 
00787      while( XtParent(wpar) != NULL ) wpar = XtParent(wpar) ;  /* find top */
00788 
00789      /*** Raise the window and SUMA will redisplay
00790           entering an infernal loop. ZSS Mon Jun 30/03 ***/
00791 #if 0
00792      XRaiseWindow( dc->display , XtWindow(wpar) ) ;    /* make it visible */
00793 #endif
00794      XFlush( dc->display ) ;
00795      XmUpdateDisplay( w ) ;
00796      if( !MCW_widget_visible(w) )            RETURN(NULL) ;
00797    }
00798 
00799    RWC_sleep(20) ;                                       /* allow refresh */
00800    XGetWindowAttributes( dc->display , win , &wa ) ;      /* get win size */
00801    xim = NULL ; badsnap = 0 ;
00802    old_handler = XSetErrorHandler( SNAP_errhandler ) ;
00803    xim = XGetImage( dc->display , win ,
00804                     0,0 , wa.width,wa.height,
00805                     (unsigned long)(-1), ZPixmap ) ;
00806    (void) XSetErrorHandler( old_handler ) ;
00807    if( badsnap ){
00808      if( xim != NULL ) MCW_kill_XImage(xim) ;
00809      RETURN(NULL) ;
00810    }
00811    if( xim == NULL ) RETURN(NULL) ;
00812 
00813    tim = XImage_to_mri( dc , xim , X2M_USE_CMAP | X2M_FORCE_RGB ) ;
00814    MCW_kill_XImage(xim) ;
00815    RETURN(tim) ;
00816 }
00817 
00818 /*----------------------------------------------------------------------*/
00819 /*! Call this function to get a snapshot of a widget and save
00820     it into a PPM file.
00821 ------------------------------------------------------------------------*/
00822 
00823 void ISQ_snapfile( Widget w )
00824 {
00825    MRI_IMAGE *tim ;
00826    Window win ;
00827    char fname[64] , *eee , prefix[32] ;
00828    int ii ; static int last_ii=1 ;
00829 
00830 ENTRY("ISQ_snapfile") ;
00831 
00832    if( w == NULL || !XtIsWidget(w) )         EXRETURN ;
00833    if( !XtIsRealized(w) || !XtIsManaged(w) ) EXRETURN ;
00834    win = XtWindow(w); if( win == (Window)0 ) EXRETURN ;
00835 
00836    /* create display context if we don't have one */
00837 
00838    if( snap_dc == NULL ){
00839      if( first_dc != NULL ) snap_dc = first_dc ;
00840      else                   snap_dc = MCW_new_DC( w, 4,0, NULL,NULL, 1.0,0 );
00841    }
00842 
00843    /* try to get image */
00844 
00845    tim = SNAP_grab_image( w , snap_dc ) ;
00846    if( tim == NULL )                         EXRETURN ;
00847 
00848    eee = getenv("AFNI_SNAPFILE_PREFIX") ;
00849    if( eee == NULL ){
00850      strcpy(prefix,"S_") ;
00851    } else {
00852      strncpy(prefix,eee,30) ; prefix[30] = '\0' ; strcat(prefix,"_") ;
00853      if( !THD_filename_ok(prefix) ) strcpy(prefix,"S_") ;
00854    }
00855    for( ii=last_ii ; ii <= 999999 ; ii++ ){
00856      sprintf(fname,"%s%06d.ppm",prefix,ii) ;
00857      if( ! THD_is_ondisk(fname) ) break ;
00858    }
00859    if( ii <= 999999 ) mri_write_pnm( fname , tim ) ;
00860    mri_free(tim) ; last_ii = ii ;
00861    EXRETURN ;
00862 }
 

Powered by Plone

This site conforms to the following standards: