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)
  6: #else
  7: #define PetscDrawValidColor(color) do {} while (0)
  8: #endif

 10: #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)))))
 11: #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)))))

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

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

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

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

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

 51: /*
 52: static PetscErrorCode PetscDrawPointSetSize_Image(PetscDraw draw,PetscReal width)
 53: {
 54:   return 0;
 55: }*/
 56: #define PetscDrawPointSetSize_Image NULL

 58: static PetscErrorCode PetscDrawPoint_Image(PetscDraw draw,PetscReal x,PetscReal y,int c)
 59: {
 60:   PetscImage img = (PetscImage)draw->data;
 61:   PetscDrawValidColor(c);
 62:   {
 63:     int j, xx = XTRANS(draw,img,x);
 64:     int i, yy = YTRANS(draw,img,y);
 65:     for (i=-1; i<=1; i++)
 66:       for (j=-1; j<=1; j++)
 67:         PetscImageDrawPixel(img,xx+j,yy+i,c);
 68:   }
 69:   return 0;
 70: }

 72: static PetscErrorCode PetscDrawPointPixel_Image(PetscDraw draw,int x,int y,int c)
 73: {
 74:   PetscImage img = (PetscImage)draw->data;
 75:   PetscDrawValidColor(c);
 76:   {
 77:     PetscImageDrawPixel(img,x,y,c);
 78:   }
 79:   return 0;
 80: }

 82: /*
 83: static PetscErrorCode PetscDrawLineSetWidth_Image(PetscDraw draw,PetscReal width)
 84: {
 85:   return 0;
 86: }*/
 87: #define PetscDrawLineSetWidth_Image NULL

 89: static PetscErrorCode PetscDrawLineGetWidth_Image(PetscDraw draw,PetscReal *width)
 90: {
 91:   PetscImage img = (PetscImage)draw->data;
 92:   {
 93:     int lw = 1;
 94:     *width = lw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
 95:   }
 96:   return 0;
 97: }

 99: static PetscErrorCode PetscDrawLine_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
100: {
101:   PetscImage img = (PetscImage)draw->data;
102:   {
103:     int x_1 = XTRANS(draw,img,xl), x_2 = XTRANS(draw,img,xr);
104:     int y_1 = YTRANS(draw,img,yl), y_2 = YTRANS(draw,img,yr);
105:     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
106:   }
107:   return 0;
108: }

110: static PetscErrorCode PetscDrawArrow_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c)
111: {
112:   PetscImage img = (PetscImage)draw->data;
113:   PetscDrawValidColor(c);
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:     if (x_1 == x_2 && y_1 == y_2) return 0;
118:     PetscImageDrawLine(img,x_1,y_1,x_2,y_2,c);
119:     if (x_1 == x_2 && PetscAbs(y_1 - y_2) > 7) {
120:       if (y_2 > y_1) {
121:         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2-3,c);
122:         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2-3,c);
123:       } else {
124:         PetscImageDrawLine(img,x_2,y_2,x_2-3,y_2+3,c);
125:         PetscImageDrawLine(img,x_2,y_2,x_2+3,y_2+3,c);
126:       }
127:     }
128:     if (y_1 == y_2 && PetscAbs(x_1 - x_2) > 7) {
129:       if (x_2 > x_1) {
130:         PetscImageDrawLine(img,x_2-3,y_2-3,x_2,y_2,c);
131:         PetscImageDrawLine(img,x_2-3,y_2+3,x_2,y_2,c);
132:       } else {
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:       }
136:     }
137:    }
138:   return 0;
139: }

141: static PetscErrorCode PetscDrawRectangle_Image(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
142: {
143:   PetscImage img = (PetscImage)draw->data;
144:   PetscDrawValidColor(c1);
145:   PetscDrawValidColor(c2);
146:   PetscDrawValidColor(c3);
147:   PetscDrawValidColor(c4);
148:   {
149:     int x = XTRANS(draw,img,xl), w = XTRANS(draw,img,xr) + 1 - x;
150:     int y = YTRANS(draw,img,yr), h = YTRANS(draw,img,yl) + 1 - y;
151:     int c  = (c1 + c2 + c3 + c4)/4;
152:     PetscImageDrawRectangle(img,x,y,w,h,c);
153:   }
154:   return 0;
155: }

157: static PetscErrorCode PetscDrawEllipse_Image(PetscDraw draw,PetscReal x,PetscReal y,PetscReal a,PetscReal b,int c)
158: {
159:   PetscImage img = (PetscImage)draw->data;
160:   PetscDrawValidColor(c);
161:   a = PetscAbsReal(a);
162:   b = PetscAbsReal(b);
163:   {
164:     int xc = XTRANS(draw,img,x), w = XTRANS(draw,img,x + a/2) + 0 - xc;
165:     int yc = YTRANS(draw,img,y), h = YTRANS(draw,img,y - b/2) + 0 - yc;
166:     if (PetscAbsReal(a-b) <= 0)  w = h = PetscMin(w,h); /* workaround truncation errors */
167:     PetscImageDrawEllipse(img,xc,yc,w,h,c);
168:   }
169:   return 0;
170: }

172: 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)
173: {
174:   PetscImage img = (PetscImage)draw->data;
175:   PetscDrawValidColor(c1);
176:   PetscDrawValidColor(c2);
177:   PetscDrawValidColor(c3);
178:   {
179:     int x_1 = XTRANS(draw,img,X_1), x_2 = XTRANS(draw,img,X_2), x_3 = XTRANS(draw,img,X_3);
180:     int y_1 = YTRANS(draw,img,Y_1), y_2 = YTRANS(draw,img,Y_2), y_3 = YTRANS(draw,img,Y_3);
181:     PetscImageDrawTriangle(img,x_1,y_1,c1,x_2,y_2,c2,x_3,y_3,c3);
182:   }
183:   return 0;
184: }

186: /*
187: static PetscErrorCode PetscDrawStringSetSize_Image(PetscDraw draw,PetscReal w,PetscReal h)
188: {
189:   return 0;
190: }*/
191: #define PetscDrawStringSetSize_Image NULL

193: static PetscErrorCode PetscDrawStringGetSize_Image(PetscDraw draw,PetscReal *w,PetscReal  *h)
194: {
195:   PetscImage img = (PetscImage)draw->data;
196:   {
197:     int tw = PetscImageFontWidth;
198:     int th = PetscImageFontHeight;
199:     if (w) *w = tw*(draw->coor_xr - draw->coor_xl)/(img->w*(draw->port_xr - draw->port_xl));
200:     if (h) *h = th*(draw->coor_yr - draw->coor_yl)/(img->h*(draw->port_yr - draw->port_yl));
201:   }
202:   return 0;
203: }

205: static PetscErrorCode PetscDrawString_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
206: {
207:   PetscImage     img = (PetscImage)draw->data;
208:   PetscToken     token;
209:   char           *subtext;
210:   PetscDrawValidColor(c);
211:   {
212:     int xx = XTRANS(draw,img,x);
213:     int yy = YTRANS(draw,img,y);
214:     PetscTokenCreate(text,'\n',&token);
215:     PetscTokenFind(token,&subtext);
216:     while (subtext) {
217:       PetscImageDrawText(img,xx,yy,c,subtext);
218:       yy += PetscImageFontHeight;
219:       PetscTokenFind(token,&subtext);
220:     }
221:     PetscTokenDestroy(&token);
222:   }
223:   return 0;
224: }

226: static PetscErrorCode PetscDrawStringVertical_Image(PetscDraw draw,PetscReal x,PetscReal y,int c,const char text[])
227: {
228:   PetscImage img = (PetscImage)draw->data;
229:   PetscDrawValidColor(c);
230:   {
231:     char chr[2] = {0, 0};
232:     int  xx = XTRANS(draw,img,x);
233:     int  yy = YTRANS(draw,img,y);
234:     int  offset = PetscImageFontHeight;
235:     while ((chr[0] = *text++)) {
236:       PetscImageDrawText(img,xx,yy+offset,c,chr);
237:       yy += PetscImageFontHeight;
238:     }
239:   }
240:   return 0;
241: }

243: /*
244: static PetscErrorCode PetscDrawStringBoxed_Image(PetscDraw draw,PetscReal sxl,PetscReal syl,int sc,int bc,const char text[],PetscReal *w,PetscReal *h)
245: {
246:   if (w) *w = 0;
247:   if (h) *h = 0;
248:   return 0;
249: */
250: #define PetscDrawStringBoxed_Image NULL

252: /*
253: static PetscErrorCode PetscDrawFlush_Image(PetscDraw draw)
254: {
255:   return 0;
256: }*/
257: #define PetscDrawFlush_Image NULL

259: static PetscErrorCode PetscDrawClear_Image(PetscDraw draw)
260: {
261:   PetscImage     img = (PetscImage)draw->data;
262:   {
263:     PetscImageClear(img);
264:   }
265:   return 0;
266: }

268: /*
269: static PetscErrorCode PetscDrawSetDoubleBuffer_Image(PetscDraw draw)
270: {
271:   return 0;
272: }*/
273: #define PetscDrawSetDoubleBuffer_Image NULL

275: static PetscErrorCode PetscDrawGetPopup_Image(PetscDraw draw,PetscDraw *popup)
276: {
277:   PetscBool      flg = PETSC_FALSE;

279:   PetscOptionsGetBool(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_popup",&flg,NULL);
280:   if (!flg) {*popup = NULL; return 0;}
281:   PetscDrawCreate(PetscObjectComm((PetscObject)draw),NULL,NULL,0,0,220,220,popup);
282:   PetscDrawSetType(*popup,PETSC_DRAW_IMAGE);
283:   PetscObjectSetOptionsPrefix((PetscObject)*popup,"popup_");
284:   PetscObjectAppendOptionsPrefix((PetscObject)*popup,((PetscObject)draw)->prefix);
285:   draw->popup = *popup;
286:   return 0;
287: }

289: /*
290: static PetscErrorCode PetscDrawSetTitle_Image(PetscDraw draw,const char title[])
291: {
292:   return 0;
293: }*/
294: #define PetscDrawSetTitle_Image NULL

296: /*
297: static PetscErrorCode PetscDrawCheckResizedWindow_Image(PetscDraw draw)
298: {
299:   return 0;
300: }*/
301: #define PetscDrawCheckResizedWindow_Image NULL

303: static PetscErrorCode PetscDrawResizeWindow_Image(PetscDraw draw,int w,int h)
304: {
305:   PetscImage     img = (PetscImage)draw->data;

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

310:   img->w = w; img->h = h;
311:   PetscCalloc1((size_t)(img->w*img->h),&img->buffer);
312:   PetscDrawSetViewport_Image(draw,draw->port_xl,draw->port_yl,draw->port_xr,draw->port_yr);
313:   return 0;
314: }

316: static PetscErrorCode PetscDrawDestroy_Image(PetscDraw draw)
317: {
318:   PetscImage     img = (PetscImage)draw->data;

320:   PetscDrawDestroy(&draw->popup);
321:   PetscFree(img->buffer);
322:   PetscFree(draw->data);
323:   return 0;
324: }

326: /*
327: static PetscErrorCode PetscDrawView_Image(PetscDraw draw,PetscViewer viewer)
328: {
329:   return 0;
330: }*/
331: #define PetscDrawView_Image NULL

333: /*
334: static PetscErrorCode PetscDrawGetMouseButton_Image(PetscDraw draw,PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
335: {
336:   *button = PETSC_BUTTON_NONE;
337:   if (x_user) *x_user = 0;
338:   if (y_user) *y_user = 0;
339:   if (x_phys) *x_phys = 0;
340:   if (y_phys) *y_phys = 0;
341:   return 0;
342: }*/
343: #define PetscDrawGetMouseButton_Image NULL

345: /*
346: static PetscErrorCode PetscDrawPause_Image(PetscDraw draw)
347: {
348:   return 0;
349: }*/
350: #define PetscDrawPause_Image NULL

352: /*
353: static PetscErrorCode PetscDrawBeginPage_Image(PetscDraw draw)
354: {
355:   return 0;
356: }*/
357: #define PetscDrawBeginPage_Image NULL

359: /*
360: static PetscErrorCode PetscDrawEndPage_Image(PetscDraw draw)
361: {
362:   return 0;
363: }*/
364: #define PetscDrawEndPage_Image NULL

366: static PetscErrorCode PetscDrawGetSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
367: {
368:   PetscImage     pimg = (PetscImage)draw->data;
369:   PetscImage     simg;

371:   PetscDrawCreate(PETSC_COMM_SELF,NULL,NULL,0,0,draw->w,draw->h,sdraw);
372:   PetscDrawSetType(*sdraw,PETSC_DRAW_IMAGE);
373:   (*sdraw)->ops->resizewindow = NULL;
374:   simg = (PetscImage)(*sdraw)->data;
375:   PetscArraycpy(simg->buffer,pimg->buffer,pimg->w*pimg->h);
376:   return 0;
377: }

379: static PetscErrorCode PetscDrawRestoreSingleton_Image(PetscDraw draw,PetscDraw *sdraw)
380: {
381:   PetscImage     pimg = (PetscImage)draw->data;
382:   PetscImage     simg = (PetscImage)(*sdraw)->data;

384:   PetscArraycpy(pimg->buffer,simg->buffer,pimg->w*pimg->h);
385:   PetscDrawDestroy(sdraw);
386:   return 0;
387: }

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

396: static PetscErrorCode PetscDrawGetImage_Image(PetscDraw draw,unsigned char palette[256][3],unsigned int *w,unsigned int *h,unsigned char *pixels[])
397: {
398:   PetscImage     img = (PetscImage)draw->data;
399:   unsigned char  *buffer = NULL;
400:   PetscMPIInt    rank,size;

402:   if (w) *w = (unsigned int)img->w;
403:   if (h) *h = (unsigned int)img->h;
404:   if (pixels) *pixels = NULL;
405:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
406:   if (rank == 0) {
407:     PetscMemcpy(palette,img->palette,sizeof(img->palette));
408:     PetscMalloc1((size_t)(img->w*img->h),&buffer);
409:     if (pixels) *pixels = buffer;
410:   }
411:   MPI_Comm_size(PetscObjectComm((PetscObject)draw),&size);
412:   if (size == 1) {
413:     PetscArraycpy(buffer,img->buffer,img->w*img->h);
414:   } else {
415:     MPI_Reduce(img->buffer,buffer,img->w*img->h,MPI_UNSIGNED_CHAR,MPI_MAX,0,PetscObjectComm((PetscObject)draw));
416:   }
417:   return 0;
418: }

420: static struct _PetscDrawOps DvOps = {
421:   PetscDrawSetDoubleBuffer_Image,
422:   PetscDrawFlush_Image,
423:   PetscDrawLine_Image,
424:   PetscDrawLineSetWidth_Image,
425:   PetscDrawLineGetWidth_Image,
426:   PetscDrawPoint_Image,
427:   PetscDrawPointSetSize_Image,
428:   PetscDrawString_Image,
429:   PetscDrawStringVertical_Image,
430:   PetscDrawStringSetSize_Image,
431:   PetscDrawStringGetSize_Image,
432:   PetscDrawSetViewport_Image,
433:   PetscDrawClear_Image,
434:   PetscDrawRectangle_Image,
435:   PetscDrawTriangle_Image,
436:   PetscDrawEllipse_Image,
437:   PetscDrawGetMouseButton_Image,
438:   PetscDrawPause_Image,
439:   PetscDrawBeginPage_Image,
440:   PetscDrawEndPage_Image,
441:   PetscDrawGetPopup_Image,
442:   PetscDrawSetTitle_Image,
443:   PetscDrawCheckResizedWindow_Image,
444:   PetscDrawResizeWindow_Image,
445:   PetscDrawDestroy_Image,
446:   PetscDrawView_Image,
447:   PetscDrawGetSingleton_Image,
448:   PetscDrawRestoreSingleton_Image,
449:   PetscDrawSave_Image,
450:   PetscDrawGetImage_Image,
451:   PetscDrawSetCoordinates_Image,
452:   PetscDrawArrow_Image,
453:   PetscDrawCoordinateToPixel_Image,
454:   PetscDrawPixelToCoordinate_Image,
455:   PetscDrawPointPixel_Image,
456:   PetscDrawStringBoxed_Image
457: };

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

495: /*MC
496:    PETSC_DRAW_IMAGE - PETSc graphics device that uses a raster buffer

498:    Options Database Keys:
499: .  -draw_size w,h - size of image in pixels

501:    Level: beginner

503: .seealso:  PetscDrawOpenImage(), PetscDrawSetFromOptions()
504: M*/
505: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw);

507: PETSC_EXTERN PetscErrorCode PetscDrawCreate_Image(PetscDraw draw)
508: {
509:   PetscImage     img;
510:   int            w = draw->w, h = draw->h;
511:   PetscInt       size[2], nsize = 2;
512:   PetscBool      set;

514:   draw->pause   = 0;
515:   draw->coor_xl = 0; draw->coor_xr = 1;
516:   draw->coor_yl = 0; draw->coor_yr = 1;
517:   draw->port_xl = 0; draw->port_xr = 1;
518:   draw->port_yl = 0; draw->port_yr = 1;

520:   size[0] = w; if (size[0] < 1) size[0] = 300;
521:   size[1] = h; if (size[1] < 1) size[1] = size[0];
522:   PetscOptionsGetIntArray(((PetscObject)draw)->options,((PetscObject)draw)->prefix,"-draw_size",size,&nsize,&set);
523:   if (set && nsize == 1) size[1] = size[0];
524:   if (size[0] < 1) size[0] = 300;
525:   if (size[1] < 1) size[1] = size[0];
526:   draw->w = w = size[0]; draw->x = 0;
527:   draw->h = h = size[1]; draw->x = 0;

529:   PetscNewLog(draw,&img);
530:   PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));
531:   draw->data = (void*)img;

533:   img->w = w; img->h = h;
534:   PetscCalloc1((size_t)(img->w*img->h),&img->buffer);
535:   PetscImageSetClip(img,0,0,img->w,img->h);
536:   {
537:     int i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
538:     unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
539:     unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
540:     unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
541:     PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);
542:     for (k=0; k<PETSC_DRAW_BASIC_COLORS; k++) {
543:       img->palette[k][0] = BasicColors[k][0];
544:       img->palette[k][1] = BasicColors[k][1];
545:       img->palette[k][2] = BasicColors[k][2];
546:     }
547:     for (i=0; i<ncolors; i++, k++) {
548:       img->palette[k][0] = R[i];
549:       img->palette[k][1] = G[i];
550:       img->palette[k][2] = B[i];
551:     }
552:   }

554:   if (!draw->savefilename) PetscDrawSetSave(draw,draw->title);
555:   return 0;
556: }

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

561:    Collective

563:    Input Parameters:
564: +  comm - the communicator that will share image
565: -  filename - optional name of the file
566: -  w, h - the image width and height in pixels

568:    Output Parameters:
569: .  draw - the drawing context.

571:    Level: beginner

573: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
574: @*/
575: PetscErrorCode PetscDrawOpenImage(MPI_Comm comm,const char filename[],int w,int h,PetscDraw *draw)
576: {
577:   PetscDrawCreate(comm,NULL,NULL,0,0,w,h,draw);
578:   PetscDrawSetType(*draw,PETSC_DRAW_IMAGE);
579:   PetscDrawSetSave(*draw,filename);
580:   return 0;
581: }