xref: /petsc/src/sys/classes/draw/impls/image/drawimage.c (revision bfc4c25e64040512a7cdc7bcb995f785926f51e6)
1 #include <../src/sys/classes/draw/impls/image/drawimage.h>   /*I  "petscdraw.h" I*/
2 #include <petsc/private/drawimpl.h>                          /*I  "petscdraw.h" I*/
3 
4 #if defined(PETSC_USE_DEBUG)
5 #define PetscDrawValidColor(color) \
6 do { if (PetscUnlikely((color)<0||(color)>=256)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Color value %D out of range [0..255]",(PetscInt)(color)); } while (0)
7 #else
8 #define PetscDrawValidColor(color) do {} while (0)
9 #endif
10 
11 #define XTRANS(draw,img,x)  ((int)(((img)->w-1)*((draw)->port_xl + ((((x) - (draw)->coor_xl)*((draw)->port_xr - (draw)->port_xl))/((draw)->coor_xr - (draw)->coor_xl)))))
12 #define YTRANS(draw,img,y)  (((img)->h-1) - (int)(((img)->h-1)*((draw)->port_yl + ((((y) - (draw)->coor_yl)*((draw)->port_yr - (draw)->port_yl))/((draw)->coor_yr - (draw)->coor_yl)))))
13 
14 #define ITRANS(draw,img,i)  ((draw)->coor_xl + (((PetscReal)(i))*((draw)->coor_xr - (draw)->coor_xl)/((img)->w-1) - (draw)->port_xl)/((draw)->port_xr - (draw)->port_xl))
15 #define JTRANS(draw,img,j)  ((draw)->coor_yl + (((PetscReal)(j))/((img)->h-1) + (draw)->port_yl - 1)*((draw)->coor_yr - (draw)->coor_yl)/((draw)->port_yl - (draw)->port_yr))
16 
17 
18 #undef __FUNCT__
19 #define __FUNCT__ "PetscDrawSetViewport_Image"
20 static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
21 {
22   PetscImage img = (PetscImage)draw->data;
23   PetscFunctionBegin;
24   {
25     int xmax = img->w - 1,   ymax = img->h - 1;
26     int xa = (int)(xl*xmax), ya = ymax - (int)(yr*ymax);
27     int xb = (int)(xr*xmax), yb = ymax - (int)(yl*ymax);
28     PetscImageSetClip(img,xa,ya,xb+1-xa,yb+1-ya);
29   }
30   PetscFunctionReturn(0);
31 }
32 
33 /*
34 #undef __FUNCT__
35 #define __FUNCT__ "PetscDrawSetCoordinates_Image"
36 static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
37 {
38   PetscFunctionBegin;
39   PetscFunctionReturn(0);
40 }*/
41 #define PetscDrawSetCoordinates_Image NULL
42 
43 #undef __FUNCT__
44 #define __FUNCT__ "PetscDrawCoordinateToPixel_Image"
45 static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw,PetscReal x,PetscReal y,int *i,int *j)
46 {
47   PetscImage img = (PetscImage)draw->data;
48   PetscFunctionBegin;
49   if (i) *i = XTRANS(draw,img,x);
50   if (j) *j = YTRANS(draw,img,y);
51   PetscFunctionReturn(0);
52 }
53 
54 #undef __FUNCT__
55 #define __FUNCT__ "PetscDrawPixelToCoordinate_Image"
56 static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw,int i,int j,PetscReal *x,PetscReal *y)
57 {
58   PetscImage img = (PetscImage)draw->data;
59   PetscFunctionBegin;
60   if (x) *x = ITRANS(draw,img,i);
61   if (y) *y = JTRANS(draw,img,j);
62   PetscFunctionReturn(0);
63 }
64 
65 /*
66 #undef __FUNCT__
67 #define __FUNCT__ "PetscDrawPointSetSize_Image"
68 static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
69 {
70   PetscFunctionBegin;
71   PetscFunctionReturn(0);
72 }*/
73 #define PetscDrawPointSetSize_Image NULL
74 
75 #undef __FUNCT__
76 #define __FUNCT__ "PetscDrawPoint_Image"
77 static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw,PetscReal x,PetscReal y,int c)
78 {
79   PetscImage img = (PetscImage)draw->data;
80   PetscFunctionBegin;
81   PetscDrawValidColor(c);
82   {
83     int j, xx = XTRANS(draw,img,x);
84     int i, yy = YTRANS(draw,img,y);
85     for (i=-1; i<=1; i++)
86       for (j=-1; j<=1; j++)
87         PetscImageDrawPixel(img,xx+j,yy+i,c);
88   }
89   PetscFunctionReturn(0);
90 }
91 
92 #undef __FUNCT__
93 #define __FUNCT__ "PetscDrawPointPixel_Image"
94 static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw,int x,int y,int c)
95 {
96   PetscImage img = (PetscImage)draw->data;
97   PetscFunctionBegin;
98   PetscDrawValidColor(c);
99   {
100     PetscImageDrawPixel(img,x,y,c);
101   }
102   PetscFunctionReturn(0);
103 }
104 
105 /*
106 #undef __FUNCT__
107 #define __FUNCT__ "PetscDrawLineSetWidth_Image"
108 static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
109 {
110   PetscFunctionBegin;
111   PetscFunctionReturn(0);
112 }*/
113 #define PetscDrawLineSetWidth_Image NULL
114 
115 #undef __FUNCT__
116 #define __FUNCT__ "PetscDrawLineGetWidth_Image"
117 static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw,PetscReal *width)
118 {
119   PetscImage img = (PetscImage)draw->data;
120   PetscFunctionBegin;
121   {
122     int lw = 1;
123     *width = lw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
124   }
125   PetscFunctionReturn(0);
126 }
127 
128 #undef __FUNCT__
129 #define __FUNCT__ "PetscDrawLine_Image"
130 static PetscErrorCode PetscDrawLine_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
131 {
132   PetscImage img = (PetscImage)draw->data;
133   PetscFunctionBegin;
134   {
135     int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
136     int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
137     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
138   }
139   PetscFunctionReturn(0);
140 }
141 
142 #undef __FUNCT__
143 #define __FUNCT__ "PetscDrawArrow_Image"
144 static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
145 {
146   PetscImage img = (PetscImage)draw->data;
147   PetscFunctionBegin;
148   PetscDrawValidColor(c);
149   {
150     int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
151     int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
152     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(0);
153     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
154     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
155       if (y_2 > y_1) {
156         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2-3,c);
157         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
158       } else {
159         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2+3,c);
160         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
161       }
162     }
163     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
164       if (x_2 > x_1) {
165         PetscImageDrawLine(img,x_2-3,y_2-3,x_2,y_2,c);
166         PetscImageDrawLine(img,x_2-3,y_2+3,x_2,y_2,c);
167       } else {
168         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
169         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
170       }
171     }
172    }
173   PetscFunctionReturn(0);
174 }
175 
176 #undef __FUNCT__
177 #define __FUNCT__ "PetscDrawRectangle_Image"
178 static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
179 {
180   PetscImage img = (PetscImage)draw->data;
181   PetscFunctionBegin;
182   PetscDrawValidColor(c1);
183   PetscDrawValidColor(c2);
184   PetscDrawValidColor(c3);
185   PetscDrawValidColor(c4);
186   {
187     int x = XTRANS(draw,img,xl), w = XTRANS(draw,img,xr) + 1 - x;
188     int y = YTRANS(draw,img,yr), h = YTRANS(draw,img,yl) + 1 - y;
189     int c  = (c1 + c2 + c3 + c4)/4;
190     PetscImageDrawRectangle(img,x,y,w,h,c);
191   }
192   PetscFunctionReturn(0);
193 }
194 
195 #undef __FUNCT__
196 #define __FUNCT__ "PetscDrawEllipse_Image"
197 static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
198 {
199   PetscImage img = (PetscImage)draw->data;
200   PetscFunctionBegin;
201   PetscDrawValidColor(c);
202   a = PetscAbsReal(a);
203   b = PetscAbsReal(b);
204   {
205     int xc = XTRANS(draw,img,x), w = XTRANS(draw,img,x + a/2) + 0 - xc;
206     int yc = YTRANS(draw,img,y), h = YTRANS(draw,img,y - b/2) + 0 - yc;
207     if (PetscAbsReal(a-b) <= 0)  w = h = PetscMin(w,h); /* workaround truncation errors */
208     PetscImageDrawEllipse(img,xc,yc,w,h,c);
209   }
210   PetscFunctionReturn(0);
211 }
212 
213 #undef __FUNCT__
214 #define __FUNCT__ "PetscDrawTriangle_Image"
215 static PetscErrorCode PetscDrawTriangle_Image(PetscDraw draw,PetscReal X_1,PetscReal Y_1,PetscReal X_2,PetscReal Y_2,PetscReal X_3,PetscReal Y_3,int c1,int c2,int c3)
216 {
217   PetscImage img = (PetscImage)draw->data;
218   PetscFunctionBegin;
219   PetscDrawValidColor(c1);
220   PetscDrawValidColor(c2);
221   PetscDrawValidColor(c3);
222   {
223     int x_1 = XTRANS(draw,img,X_1), x_2 = XTRANS(draw,img,X_2), x_3 = XTRANS(draw,img,X_3);
224     int y_1 = YTRANS(draw,img,Y_1), y_2 = YTRANS(draw,img,Y_2), y_3 = YTRANS(draw,img,Y_3);
225     PetscImageDrawTriangle(img,x_1,y_1,c1,x_2,y_2,c2,x_3,y_3,c3);
226   }
227   PetscFunctionReturn(0);
228 }
229 
230 /*
231 #undef __FUNCT__
232 #define __FUNCT__ "PetscDrawStringSetSize_Image"
233 static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
234 {
235   PetscFunctionBegin;
236   PetscFunctionReturn(0);
237 }*/
238 #define PetscDrawStringSetSize_Image NULL
239 
240 #undef __FUNCT__
241 #define __FUNCT__ "PetscDrawStringGetSize_Image"
242 static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw,PetscReal *w,PetscReal  *h)
243 {
244   PetscImage img = (PetscImage)draw->data;
245   PetscFunctionBegin;
246   {
247     int tw = PetscImageFontWidth;
248     int th = PetscImageFontHeight;
249     if (w) *w = tw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
250     if (h) *h = th*(draw->coor_yr - draw->coor_yl)/(img->h*(draw->port_yr - draw->port_yl));
251   }
252   PetscFunctionReturn(0);
253 }
254 
255 #undef __FUNCT__
256 #define __FUNCT__ "PetscDrawString_Image"
257 static PetscErrorCode PetscDrawString_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
258 {
259   PetscImage     img = (PetscImage)draw->data;
260   PetscToken     token;
261   char           *subtext;
262   PetscErrorCode ierr;
263   PetscFunctionBegin;
264   PetscDrawValidColor(c);
265   {
266     int xx = XTRANS(draw,img,x);
267     int yy = YTRANS(draw,img,y);
268     ierr = PetscTokenCreate(text,'\n',&token);CHKERRQ(ierr);
269     ierr = PetscTokenFind(token,&subtext);CHKERRQ(ierr);
270     while (subtext) {
271       PetscImageDrawText(img,xx,yy,c,subtext);
272       yy += PetscImageFontHeight;
273       ierr = PetscTokenFind(token,&subtext);CHKERRQ(ierr);
274     }
275     ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
276   }
277   PetscFunctionReturn(0);
278 }
279 
280 #undef __FUNCT__
281 #define __FUNCT__ "PetscDrawStringVertical_Image"
282 static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
283 {
284   PetscImage img = (PetscImage)draw->data;
285   PetscFunctionBegin;
286   PetscDrawValidColor(c);
287   {
288     char chr[2] = {0, 0};
289     int  xx = XTRANS(draw,img,x);
290     int  yy = YTRANS(draw,img,y);
291     int  offset = PetscImageFontHeight;
292     while ((chr[0] = *text++)) {
293       PetscImageDrawText(img,xx,yy+offset,c,chr);
294       yy += PetscImageFontHeight;
295     }
296   }
297   PetscFunctionReturn(0);
298 }
299 
300 /*
301 #undef __FUNCT__
302 #define __FUNCT__ "PetscDrawStringBoxed_Image"
303 static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
304 {
305   PetscFunctionBegin;
306   if (w) *w = 0;
307   if (h) *h = 0;
308   PetscFunctionReturn(0);
309 */
310 #define PetscDrawStringBoxed_Image NULL
311 
312 /*
313 #undef __FUNCT__
314 #define __FUNCT__ "PetscDrawFlush_Image"
315 static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
316 {
317   PetscFunctionBegin;
318   PetscFunctionReturn(0);
319 }*/
320 #define PetscDrawFlush_Image NULL
321 
322 #undef __FUNCT__
323 #define __FUNCT__ "PetscDrawClear_Image"
324 static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
325 {
326   PetscImage     img = (PetscImage)draw->data;
327   PetscFunctionBegin;
328   {
329     PetscImageClear(img);
330   }
331   PetscFunctionReturn(0);
332 }
333 
334 /*
335 #undef __FUNCT__
336 #define __FUNCT__ "PetscDrawSetDoubleBuffer_Image"
337 static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
338 {
339   PetscFunctionBegin;
340   PetscFunctionReturn(0);
341 }*/
342 #define PetscDrawSetDoubleBuffer_Image NULL
343 
344 #undef __FUNCT__
345 #define __FUNCT__ "PetscDrawGetPopup_Image"
346 static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw,PetscDraw *popup)
347 {
348   PetscBool      flg = PETSC_FALSE;
349   PetscErrorCode ierr;
350 
351   PetscFunctionBegin;
352   ierr = PetscOptionsGetBool(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_popup",&flg,NULL);CHKERRQ(ierr);
353   if (!flg) {*popup = NULL; PetscFunctionReturn(0);}
354   ierr = PetscDrawCreate(PetscObjectComm((PetscObject)draw),NULL,NULL,0,0,220,220,popup);CHKERRQ(ierr);
355   ierr = PetscDrawSetType(*popup,PETSC_DRAW_IMAGE);CHKERRQ(ierr);
356   ierr = PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");CHKERRQ(ierr);
357   ierr = PetscObjectAppendOptionsPrefix((PetscObject)*popup,((PetscObject)draw)->prefix);CHKERRQ(ierr);
358   draw->popup = *popup;
359   PetscFunctionReturn(0);
360 }
361 
362 /*
363 #undef __FUNCT__
364 #define __FUNCT__ "PetscDrawSetTitle_Image"
365 static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
366 {
367   PetscFunctionBegin;
368   PetscFunctionReturn(0);
369 }*/
370 #define PetscDrawSetTitle_Image NULL
371 
372 /*
373 #undef __FUNCT__
374 #define __FUNCT__ "PetscDrawCheckResizedWindow_Image"
375 static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
376 {
377   PetscFunctionBegin;
378   PetscFunctionReturn(0);
379 }*/
380 #define PetscDrawCheckResizedWindow_Image NULL
381 
382 #undef __FUNCT__
383 #define __FUNCT__ "PetscDrawResizeWindow_Image"
384 static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw,int w,int h)
385 {
386   PetscImage     img = (PetscImage)draw->data;
387   PetscErrorCode ierr;
388 
389   PetscFunctionBegin;
390   if (w == img->w && h == img->h) PetscFunctionReturn(0);
391   ierr = PetscFree(img->buffer);CHKERRQ(ierr);
392 
393   img->w = w; img->h = h;
394   ierr = PetscCalloc1((size_t)(img->w*img->h),&img->buffer);CHKERRQ(ierr);
395   ierr = PetscDrawSetViewport_Image(draw,draw->port_xl,draw->port_yl,draw->port_xr,draw->port_yr);CHKERRQ(ierr);
396   PetscFunctionReturn(0);
397 }
398 
399 #undef __FUNCT__
400 #define __FUNCT__ "PetscDrawDestroy_Image"
401 static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
402 {
403   PetscImage     img = (PetscImage)draw->data;
404   PetscErrorCode ierr;
405 
406   PetscFunctionBegin;
407   ierr = PetscDrawDestroy(&draw->popup);CHKERRQ(ierr);
408   ierr = PetscFree(img->buffer);CHKERRQ(ierr);
409   ierr = PetscFree(draw->data);CHKERRQ(ierr);
410   PetscFunctionReturn(0);
411 }
412 
413 /*
414 #undef __FUNCT__
415 #define __FUNCT__ "PetscDrawView_Image"
416 static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
417 {
418   PetscFunctionBegin;
419   PetscFunctionReturn(0);
420 }*/
421 #define PetscDrawView_Image NULL
422 
423 /*
424 #undef __FUNCT__
425 #define __FUNCT__ "PetscDrawGetMouseButton_Image"
426 static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
427 {
428   PetscFunctionBegin;
429   *button = PETSC_BUTTON_NONE;
430   if (x_user) *x_user = 0;
431   if (y_user) *y_user = 0;
432   if (x_phys) *x_phys = 0;
433   if (y_phys) *y_phys = 0;
434   PetscFunctionReturn(0);
435 }*/
436 #define PetscDrawGetMouseButton_Image NULL
437 
438 /*
439 #undef __FUNCT__
440 #define __FUNCT__ "PetscDrawPause_Image"
441 static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
442 {
443   PetscFunctionBegin;
444   PetscFunctionReturn(0);
445 }*/
446 #define PetscDrawPause_Image NULL
447 
448 /*
449 #undef __FUNCT__
450 #define __FUNCT__ "PetscDrawBeginPage_Image"
451 static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
452 {
453   PetscFunctionBegin;
454   PetscFunctionReturn(0);
455 }*/
456 #define PetscDrawBeginPage_Image NULL
457 
458 /*
459 #undef __FUNCT__
460 #define __FUNCT__ "PetscDrawEndPage_Image"
461 static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
462 {
463   PetscFunctionBegin;
464   PetscFunctionReturn(0);
465 }*/
466 #define PetscDrawEndPage_Image NULL
467 
468 #undef __FUNCT__
469 #define __FUNCT__ "PetscDrawGetSingleton_Image"
470 static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
471 {
472   PetscImage     pimg = (PetscImage)draw->data;
473   PetscImage     simg;
474   PetscErrorCode ierr;
475 
476   PetscFunctionBegin;
477   ierr = PetscDrawCreate(PETSC_COMM_SELF,NULL,NULL,0,0,draw->w,draw->h,sdraw);CHKERRQ(ierr);
478   ierr = PetscDrawSetType(*sdraw,PETSC_DRAW_IMAGE);CHKERRQ(ierr);
479   (*sdraw)->ops->resizewindow = NULL;
480   simg = (PetscImage)(*sdraw)->data;
481   ierr = PetscMemcpy(simg->buffer,pimg->buffer,(size_t)(pimg->w*pimg->h));CHKERRQ(ierr);
482   PetscFunctionReturn(0);
483 }
484 
485 #undef __FUNCT__
486 #define __FUNCT__ "PetscDrawRestoreSingleton_Image"
487 static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
488 {
489   PetscImage     pimg = (PetscImage)draw->data;
490   PetscImage     simg = (PetscImage)(*sdraw)->data;
491   PetscErrorCode ierr;
492 
493   PetscFunctionBegin;
494   ierr = PetscMemcpy(pimg->buffer,simg->buffer,(size_t)(pimg->w*pimg->h));CHKERRQ(ierr);
495   ierr = PetscDrawDestroy(sdraw);CHKERRQ(ierr);
496   PetscFunctionReturn(0);
497 }
498 
499 /*
500 #undef __FUNCT__
501 #define __FUNCT__ "PetscDrawSave_Image"
502 static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
503 {
504   PetscFunctionBegin;
505   PetscFunctionReturn(0);
506 }*/
507 #define PetscDrawSave_Image NULL
508 
509 #undef __FUNCT__
510 #define __FUNCT__ "PetscDrawGetImage_Image"
511 static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw,unsigned char palette[256][3],unsigned int *w,unsigned int *h,unsigned char *pixels[])
512 {
513   PetscImage     img = (PetscImage)draw->data;
514   unsigned char  *buffer = NULL;
515   PetscMPIInt    rank,size;
516   PetscErrorCode ierr;
517 
518   PetscFunctionBegin;
519   if (w) *w = (unsigned int)img->w;
520   if (h) *h = (unsigned int)img->h;
521   if (pixels) *pixels = NULL;
522   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
523   if (!rank) {
524     ierr = PetscMemcpy(palette,img->palette,sizeof(img->palette));CHKERRQ(ierr);
525     ierr = PetscMalloc1((size_t)(img->w*img->h),&buffer);CHKERRQ(ierr);
526     if (pixels) *pixels = buffer;
527   }
528   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);CHKERRQ(ierr);
529   if (size == 1) {
530     ierr = PetscMemcpy(buffer,img->buffer,(size_t)(img->w*img->h));CHKERRQ(ierr);
531   } else {
532     ierr = MPI_Reduce(img->buffer,buffer,img->w*img->h,MPI_UNSIGNED_CHAR,MPI_MAX,0,PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
533   }
534   PetscFunctionReturn(0);
535 }
536 
537 static struct _PetscDrawOps DvOps = {
538   PetscDrawSetDoubleBuffer_Image,
539   PetscDrawFlush_Image,
540   PetscDrawLine_Image,
541   PetscDrawLineSetWidth_Image,
542   PetscDrawLineGetWidth_Image,
543   PetscDrawPoint_Image,
544   PetscDrawPointSetSize_Image,
545   PetscDrawString_Image,
546   PetscDrawStringVertical_Image,
547   PetscDrawStringSetSize_Image,
548   PetscDrawStringGetSize_Image,
549   PetscDrawSetViewport_Image,
550   PetscDrawClear_Image,
551   PetscDrawRectangle_Image,
552   PetscDrawTriangle_Image,
553   PetscDrawEllipse_Image,
554   PetscDrawGetMouseButton_Image,
555   PetscDrawPause_Image,
556   PetscDrawBeginPage_Image,
557   PetscDrawEndPage_Image,
558   PetscDrawGetPopup_Image,
559   PetscDrawSetTitle_Image,
560   PetscDrawCheckResizedWindow_Image,
561   PetscDrawResizeWindow_Image,
562   PetscDrawDestroy_Image,
563   PetscDrawView_Image,
564   PetscDrawGetSingleton_Image,
565   PetscDrawRestoreSingleton_Image,
566   PetscDrawSave_Image,
567   PetscDrawGetImage_Image,
568   PetscDrawSetCoordinates_Image,
569   PetscDrawArrow_Image,
570   PetscDrawCoordinateToPixel_Image,
571   PetscDrawPixelToCoordinate_Image,
572   PetscDrawPointPixel_Image,
573   PetscDrawStringBoxed_Image
574 };
575 
576 static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
577   { 255, 255, 255 }, /* white */
578   {   0,   0,   0 }, /* black */
579   { 255,   0,   0 }, /* red */
580   {   0, 255,   0 }, /* green */
581   {   0, 255, 255 }, /* cyan */
582   {   0,   0, 255 }, /* blue */
583   { 255,   0, 255 }, /* magenta */
584   { 127, 255, 212 }, /* aquamarine */
585   {  34, 139,  34 }, /* forestgreen */
586   { 255, 165,   0 }, /* orange */
587   { 238, 130, 238 }, /* violet */
588   { 165,  42,  42 }, /* brown */
589   { 255, 192, 203 }, /* pink */
590   { 255, 127,  80 }, /* coral */
591   { 190, 190, 190 }, /* gray */
592   { 255, 255,   0 }, /* yellow */
593   { 255, 215,   0 }, /* gold */
594   { 255, 182, 193 }, /* lightpink */
595   {  72, 209, 204 }, /* mediumturquoise */
596   { 240, 230, 140 }, /* khaki */
597   { 105, 105, 105 }, /* dimgray */
598   {  54, 205,  50 }, /* yellowgreen */
599   { 135, 206, 235 }, /* skyblue */
600   {   0, 100,   0 }, /* darkgreen */
601   {   0,   0, 128 }, /* navyblue */
602   { 244, 164,  96 }, /* sandybrown */
603   {  95, 158, 160 }, /* cadetblue */
604   { 176, 224, 230 }, /* powderblue */
605   { 255,  20, 147 }, /* deeppink */
606   { 216, 191, 216 }, /* thistle */
607   {  50, 205,  50 }, /* limegreen */
608   { 255, 240, 245 }, /* lavenderblush */
609   { 221, 160, 221 }, /* plum */
610 };
611 
612 
613 /*MC
614    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
615 
616    Options Database Keys:
617 .  -draw_size w,h - size of image in pixels
618 
619    Level: beginner
620 
621 .seealso:  PetscDrawOpenImage(), PetscDrawSetFromOptions()
622 M*/
623 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
624 
625 #undef __FUNCT__
626 #define __FUNCT__ "PetscDrawCreate_Image"
627 PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
628 {
629   PetscImage     img;
630   int            w = draw->w, h = draw->h;
631   PetscInt       size[2], nsize = 2;
632   PetscBool      set;
633   PetscErrorCode ierr;
634 
635   PetscFunctionBegin;
636   draw->pause   = 0;
637   draw->coor_xl = 0; draw->coor_xr = 1;
638   draw->coor_yl = 0; draw->coor_yr = 1;
639   draw->port_xl = 0; draw->port_xr = 1;
640   draw->port_yl = 0; draw->port_yr = 1;
641 
642   size[0] = w; if (size[0] < 1) size[0] = 300;
643   size[1] = h; if (size[1] < 1) size[1] = size[0];
644   ierr = PetscOptionsGetIntArray(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_size",size,&nsize,&set);CHKERRQ(ierr);
645   if (set && nsize == 1) size[1] = size[0];
646   if (size[0] < 1) size[0] = 300;
647   if (size[1] < 1) size[1] = size[0];
648   draw->w = w = size[0]; draw->x = 0;
649   draw->h = h = size[1]; draw->x = 0;
650 
651   ierr = PetscNewLog(draw,&img);CHKERRQ(ierr);
652   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
653   draw->data = (void*)img;
654 
655   img->w = w; img->h = h;
656   ierr = PetscCalloc1((size_t)(img->w*img->h),&img->buffer);CHKERRQ(ierr);
657   PetscImageSetClip(img,0,0,img->w,img->h);
658   {
659     int i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
660     unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
661     unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
662     unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
663     ierr = PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);CHKERRQ(ierr);
664     for (k=0; k<PETSC_DRAW_BASIC_COLORS; k++) {
665       img->palette[k][0] = BasicColors[k][0];
666       img->palette[k][1] = BasicColors[k][1];
667       img->palette[k][2] = BasicColors[k][2];
668     }
669     for (i=0; i<ncolors; i++, k++) {
670       img->palette[k][0] = R[i];
671       img->palette[k][1] = G[i];
672       img->palette[k][2] = B[i];
673     }
674   }
675 
676   if (!draw->savefilename ){ierr = PetscDrawSetSave(draw,"");CHKERRQ(ierr);}
677   PetscFunctionReturn(0);
678 }
679 
680 #undef __FUNCT__
681 #define __FUNCT__ "PetscDrawOpenImage"
682 /*@C
683    PetscDrawOpenImage - Opens an image for use with the PetscDraw routines.
684 
685    Collective on MPI_Comm
686 
687    Input Parameters:
688 +  comm - the communicator that will share image
689 -  filename - optional name of the file
690 -  w, h - the image width and height in pixels
691 
692    Output Parameters:
693 .  draw - the drawing context.
694 
695    Level: beginner
696 
697 .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
698 @*/
699 PetscErrorCode PetscDrawOpenImage(MPI_Comm comm,const char filename[],int w,int h,PetscDraw *draw)
700 {
701   PetscErrorCode ierr;
702 
703   PetscFunctionBegin;
704   ierr = PetscDrawCreate(comm,NULL,NULL,0,0,w,h,draw);CHKERRQ(ierr);
705   ierr = PetscDrawSetType(*draw,PETSC_DRAW_IMAGE);CHKERRQ(ierr);
706   ierr = PetscDrawSetSave(*draw,filename);CHKERRQ(ierr);
707   PetscFunctionReturn(0);
708 }
709