Actual source code: drawimage.c
1: #include <../src/sys/classes/draw/impls/image/drawimage.h>
2: #include <petsc/private/drawimpl.h>
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
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)))))
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))
17: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
18: {
19: PetscImage img = (PetscImage)draw->data;
21: {
22: int xmax = img->w - 1, ymax = img->h - 1;
23: int xa = (int)(xl*xmax), ya = ymax - (int)(yr*ymax);
24: int xb = (int)(xr*xmax), yb = ymax - (int)(yl*ymax);
25: PetscImageSetClip(img,xa,ya,xb+1-xa,yb+1-ya);
26: }
27: return(0);
28: }
30: /*
31: static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
32: {
34: return(0);
35: }*/
36: #define PetscDrawSetCoordinates_Image NULL
38: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw,PetscReal x,PetscReal y,int *i,int *j)
39: {
40: PetscImage img = (PetscImage)draw->data;
42: if (i) *i = XTRANS(draw,img,x);
43: if (j) *j = YTRANS(draw,img,y);
44: return(0);
45: }
47: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw,int i,int j,PetscReal *x,PetscReal *y)
48: {
49: PetscImage img = (PetscImage)draw->data;
51: if (x) *x = ITRANS(draw,img,i);
52: if (y) *y = JTRANS(draw,img,j);
53: return(0);
54: }
56: /*
57: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
58: {
60: return(0);
61: }*/
62: #define PetscDrawPointSetSize_Image NULL
64: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw,PetscReal x,PetscReal y,int c)
65: {
66: PetscImage img = (PetscImage)draw->data;
68: PetscDrawValidColor(c);
69: {
70: int j, xx = XTRANS(draw,img,x);
71: int i, yy = YTRANS(draw,img,y);
72: for (i=-1; i<=1; i++)
73: for (j=-1; j<=1; j++)
74: PetscImageDrawPixel(img,xx+j,yy+i,c);
75: }
76: return(0);
77: }
79: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw,int x,int y,int c)
80: {
81: PetscImage img = (PetscImage)draw->data;
83: PetscDrawValidColor(c);
84: {
85: PetscImageDrawPixel(img,x,y,c);
86: }
87: return(0);
88: }
90: /*
91: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
92: {
94: return(0);
95: }*/
96: #define PetscDrawLineSetWidth_Image NULL
98: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw,PetscReal *width)
99: {
100: PetscImage img = (PetscImage)draw->data;
102: {
103: int lw = 1;
104: *width = lw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
105: }
106: return(0);
107: }
109: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
110: {
111: PetscImage img = (PetscImage)draw->data;
113: {
114: int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
115: int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
116: PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
117: }
118: return(0);
119: }
121: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
122: {
123: PetscImage img = (PetscImage)draw->data;
125: PetscDrawValidColor(c);
126: {
127: int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
128: int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
129: if (x_1 == x_2 && y_1 == y_2) return(0);
130: PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
131: if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
132: if (y_2 > y_1) {
133: PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2-3,c);
134: PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
135: } else {
136: PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2+3,c);
137: PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
138: }
139: }
140: if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
141: if (x_2 > x_1) {
142: PetscImageDrawLine(img,x_2-3,y_2-3,x_2,y_2,c);
143: PetscImageDrawLine(img,x_2-3,y_2+3,x_2,y_2,c);
144: } else {
145: PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
146: PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
147: }
148: }
149: }
150: return(0);
151: }
153: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
154: {
155: PetscImage img = (PetscImage)draw->data;
157: PetscDrawValidColor(c1);
158: PetscDrawValidColor(c2);
159: PetscDrawValidColor(c3);
160: PetscDrawValidColor(c4);
161: {
162: int x = XTRANS(draw,img,xl), w = XTRANS(draw,img,xr) + 1 - x;
163: int y = YTRANS(draw,img,yr), h = YTRANS(draw,img,yl) + 1 - y;
164: int c = (c1 + c2 + c3 + c4)/4;
165: PetscImageDrawRectangle(img,x,y,w,h,c);
166: }
167: return(0);
168: }
170: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
171: {
172: PetscImage img = (PetscImage)draw->data;
174: PetscDrawValidColor(c);
175: a = PetscAbsReal(a);
176: b = PetscAbsReal(b);
177: {
178: int xc = XTRANS(draw,img,x), w = XTRANS(draw,img,x + a/2) + 0 - xc;
179: int yc = YTRANS(draw,img,y), h = YTRANS(draw,img,y - b/2) + 0 - yc;
180: if (PetscAbsReal(a-b) <= 0) w = h = PetscMin(w,h); /* workaround truncation errors */
181: PetscImageDrawEllipse(img,xc,yc,w,h,c);
182: }
183: return(0);
184: }
186: 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)
187: {
188: PetscImage img = (PetscImage)draw->data;
190: PetscDrawValidColor(c1);
191: PetscDrawValidColor(c2);
192: PetscDrawValidColor(c3);
193: {
194: int x_1 = XTRANS(draw,img,X_1), x_2 = XTRANS(draw,img,X_2), x_3 = XTRANS(draw,img,X_3);
195: int y_1 = YTRANS(draw,img,Y_1), y_2 = YTRANS(draw,img,Y_2), y_3 = YTRANS(draw,img,Y_3);
196: PetscImageDrawTriangle(img,x_1,y_1,c1,x_2,y_2,c2,x_3,y_3,c3);
197: }
198: return(0);
199: }
201: /*
202: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
203: {
205: return(0);
206: }*/
207: #define PetscDrawStringSetSize_Image NULL
209: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw,PetscReal *w,PetscReal *h)
210: {
211: PetscImage img = (PetscImage)draw->data;
213: {
214: int tw = PetscImageFontWidth;
215: int th = PetscImageFontHeight;
216: if (w) *w = tw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
217: if (h) *h = th*(draw->coor_yr - draw->coor_yl)/(img->h*(draw->port_yr - draw->port_yl));
218: }
219: return(0);
220: }
222: static PetscErrorCode PetscDrawString_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
223: {
224: PetscImage img = (PetscImage)draw->data;
225: PetscToken token;
226: char *subtext;
229: PetscDrawValidColor(c);
230: {
231: int xx = XTRANS(draw,img,x);
232: int yy = YTRANS(draw,img,y);
233: PetscTokenCreate(text,'\n',&token);
234: PetscTokenFind(token,&subtext);
235: while (subtext) {
236: PetscImageDrawText(img,xx,yy,c,subtext);
237: yy += PetscImageFontHeight;
238: PetscTokenFind(token,&subtext);
239: }
240: PetscTokenDestroy(&token);
241: }
242: return(0);
243: }
245: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
246: {
247: PetscImage img = (PetscImage)draw->data;
249: PetscDrawValidColor(c);
250: {
251: char chr[2] = {0, 0};
252: int xx = XTRANS(draw,img,x);
253: int yy = YTRANS(draw,img,y);
254: int offset = PetscImageFontHeight;
255: while ((chr[0] = *text++)) {
256: PetscImageDrawText(img,xx,yy+offset,c,chr);
257: yy += PetscImageFontHeight;
258: }
259: }
260: return(0);
261: }
263: /*
264: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
265: {
267: if (w) *w = 0;
268: if (h) *h = 0;
269: return(0);
270: */
271: #define PetscDrawStringBoxed_Image NULL
273: /*
274: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
275: {
277: return(0);
278: }*/
279: #define PetscDrawFlush_Image NULL
281: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
282: {
283: PetscImage img = (PetscImage)draw->data;
285: {
286: PetscImageClear(img);
287: }
288: return(0);
289: }
291: /*
292: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
293: {
295: return(0);
296: }*/
297: #define PetscDrawSetDoubleBuffer_Image NULL
299: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw,PetscDraw *popup)
300: {
301: PetscBool flg = PETSC_FALSE;
305: PetscOptionsGetBool(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_popup",&flg,NULL);
306: if (!flg) {*popup = NULL; return(0);}
307: PetscDrawCreate(PetscObjectComm((PetscObject)draw),NULL,NULL,0,0,220,220,popup);
308: PetscDrawSetType(*popup,PETSC_DRAW_IMAGE);
309: PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");
310: PetscObjectAppendOptionsPrefix((PetscObject)*popup,((PetscObject)draw)->prefix);
311: draw->popup = *popup;
312: return(0);
313: }
315: /*
316: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
317: {
319: return(0);
320: }*/
321: #define PetscDrawSetTitle_Image NULL
323: /*
324: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
325: {
327: return(0);
328: }*/
329: #define PetscDrawCheckResizedWindow_Image NULL
331: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw,int w,int h)
332: {
333: PetscImage img = (PetscImage)draw->data;
337: if (w == img->w && h == img->h) return(0);
338: PetscFree(img->buffer);
340: img->w = w; img->h = h;
341: PetscCalloc1((size_t)(img->w*img->h),&img->buffer);
342: PetscDrawSetViewport_Image(draw,draw->port_xl,draw->port_yl,draw->port_xr,draw->port_yr);
343: return(0);
344: }
346: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
347: {
348: PetscImage img = (PetscImage)draw->data;
352: PetscDrawDestroy(&draw->popup);
353: PetscFree(img->buffer);
354: PetscFree(draw->data);
355: return(0);
356: }
358: /*
359: static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
360: {
362: return(0);
363: }*/
364: #define PetscDrawView_Image NULL
366: /*
367: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
368: {
370: *button = PETSC_BUTTON_NONE;
371: if (x_user) *x_user = 0;
372: if (y_user) *y_user = 0;
373: if (x_phys) *x_phys = 0;
374: if (y_phys) *y_phys = 0;
375: return(0);
376: }*/
377: #define PetscDrawGetMouseButton_Image NULL
379: /*
380: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
381: {
383: return(0);
384: }*/
385: #define PetscDrawPause_Image NULL
387: /*
388: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
389: {
391: return(0);
392: }*/
393: #define PetscDrawBeginPage_Image NULL
395: /*
396: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
397: {
399: return(0);
400: }*/
401: #define PetscDrawEndPage_Image NULL
403: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
404: {
405: PetscImage pimg = (PetscImage)draw->data;
406: PetscImage simg;
410: PetscDrawCreate(PETSC_COMM_SELF,NULL,NULL,0,0,draw->w,draw->h,sdraw);
411: PetscDrawSetType(*sdraw,PETSC_DRAW_IMAGE);
412: (*sdraw)->ops->resizewindow = NULL;
413: simg = (PetscImage)(*sdraw)->data;
414: PetscArraycpy(simg->buffer,pimg->buffer,pimg->w*pimg->h);
415: return(0);
416: }
418: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
419: {
420: PetscImage pimg = (PetscImage)draw->data;
421: PetscImage simg = (PetscImage)(*sdraw)->data;
425: PetscArraycpy(pimg->buffer,simg->buffer,pimg->w*pimg->h);
426: PetscDrawDestroy(sdraw);
427: return(0);
428: }
430: /*
431: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
432: {
434: return(0);
435: }*/
436: #define PetscDrawSave_Image NULL
438: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw,unsigned char palette[256][3],unsigned int *w,unsigned int *h,unsigned char *pixels[])
439: {
440: PetscImage img = (PetscImage)draw->data;
441: unsigned char *buffer = NULL;
442: PetscMPIInt rank,size;
446: if (w) *w = (unsigned int)img->w;
447: if (h) *h = (unsigned int)img->h;
448: if (pixels) *pixels = NULL;
449: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
450: if (rank == 0) {
451: PetscMemcpy(palette,img->palette,sizeof(img->palette));
452: PetscMalloc1((size_t)(img->w*img->h),&buffer);
453: if (pixels) *pixels = buffer;
454: }
455: MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);
456: if (size == 1) {
457: PetscArraycpy(buffer,img->buffer,img->w*img->h);
458: } else {
459: MPI_Reduce(img->buffer,buffer,img->w*img->h,MPI_UNSIGNED_CHAR,MPI_MAX,0,PetscObjectComm((PetscObject)draw));
460: }
461: return(0);
462: }
464: static struct _PetscDrawOps DvOps = {
465: PetscDrawSetDoubleBuffer_Image,
466: PetscDrawFlush_Image,
467: PetscDrawLine_Image,
468: PetscDrawLineSetWidth_Image,
469: PetscDrawLineGetWidth_Image,
470: PetscDrawPoint_Image,
471: PetscDrawPointSetSize_Image,
472: PetscDrawString_Image,
473: PetscDrawStringVertical_Image,
474: PetscDrawStringSetSize_Image,
475: PetscDrawStringGetSize_Image,
476: PetscDrawSetViewport_Image,
477: PetscDrawClear_Image,
478: PetscDrawRectangle_Image,
479: PetscDrawTriangle_Image,
480: PetscDrawEllipse_Image,
481: PetscDrawGetMouseButton_Image,
482: PetscDrawPause_Image,
483: PetscDrawBeginPage_Image,
484: PetscDrawEndPage_Image,
485: PetscDrawGetPopup_Image,
486: PetscDrawSetTitle_Image,
487: PetscDrawCheckResizedWindow_Image,
488: PetscDrawResizeWindow_Image,
489: PetscDrawDestroy_Image,
490: PetscDrawView_Image,
491: PetscDrawGetSingleton_Image,
492: PetscDrawRestoreSingleton_Image,
493: PetscDrawSave_Image,
494: PetscDrawGetImage_Image,
495: PetscDrawSetCoordinates_Image,
496: PetscDrawArrow_Image,
497: PetscDrawCoordinateToPixel_Image,
498: PetscDrawPixelToCoordinate_Image,
499: PetscDrawPointPixel_Image,
500: PetscDrawStringBoxed_Image
501: };
503: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
504: { 255, 255, 255 }, /* white */
505: { 0, 0, 0 }, /* black */
506: { 255, 0, 0 }, /* red */
507: { 0, 255, 0 }, /* green */
508: { 0, 255, 255 }, /* cyan */
509: { 0, 0, 255 }, /* blue */
510: { 255, 0, 255 }, /* magenta */
511: { 127, 255, 212 }, /* aquamarine */
512: { 34, 139, 34 }, /* forestgreen */
513: { 255, 165, 0 }, /* orange */
514: { 238, 130, 238 }, /* violet */
515: { 165, 42, 42 }, /* brown */
516: { 255, 192, 203 }, /* pink */
517: { 255, 127, 80 }, /* coral */
518: { 190, 190, 190 }, /* gray */
519: { 255, 255, 0 }, /* yellow */
520: { 255, 215, 0 }, /* gold */
521: { 255, 182, 193 }, /* lightpink */
522: { 72, 209, 204 }, /* mediumturquoise */
523: { 240, 230, 140 }, /* khaki */
524: { 105, 105, 105 }, /* dimgray */
525: { 54, 205, 50 }, /* yellowgreen */
526: { 135, 206, 235 }, /* skyblue */
527: { 0, 100, 0 }, /* darkgreen */
528: { 0, 0, 128 }, /* navyblue */
529: { 244, 164, 96 }, /* sandybrown */
530: { 95, 158, 160 }, /* cadetblue */
531: { 176, 224, 230 }, /* powderblue */
532: { 255, 20, 147 }, /* deeppink */
533: { 216, 191, 216 }, /* thistle */
534: { 50, 205, 50 }, /* limegreen */
535: { 255, 240, 245 }, /* lavenderblush */
536: { 221, 160, 221 }, /* plum */
537: };
539: /*MC
540: PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
542: Options Database Keys:
543: . -draw_size w,h - size of image in pixels
545: Level: beginner
547: .seealso: PetscDrawOpenImage(), PetscDrawSetFromOptions()
548: M*/
549: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
551: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
552: {
553: PetscImage img;
554: int w = draw->w, h = draw->h;
555: PetscInt size[2], nsize = 2;
556: PetscBool set;
560: draw->pause = 0;
561: draw->coor_xl = 0; draw->coor_xr = 1;
562: draw->coor_yl = 0; draw->coor_yr = 1;
563: draw->port_xl = 0; draw->port_xr = 1;
564: draw->port_yl = 0; draw->port_yr = 1;
566: size[0] = w; if (size[0] < 1) size[0] = 300;
567: size[1] = h; if (size[1] < 1) size[1] = size[0];
568: PetscOptionsGetIntArray(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_size",size,&nsize,&set);
569: if (set && nsize == 1) size[1] = size[0];
570: if (size[0] < 1) size[0] = 300;
571: if (size[1] < 1) size[1] = size[0];
572: draw->w = w = size[0]; draw->x = 0;
573: draw->h = h = size[1]; draw->x = 0;
575: PetscNewLog(draw,&img);
576: PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
577: draw->data = (void*)img;
579: img->w = w; img->h = h;
580: PetscCalloc1((size_t)(img->w*img->h),&img->buffer);
581: PetscImageSetClip(img,0,0,img->w,img->h);
582: {
583: int i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
584: unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
585: unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
586: unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
587: PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);
588: for (k=0; k<PETSC_DRAW_BASIC_COLORS; k++) {
589: img->palette[k][0] = BasicColors[k][0];
590: img->palette[k][1] = BasicColors[k][1];
591: img->palette[k][2] = BasicColors[k][2];
592: }
593: for (i=0; i<ncolors; i++, k++) {
594: img->palette[k][0] = R[i];
595: img->palette[k][1] = G[i];
596: img->palette[k][2] = B[i];
597: }
598: }
600: if (!draw->savefilename) {PetscDrawSetSave(draw,draw->title);}
601: return(0);
602: }
604: /*@C
605: PetscDrawOpenImage - Opens an image for use with the PetscDraw routines.
607: Collective
609: Input Parameters:
610: + comm - the communicator that will share image
611: - filename - optional name of the file
612: - w, h - the image width and height in pixels
614: Output Parameters:
615: . draw - the drawing context.
617: Level: beginner
619: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
620: @*/
621: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm,const char filename[],int w,int h,PetscDraw *draw)
622: {
626: PetscDrawCreate(comm,NULL,NULL,0,0,w,h,draw);
627: PetscDrawSetType(*draw,PETSC_DRAW_IMAGE);
628: PetscDrawSetSave(*draw,filename);
629: return(0);
630: }