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))

     18: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
     19: {
     20:   PetscImage img = (PetscImage)draw->data;
     22:   {
     23:     int xmax = img->w - 1,   ymax = img->h - 1;
     24:     int xa = (int)(xl*xmax), ya = ymax - (int)(yr*ymax);
     25:     int xb = (int)(xr*xmax), yb = ymax - (int)(yl*ymax);
     26:     PetscImageSetClip(img,xa,ya,xb+1-xa,yb+1-ya);
     27:   }
     28:   return(0);
     29: }

     31: /*
     32: static PetscErrorCode PetscDrawSetCoordinates_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
     33: {
     35:   return(0);
     36: }*/
     37: #define PetscDrawSetCoordinates_Image NULL

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

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

     57: /*
     58: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
     59: {
     61:   return(0);
     62: }*/
     63: #define PetscDrawPointSetSize_Image NULL

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

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

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

     99: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw,PetscReal *width)
    100: {
    101:   PetscImage img = (PetscImage)draw->data;
    103:   {
    104:     int lw = 1;
    105:     *width = lw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
    106:   }
    107:   return(0);
    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;
    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:   return(0);
    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;
    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) return(0);
    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:   return(0);
    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;
    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:   return(0);
    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;
    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:   return(0);
    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;
    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:   return(0);
    200: }

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

    210: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw,PetscReal *w,PetscReal  *h)
    211: {
    212:   PetscImage img = (PetscImage)draw->data;
    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:   return(0);
    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;
    230:   PetscDrawValidColor(c);
    231:   {
    232:     int xx = XTRANS(draw,img,x);
    233:     int yy = YTRANS(draw,img,y);
    234:     PetscTokenCreate(text,'\n',&token);
    235:     PetscTokenFind(token,&subtext);
    236:     while (subtext) {
    237:       PetscImageDrawText(img,xx,yy,c,subtext);
    238:       yy += PetscImageFontHeight;
    239:       PetscTokenFind(token,&subtext);
    240:     }
    241:     PetscTokenDestroy(&token);
    242:   }
    243:   return(0);
    244: }

    246: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
    247: {
    248:   PetscImage img = (PetscImage)draw->data;
    250:   PetscDrawValidColor(c);
    251:   {
    252:     char chr[2] = {0, 0};
    253:     int  xx = XTRANS(draw,img,x);
    254:     int  yy = YTRANS(draw,img,y);
    255:     int  offset = PetscImageFontHeight;
    256:     while ((chr[0] = *text++)) {
    257:       PetscImageDrawText(img,xx,yy+offset,c,chr);
    258:       yy += PetscImageFontHeight;
    259:     }
    260:   }
    261:   return(0);
    262: }

    264: /*
    265: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
    266: {
    268:   if (w) *w = 0;
    269:   if (h) *h = 0;
    270:   return(0);
    271: */
    272: #define PetscDrawStringBoxed_Image NULL

    274: /*
    275: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
    276: {
    278:   return(0);
    279: }*/
    280: #define PetscDrawFlush_Image NULL

    282: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
    283: {
    284:   PetscImage     img = (PetscImage)draw->data;
    286:   {
    287:     PetscImageClear(img);
    288:   }
    289:   return(0);
    290: }

    292: /*
    293: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
    294: {
    296:   return(0);
    297: }*/
    298: #define PetscDrawSetDoubleBuffer_Image NULL

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

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

    316: /*
    317: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
    318: {
    320:   return(0);
    321: }*/
    322: #define PetscDrawSetTitle_Image NULL

    324: /*
    325: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
    326: {
    328:   return(0);
    329: }*/
    330: #define PetscDrawCheckResizedWindow_Image NULL

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

    338:   if (w == img->w && h == img->h) return(0);
    339:   PetscFree(img->buffer);

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

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

    353:   PetscDrawDestroy(&draw->popup);
    354:   PetscFree(img->buffer);
    355:   PetscFree(draw->data);
    356:   return(0);
    357: }

    359: /*
    360: static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
    361: {
    363:   return(0);
    364: }*/
    365: #define PetscDrawView_Image NULL

    367: /*
    368: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
    369: {
    371:   *button = PETSC_BUTTON_NONE;
    372:   if (x_user) *x_user = 0;
    373:   if (y_user) *y_user = 0;
    374:   if (x_phys) *x_phys = 0;
    375:   if (y_phys) *y_phys = 0;
    376:   return(0);
    377: }*/
    378: #define PetscDrawGetMouseButton_Image NULL

    380: /*
    381: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
    382: {
    384:   return(0);
    385: }*/
    386: #define PetscDrawPause_Image NULL

    388: /*
    389: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
    390: {
    392:   return(0);
    393: }*/
    394: #define PetscDrawBeginPage_Image NULL

    396: /*
    397: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
    398: {
    400:   return(0);
    401: }*/
    402: #define PetscDrawEndPage_Image NULL

    404: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
    405: {
    406:   PetscImage     pimg = (PetscImage)draw->data;
    407:   PetscImage     simg;

    411:   PetscDrawCreate(PETSC_COMM_SELF,NULL,NULL,0,0,draw->w,draw->h,sdraw);
    412:   PetscDrawSetType(*sdraw,PETSC_DRAW_IMAGE);
    413:   (*sdraw)->ops->resizewindow = NULL;
    414:   simg = (PetscImage)(*sdraw)->data;
    415:   PetscArraycpy(simg->buffer,pimg->buffer,pimg->w*pimg->h);
    416:   return(0);
    417: }

    419: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
    420: {
    421:   PetscImage     pimg = (PetscImage)draw->data;
    422:   PetscImage     simg = (PetscImage)(*sdraw)->data;

    426:   PetscArraycpy(pimg->buffer,simg->buffer,pimg->w*pimg->h);
    427:   PetscDrawDestroy(sdraw);
    428:   return(0);
    429: }

    431: /*
    432: static PetscErrorCode PetscDrawSave_Image(PetscDraw draw)
    433: {
    435:   return(0);
    436: }*/
    437: #define PetscDrawSave_Image NULL

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

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

    465: static struct _PetscDrawOps DvOps = {
    466:   PetscDrawSetDoubleBuffer_Image,
    467:   PetscDrawFlush_Image,
    468:   PetscDrawLine_Image,
    469:   PetscDrawLineSetWidth_Image,
    470:   PetscDrawLineGetWidth_Image,
    471:   PetscDrawPoint_Image,
    472:   PetscDrawPointSetSize_Image,
    473:   PetscDrawString_Image,
    474:   PetscDrawStringVertical_Image,
    475:   PetscDrawStringSetSize_Image,
    476:   PetscDrawStringGetSize_Image,
    477:   PetscDrawSetViewport_Image,
    478:   PetscDrawClear_Image,
    479:   PetscDrawRectangle_Image,
    480:   PetscDrawTriangle_Image,
    481:   PetscDrawEllipse_Image,
    482:   PetscDrawGetMouseButton_Image,
    483:   PetscDrawPause_Image,
    484:   PetscDrawBeginPage_Image,
    485:   PetscDrawEndPage_Image,
    486:   PetscDrawGetPopup_Image,
    487:   PetscDrawSetTitle_Image,
    488:   PetscDrawCheckResizedWindow_Image,
    489:   PetscDrawResizeWindow_Image,
    490:   PetscDrawDestroy_Image,
    491:   PetscDrawView_Image,
    492:   PetscDrawGetSingleton_Image,
    493:   PetscDrawRestoreSingleton_Image,
    494:   PetscDrawSave_Image,
    495:   PetscDrawGetImage_Image,
    496:   PetscDrawSetCoordinates_Image,
    497:   PetscDrawArrow_Image,
    498:   PetscDrawCoordinateToPixel_Image,
    499:   PetscDrawPixelToCoordinate_Image,
    500:   PetscDrawPointPixel_Image,
    501:   PetscDrawStringBoxed_Image
    502: };

    504: static const unsigned char BasicColors[PETSC_DRAW_BASIC_COLORS][3] = {
    505:   { 255, 255, 255 }, /* white */
    506:   {   0,   0,   0 }, /* black */
    507:   { 255,   0,   0 }, /* red */
    508:   {   0, 255,   0 }, /* green */
    509:   {   0, 255, 255 }, /* cyan */
    510:   {   0,   0, 255 }, /* blue */
    511:   { 255,   0, 255 }, /* magenta */
    512:   { 127, 255, 212 }, /* aquamarine */
    513:   {  34, 139,  34 }, /* forestgreen */
    514:   { 255, 165,   0 }, /* orange */
    515:   { 238, 130, 238 }, /* violet */
    516:   { 165,  42,  42 }, /* brown */
    517:   { 255, 192, 203 }, /* pink */
    518:   { 255, 127,  80 }, /* coral */
    519:   { 190, 190, 190 }, /* gray */
    520:   { 255, 255,   0 }, /* yellow */
    521:   { 255, 215,   0 }, /* gold */
    522:   { 255, 182, 193 }, /* lightpink */
    523:   {  72, 209, 204 }, /* mediumturquoise */
    524:   { 240, 230, 140 }, /* khaki */
    525:   { 105, 105, 105 }, /* dimgray */
    526:   {  54, 205,  50 }, /* yellowgreen */
    527:   { 135, 206, 235 }, /* skyblue */
    528:   {   0, 100,   0 }, /* darkgreen */
    529:   {   0,   0, 128 }, /* navyblue */
    530:   { 244, 164,  96 }, /* sandybrown */
    531:   {  95, 158, 160 }, /* cadetblue */
    532:   { 176, 224, 230 }, /* powderblue */
    533:   { 255,  20, 147 }, /* deeppink */
    534:   { 216, 191, 216 }, /* thistle */
    535:   {  50, 205,  50 }, /* limegreen */
    536:   { 255, 240, 245 }, /* lavenderblush */
    537:   { 221, 160, 221 }, /* plum */
    538: };

    541: /*MC
    542:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

    544:    Options Database Keys:
    545: .  -draw_size w,h - size of image in pixels

    547:    Level: beginner

    549: .seealso:  PetscDrawOpenImage(), PetscDrawSetFromOptions()
    550: M*/
    551: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);

    553: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
    554: {
    555:   PetscImage     img;
    556:   int            w = draw->w, h = draw->h;
    557:   PetscInt       size[2], nsize = 2;
    558:   PetscBool      set;

    562:   draw->pause   = 0;
    563:   draw->coor_xl = 0; draw->coor_xr = 1;
    564:   draw->coor_yl = 0; draw->coor_yr = 1;
    565:   draw->port_xl = 0; draw->port_xr = 1;
    566:   draw->port_yl = 0; draw->port_yr = 1;

    568:   size[0] = w; if (size[0] < 1) size[0] = 300;
    569:   size[1] = h; if (size[1] < 1) size[1] = size[0];
    570:   PetscOptionsGetIntArray(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_size",size,&nsize,&set);
    571:   if (set && nsize == 1) size[1] = size[0];
    572:   if (size[0] < 1) size[0] = 300;
    573:   if (size[1] < 1) size[1] = size[0];
    574:   draw->w = w = size[0]; draw->x = 0;
    575:   draw->h = h = size[1]; draw->x = 0;

    577:   PetscNewLog(draw,&img);
    578:   PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
    579:   draw->data = (void*)img;

    581:   img->w = w; img->h = h;
    582:   PetscCalloc1((size_t)(img->w*img->h),&img->buffer);
    583:   PetscImageSetClip(img,0,0,img->w,img->h);
    584:   {
    585:     int i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
    586:     unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
    587:     unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
    588:     unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
    589:     PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);
    590:     for (k=0; k<PETSC_DRAW_BASIC_COLORS; k++) {
    591:       img->palette[k][0] = BasicColors[k][0];
    592:       img->palette[k][1] = BasicColors[k][1];
    593:       img->palette[k][2] = BasicColors[k][2];
    594:     }
    595:     for (i=0; i<ncolors; i++, k++) {
    596:       img->palette[k][0] = R[i];
    597:       img->palette[k][1] = G[i];
    598:       img->palette[k][2] = B[i];
    599:     }
    600:   }

    602:   if (!draw->savefilename) {PetscDrawSetSave(draw,draw->title);}
    603:   return(0);
    604: }

    606: /*@C
    607:    PetscDrawOpenImage - Opens an image for use with the PetscDraw routines.

    609:    Collective

    611:    Input Parameters:
    612: +  comm - the communicator that will share image
    613: -  filename - optional name of the file
    614: -  w, h - the image width and height in pixels

    616:    Output Parameters:
    617: .  draw - the drawing context.

    619:    Level: beginner

    621: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
    622: @*/
    623: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm,const char filename[],int w,int h,PetscDraw *draw)
    624: {

    628:   PetscDrawCreate(comm,NULL,NULL,0,0,w,h,draw);
    629:   PetscDrawSetType(*draw,PETSC_DRAW_IMAGE);
    630:   PetscDrawSetSave(*draw,filename);
    631:   return(0);
    632: }