Actual source code: ximage.c
petsc-3.9.4 2018-09-11
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: }