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*[]);

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

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

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

 57:   if (out_w)      *out_w      = 0;
 58:   if (out_h)      *out_h      = 0;
 59:   if (out_pixels) *out_pixels = NULL;
 60:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

 62:   /* make sure the X server processed requests from all processes */
 63:   PetscDrawCollectiveBegin(draw);
 64:   XSync(Xwin->disp,True);
 65:   PetscDrawCollectiveEnd(draw);
 66:   MPI_Barrier(PetscObjectComm((PetscObject)draw));

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