Actual source code: dsave.c

petsc-3.9.4 2018-09-11
Report Typos and Errors
  1:  #include <petsc/private/drawimpl.h>

  3: PETSC_EXTERN PetscErrorCode PetscDrawImageSave(const char[],const char[],unsigned char[][3],unsigned int,unsigned int,const unsigned char[]);
  4: PETSC_EXTERN PetscErrorCode PetscDrawMovieSave(const char[],PetscInt,const char[],PetscInt,const char[]);
  5: PETSC_EXTERN PetscErrorCode PetscDrawImageCheckFormat(const char *[]);
  6: PETSC_EXTERN PetscErrorCode PetscDrawMovieCheckFormat(const char *[]);

  8: #if defined(PETSC_HAVE_SAWS)
  9: static PetscErrorCode PetscDrawSave_SAWs(PetscDraw);
 10: #endif

 12: /*@C
 13:    PetscDrawSetSave - Saves images produced in a PetscDraw into a file

 15:    Collective on PetscDraw

 17:    Input Parameter:
 18: +  draw      - the graphics context
 19: -  filename  - name of the file, if .ext then uses name of draw object plus .ext using .ext to determine the image type

 21:    Options Database Command:
 22: +  -draw_save <filename>  - filename could be name.ext or .ext (where .ext determines the type of graphics file to save, for example .png)
 23: .  -draw_save_final_image [optional filename] - saves the final image displayed in a window
 24: -  -draw_save_single_file - saves each new image in the same file, normally each new image is saved in a new file with filename/filename_%d.ext

 26:    Level: intermediate

 28:    Concepts: X windows^graphics

 30:    Notes: You should call this BEFORE creating your image and calling PetscDrawSave().
 31:    The supported image types are .png, .gif, .jpg, and .ppm (PETSc chooses the default in that order).
 32:    Support for .png images requires configure --with-libpng.
 33:    Support for .gif images requires configure --with-giflib.
 34:    Support for .jpg images requires configure --with-libjpeg.
 35:    Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).

 37: .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawSetSaveFinalImage()
 38: @*/
 39: PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char filename[])
 40: {
 41:   const char     *savename = NULL;
 42:   const char     *imageext = NULL;
 43:   char           buf[PETSC_MAX_PATH_LEN];


 50:   /* determine save filename and image extension */
 51:   if (filename && filename[0]) {
 52:     PetscStrchr(filename,'.',(char **)&imageext);
 53:     if (!imageext) savename = filename;
 54:     else if (imageext != filename) {
 55:       size_t l1 = 0,l2 = 0;
 56:       PetscStrlen(filename,&l1);
 57:       PetscStrlen(imageext,&l2);
 58:       PetscStrncpy(buf,filename,l1-l2+1);
 59:       savename = buf;
 60:     }
 61:   }

 63:   if (!savename) {PetscObjectGetName((PetscObject)draw,&savename);}
 64:   PetscDrawImageCheckFormat(&imageext);

 66:   draw->savefilecount = 0;
 67:   PetscFree(draw->savefilename);
 68:   PetscFree(draw->saveimageext);
 69:   PetscStrallocpy(savename,&draw->savefilename);
 70:   PetscStrallocpy(imageext,&draw->saveimageext);

 72:   if (draw->savesinglefile) {
 73:     PetscInfo2(NULL,"Will save image to file %s%s\n",draw->savefilename,draw->saveimageext);
 74:   } else {
 75:     PetscInfo3(NULL,"Will save images to file %s/%s_%%d%s\n",draw->savefilename,draw->savefilename,draw->saveimageext);
 76:   }
 77:   return(0);
 78: }

 80: /*@C
 81:    PetscDrawSetSaveMovie - Saves a movie produced from a PetscDraw into a file

 83:    Collective on PetscDraw

 85:    Input Parameter:
 86: +  draw      - the graphics context
 87: -  movieext  - optional extension defining the movie format

 89:    Options Database Command:
 90: .  -draw_save_movie <.ext> - saves a movie with extension .ext

 92:    Level: intermediate

 94:    Concepts: X windows^graphics

 96:    Notes: You should call this AFTER calling PetscDrawSetSave() and BEFORE creating your image with PetscDrawSave().
 97:    The ffmpeg utility must be in your path to make the movie.

 99: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
100: @*/
101: PetscErrorCode  PetscDrawSetSaveMovie(PetscDraw draw,const char movieext[])
102: {



110:   if (!draw->savefilename) {PetscDrawSetSave(draw,"");}
111:   PetscDrawMovieCheckFormat(&movieext);
112:   PetscStrallocpy(movieext,&draw->savemovieext);
113:   draw->savesinglefile = PETSC_FALSE; /* otherwise we cannot generage movies */

115:   PetscInfo2(NULL,"Will save movie to file %s%s\n",draw->savefilename,draw->savemovieext);
116:   return(0);
117: }

119: /*@C
120:    PetscDrawSetSaveFinalImage - Saves the final image produced in a PetscDraw into a file

122:    Collective on PetscDraw

124:    Input Parameter:
125: +  draw      - the graphics context
126: -  filename  - name of the file, if NULL or empty uses name set with PetscDrawSetSave() or name of draw object

128:    Options Database Command:
129: .  -draw_save_final_image  <filename> - filename could be name.ext or .ext (where .ext determines the type of graphics file to save, for example .png)

131:    Level: intermediate

133:    Concepts: X windows^graphics

135:    Notes: You should call this BEFORE creating your image and calling PetscDrawSave().
136:    The supported image types are .png, .gif, and .ppm (PETSc chooses the default in that order).
137:    Support for .png images requires configure --with-libpng.
138:    Support for .gif images requires configure --with-giflib.
139:    Support for .jpg images requires configure --with-libjpeg.
140:    Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).

142: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
143: @*/
144: PetscErrorCode  PetscDrawSetSaveFinalImage(PetscDraw draw,const char filename[])
145: {
146:   char           buf[PETSC_MAX_PATH_LEN];

151:   if (!filename || !filename[0]) {
152:     if (!draw->savefilename) {
153:       PetscObjectGetName((PetscObject)draw,&filename);
154:     } else {
155:       PetscSNPrintf(buf,sizeof(buf),"%s%s",draw->savefilename,draw->saveimageext);
156:       filename = buf;
157:     }
158:   }
159:   PetscFree(draw->savefinalfilename);
160:   PetscStrallocpy(filename,&draw->savefinalfilename);
161:   return(0);
162: }

164: /*@
165:    PetscDrawSave - Saves a drawn image

167:    Collective on PetscDraw

169:    Input Parameters:
170: .  draw - the drawing context

172:    Level: advanced

174:    Notes: this is not normally called by the user.

176: .seealso: PetscDrawSetSave()

178: @*/
179: PetscErrorCode  PetscDrawSave(PetscDraw draw)
180: {
181:   PetscInt       saveindex;
182:   char           basename[PETSC_MAX_PATH_LEN];
183:   unsigned char  palette[256][3];
184:   unsigned int   w,h;
185:   unsigned char  *pixels = NULL;
186:   PetscMPIInt    rank;

191:   if (!draw->ops->save && !draw->ops->getimage) return(0);
192:   if (draw->ops->save) {(*draw->ops->save)(draw); goto finally;}
193:   if (!draw->savefilename || !draw->saveimageext) return(0);
194:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);

196:   saveindex = draw->savefilecount++;

198:   if (!rank && !saveindex) {
199:     char path[PETSC_MAX_PATH_LEN];
200:     if (draw->savesinglefile) {
201:       PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->saveimageext);
202:       (void)remove(path);
203:     } else {
204:       PetscSNPrintf(path,sizeof(path),"%s",draw->savefilename);
205:       PetscRMTree(path);
206:       PetscMkdir(path);
207:     }
208:     if (draw->savemovieext) {
209:       PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->savemovieext);
210:       (void)remove(path);
211:     }
212:   }
213:   if (draw->savesinglefile) {
214:     PetscSNPrintf(basename,sizeof(basename),"%s",draw->savefilename);
215:   } else {
216:     PetscSNPrintf(basename,sizeof(basename),"%s/%s_%d",draw->savefilename,draw->savefilename,(int)saveindex);
217:   }

219:   /* this call is collective, only the first process gets the image data */
220:   (*draw->ops->getimage)(draw,palette,&w,&h,&pixels);
221:   /* only the first process handles the saving business */
222:   if (!rank) {PetscDrawImageSave(basename,draw->saveimageext,palette,w,h,pixels);}
223:   PetscFree(pixels);
224:   MPI_Barrier(PetscObjectComm((PetscObject)draw));

226: finally:
227: #if defined(PETSC_HAVE_SAWS)
228:   PetscDrawSave_SAWs(draw);
229: #endif
230:   return(0);
231: }

233: /*@
234:    PetscDrawSaveMovie - Saves a movie from previously saved images

236:    Collective on PetscDraw

238:    Input Parameters:
239: .  draw - the drawing context

241:    Level: advanced

243:    Notes: this is not normally called by the user.
244:    The ffmpeg utility must be in your path to make the movie.

246: .seealso: PetscDrawSetSave(), PetscDrawSetSaveMovie()

248: @*/
249: PetscErrorCode PetscDrawSaveMovie(PetscDraw draw)
250: {
251:   PetscMPIInt    rank;

256:   if (!draw->ops->save && !draw->ops->getimage) return(0);
257:   if (!draw->savefilename || !draw->savemovieext || draw->savesinglefile) return(0);
258:   MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
259:   {
260:     const char *fname = draw->savefilename;
261:     const char *imext = draw->saveimageext;
262:     const char *mvext = draw->savemovieext;
263:     if (!rank) {PetscDrawMovieSave(fname,draw->savefilecount,imext,draw->savemoviefps,mvext);}
264:     MPI_Barrier(PetscObjectComm((PetscObject)draw));
265:   }
266:   return(0);
267: }


270: #if defined(PETSC_HAVE_SAWS)
271:  #include <petscviewersaws.h>
272: /*
273:   The PetscImageList object and functions are used to maintain a list of file images
274:   that can be displayed by the SAWs webserver.
275: */
276: typedef struct _P_PetscImageList *PetscImageList;
277: struct _P_PetscImageList {
278:   PetscImageList next;
279:   char           *filename;
280:   char           *ext;
281:   PetscInt       count;
282: } ;

284: static PetscImageList SAWs_images = NULL;

286: static PetscErrorCode PetscImageListDestroy(void)
287: {
289:   PetscImageList image = SAWs_images;

292:   while (image) {
293:     PetscImageList next = image->next;
294:     PetscFree(image->filename);
295:     PetscFree(image->ext);
296:     PetscFree(image);
297:     image = next;
298:   }
299:   return(0);
300: }

302: static PetscErrorCode PetscImageListAdd(const char filename[],const char ext[],PetscInt count)
303: {
304:   PetscErrorCode  ierr;
305:   PetscImageList  image,oimage = SAWs_images;
306:   PetscBool       flg;

309:   if (oimage) {
310:     PetscStrcmp(filename,oimage->filename,&flg);
311:     if (flg) {
312:       oimage->count = count;
313:       return(0);
314:     }
315:     while (oimage->next) {
316:       oimage = oimage->next;
317:       PetscStrcmp(filename,oimage->filename,&flg);
318:       if (flg) {
319:         oimage->count = count;
320:         return(0);
321:       }
322:     }
323:     PetscNew(&image);
324:     oimage->next = image;
325:   } else {
326:     PetscRegisterFinalize(PetscImageListDestroy);
327:     PetscNew(&image);
328:     SAWs_images = image;
329:   }
330:   PetscStrallocpy(filename,&image->filename);
331:   PetscStrallocpy(ext,&image->ext);
332:   image->count = count;
333:   return(0);
334: }

336: static PetscErrorCode PetscDrawSave_SAWs(PetscDraw draw)
337: {
338:   PetscImageList image;
339:   char           body[4096];
340:   size_t         len = 0;

344:   if (!draw->savefilename || !draw->saveimageext) return(0);
345:   PetscImageListAdd(draw->savefilename,draw->saveimageext,draw->savefilecount-1);
346:   image = SAWs_images;
347:   while (image) {
348:     const char *name = image->filename;
349:     const char *ext  = image->ext;
350:     if (draw->savesinglefile) {
351:       PetscSNPrintf(body+len,4086-len,"<img src=\"%s%s\" alt=\"None\">",name,ext);
352:     } else {
353:       PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s_%d%s\" alt=\"None\">",name,name,image->count,ext);
354:     }
355:     PetscStrlen(body,&len);
356:     image = image->next;
357:   }
358:   PetscStrlcat(body,"<br>\n",sizeof(body));
359:   if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
360:   PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
361:   return(0);
362: }

364: #endif