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)
6: #else
7: #define PetscDrawValidColor(color) \
8: do { \
9: } while (0)
10: #endif
12: #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)))))
13: #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)))))
15: #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))
16: #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))
18: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
19: {
20: 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: {
33: return 0;
34: }*/
35: #define PetscDrawSetCoordinates_Image NULL
37: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
38: {
39: PetscImage img = (PetscImage)draw->data;
40: if (i) *i = XTRANS(draw, img, x);
41: if (j) *j = YTRANS(draw, img, y);
42: return 0;
43: }
45: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
46: {
47: PetscImage img = (PetscImage)draw->data;
48: if (x) *x = ITRANS(draw, img, i);
49: if (y) *y = JTRANS(draw, img, j);
50: return 0;
51: }
53: /*
54: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
55: {
56: return 0;
57: }*/
58: #define PetscDrawPointSetSize_Image NULL
60: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
61: {
62: PetscImage img = (PetscImage)draw->data;
63: PetscDrawValidColor(c);
64: {
65: int j, xx = XTRANS(draw, img, x);
66: int i, yy = YTRANS(draw, img, y);
67: for (i = -1; i <= 1; i++)
68: for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
69: }
70: return 0;
71: }
73: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
74: {
75: PetscImage img = (PetscImage)draw->data;
76: PetscDrawValidColor(c);
77: {
78: PetscImageDrawPixel(img, x, y, c);
79: }
80: return 0;
81: }
83: /*
84: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
85: {
86: return 0;
87: }*/
88: #define PetscDrawLineSetWidth_Image NULL
90: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
91: {
92: PetscImage img = (PetscImage)draw->data;
93: {
94: int lw = 1;
95: *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
96: }
97: return 0;
98: }
100: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
101: {
102: PetscImage img = (PetscImage)draw->data;
103: {
104: int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
105: int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
106: PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
107: }
108: return 0;
109: }
111: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
112: {
113: PetscImage img = (PetscImage)draw->data;
114: PetscDrawValidColor(c);
115: {
116: int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
117: int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
118: if (x_1 == x_2 && y_1 == y_2) return 0;
119: PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
120: if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
121: if (y_2 > y_1) {
122: PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c);
123: PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
124: } else {
125: PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c);
126: PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
127: }
128: }
129: if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
130: if (x_2 > x_1) {
131: PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
132: PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
133: } else {
134: PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
135: PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
136: }
137: }
138: }
139: return 0;
140: }
142: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4)
143: {
144: PetscImage img = (PetscImage)draw->data;
145: PetscDrawValidColor(c1);
146: PetscDrawValidColor(c2);
147: PetscDrawValidColor(c3);
148: PetscDrawValidColor(c4);
149: {
150: int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
151: int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
152: int c = (c1 + c2 + c3 + c4) / 4;
153: PetscImageDrawRectangle(img, x, y, w, h, c);
154: }
155: return 0;
156: }
158: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
159: {
160: PetscImage img = (PetscImage)draw->data;
161: PetscDrawValidColor(c);
162: a = PetscAbsReal(a);
163: b = PetscAbsReal(b);
164: {
165: int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
166: int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
167: if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
168: PetscImageDrawEllipse(img, xc, yc, w, h, c);
169: }
170: return 0;
171: }
173: 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)
174: {
175: PetscImage img = (PetscImage)draw->data;
176: PetscDrawValidColor(c1);
177: PetscDrawValidColor(c2);
178: PetscDrawValidColor(c3);
179: {
180: int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
181: int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
182: PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
183: }
184: return 0;
185: }
187: /*
188: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
189: {
190: return 0;
191: }*/
192: #define PetscDrawStringSetSize_Image NULL
194: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
195: {
196: PetscImage img = (PetscImage)draw->data;
197: {
198: int tw = PetscImageFontWidth;
199: int th = PetscImageFontHeight;
200: if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
201: if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
202: }
203: return 0;
204: }
206: static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
207: {
208: PetscImage img = (PetscImage)draw->data;
209: PetscToken token;
210: char *subtext;
211: PetscDrawValidColor(c);
212: {
213: int xx = XTRANS(draw, img, x);
214: int yy = YTRANS(draw, img, y);
215: PetscTokenCreate(text, '\n', &token);
216: PetscTokenFind(token, &subtext);
217: while (subtext) {
218: PetscImageDrawText(img, xx, yy, c, subtext);
219: yy += PetscImageFontHeight;
220: PetscTokenFind(token, &subtext);
221: }
222: PetscTokenDestroy(&token);
223: }
224: return 0;
225: }
227: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
228: {
229: PetscImage img = (PetscImage)draw->data;
230: PetscDrawValidColor(c);
231: {
232: char chr[2] = {0, 0};
233: int xx = XTRANS(draw, img, x);
234: int yy = YTRANS(draw, img, y);
235: int offset = PetscImageFontHeight;
236: while ((chr[0] = *text++)) {
237: PetscImageDrawText(img, xx, yy + offset, c, chr);
238: yy += PetscImageFontHeight;
239: }
240: }
241: return 0;
242: }
244: /*
245: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
246: {
247: if (w) *w = 0;
248: if (h) *h = 0;
249: return 0;
250: */
251: #define PetscDrawStringBoxed_Image NULL
253: /*
254: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
255: {
256: return 0;
257: }*/
258: #define PetscDrawFlush_Image NULL
260: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
261: {
262: PetscImage img = (PetscImage)draw->data;
263: {
264: PetscImageClear(img);
265: }
266: return 0;
267: }
269: /*
270: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
271: {
272: return 0;
273: }*/
274: #define PetscDrawSetDoubleBuffer_Image NULL
276: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
277: {
278: PetscBool flg = PETSC_FALSE;
280: PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL);
281: if (!flg) {
282: *popup = NULL;
283: return 0;
284: }
285: PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup);
286: PetscDrawSetType(*popup, PETSC_DRAW_IMAGE);
287: PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_");
288: PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix);
289: draw->popup = *popup;
290: return 0;
291: }
293: /*
294: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
295: {
296: return 0;
297: }*/
298: #define PetscDrawSetTitle_Image NULL
300: /*
301: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
302: {
303: return 0;
304: }*/
305: #define PetscDrawCheckResizedWindow_Image NULL
307: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
308: {
309: PetscImage img = (PetscImage)draw->data;
311: if (w == img->w && h == img->h) return 0;
312: PetscFree(img->buffer);
314: img->w = w;
315: img->h = h;
316: PetscCalloc1((size_t)(img->w * img->h), &img->buffer);
317: PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr);
318: return 0;
319: }
321: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
322: {
323: PetscImage img = (PetscImage)draw->data;
325: PetscDrawDestroy(&draw->popup);
326: PetscFree(img->buffer);
327: PetscFree(draw->data);
328: return 0;
329: }
331: /*
332: static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
333: {
334: return 0;
335: }*/
336: #define PetscDrawView_Image NULL
338: /*
339: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
340: {
341: *button = PETSC_BUTTON_NONE;
342: if (x_user) *x_user = 0;
343: if (y_user) *y_user = 0;
344: if (x_phys) *x_phys = 0;
345: if (y_phys) *y_phys = 0;
346: return 0;
347: }*/
348: #define PetscDrawGetMouseButton_Image NULL
350: /*
351: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
352: {
353: return 0;
354: }*/
355: #define PetscDrawPause_Image NULL
357: /*
358: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
359: {
360: return 0;
361: }*/
362: #define PetscDrawBeginPage_Image NULL
364: /*
365: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
366: {
367: return 0;
368: }*/
369: #define PetscDrawEndPage_Image NULL
371: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
372: {
373: PetscImage pimg = (PetscImage)draw->data;
374: PetscImage simg;
376: PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw);
377: PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE);
378: (*sdraw)->ops->resizewindow = NULL;
379: simg = (PetscImage)(*sdraw)->data;
380: PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h);
381: return 0;
382: }
384: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
385: {
386: PetscImage pimg = (PetscImage)draw->data;
387: PetscImage simg = (PetscImage)(*sdraw)->data;
389: PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h);
390: PetscDrawDestroy(sdraw);
391: return 0;
392: }
394: /*
395: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
396: {
397: return 0;
398: }*/
399: #define PetscDrawSave_Image NULL
401: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[])
402: {
403: PetscImage img = (PetscImage)draw->data;
404: unsigned char *buffer = NULL;
405: PetscMPIInt rank, size;
407: if (w) *w = (unsigned int)img->w;
408: if (h) *h = (unsigned int)img->h;
409: if (pixels) *pixels = NULL;
410: MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank);
411: if (rank == 0) {
412: PetscMemcpy(palette, img->palette, sizeof(img->palette));
413: PetscMalloc1((size_t)(img->w * img->h), &buffer);
414: if (pixels) *pixels = buffer;
415: }
416: MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size);
417: if (size == 1) {
418: PetscArraycpy(buffer, img->buffer, img->w * img->h);
419: } else {
420: MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw));
421: }
422: return 0;
423: }
425: static struct _PetscDrawOps DvOps = {PetscDrawSetDoubleBuffer_Image, PetscDrawFlush_Image, PetscDrawLine_Image, PetscDrawLineSetWidth_Image, PetscDrawLineGetWidth_Image, PetscDrawPoint_Image, PetscDrawPointSetSize_Image, PetscDrawString_Image, PetscDrawStringVertical_Image, PetscDrawStringSetSize_Image, PetscDrawStringGetSize_Image, PetscDrawSetViewport_Image, PetscDrawClear_Image, PetscDrawRectangle_Image, PetscDrawTriangle_Image, PetscDrawEllipse_Image, PetscDrawGetMouseButton_Image, PetscDrawPause_Image, PetscDrawBeginPage_Image, PetscDrawEndPage_Image, PetscDrawGetPopup_Image, PetscDrawSetTitle_Image, PetscDrawCheckResizedWindow_Image, PetscDrawResizeWindow_Image, PetscDrawDestroy_Image, PetscDrawView_Image, PetscDrawGetSingleton_Image, PetscDrawRestoreSingleton_Image, PetscDrawSave_Image, PetscDrawGetImage_Image, PetscDrawSetCoordinates_Image, PetscDrawArrow_Image, PetscDrawCoordinateToPixel_Image, PetscDrawPixelToCoordinate_Image, PetscDrawPointPixel_Image, PetscDrawStringBoxed_Image};
427: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
428: {255, 255, 255}, /* white */
429: {0, 0, 0 }, /* black */
430: {255, 0, 0 }, /* red */
431: {0, 255, 0 }, /* green */
432: {0, 255, 255}, /* cyan */
433: {0, 0, 255}, /* blue */
434: {255, 0, 255}, /* magenta */
435: {127, 255, 212}, /* aquamarine */
436: {34, 139, 34 }, /* forestgreen */
437: {255, 165, 0 }, /* orange */
438: {238, 130, 238}, /* violet */
439: {165, 42, 42 }, /* brown */
440: {255, 192, 203}, /* pink */
441: {255, 127, 80 }, /* coral */
442: {190, 190, 190}, /* gray */
443: {255, 255, 0 }, /* yellow */
444: {255, 215, 0 }, /* gold */
445: {255, 182, 193}, /* lightpink */
446: {72, 209, 204}, /* mediumturquoise */
447: {240, 230, 140}, /* khaki */
448: {105, 105, 105}, /* dimgray */
449: {54, 205, 50 }, /* yellowgreen */
450: {135, 206, 235}, /* skyblue */
451: {0, 100, 0 }, /* darkgreen */
452: {0, 0, 128}, /* navyblue */
453: {244, 164, 96 }, /* sandybrown */
454: {95, 158, 160}, /* cadetblue */
455: {176, 224, 230}, /* powderblue */
456: {255, 20, 147}, /* deeppink */
457: {216, 191, 216}, /* thistle */
458: {50, 205, 50 }, /* limegreen */
459: {255, 240, 245}, /* lavenderblush */
460: {221, 160, 221}, /* plum */
461: };
463: /*MC
464: PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer
466: Options Database Keys:
467: . -draw_size w,h - size of image in pixels
469: Level: beginner
471: .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
472: M*/
473: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);
475: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
476: {
477: PetscImage img;
478: int w = draw->w, h = draw->h;
479: PetscInt size[2], nsize = 2;
480: PetscBool set;
482: draw->pause = 0;
483: draw->coor_xl = 0;
484: draw->coor_xr = 1;
485: draw->coor_yl = 0;
486: draw->coor_yr = 1;
487: draw->port_xl = 0;
488: draw->port_xr = 1;
489: draw->port_yl = 0;
490: draw->port_yr = 1;
492: size[0] = w;
493: if (size[0] < 1) size[0] = 300;
494: size[1] = h;
495: if (size[1] < 1) size[1] = size[0];
496: PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set);
497: if (set && nsize == 1) size[1] = size[0];
498: if (size[0] < 1) size[0] = 300;
499: if (size[1] < 1) size[1] = size[0];
500: draw->w = w = size[0];
501: draw->x = 0;
502: draw->h = h = size[1];
503: draw->x = 0;
505: PetscNew(&img);
506: PetscMemcpy(draw->ops, &DvOps, sizeof(DvOps));
507: draw->data = (void *)img;
509: img->w = w;
510: img->h = h;
511: PetscCalloc1((size_t)(img->w * img->h), &img->buffer);
512: PetscImageSetClip(img, 0, 0, img->w, img->h);
513: {
514: int i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
515: unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
516: unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
517: unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
518: PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B);
519: for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
520: img->palette[k][0] = BasicColors[k][0];
521: img->palette[k][1] = BasicColors[k][1];
522: img->palette[k][2] = BasicColors[k][2];
523: }
524: for (i = 0; i < ncolors; i++, k++) {
525: img->palette[k][0] = R[i];
526: img->palette[k][1] = G[i];
527: img->palette[k][2] = B[i];
528: }
529: }
531: if (!draw->savefilename) PetscDrawSetSave(draw, draw->title);
532: return 0;
533: }
535: /*@C
536: PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.
538: Collective
540: Input Parameters:
541: + comm - the communicator that will share image
542: - filename - optional name of the file where the image will be stored
543: - w, h - the image width and height in pixels
545: Output Parameters:
546: . draw - the drawing context.
548: Level: beginner
550: .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`
551: @*/
552: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw)
553: {
554: PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw);
555: PetscDrawSetType(*draw, PETSC_DRAW_IMAGE);
556: PetscDrawSetSave(*draw, filename);
557: return 0;
558: }