#include <../src/sys/classes/draw/impls/image/drawimage.h> /*I "petscdraw.h" I*/ #include /*I "petscdraw.h" I*/ #include #if defined(PETSC_USE_DEBUG) #define PetscDrawValidColor(color) PetscCheck((color) >= 0 && (color) < 256, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Color value %d out of range [0..255]", (color)) #else #define PetscDrawValidColor(color) \ do { \ } while (0) #endif #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))))) #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))))) #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)) #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)) static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; { int xmax = img->w - 1, ymax = img->h - 1; int xa = (int)(xl * xmax), ya = ymax - (int)(yr * ymax); int xb = (int)(xr * xmax), yb = ymax - (int)(yl * ymax); PetscImageSetClip(img, xa, ya, xb + 1 - xa, yb + 1 - ya); } PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawSetCoordinates_Image NULL static PetscErrorCode PetscDrawCoordinateToPixel_Image(PetscDraw draw, PetscReal x, PetscReal y, int *i, int *j) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; if (i) *i = XTRANS(draw, img, x); if (j) *j = YTRANS(draw, img, y); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawPixelToCoordinate_Image(PetscDraw draw, int i, int j, PetscReal *x, PetscReal *y) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; if (x) *x = ITRANS(draw, img, i); if (y) *y = JTRANS(draw, img, j); PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawPointSetSize_Image NULL static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw, PetscReal x, PetscReal y, int c) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c); { int j, xx = XTRANS(draw, img, x); int i, yy = YTRANS(draw, img, y); for (i = -1; i <= 1; i++) for (j = -1; j <= 1; j++) PetscImageDrawPixel(img, xx + j, yy + i, c); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw, int x, int y, int c) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c); { PetscImageDrawPixel(img, x, y, c); } PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawLineSetWidth_Image NULL static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw, PetscReal *width) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; { int lw = 1; *width = lw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl)); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawLine_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; { int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr); int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr); PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c); { int x_1 = XTRANS(draw, img, xl), x_2 = XTRANS(draw, img, xr); int y_1 = YTRANS(draw, img, yl), y_2 = YTRANS(draw, img, yr); if (x_1 == x_2 && y_1 == y_2) PetscFunctionReturn(PETSC_SUCCESS); PetscImageDrawLine(img, x_1, y_1, x_2, y_2, c); if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) { if (y_2 > y_1) { PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 - 3, c); PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c); } else { PetscImageDrawLine(img, x_2, y_2, x_2 - 3, y_2 + 3, c); PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c); } } if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) { if (x_2 > x_1) { PetscImageDrawLine(img, x_2 - 3, y_2 - 3, x_2, y_2, c); PetscImageDrawLine(img, x_2 - 3, y_2 + 3, x_2, y_2, c); } else { PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 - 3, c); PetscImageDrawLine(img, x_2, y_2, x_2 + 3, y_2 + 3, c); } } } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c1); PetscDrawValidColor(c2); PetscDrawValidColor(c3); PetscDrawValidColor(c4); { int x = XTRANS(draw, img, xl), w = XTRANS(draw, img, xr) + 1 - x; int y = YTRANS(draw, img, yr), h = YTRANS(draw, img, yl) + 1 - y; int c = (c1 + c2 + c3 + c4) / 4; PetscImageDrawRectangle(img, x, y, w, h, c); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c); a = PetscAbsReal(a); b = PetscAbsReal(b); { int xc = XTRANS(draw, img, x), w = XTRANS(draw, img, x + a / 2) + 0 - xc; int yc = YTRANS(draw, img, y), h = YTRANS(draw, img, y - b / 2) + 0 - yc; if (PetscAbsReal(a - b) <= 0) w = h = PetscMin(w, h); /* workaround truncation errors */ PetscImageDrawEllipse(img, xc, yc, w, h, c); } PetscFunctionReturn(PETSC_SUCCESS); } 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) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c1); PetscDrawValidColor(c2); PetscDrawValidColor(c3); { int x_1 = XTRANS(draw, img, X_1), x_2 = XTRANS(draw, img, X_2), x_3 = XTRANS(draw, img, X_3); int y_1 = YTRANS(draw, img, Y_1), y_2 = YTRANS(draw, img, Y_2), y_3 = YTRANS(draw, img, Y_3); PetscImageDrawTriangle(img, x_1, y_1, c1, x_2, y_2, c2, x_3, y_3, c3); } PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawStringSetSize_Image NULL static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw, PetscReal *w, PetscReal *h) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; { int tw = PetscImageFontWidth; int th = PetscImageFontHeight; if (w) *w = tw * (draw->coor_xr - draw->coor_xl) / (img->w * (draw->port_xr - draw->port_xl)); if (h) *h = th * (draw->coor_yr - draw->coor_yl) / (img->h * (draw->port_yr - draw->port_yl)); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawString_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[]) { PetscImage img = (PetscImage)draw->data; PetscToken token; const char *subtext; PetscFunctionBegin; PetscDrawValidColor(c); { int xx = XTRANS(draw, img, x); int yy = YTRANS(draw, img, y); PetscCall(PetscTokenCreate(text, '\n', &token)); PetscCall(PetscTokenFind(token, &subtext)); while (subtext) { PetscImageDrawText(img, xx, yy, c, subtext); yy += PetscImageFontHeight; PetscCall(PetscTokenFind(token, &subtext)); } PetscCall(PetscTokenDestroy(&token)); } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw, PetscReal x, PetscReal y, int c, const char text[]) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscDrawValidColor(c); { char chr[2] = {0, 0}; int xx = XTRANS(draw, img, x); int yy = YTRANS(draw, img, y); int offset = PetscImageFontHeight; while ((chr[0] = *text++)) { PetscImageDrawText(img, xx, yy + offset, c, chr); yy += PetscImageFontHeight; } } PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h) { PetscFunctionBegin; if (w) *w = 0; if (h) *h = 0; PetscFunctionReturn(PETSC_SUCCESS); */ #define PetscDrawStringBoxed_Image NULL /* static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawFlush_Image NULL static PetscErrorCode PetscDrawClear_Image(PetscDraw draw) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; { PetscImageClear(img); } PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawSetDoubleBuffer_Image NULL static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw, PetscDraw *popup) { PetscBool flg = PETSC_FALSE; PetscFunctionBegin; PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL)); if (!flg) { *popup = NULL; PetscFunctionReturn(PETSC_SUCCESS); } PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, 0, 0, 220, 220, popup)); PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_IMAGE)); PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*popup, "popup_")); PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*popup, ((PetscObject)draw)->prefix)); draw->popup = *popup; PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[]) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawSetTitle_Image NULL /* static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawCheckResizedWindow_Image NULL static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw, int w, int h) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; if (w == img->w && h == img->h) PetscFunctionReturn(PETSC_SUCCESS); PetscCall(PetscFree(img->buffer)); img->w = w; img->h = h; PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer)); PetscCall(PetscDrawSetViewport_Image(draw, draw->port_xl, draw->port_yl, draw->port_xr, draw->port_yr)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw) { PetscImage img = (PetscImage)draw->data; PetscFunctionBegin; PetscCall(PetscDrawDestroy(&draw->popup)); PetscCall(PetscFree(img->buffer)); PetscCall(PetscFree(draw->data)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawView_Image(PetscDraw draw, PetscViewer viewer) { PetscBool isascii; PetscFunctionBegin; PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); if (isascii) { const char *filename = draw->savefilename ? draw->savefilename : draw->title; PetscCall(PetscViewerASCIIPrintf(viewer, " Image file name %s\n", filename)); } PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys) { PetscFunctionBegin; *button = PETSC_BUTTON_NONE; if (x_user) *x_user = 0; if (y_user) *y_user = 0; if (x_phys) *x_phys = 0; if (y_phys) *y_phys = 0; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawGetMouseButton_Image NULL /* static PetscErrorCode PetscDrawPause_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawPause_Image NULL /* static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawBeginPage_Image NULL /* static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawEndPage_Image NULL static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw, PetscDraw *sdraw) { PetscImage pimg = (PetscImage)draw->data; PetscImage simg; PetscFunctionBegin; PetscCall(PetscDrawCreate(PETSC_COMM_SELF, NULL, NULL, 0, 0, draw->w, draw->h, sdraw)); PetscCall(PetscDrawSetType(*sdraw, PETSC_DRAW_IMAGE)); (*sdraw)->ops->resizewindow = NULL; simg = (PetscImage)(*sdraw)->data; PetscCall(PetscArraycpy(simg->buffer, pimg->buffer, pimg->w * pimg->h)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw, PetscDraw *sdraw) { PetscImage pimg = (PetscImage)draw->data; PetscImage simg = (PetscImage)(*sdraw)->data; PetscFunctionBegin; PetscCall(PetscArraycpy(pimg->buffer, simg->buffer, pimg->w * pimg->h)); PetscCall(PetscDrawDestroy(sdraw)); PetscFunctionReturn(PETSC_SUCCESS); } /* static PetscErrorCode PetscDrawSave_Image(PetscDraw draw) { PetscFunctionBegin; PetscFunctionReturn(PETSC_SUCCESS); }*/ #define PetscDrawSave_Image NULL static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw, unsigned char palette[256][3], unsigned int *w, unsigned int *h, unsigned char *pixels[]) { PetscImage img = (PetscImage)draw->data; unsigned char *buffer = NULL; PetscMPIInt rank, size; PetscFunctionBegin; if (w) *w = (unsigned int)img->w; if (h) *h = (unsigned int)img->h; if (pixels) *pixels = NULL; PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank)); if (rank == 0) { PetscCall(PetscMemcpy(palette, img->palette, sizeof(img->palette))); PetscCall(PetscMalloc1((size_t)(img->w * img->h), &buffer)); if (pixels) *pixels = buffer; } PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)draw), &size)); if (size == 1) { PetscCall(PetscArraycpy(buffer, img->buffer, img->w * img->h)); } else { PetscCallMPI(MPI_Reduce(img->buffer, buffer, img->w * img->h, MPI_UNSIGNED_CHAR, MPI_MAX, 0, PetscObjectComm((PetscObject)draw))); } PetscFunctionReturn(PETSC_SUCCESS); } 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}; static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = { {255, 255, 255}, /* white */ {0, 0, 0 }, /* black */ {255, 0, 0 }, /* red */ {0, 255, 0 }, /* green */ {0, 255, 255}, /* cyan */ {0, 0, 255}, /* blue */ {255, 0, 255}, /* magenta */ {127, 255, 212}, /* aquamarine */ {34, 139, 34 }, /* forestgreen */ {255, 165, 0 }, /* orange */ {238, 130, 238}, /* violet */ {165, 42, 42 }, /* brown */ {255, 192, 203}, /* pink */ {255, 127, 80 }, /* coral */ {190, 190, 190}, /* gray */ {255, 255, 0 }, /* yellow */ {255, 215, 0 }, /* gold */ {255, 182, 193}, /* lightpink */ {72, 209, 204}, /* mediumturquoise */ {240, 230, 140}, /* khaki */ {105, 105, 105}, /* dimgray */ {54, 205, 50 }, /* yellowgreen */ {135, 206, 235}, /* skyblue */ {0, 100, 0 }, /* darkgreen */ {0, 0, 128}, /* navyblue */ {244, 164, 96 }, /* sandybrown */ {95, 158, 160}, /* cadetblue */ {176, 224, 230}, /* powderblue */ {255, 20, 147}, /* deeppink */ {216, 191, 216}, /* thistle */ {50, 205, 50 }, /* limegreen */ {255, 240, 245}, /* lavenderblush */ {221, 160, 221}, /* plum */ }; /*MC PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer Options Database Keys: . -draw_size w,h - size of image in pixels Level: beginner .seealso: `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()` M*/ PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw); PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw) { PetscImage img; int w = draw->w, h = draw->h; PetscInt size[2], nsize = 2; PetscBool set; PetscFunctionBegin; draw->pause = 0; draw->coor_xl = 0; draw->coor_xr = 1; draw->coor_yl = 0; draw->coor_yr = 1; draw->port_xl = 0; draw->port_xr = 1; draw->port_yl = 0; draw->port_yr = 1; size[0] = w; if (size[0] < 1) size[0] = 300; size[1] = h; if (size[1] < 1) size[1] = size[0]; PetscCall(PetscOptionsGetIntArray(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_size", size, &nsize, &set)); if (set && nsize == 1) size[1] = size[0]; if (size[0] < 1) size[0] = 300; if (size[1] < 1) size[1] = size[0]; PetscCall(PetscCIntCast(size[0], &w)); PetscCall(PetscCIntCast(size[1], &h)); draw->w = w; draw->h = h; draw->x = 0; PetscCall(PetscNew(&img)); draw->ops[0] = DvOps; draw->data = (void *)img; img->w = w; img->h = h; PetscCall(PetscCalloc1((size_t)(img->w * img->h), &img->buffer)); PetscImageSetClip(img, 0, 0, img->w, img->h); { int i, k, ncolors = 256 - PETSC_DRAW_BASIC_COLORS; unsigned char R[256 - PETSC_DRAW_BASIC_COLORS]; unsigned char G[256 - PETSC_DRAW_BASIC_COLORS]; unsigned char B[256 - PETSC_DRAW_BASIC_COLORS]; PetscCall(PetscDrawUtilitySetCmap(NULL, ncolors, R, G, B)); for (k = 0; k < PETSC_DRAW_BASIC_COLORS; k++) { img->palette[k][0] = BasicColors[k][0]; img->palette[k][1] = BasicColors[k][1]; img->palette[k][2] = BasicColors[k][2]; } for (i = 0; i < ncolors; i++, k++) { img->palette[k][0] = R[i]; img->palette[k][1] = G[i]; img->palette[k][2] = B[i]; } } if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, draw->title)); PetscFunctionReturn(PETSC_SUCCESS); } /*@ PetscDrawOpenImage - Opens an image for use with the `PetscDraw` routines. Collective Input Parameters: + comm - the communicator that will share image . filename - optional name of the file where the image will be stored . w - the image width in pixels - h - the image height in pixels Output Parameter: . draw - the drawing context. Level: beginner .seealso: `PetscDraw`, `PETSC_DRAW_IMAGE`, `PETSC_DRAW_X`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()` @*/ PetscErrorCode PetscDrawOpenImage(MPI_Comm comm, const char filename[], int w, int h, PetscDraw *draw) { PetscFunctionBegin; PetscCall(PetscDrawCreate(comm, NULL, NULL, 0, 0, w, h, draw)); PetscCall(PetscDrawSetType(*draw, PETSC_DRAW_IMAGE)); PetscCall(PetscDrawSetSave(*draw, filename)); PetscFunctionReturn(PETSC_SUCCESS); }