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