18067a7d5SLisandro Dalcin /* 28067a7d5SLisandro Dalcin Code for getting raster images out of a X image or pixmap 38067a7d5SLisandro Dalcin */ 48067a7d5SLisandro Dalcin 58067a7d5SLisandro Dalcin #include <../src/sys/classes/draw/impls/x/ximpl.h> 68067a7d5SLisandro Dalcin 78067a7d5SLisandro Dalcin PETSC_INTERN PetscErrorCode PetscDrawGetImage_X(PetscDraw,unsigned char[][3],unsigned int*,unsigned int*,unsigned char*[]); 88067a7d5SLisandro Dalcin 98067a7d5SLisandro Dalcin 10*f4e3882fSLisandro Dalcin #undef __FUNCT__ 11*f4e3882fSLisandro Dalcin #define __FUNCT__ "PetscArgSortPixVal" 12*f4e3882fSLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode PetscArgSortPixVal(const PetscDrawXiPixVal v[256],int idx[],int right) 13*f4e3882fSLisandro Dalcin { 14*f4e3882fSLisandro Dalcin PetscDrawXiPixVal vl; 15*f4e3882fSLisandro Dalcin int i,last,tmp; 16*f4e3882fSLisandro Dalcin PetscErrorCode ierr; 17*f4e3882fSLisandro Dalcin # define SWAP(a,b) {tmp=a;a=b;b=tmp;} 188067a7d5SLisandro Dalcin PetscFunctionBegin; 19*f4e3882fSLisandro Dalcin if (right <= 1) { 20*f4e3882fSLisandro Dalcin if (right == 1) { 21*f4e3882fSLisandro Dalcin if (v[idx[0]] > v[idx[1]]) SWAP(idx[0],idx[1]); 228067a7d5SLisandro Dalcin } 23*f4e3882fSLisandro Dalcin PetscFunctionReturn(0); 248067a7d5SLisandro Dalcin } 25*f4e3882fSLisandro Dalcin SWAP(idx[0],idx[right/2]); 26*f4e3882fSLisandro Dalcin vl = v[idx[0]]; last = 0; 27*f4e3882fSLisandro Dalcin for (i=1; i<=right; i++) 28*f4e3882fSLisandro Dalcin if (v[idx[i]] < vl) {last++; SWAP(idx[last],idx[i]);} 29*f4e3882fSLisandro Dalcin SWAP(idx[0],idx[last]); 30*f4e3882fSLisandro Dalcin ierr = PetscArgSortPixVal(v,idx,last-1);CHKERRQ(ierr); 31*f4e3882fSLisandro Dalcin ierr = PetscArgSortPixVal(v,idx+last+1,right-(last+1));CHKERRQ(ierr); 32*f4e3882fSLisandro Dalcin # undef SWAP 338067a7d5SLisandro Dalcin PetscFunctionReturn(0); 348067a7d5SLisandro Dalcin } 358067a7d5SLisandro Dalcin 368067a7d5SLisandro Dalcin /* 378067a7d5SLisandro Dalcin Map a pixel value to PETSc color value (index in the colormap) 388067a7d5SLisandro Dalcin */ 398067a7d5SLisandro Dalcin #undef __FUNCT__ 40*f4e3882fSLisandro Dalcin #define __FUNCT__ "PetscFindPixVal" 41*f4e3882fSLisandro Dalcin PETSC_STATIC_INLINE int PetscDrawXiPixelToColor(PetscDraw_X *Xwin,const int arg[256],PetscDrawXiPixVal pix) 428067a7d5SLisandro Dalcin { 43*f4e3882fSLisandro Dalcin const PetscDrawXiPixVal *cmap = Xwin->cmapping; 44*f4e3882fSLisandro Dalcin int lo, mid, hi = 256; 45*f4e3882fSLisandro Dalcin /* linear search the first few entries */ 46*f4e3882fSLisandro Dalcin for (lo=0; lo<8; lo++) 47*f4e3882fSLisandro Dalcin if (pix == cmap[lo]) 48*f4e3882fSLisandro Dalcin return lo; 49*f4e3882fSLisandro Dalcin /* binary search the remaining entries */ 50*f4e3882fSLisandro Dalcin while (hi - lo > 1) { 51*f4e3882fSLisandro Dalcin mid = lo + (hi - lo)/2; 52*f4e3882fSLisandro Dalcin if (pix < cmap[arg[mid]]) hi = mid; 53*f4e3882fSLisandro Dalcin else lo = mid; 54*f4e3882fSLisandro Dalcin } 55*f4e3882fSLisandro Dalcin return arg[lo]; 568067a7d5SLisandro Dalcin } 578067a7d5SLisandro Dalcin 588067a7d5SLisandro Dalcin #undef __FUNCT__ 598067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawGetImage_X" 608067a7d5SLisandro Dalcin PetscErrorCode PetscDrawGetImage_X(PetscDraw draw,unsigned char palette[256][3],unsigned int *out_w,unsigned int *out_h,unsigned char *out_pixels[]) 618067a7d5SLisandro Dalcin { 628067a7d5SLisandro Dalcin PetscDraw_X *Xwin = (PetscDraw_X*)draw->data; 638067a7d5SLisandro Dalcin PetscMPIInt rank; 648067a7d5SLisandro Dalcin PetscErrorCode ierr; 658067a7d5SLisandro Dalcin 668067a7d5SLisandro Dalcin PetscFunctionBegin; 678067a7d5SLisandro Dalcin if (out_w) *out_w = 0; 688067a7d5SLisandro Dalcin if (out_h) *out_h = 0; 698067a7d5SLisandro Dalcin if (out_pixels) *out_pixels = NULL; 708067a7d5SLisandro Dalcin ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 718067a7d5SLisandro Dalcin 728067a7d5SLisandro Dalcin /* make sure the X server processed requests from all processes */ 738067a7d5SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 748067a7d5SLisandro Dalcin XSync(Xwin->disp,True); 758067a7d5SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 768067a7d5SLisandro Dalcin ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr); 778067a7d5SLisandro Dalcin 78*f4e3882fSLisandro Dalcin /* only the first process return image data */ 798067a7d5SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 808067a7d5SLisandro Dalcin if (!rank) { 818067a7d5SLisandro Dalcin Window root; 828067a7d5SLisandro Dalcin XImage *ximage; 83*f4e3882fSLisandro Dalcin int pmap[256]; 848067a7d5SLisandro Dalcin unsigned char *pixels = NULL; 858067a7d5SLisandro Dalcin unsigned int w,h,dummy; 868067a7d5SLisandro Dalcin int x,y,p; 87*f4e3882fSLisandro Dalcin /* copy colormap palette to the caller */ 88*f4e3882fSLisandro Dalcin ierr = PetscMemcpy(palette,Xwin->cpalette,sizeof(Xwin->cpalette));CHKERRQ(ierr); 898067a7d5SLisandro Dalcin /* get image out of the drawable */ 908067a7d5SLisandro Dalcin XGetGeometry(Xwin->disp,PetscDrawXiDrawable(Xwin),&root,&x,&y,&w,&h,&dummy,&dummy); 918067a7d5SLisandro Dalcin ximage = XGetImage(Xwin->disp,PetscDrawXiDrawable(Xwin),0,0,w,h,AllPlanes,ZPixmap); 928067a7d5SLisandro Dalcin if (!ximage) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot XGetImage()"); 93*f4e3882fSLisandro Dalcin /* build indirect sort permutation (a.k.a argsort) of the color -> pixel mapping */ 94*f4e3882fSLisandro Dalcin for (p=0; p<256; p++) pmap[p] = p; /* identity permutation */ 95*f4e3882fSLisandro Dalcin ierr = PetscArgSortPixVal(Xwin->cmapping,pmap,255);CHKERRQ(ierr); 96*f4e3882fSLisandro Dalcin /* extract pixel values out of the image and map them to color indices */ 978067a7d5SLisandro Dalcin ierr = PetscMalloc1(w*h,&pixels);CHKERRQ(ierr); 988067a7d5SLisandro Dalcin for (p=0,y=0; y<(int)h; y++) 99*f4e3882fSLisandro Dalcin for (x=0; x<(int)w; x++) { 100*f4e3882fSLisandro Dalcin PetscDrawXiPixVal pix = XGetPixel(ximage,x,y); 101*f4e3882fSLisandro Dalcin pixels[p++] = (unsigned char)PetscDrawXiPixelToColor(Xwin,pmap,pix); 102*f4e3882fSLisandro Dalcin } 1038067a7d5SLisandro Dalcin XDestroyImage(ximage); 1048067a7d5SLisandro Dalcin *out_w = w; 1058067a7d5SLisandro Dalcin *out_h = h; 1068067a7d5SLisandro Dalcin *out_pixels = pixels; 1078067a7d5SLisandro Dalcin } 1088067a7d5SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 1098067a7d5SLisandro Dalcin PetscFunctionReturn(0); 1108067a7d5SLisandro Dalcin } 111