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

 17: static PetscErrorCode PetscDrawSetViewport_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
 18: {
 19:   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: {
 34:   return(0);
 35: }*/
 36: #define PetscDrawSetCoordinates_Image NULL

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

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

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

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

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

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

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

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

121: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
122: {
123:   PetscImage img = (PetscImage)draw->data;
125:   PetscDrawValidColor(c);
126:   {
127:     int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
128:     int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
129:     if (x_1 == x_2 && y_1 == y_2) return(0);
130:     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
131:     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
132:       if (y_2 > y_1) {
133:         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2-3,c);
134:         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
135:       } else {
136:         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2+3,c);
137:         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
138:       }
139:     }
140:     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
141:       if (x_2 > x_1) {
142:         PetscImageDrawLine(img,x_2-3,y_2-3,x_2,y_2,c);
143:         PetscImageDrawLine(img,x_2-3,y_2+3,x_2,y_2,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:    }
150:   return(0);
151: }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

539: /*MC
540:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

542:    Options Database Keys:
543: .  -draw_size w,h - size of image in pixels

545:    Level: beginner

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

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

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

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

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

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

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

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

607:    Collective

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

614:    Output Parameters:
615: .  draw - the drawing context.

617:    Level: beginner

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

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