Actual source code: drawimage.c

  1: #include <../src/sys/classes/draw/impls/image/drawimage.h>
  2: #include <petsc/private/drawimpl.h>
  3: #include <petscviewer.h>

  5: #if defined(PETSC_USE_DEBUG)
  6:   #define PetscDrawValidColor(color) PetscCheck((color) >= 0 && (color) < 256, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Color value %" PetscInt_FMT " out of range [0..255]", (PetscInt)(color))
  7: #else
  8:   #define PetscDrawValidColor(color) \
  9:     do { \
 10:     } while (0)
 11: #endif

 13: #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)))))
 14: #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)))))

 16: #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))
 17: #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))

 19: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr)
 20: {
 21:   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(PETSC_SUCCESS);
 31: }

 33: /*
 34: static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
 35: {
 36:   PetscFunctionBegin;
 37:   PetscFunctionReturn(PETSC_SUCCESS);
 38: }*/
 39: #define PetscDrawSetCoordinates_Image NULL

 41: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
 42: {
 43:   PetscImage img = (PetscImage)draw->data;

 45:   PetscFunctionBegin;
 46:   if (i) *i = XTRANS(draw, img, x);
 47:   if (j) *j = YTRANS(draw, img, y);
 48:   PetscFunctionReturn(PETSC_SUCCESS);
 49: }

 51: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
 52: {
 53:   PetscImage img = (PetscImage)draw->data;

 55:   PetscFunctionBegin;
 56:   if (x) *x = ITRANS(draw, img, i);
 57:   if (y) *y = JTRANS(draw, img, j);
 58:   PetscFunctionReturn(PETSC_SUCCESS);
 59: }

 61: /*
 62: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
 63: {
 64:   PetscFunctionBegin;
 65:   PetscFunctionReturn(PETSC_SUCCESS);
 66: }*/
 67: #define PetscDrawPointSetSize_Image NULL

 69: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
 70: {
 71:   PetscImage img = (PetscImage)draw->data;

 73:   PetscFunctionBegin;
 74:   PetscDrawValidColor(c);
 75:   {
 76:     int j, xx = XTRANS(draw, img, x);
 77:     int i, yy = YTRANS(draw, img, y);
 78:     for (i = -1; i <= 1; i++)
 79:       for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
 80:   }
 81:   PetscFunctionReturn(PETSC_SUCCESS);
 82: }

 84: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
 85: {
 86:   PetscImage img = (PetscImage)draw->data;

 88:   PetscFunctionBegin;
 89:   PetscDrawValidColor(c);
 90:   {
 91:     PetscImageDrawPixel(img, x, y, c);
 92:   }
 93:   PetscFunctionReturn(PETSC_SUCCESS);
 94: }

 96: /*
 97: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
 98: {
 99:   PetscFunctionBegin;
100:   PetscFunctionReturn(PETSC_SUCCESS);
101: }*/
102: #define PetscDrawLineSetWidth_Image NULL

104: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
105: {
106:   PetscImage img = (PetscImage)draw->data;

108:   PetscFunctionBegin;
109:   {
110:     int lw = 1;
111:     *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
112:   }
113:   PetscFunctionReturn(PETSC_SUCCESS);
114: }

116: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
117: {
118:   PetscImage img = (PetscImage)draw->data;

120:   PetscFunctionBegin;
121:   {
122:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
123:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
124:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
125:   }
126:   PetscFunctionReturn(PETSC_SUCCESS);
127: }

129: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
130: {
131:   PetscImage img = (PetscImage)draw->data;

133:   PetscFunctionBegin;
134:   PetscDrawValidColor(c);
135:   {
136:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
137:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
138:     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(PETSC_SUCCESS);
139:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
140:     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
141:       if (y_2 > y_1) {
142:         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c);
143:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, 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:     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
150:       if (x_2 > x_1) {
151:         PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
152:         PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
153:       } else {
154:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
155:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
156:       }
157:     }
158:   }
159:   PetscFunctionReturn(PETSC_SUCCESS);
160: }

162: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4)
163: {
164:   PetscImage img = (PetscImage)draw->data;

166:   PetscFunctionBegin;
167:   PetscDrawValidColor(c1);
168:   PetscDrawValidColor(c2);
169:   PetscDrawValidColor(c3);
170:   PetscDrawValidColor(c4);
171:   {
172:     int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
173:     int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
174:     int c = (c1 + c2 + c3 + c4) / 4;
175:     PetscImageDrawRectangle(img, x, y, w, h, c);
176:   }
177:   PetscFunctionReturn(PETSC_SUCCESS);
178: }

180: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
181: {
182:   PetscImage img = (PetscImage)draw->data;

184:   PetscFunctionBegin;
185:   PetscDrawValidColor(c);
186:   a = PetscAbsReal(a);
187:   b = PetscAbsReal(b);
188:   {
189:     int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
190:     int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
191:     if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
192:     PetscImageDrawEllipse(img, xc, yc, w, h, c);
193:   }
194:   PetscFunctionReturn(PETSC_SUCCESS);
195: }

197: 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)
198: {
199:   PetscImage img = (PetscImage)draw->data;

201:   PetscFunctionBegin;
202:   PetscDrawValidColor(c1);
203:   PetscDrawValidColor(c2);
204:   PetscDrawValidColor(c3);
205:   {
206:     int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
207:     int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
208:     PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
209:   }
210:   PetscFunctionReturn(PETSC_SUCCESS);
211: }

213: /*
214: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
215: {
216:   PetscFunctionBegin;
217:   PetscFunctionReturn(PETSC_SUCCESS);
218: }*/
219: #define PetscDrawStringSetSize_Image NULL

221: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
222: {
223:   PetscImage img = (PetscImage)draw->data;

225:   PetscFunctionBegin;
226:   {
227:     int tw = PetscImageFontWidth;
228:     int th = PetscImageFontHeight;
229:     if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
230:     if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
231:   }
232:   PetscFunctionReturn(PETSC_SUCCESS);
233: }

235: static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
236: {
237:   PetscImage img = (PetscImage)draw->data;
238:   PetscToken token;
239:   char      *subtext;

241:   PetscFunctionBegin;
242:   PetscDrawValidColor(c);
243:   {
244:     int xx = XTRANS(draw, img, x);
245:     int yy = YTRANS(draw, img, y);
246:     PetscCall(PetscTokenCreate(text, '\n', &token));
247:     PetscCall(PetscTokenFind(token, &subtext));
248:     while (subtext) {
249:       PetscImageDrawText(img, xx, yy, c, subtext);
250:       yy += PetscImageFontHeight;
251:       PetscCall(PetscTokenFind(token, &subtext));
252:     }
253:     PetscCall(PetscTokenDestroy(&token));
254:   }
255:   PetscFunctionReturn(PETSC_SUCCESS);
256: }

258: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
259: {
260:   PetscImage img = (PetscImage)draw->data;

262:   PetscFunctionBegin;
263:   PetscDrawValidColor(c);
264:   {
265:     char chr[2] = {0, 0};
266:     int  xx     = XTRANS(draw, img, x);
267:     int  yy     = YTRANS(draw, img, y);
268:     int  offset = PetscImageFontHeight;
269:     while ((chr[0] = *text++)) {
270:       PetscImageDrawText(img, xx, yy + offset, c, chr);
271:       yy += PetscImageFontHeight;
272:     }
273:   }
274:   PetscFunctionReturn(PETSC_SUCCESS);
275: }

277: /*
278: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
279: {
280:   PetscFunctionBegin;
281:   if (w) *w = 0;
282:   if (h) *h = 0;
283:   PetscFunctionReturn(PETSC_SUCCESS);
284: */
285: #define PetscDrawStringBoxed_Image NULL

287: /*
288: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
289: {
290:   PetscFunctionBegin;
291:   PetscFunctionReturn(PETSC_SUCCESS);
292: }*/
293: #define PetscDrawFlush_Image NULL

295: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
296: {
297:   PetscImage img = (PetscImage)draw->data;

299:   PetscFunctionBegin;
300:   {
301:     PetscImageClear(img);
302:   }
303:   PetscFunctionReturn(PETSC_SUCCESS);
304: }

306: /*
307: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
308: {
309:   PetscFunctionBegin;
310:   PetscFunctionReturn(PETSC_SUCCESS);
311: }*/
312: #define PetscDrawSetDoubleBuffer_Image NULL

314: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
315: {
316:   PetscBool flg = PETSC_FALSE;

318:   PetscFunctionBegin;
319:   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL));
320:   if (!flg) {
321:     *popup = NULL;
322:     PetscFunctionReturn(PETSC_SUCCESS);
323:   }
324:   PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup));
325:   PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE));
326:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
327:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix));
328:   draw->popup = *popup;
329:   PetscFunctionReturn(PETSC_SUCCESS);
330: }

332: /*
333: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
334: {
335:   PetscFunctionBegin;
336:   PetscFunctionReturn(PETSC_SUCCESS);
337: }*/
338: #define PetscDrawSetTitle_Image NULL

340: /*
341: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
342: {
343:   PetscFunctionBegin;
344:   PetscFunctionReturn(PETSC_SUCCESS);
345: }*/
346: #define PetscDrawCheckResizedWindow_Image NULL

348: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
349: {
350:   PetscImage img = (PetscImage)draw->data;

352:   PetscFunctionBegin;
353:   if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS);
354:   PetscCall(PetscFree(img->buffer));

356:   img->w = w;
357:   img->h = h;
358:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
359:   PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr));
360:   PetscFunctionReturn(PETSC_SUCCESS);
361: }

363: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
364: {
365:   PetscImage img = (PetscImage)draw->data;

367:   PetscFunctionBegin;
368:   PetscCall(PetscDrawDestroy(&draw->popup));
369:   PetscCall(PetscFree(img->buffer));
370:   PetscCall(PetscFree(draw->data));
371:   PetscFunctionReturn(PETSC_SUCCESS);
372: }

374: static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer)
375: {
376:   PetscBool iascii;

378:   PetscFunctionBegin;
379:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
380:   if (iascii) {
381:     const char *filename = draw->savefilename ? draw->savefilename : draw->title;
382:     PetscCall(PetscViewerASCIIPrintf(viewer, "  Image file name %s\n", filename));
383:   }
384:   PetscFunctionReturn(PETSC_SUCCESS);
385: }

387: /*
388: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
389: {
390:   PetscFunctionBegin;
391:   *button = PETSC_BUTTON_NONE;
392:   if (x_user) *x_user = 0;
393:   if (y_user) *y_user = 0;
394:   if (x_phys) *x_phys = 0;
395:   if (y_phys) *y_phys = 0;
396:   PetscFunctionReturn(PETSC_SUCCESS);
397: }*/
398: #define PetscDrawGetMouseButton_Image NULL

400: /*
401: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
402: {
403:   PetscFunctionBegin;
404:   PetscFunctionReturn(PETSC_SUCCESS);
405: }*/
406: #define PetscDrawPause_Image NULL

408: /*
409: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
410: {
411:   PetscFunctionBegin;
412:   PetscFunctionReturn(PETSC_SUCCESS);
413: }*/
414: #define PetscDrawBeginPage_Image NULL

416: /*
417: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
418: {
419:   PetscFunctionBegin;
420:   PetscFunctionReturn(PETSC_SUCCESS);
421: }*/
422: #define PetscDrawEndPage_Image NULL

424: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
425: {
426:   PetscImage pimg = (PetscImage)draw->data;
427:   PetscImage simg;

429:   PetscFunctionBegin;
430:   PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw));
431:   PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE));
432:   (*sdraw)->ops->resizewindow = NULL;
433:   simg                        = (PetscImage)(*sdraw)->data;
434:   PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h));
435:   PetscFunctionReturn(PETSC_SUCCESS);
436: }

438: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
439: {
440:   PetscImage pimg = (PetscImage)draw->data;
441:   PetscImage simg = (PetscImage)(*sdraw)->data;

443:   PetscFunctionBegin;
444:   PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
445:   PetscCall(PetscDrawDestroy(sdraw));
446:   PetscFunctionReturn(PETSC_SUCCESS);
447: }

449: /*
450: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
451: {
452:   PetscFunctionBegin;
453:   PetscFunctionReturn(PETSC_SUCCESS);
454: }*/
455: #define PetscDrawSave_Image NULL

457: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[])
458: {
459:   PetscImage     img    = (PetscImage)draw->data;
460:   unsigned char *buffer = NULL;
461:   PetscMPIInt    rank, size;

463:   PetscFunctionBegin;
464:   if (w) *w = (unsigned int)img->w;
465:   if (h) *h = (unsigned int)img->h;
466:   if (pixels) *pixels = NULL;
467:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank));
468:   if (rank == 0) {
469:     PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette)));
470:     PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer));
471:     if (pixels) *pixels = buffer;
472:   }
473:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
474:   if (size == 1) {
475:     PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h));
476:   } else {
477:     PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw)));
478:   }
479:   PetscFunctionReturn(PETSC_SUCCESS);
480: }

482: 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, NULL};

484: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
485:   {255, 255, 255}, /* white */
486:   {0,   0,   0  }, /* black */
487:   {255, 0,   0  }, /* red */
488:   {0,   255, 0  }, /* green */
489:   {0,   255, 255}, /* cyan */
490:   {0,   0,   255}, /* blue */
491:   {255, 0,   255}, /* magenta */
492:   {127, 255, 212}, /* aquamarine */
493:   {34,  139, 34 }, /* forestgreen */
494:   {255, 165, 0  }, /* orange */
495:   {238, 130, 238}, /* violet */
496:   {165, 42,  42 }, /* brown */
497:   {255, 192, 203}, /* pink */
498:   {255, 127, 80 }, /* coral */
499:   {190, 190, 190}, /* gray */
500:   {255, 255, 0  }, /* yellow */
501:   {255, 215, 0  }, /* gold */
502:   {255, 182, 193}, /* lightpink */
503:   {72,  209, 204}, /* mediumturquoise */
504:   {240, 230, 140}, /* khaki */
505:   {105, 105, 105}, /* dimgray */
506:   {54,  205, 50 }, /* yellowgreen */
507:   {135, 206, 235}, /* skyblue */
508:   {0,   100, 0  }, /* darkgreen */
509:   {0,   0,   128}, /* navyblue */
510:   {244, 164, 96 }, /* sandybrown */
511:   {95,  158, 160}, /* cadetblue */
512:   {176, 224, 230}, /* powderblue */
513:   {255, 20,  147}, /* deeppink */
514:   {216, 191, 216}, /* thistle */
515:   {50,  205, 50 }, /* limegreen */
516:   {255, 240, 245}, /* lavenderblush */
517:   {221, 160, 221}, /* plum */
518: };

520: /*MC
521:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

523:    Options Database Keys:
524: .  -draw_size w,h - size of image in pixels

526:    Level: beginner

528: .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
529: M*/
530: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);

532: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
533: {
534:   PetscImage img;
535:   int        w = draw->w, h = draw->h;
536:   PetscInt   size[2], nsize = 2;
537:   PetscBool  set;

539:   PetscFunctionBegin;
540:   draw->pause   = 0;
541:   draw->coor_xl = 0;
542:   draw->coor_xr = 1;
543:   draw->coor_yl = 0;
544:   draw->coor_yr = 1;
545:   draw->port_xl = 0;
546:   draw->port_xr = 1;
547:   draw->port_yl = 0;
548:   draw->port_yr = 1;

550:   size[0] = w;
551:   if (size[0] < 1) size[0] = 300;
552:   size[1] = h;
553:   if (size[1] < 1) size[1] = size[0];
554:   PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set));
555:   if (set && nsize == 1) size[1] = size[0];
556:   if (size[0] < 1) size[0] = 300;
557:   if (size[1] < 1) size[1] = size[0];
558:   draw->w = w = size[0];
559:   draw->x     = 0;
560:   draw->h = h = size[1];
561:   draw->x     = 0;

563:   PetscCall(PetscNew(&img));
564:   draw->ops[0] = DvOps;
565:   draw->data   = (void *)img;

567:   img->w = w;
568:   img->h = h;
569:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
570:   PetscImageSetClip(img, 0, 0, img->w, img->h);
571:   {
572:     int           i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
573:     unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
574:     unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
575:     unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
576:     PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B));
577:     for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
578:       img->palette[k][0] = BasicColors[k][0];
579:       img->palette[k][1] = BasicColors[k][1];
580:       img->palette[k][2] = BasicColors[k][2];
581:     }
582:     for (i = 0; i < ncolors; i++, k++) {
583:       img->palette[k][0] = R[i];
584:       img->palette[k][1] = G[i];
585:       img->palette[k][2] = B[i];
586:     }
587:   }

589:   if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
590:   PetscFunctionReturn(PETSC_SUCCESS);
591: }

593: /*@C
594:   PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines.

596:   Collective

598:   Input Parameters:
599: + comm     - the communicator that will share image
600: . filename - optional name of the file where the image will be stored
601: . w        - the image width in pixels
602: - h        - the image height in pixels

604:   Output Parameter:
605: . draw - the drawing context.

607:   Level: beginner

609: .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`
610: @*/
611: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw)
612: {
613:   PetscFunctionBegin;
614:   PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw));
615:   PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE));
616:   PetscCall(PetscDrawSetSave(*draw, filename));
617:   PetscFunctionReturn(PETSC_SUCCESS);
618: }