Actual source code: ximage.c

petsc-3.10.5 2019-03-28
Report Typos and Errors
  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[][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: }