xref: /petsc/src/sys/classes/draw/impls/x/ximage.c (revision 8067a7d5d1c29607366ed2aff819d529007817c0)
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    Get RGB color entries out of the X colormap
11 */
12 #undef __FUNCT__
13 #define __FUNCT__ "PetscDrawXiGetColorsRGB"
14 static PetscErrorCode PetscDrawXiGetColorsRGB(PetscDraw_X *Xwin,unsigned char rgb[256][3])
15 {
16   int    k;
17   XColor colordef[256];
18 
19   PetscFunctionBegin;
20   for (k=0; k<256; k++) {
21     colordef[k].pixel = Xwin->cmapping[k];
22     colordef[k].flags = DoRed|DoGreen|DoBlue;
23   }
24   XQueryColors(Xwin->disp,Xwin->cmap,colordef,256);
25   for (k=0; k<256; k++) {
26     rgb[k][0] = (unsigned char)(colordef[k].red   >> 8);
27     rgb[k][1] = (unsigned char)(colordef[k].green >> 8);
28     rgb[k][2] = (unsigned char)(colordef[k].blue  >> 8);
29   }
30   PetscFunctionReturn(0);
31 }
32 
33 /*
34    Map a pixel value to PETSc color value (index in the colormap)
35 */
36 #undef __FUNCT__
37 #define __FUNCT__ "PetscDrawXiPixelToColor"
38 PETSC_STATIC_INLINE int PetscDrawXiPixelToColor(PetscDraw_X *Xwin,PetscDrawXiPixVal pixval)
39 {
40   int               color;
41   PetscDrawXiPixVal *cmap = Xwin->cmapping;
42 
43   PetscFunctionBegin;
44   for (color=0; color<256; color++)   /* slow linear search */
45     if (cmap[color] == pixval) break; /* found color */
46   if (PetscUnlikely(color == 256))    /* should not happen */
47     color = PETSC_DRAW_BLACK;
48   PetscFunctionReturn(color);
49 }
50 
51 #undef __FUNCT__
52 #define __FUNCT__ "PetscDrawGetImage_X"
53 PetscErrorCode PetscDrawGetImage_X(PetscDraw draw,unsigned char palette[256][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;
58 
59   PetscFunctionBegin;
60   if (out_w)      *out_w      = 0;
61   if (out_h)      *out_h      = 0;
62   if (out_pixels) *out_pixels = NULL;
63   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
64 
65   /* make sure the X server processed requests from all processes */
66   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
67   XSync(Xwin->disp,True);
68   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
69   ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
70 
71   /* only the first process handles the saving business */
72   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
73   if (!rank) {
74     Window        root;
75     XImage        *ximage;
76     unsigned char *pixels = NULL;
77     unsigned int  w,h,dummy;
78     int           x,y,p;
79     /* get RGB colors out of the colormap */
80     ierr = PetscDrawXiGetColorsRGB(Xwin,palette);CHKERRQ(ierr);
81     /* get image out of the drawable */
82     XGetGeometry(Xwin->disp,PetscDrawXiDrawable(Xwin),&root,&x,&y,&w,&h,&dummy,&dummy);
83     ximage = XGetImage(Xwin->disp,PetscDrawXiDrawable(Xwin),0,0,w,h,AllPlanes,ZPixmap);
84     if (!ximage) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot XGetImage()");
85     /* extract pixel values out of the image  */
86     ierr = PetscMalloc1(w*h,&pixels);CHKERRQ(ierr);
87     for (p=0,y=0; y<(int)h; y++)
88       for (x=0; x<(int)w; x++)
89         pixels[p++] = PetscDrawXiPixelToColor(Xwin,XGetPixel(ximage,x,y));
90     XDestroyImage(ximage);
91     *out_w      = w;
92     *out_h      = h;
93     *out_pixels = pixels;
94   }
95   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98