1 /* 2 Code for getting raster images out of a X image or pixmap 3 */ 4 5 #include <../src/sys/classes/draw/impls/x/ximpl.h> 6 7 PETSC_INTERN PetscErrorCode PetscDrawGetImage_X(PetscDraw,unsigned char[][3],unsigned int*,unsigned int*,unsigned char*[]); 8 9 10 #undef __FUNCT__ 11 #define __FUNCT__ "PetscArgSortPixVal" 12 PETSC_STATIC_INLINE PetscErrorCode PetscArgSortPixVal(const PetscDrawXiPixVal v[256],int idx[],int right) 13 { 14 PetscDrawXiPixVal vl; 15 int i,last,tmp; 16 PetscErrorCode ierr; 17 # define SWAP(a,b) {tmp=a;a=b;b=tmp;} 18 PetscFunctionBegin; 19 if (right <= 1) { 20 if (right == 1) { 21 if (v[idx[0]] > v[idx[1]]) SWAP(idx[0],idx[1]); 22 } 23 PetscFunctionReturn(0); 24 } 25 SWAP(idx[0],idx[right/2]); 26 vl = v[idx[0]]; last = 0; 27 for (i=1; i<=right; i++) 28 if (v[idx[i]] < vl) {last++; SWAP(idx[last],idx[i]);} 29 SWAP(idx[0],idx[last]); 30 ierr = PetscArgSortPixVal(v,idx,last-1);CHKERRQ(ierr); 31 ierr = PetscArgSortPixVal(v,idx+last+1,right-(last+1));CHKERRQ(ierr); 32 # undef SWAP 33 PetscFunctionReturn(0); 34 } 35 36 /* 37 Map a pixel value to PETSc color value (index in the colormap) 38 */ 39 #undef __FUNCT__ 40 #define __FUNCT__ "PetscFindPixVal" 41 PETSC_STATIC_INLINE int PetscDrawXiPixelToColor(PetscDraw_X *Xwin,const int arg[256],PetscDrawXiPixVal pix) 42 { 43 const PetscDrawXiPixVal *cmap = Xwin->cmapping; 44 int lo, mid, hi = 256; 45 /* linear search the first few entries */ 46 for (lo=0; lo<8; lo++) 47 if (pix == cmap[lo]) 48 return lo; 49 /* binary search the remaining entries */ 50 while (hi - lo > 1) { 51 mid = lo + (hi - lo)/2; 52 if (pix < cmap[arg[mid]]) hi = mid; 53 else lo = mid; 54 } 55 return arg[lo]; 56 } 57 58 #undef __FUNCT__ 59 #define __FUNCT__ "PetscDrawGetImage_X" 60 PetscErrorCode PetscDrawGetImage_X(PetscDraw draw,unsigned char palette[256][3],unsigned int *out_w,unsigned int *out_h,unsigned char *out_pixels[]) 61 { 62 PetscDraw_X *Xwin = (PetscDraw_X*)draw->data; 63 PetscMPIInt rank; 64 PetscErrorCode ierr; 65 66 PetscFunctionBegin; 67 if (out_w) *out_w = 0; 68 if (out_h) *out_h = 0; 69 if (out_pixels) *out_pixels = NULL; 70 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 71 72 /* make sure the X server processed requests from all processes */ 73 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 74 XSync(Xwin->disp,True); 75 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 76 ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr); 77 78 /* only the first process return image data */ 79 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 80 if (!rank) { 81 Window root; 82 XImage *ximage; 83 int pmap[256]; 84 unsigned char *pixels = NULL; 85 unsigned int w,h,dummy; 86 int x,y,p; 87 /* copy colormap palette to the caller */ 88 ierr = PetscMemcpy(palette,Xwin->cpalette,sizeof(Xwin->cpalette));CHKERRQ(ierr); 89 /* get image out of the drawable */ 90 XGetGeometry(Xwin->disp,PetscDrawXiDrawable(Xwin),&root,&x,&y,&w,&h,&dummy,&dummy); 91 ximage = XGetImage(Xwin->disp,PetscDrawXiDrawable(Xwin),0,0,w,h,AllPlanes,ZPixmap); 92 if (!ximage) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot XGetImage()"); 93 /* build indirect sort permutation (a.k.a argsort) of the color -> pixel mapping */ 94 for (p=0; p<256; p++) pmap[p] = p; /* identity permutation */ 95 ierr = PetscArgSortPixVal(Xwin->cmapping,pmap,255);CHKERRQ(ierr); 96 /* extract pixel values out of the image and map them to color indices */ 97 ierr = PetscMalloc1(w*h,&pixels);CHKERRQ(ierr); 98 for (p=0,y=0; y<(int)h; y++) 99 for (x=0; x<(int)w; x++) { 100 PetscDrawXiPixVal pix = XGetPixel(ximage,x,y); 101 pixels[p++] = (unsigned char)PetscDrawXiPixelToColor(Xwin,pmap,pix); 102 } 103 XDestroyImage(ximage); 104 *out_w = w; 105 *out_h = h; 106 *out_pixels = pixels; 107 } 108 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 109 PetscFunctionReturn(0); 110 } 111