Actual source code: ximage.c

      1: /*
      2:     Code for getting raster images out of a X image or pixmap
      3: */

      5: #include <../src/sys/classes/draw/impls/x/ximpl.h>

      7: PETSC_INTERN PetscErrorCode PetscDrawGetImage_X(PetscDraw,unsigned char[PETSC_DRAW_MAXCOLOR][3],unsigned int*,unsigned int*,unsigned char*[]);

     10: PETSC_STATIC_INLINE PetscErrorCode PetscArgSortPixVal(const PetscDrawXiPixVal v[PETSC_DRAW_MAXCOLOR],int idx[],int right)
     11: {
     12:   PetscDrawXiPixVal vl;
     13:   int               i,last,tmp;
     14:   PetscErrorCode    ierr;
     15: # define            SWAP(a,b) {tmp=a;a=b;b=tmp;}
     17:   if (right <= 1) {
     18:     if (right == 1) {
     19:       if (v[idx[0]] > v[idx[1]]) SWAP(idx[0],idx[1]);
     20:     }
     21:     return(0);
     22:   }
     23:   SWAP(idx[0],idx[right/2]);
     24:   vl = v[idx[0]]; last = 0;
     25:   for (i=1; i<=right; i++)
     26:     if (v[idx[i]] < vl) {last++; SWAP(idx[last],idx[i]);}
     27:   SWAP(idx[0],idx[last]);
     28:   PetscArgSortPixVal(v,idx,last-1);
     29:   PetscArgSortPixVal(v,idx+last+1,right-(last+1));
     30: # undef SWAP
     31:   return(0);
     32: }

     34: /*
     35:    Map a pixel value to PETSc color value (index in the colormap)
     36: */
     37: PETSC_STATIC_INLINE int PetscDrawXiPixelToColor(PetscDraw_X *Xwin,const int arg[PETSC_DRAW_MAXCOLOR],PetscDrawXiPixVal pix)
     38: {
     39:   const PetscDrawXiPixVal *cmap = Xwin->cmapping;
     40:   int                     lo, mid, hi = PETSC_DRAW_MAXCOLOR;
     41:   /* linear search the first few entries */
     42:   for (lo=0; lo<8; lo++)
     43:     if (pix == cmap[lo])
     44:       return lo;
     45:   /* binary search the remaining entries */
     46:   while (hi - lo > 1) {
     47:     mid = lo + (hi - lo)/2;
     48:     if (pix < cmap[arg[mid]]) hi = mid;
     49:     else                      lo = mid;
     50:   }
     51:   return arg[lo];
     52: }

     54: PetscErrorCode PetscDrawGetImage_X(PetscDraw draw,unsigned char palette[PETSC_DRAW_MAXCOLOR][3],unsigned int *out_w,unsigned int *out_h,unsigned char *out_pixels[])
     55: {
     56:   PetscDraw_X      *Xwin = (PetscDraw_X*)draw->data;
     57:   PetscMPIInt      rank;
     58:   PetscErrorCode   ierr;

     61:   if (out_w)      *out_w      = 0;
     62:   if (out_h)      *out_h      = 0;
     63:   if (out_pixels) *out_pixels = NULL;
     64:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

     66:   /* make sure the X server processed requests from all processes */
     67:   PetscDrawCollectiveBegin(draw);
     68:   XSync(Xwin->disp,True);
     69:   PetscDrawCollectiveEnd(draw);
     70:   MPI_Barrier(PetscObjectComm((PetscObject)draw));

     72:   /* only the first process return image data */
     73:   PetscDrawCollectiveBegin(draw);
     74:   if (!rank) {
     75:     Window        root;
     76:     XImage        *ximage;
     77:     int           pmap[PETSC_DRAW_MAXCOLOR];
     78:     unsigned char *pixels = NULL;
     79:     unsigned int  w,h,dummy;
     80:     int           x,y,p;
     81:     /* copy colormap palette to the caller */
     82:     PetscMemcpy(palette,Xwin->cpalette,sizeof(Xwin->cpalette));
     83:     /* get image out of the drawable */
     84:     XGetGeometry(Xwin->disp,PetscDrawXiDrawable(Xwin),&root,&x,&y,&w,&h,&dummy,&dummy);
     85:     ximage = XGetImage(Xwin->disp,PetscDrawXiDrawable(Xwin),0,0,w,h,AllPlanes,ZPixmap);
     86:     if (!ximage) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot XGetImage()");
     87:     /* build indirect sort permutation (a.k.a argsort) of the color -> pixel mapping */
     88:     for (p=0; p<PETSC_DRAW_MAXCOLOR; p++) pmap[p] = p; /* identity permutation */
     89:     PetscArgSortPixVal(Xwin->cmapping,pmap,255);
     90:     /* extract pixel values out of the image and map them to color indices */
     91:     PetscMalloc1(w*h,&pixels);
     92:     for (p=0,y=0; y<(int)h; y++)
     93:       for (x=0; x<(int)w; x++) {
     94:         PetscDrawXiPixVal pix = XGetPixel(ximage,x,y);
     95:         pixels[p++] = (unsigned char)PetscDrawXiPixelToColor(Xwin,pmap,pix);
     96:       }
     97:     XDestroyImage(ximage);
     98:     *out_w      = w;
     99:     *out_h      = h;
    100:     *out_pixels = pixels;
    101:   }
    102:   PetscDrawCollectiveEnd(draw);
    103:   return(0);
    104: }