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: }