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;
 22:   PetscFunctionBegin;
 23:   {
 24:     int xmax = img->w - 1, ymax = img->h - 1;
 25:     int xa = (int)(xl * xmax), ya = ymax - (int)(yr * ymax);
 26:     int xb = (int)(xr * xmax), yb = ymax - (int)(yl * ymax);
 27:     PetscImageSetClip(img, xa, ya, xb + 1 - xa, yb + 1 - ya);
 28:   }
 29:   PetscFunctionReturn(PETSC_SUCCESS);
 30: }

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

 40: static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j)
 41: {
 42:   PetscImage img = (PetscImage)draw->data;
 43:   PetscFunctionBegin;
 44:   if (i) *i = XTRANS(draw, img, x);
 45:   if (j) *j = YTRANS(draw, img, y);
 46:   PetscFunctionReturn(PETSC_SUCCESS);
 47: }

 49: static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y)
 50: {
 51:   PetscImage img = (PetscImage)draw->data;
 52:   PetscFunctionBegin;
 53:   if (x) *x = ITRANS(draw, img, i);
 54:   if (y) *y = JTRANS(draw, img, j);
 55:   PetscFunctionReturn(PETSC_SUCCESS);
 56: }

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

 66: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c)
 67: {
 68:   PetscImage img = (PetscImage)draw->data;
 69:   PetscFunctionBegin;
 70:   PetscDrawValidColor(c);
 71:   {
 72:     int j, xx = XTRANS(draw, img, x);
 73:     int i, yy = YTRANS(draw, img, y);
 74:     for (i = -1; i <= 1; i++)
 75:       for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c);
 76:   }
 77:   PetscFunctionReturn(PETSC_SUCCESS);
 78: }

 80: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c)
 81: {
 82:   PetscImage img = (PetscImage)draw->data;
 83:   PetscFunctionBegin;
 84:   PetscDrawValidColor(c);
 85:   {
 86:     PetscImageDrawPixel(img, x, y, c);
 87:   }
 88:   PetscFunctionReturn(PETSC_SUCCESS);
 89: }

 91: /*
 92: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
 93: {
 94:   PetscFunctionBegin;
 95:   PetscFunctionReturn(PETSC_SUCCESS);
 96: }*/
 97: #define PetscDrawLineSetWidth_Image NULL

 99: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width)
100: {
101:   PetscImage img = (PetscImage)draw->data;
102:   PetscFunctionBegin;
103:   {
104:     int lw = 1;
105:     *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
106:   }
107:   PetscFunctionReturn(PETSC_SUCCESS);
108: }

110: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
111: {
112:   PetscImage img = (PetscImage)draw->data;
113:   PetscFunctionBegin;
114:   {
115:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
116:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
117:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
118:   }
119:   PetscFunctionReturn(PETSC_SUCCESS);
120: }

122: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c)
123: {
124:   PetscImage img = (PetscImage)draw->data;
125:   PetscFunctionBegin;
126:   PetscDrawValidColor(c);
127:   {
128:     int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr);
129:     int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr);
130:     if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(PETSC_SUCCESS);
131:     PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c);
132:     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
133:       if (y_2 > y_1) {
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:       } else {
137:         PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c);
138:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
139:       }
140:     }
141:     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
142:       if (x_2 > x_1) {
143:         PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c);
144:         PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c);
145:       } else {
146:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c);
147:         PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c);
148:       }
149:     }
150:   }
151:   PetscFunctionReturn(PETSC_SUCCESS);
152: }

154: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4)
155: {
156:   PetscImage img = (PetscImage)draw->data;
157:   PetscFunctionBegin;
158:   PetscDrawValidColor(c1);
159:   PetscDrawValidColor(c2);
160:   PetscDrawValidColor(c3);
161:   PetscDrawValidColor(c4);
162:   {
163:     int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x;
164:     int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y;
165:     int c = (c1 + c2 + c3 + c4) / 4;
166:     PetscImageDrawRectangle(img, x, y, w, h, c);
167:   }
168:   PetscFunctionReturn(PETSC_SUCCESS);
169: }

171: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
172: {
173:   PetscImage img = (PetscImage)draw->data;
174:   PetscFunctionBegin;
175:   PetscDrawValidColor(c);
176:   a = PetscAbsReal(a);
177:   b = PetscAbsReal(b);
178:   {
179:     int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc;
180:     int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc;
181:     if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */
182:     PetscImageDrawEllipse(img, xc, yc, w, h, c);
183:   }
184:   PetscFunctionReturn(PETSC_SUCCESS);
185: }

187: 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)
188: {
189:   PetscImage img = (PetscImage)draw->data;
190:   PetscFunctionBegin;
191:   PetscDrawValidColor(c1);
192:   PetscDrawValidColor(c2);
193:   PetscDrawValidColor(c3);
194:   {
195:     int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3);
196:     int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3);
197:     PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3);
198:   }
199:   PetscFunctionReturn(PETSC_SUCCESS);
200: }

202: /*
203: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
204: {
205:   PetscFunctionBegin;
206:   PetscFunctionReturn(PETSC_SUCCESS);
207: }*/
208: #define PetscDrawStringSetSize_Image NULL

210: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h)
211: {
212:   PetscImage img = (PetscImage)draw->data;
213:   PetscFunctionBegin;
214:   {
215:     int tw = PetscImageFontWidth;
216:     int th = PetscImageFontHeight;
217:     if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl));
218:     if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl));
219:   }
220:   PetscFunctionReturn(PETSC_SUCCESS);
221: }

223: static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
224: {
225:   PetscImage img = (PetscImage)draw->data;
226:   PetscToken token;
227:   char      *subtext;
228:   PetscFunctionBegin;
229:   PetscDrawValidColor(c);
230:   {
231:     int xx = XTRANS(draw, img, x);
232:     int yy = YTRANS(draw, img, y);
233:     PetscCall(PetscTokenCreate(text, '\n', &token));
234:     PetscCall(PetscTokenFind(token, &subtext));
235:     while (subtext) {
236:       PetscImageDrawText(img, xx, yy, c, subtext);
237:       yy += PetscImageFontHeight;
238:       PetscCall(PetscTokenFind(token, &subtext));
239:     }
240:     PetscCall(PetscTokenDestroy(&token));
241:   }
242:   PetscFunctionReturn(PETSC_SUCCESS);
243: }

245: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[])
246: {
247:   PetscImage img = (PetscImage)draw->data;
248:   PetscFunctionBegin;
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:   PetscFunctionReturn(PETSC_SUCCESS);
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: {
266:   PetscFunctionBegin;
267:   if (w) *w = 0;
268:   if (h) *h = 0;
269:   PetscFunctionReturn(PETSC_SUCCESS);
270: */
271: #define PetscDrawStringBoxed_Image NULL

273: /*
274: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
275: {
276:   PetscFunctionBegin;
277:   PetscFunctionReturn(PETSC_SUCCESS);
278: }*/
279: #define PetscDrawFlush_Image NULL

281: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
282: {
283:   PetscImage img = (PetscImage)draw->data;
284:   PetscFunctionBegin;
285:   {
286:     PetscImageClear(img);
287:   }
288:   PetscFunctionReturn(PETSC_SUCCESS);
289: }

291: /*
292: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
293: {
294:   PetscFunctionBegin;
295:   PetscFunctionReturn(PETSC_SUCCESS);
296: }*/
297: #define PetscDrawSetDoubleBuffer_Image NULL

299: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup)
300: {
301:   PetscBool flg = PETSC_FALSE;

303:   PetscFunctionBegin;
304:   PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL));
305:   if (!flg) {
306:     *popup = NULL;
307:     PetscFunctionReturn(PETSC_SUCCESS);
308:   }
309:   PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup));
310:   PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE));
311:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_"));
312:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix));
313:   draw->popup = *popup;
314:   PetscFunctionReturn(PETSC_SUCCESS);
315: }

317: /*
318: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
319: {
320:   PetscFunctionBegin;
321:   PetscFunctionReturn(PETSC_SUCCESS);
322: }*/
323: #define PetscDrawSetTitle_Image NULL

325: /*
326: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
327: {
328:   PetscFunctionBegin;
329:   PetscFunctionReturn(PETSC_SUCCESS);
330: }*/
331: #define PetscDrawCheckResizedWindow_Image NULL

333: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h)
334: {
335:   PetscImage img = (PetscImage)draw->data;

337:   PetscFunctionBegin;
338:   if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS);
339:   PetscCall(PetscFree(img->buffer));

341:   img->w = w;
342:   img->h = h;
343:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
344:   PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr));
345:   PetscFunctionReturn(PETSC_SUCCESS);
346: }

348: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
349: {
350:   PetscImage img = (PetscImage)draw->data;

352:   PetscFunctionBegin;
353:   PetscCall(PetscDrawDestroy(&draw->popup));
354:   PetscCall(PetscFree(img->buffer));
355:   PetscCall(PetscFree(draw->data));
356:   PetscFunctionReturn(PETSC_SUCCESS);
357: }

359: static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer)
360: {
361:   PetscBool iascii;

363:   PetscFunctionBegin;
364:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
365:   if (iascii) {
366:     const char *filename = draw->savefilename ? draw->savefilename : draw->title;
367:     PetscCall(PetscViewerASCIIPrintf(viewer, "  Image file name %s\n", filename));
368:   }
369:   PetscFunctionReturn(PETSC_SUCCESS);
370: }

372: /*
373: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
374: {
375:   PetscFunctionBegin;
376:   *button = PETSC_BUTTON_NONE;
377:   if (x_user) *x_user = 0;
378:   if (y_user) *y_user = 0;
379:   if (x_phys) *x_phys = 0;
380:   if (y_phys) *y_phys = 0;
381:   PetscFunctionReturn(PETSC_SUCCESS);
382: }*/
383: #define PetscDrawGetMouseButton_Image NULL

385: /*
386: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
387: {
388:   PetscFunctionBegin;
389:   PetscFunctionReturn(PETSC_SUCCESS);
390: }*/
391: #define PetscDrawPause_Image NULL

393: /*
394: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
395: {
396:   PetscFunctionBegin;
397:   PetscFunctionReturn(PETSC_SUCCESS);
398: }*/
399: #define PetscDrawBeginPage_Image NULL

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

409: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw)
410: {
411:   PetscImage pimg = (PetscImage)draw->data;
412:   PetscImage simg;

414:   PetscFunctionBegin;
415:   PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw));
416:   PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE));
417:   (*sdraw)->ops->resizewindow = NULL;
418:   simg                        = (PetscImage)(*sdraw)->data;
419:   PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h));
420:   PetscFunctionReturn(PETSC_SUCCESS);
421: }

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

428:   PetscFunctionBegin;
429:   PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h));
430:   PetscCall(PetscDrawDestroy(sdraw));
431:   PetscFunctionReturn(PETSC_SUCCESS);
432: }

434: /*
435: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
436: {
437:   PetscFunctionBegin;
438:   PetscFunctionReturn(PETSC_SUCCESS);
439: }*/
440: #define PetscDrawSave_Image NULL

442: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[])
443: {
444:   PetscImage     img    = (PetscImage)draw->data;
445:   unsigned char *buffer = NULL;
446:   PetscMPIInt    rank, size;

448:   PetscFunctionBegin;
449:   if (w) *w = (unsigned int)img->w;
450:   if (h) *h = (unsigned int)img->h;
451:   if (pixels) *pixels = NULL;
452:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank));
453:   if (rank == 0) {
454:     PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette)));
455:     PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer));
456:     if (pixels) *pixels = buffer;
457:   }
458:   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size));
459:   if (size == 1) {
460:     PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h));
461:   } else {
462:     PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw)));
463:   }
464:   PetscFunctionReturn(PETSC_SUCCESS);
465: }

467: 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};

469: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
470:   {255, 255, 255}, /* white */
471:   {0,   0,   0  }, /* black */
472:   {255, 0,   0  }, /* red */
473:   {0,   255, 0  }, /* green */
474:   {0,   255, 255}, /* cyan */
475:   {0,   0,   255}, /* blue */
476:   {255, 0,   255}, /* magenta */
477:   {127, 255, 212}, /* aquamarine */
478:   {34,  139, 34 }, /* forestgreen */
479:   {255, 165, 0  }, /* orange */
480:   {238, 130, 238}, /* violet */
481:   {165, 42,  42 }, /* brown */
482:   {255, 192, 203}, /* pink */
483:   {255, 127, 80 }, /* coral */
484:   {190, 190, 190}, /* gray */
485:   {255, 255, 0  }, /* yellow */
486:   {255, 215, 0  }, /* gold */
487:   {255, 182, 193}, /* lightpink */
488:   {72,  209, 204}, /* mediumturquoise */
489:   {240, 230, 140}, /* khaki */
490:   {105, 105, 105}, /* dimgray */
491:   {54,  205, 50 }, /* yellowgreen */
492:   {135, 206, 235}, /* skyblue */
493:   {0,   100, 0  }, /* darkgreen */
494:   {0,   0,   128}, /* navyblue */
495:   {244, 164, 96 }, /* sandybrown */
496:   {95,  158, 160}, /* cadetblue */
497:   {176, 224, 230}, /* powderblue */
498:   {255, 20,  147}, /* deeppink */
499:   {216, 191, 216}, /* thistle */
500:   {50,  205, 50 }, /* limegreen */
501:   {255, 240, 245}, /* lavenderblush */
502:   {221, 160, 221}, /* plum */
503: };

505: /*MC
506:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

508:    Options Database Keys:
509: .  -draw_size w,h - size of image in pixels

511:    Level: beginner

513: .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`
514: M*/
515: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);

517: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
518: {
519:   PetscImage img;
520:   int        w = draw->w, h = draw->h;
521:   PetscInt   size[2], nsize = 2;
522:   PetscBool  set;

524:   PetscFunctionBegin;
525:   draw->pause   = 0;
526:   draw->coor_xl = 0;
527:   draw->coor_xr = 1;
528:   draw->coor_yl = 0;
529:   draw->coor_yr = 1;
530:   draw->port_xl = 0;
531:   draw->port_xr = 1;
532:   draw->port_yl = 0;
533:   draw->port_yr = 1;

535:   size[0] = w;
536:   if (size[0] < 1) size[0] = 300;
537:   size[1] = h;
538:   if (size[1] < 1) size[1] = size[0];
539:   PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set));
540:   if (set && nsize == 1) size[1] = size[0];
541:   if (size[0] < 1) size[0] = 300;
542:   if (size[1] < 1) size[1] = size[0];
543:   draw->w = w = size[0];
544:   draw->x     = 0;
545:   draw->h = h = size[1];
546:   draw->x     = 0;

548:   PetscCall(PetscNew(&img));
549:   draw->ops[0] = DvOps;
550:   draw->data   = (void *)img;

552:   img->w = w;
553:   img->h = h;
554:   PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer));
555:   PetscImageSetClip(img, 0, 0, img->w, img->h);
556:   {
557:     int           i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS;
558:     unsigned char R[256 - PETSC_DRAW_BASIC_COLORS];
559:     unsigned char G[256 - PETSC_DRAW_BASIC_COLORS];
560:     unsigned char B[256 - PETSC_DRAW_BASIC_COLORS];
561:     PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B));
562:     for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) {
563:       img->palette[k][0] = BasicColors[k][0];
564:       img->palette[k][1] = BasicColors[k][1];
565:       img->palette[k][2] = BasicColors[k][2];
566:     }
567:     for (i = 0; i < ncolors; i++, k++) {
568:       img->palette[k][0] = R[i];
569:       img->palette[k][1] = G[i];
570:       img->palette[k][2] = B[i];
571:     }
572:   }

574:   if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title));
575:   PetscFunctionReturn(PETSC_SUCCESS);
576: }

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

581:   Collective

583:   Input Parameters:
584: + comm     - the communicator that will share image
585: . filename - optional name of the file where the image will be stored
586: . w        - the image width in pixels
587: - h        - the image height in pixels

589:   Output Parameter:
590: . draw - the drawing context.

592:   Level: beginner

594: .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`
595: @*/
596: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw)
597: {
598:   PetscFunctionBegin;
599:   PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw));
600:   PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE));
601:   PetscCall(PetscDrawSetSave(*draw, filename));
602:   PetscFunctionReturn(PETSC_SUCCESS);
603: }