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