xref: /petsc/src/sys/classes/draw/interface/dsave.c (revision 49c04938f39863466cdc6a3623db8e333e9909d4)
15b399a63SLisandro Dalcin #include <petsc/private/drawimpl.h>  /*I "petscdraw.h" I*/
25b399a63SLisandro Dalcin 
38067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageSave(const char[],const char[],unsigned char[][3],unsigned int,unsigned int,const unsigned char[]);
4*49c04938SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawMovieSave(const char[],PetscInt,const char[],PetscInt,const char[]);
58067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageCheckFormat(const char *[]);
68067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawMovieCheckFormat(const char *[]);
78067a7d5SLisandro Dalcin 
88067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS)
98067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawSave_SAWs(PetscDraw);
108067a7d5SLisandro Dalcin #endif
118067a7d5SLisandro Dalcin 
125b399a63SLisandro Dalcin #undef __FUNCT__
135b399a63SLisandro Dalcin #define __FUNCT__ "PetscDrawSetSave"
145b399a63SLisandro Dalcin /*@C
158067a7d5SLisandro Dalcin    PetscDrawSetSave - Saves images produced in a PetscDraw into a file
165b399a63SLisandro Dalcin 
175b399a63SLisandro Dalcin    Collective on PetscDraw
185b399a63SLisandro Dalcin 
195b399a63SLisandro Dalcin    Input Parameter:
205b399a63SLisandro Dalcin +  draw      - the graphics context
21*49c04938SLisandro Dalcin -  filename  - name of the file, if .ext then uses name of draw object plus .ext using .ext to determine the image type
225b399a63SLisandro Dalcin 
235b399a63SLisandro Dalcin    Options Database Command:
248067a7d5SLisandro Dalcin +  -draw_save <filename>  - filename could be name.ext or .ext (where .ext determines the type of graphics file to save, for example .png)
258067a7d5SLisandro Dalcin .  -draw_save_final_image [optional filename] - saves the final image displayed in a window
268067a7d5SLisandro Dalcin -  -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
275b399a63SLisandro Dalcin 
285b399a63SLisandro Dalcin    Level: intermediate
295b399a63SLisandro Dalcin 
305b399a63SLisandro Dalcin    Concepts: X windows^graphics
315b399a63SLisandro Dalcin 
328067a7d5SLisandro Dalcin    Notes: You should call this BEFORE creating your image and calling PetscDrawSave().
338067a7d5SLisandro Dalcin    The supported image types are .png, .gif, .jpg, and .ppm (PETSc chooses the default in that order).
348067a7d5SLisandro Dalcin    Support for .png images requires configure --with-libpng.
358067a7d5SLisandro Dalcin    Support for .gif images requires configure --with-giflib.
368067a7d5SLisandro Dalcin    Support for .jpg images requires configure --with-libjpeg.
378067a7d5SLisandro Dalcin    Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).
385b399a63SLisandro Dalcin 
395b399a63SLisandro Dalcin .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawSetSaveFinalImage()
405b399a63SLisandro Dalcin @*/
41*49c04938SLisandro Dalcin PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char filename[])
425b399a63SLisandro Dalcin {
438067a7d5SLisandro Dalcin   const char     *savename = NULL;
448067a7d5SLisandro Dalcin   const char     *imageext = NULL;
4571ed57bfSLisandro Dalcin   char           buf[PETSC_MAX_PATH_LEN];
465b399a63SLisandro Dalcin   PetscErrorCode ierr;
475b399a63SLisandro Dalcin 
485b399a63SLisandro Dalcin   PetscFunctionBegin;
495b399a63SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
5071ed57bfSLisandro Dalcin   if (filename) PetscValidCharPointer(filename,2);
515b399a63SLisandro Dalcin 
528067a7d5SLisandro Dalcin   /* determine save filename and image extension */
535b399a63SLisandro Dalcin   if (filename && filename[0]) {
548067a7d5SLisandro Dalcin     ierr = PetscStrchr(filename,'.',(char **)&imageext);CHKERRQ(ierr);
558067a7d5SLisandro Dalcin     if (!imageext) savename = filename;
568067a7d5SLisandro Dalcin     else if (imageext != filename) {
5771ed57bfSLisandro Dalcin       size_t l1 = 0,l2 = 0;
585b399a63SLisandro Dalcin       ierr = PetscStrlen(filename,&l1);CHKERRQ(ierr);
598067a7d5SLisandro Dalcin       ierr = PetscStrlen(imageext,&l2);CHKERRQ(ierr);
6071ed57bfSLisandro Dalcin       ierr = PetscStrncpy(buf,filename,l1-l2+1);CHKERRQ(ierr);
618067a7d5SLisandro Dalcin       savename = buf;
625b399a63SLisandro Dalcin     }
6371ed57bfSLisandro Dalcin   }
6471ed57bfSLisandro Dalcin 
658067a7d5SLisandro Dalcin   if (!savename) {ierr = PetscObjectGetName((PetscObject)draw,&savename);CHKERRQ(ierr);}
668067a7d5SLisandro Dalcin   ierr = PetscDrawImageCheckFormat(&imageext);CHKERRQ(ierr);
678067a7d5SLisandro Dalcin 
688067a7d5SLisandro Dalcin   draw->savefilecount = 0;
698067a7d5SLisandro Dalcin   ierr = PetscFree(draw->savefilename);CHKERRQ(ierr);
708067a7d5SLisandro Dalcin   ierr = PetscFree(draw->saveimageext);CHKERRQ(ierr);
718067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(savename,&draw->savefilename);CHKERRQ(ierr);
728067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(imageext,&draw->saveimageext);CHKERRQ(ierr);
73*49c04938SLisandro Dalcin 
74*49c04938SLisandro Dalcin   if (draw->savesinglefile) {
75*49c04938SLisandro Dalcin     ierr = PetscInfo2(NULL,"Will save image to file %s%s\n",draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
76*49c04938SLisandro Dalcin   } else {
77*49c04938SLisandro Dalcin     ierr = PetscInfo3(NULL,"Will save images to file %s/%s_%%d%s\n",draw->savefilename,draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
78*49c04938SLisandro Dalcin   }
79*49c04938SLisandro Dalcin   PetscFunctionReturn(0);
80*49c04938SLisandro Dalcin }
81*49c04938SLisandro Dalcin 
82*49c04938SLisandro Dalcin #undef __FUNCT__
83*49c04938SLisandro Dalcin #define __FUNCT__ "PetscDrawSetSaveMovie"
84*49c04938SLisandro Dalcin /*@C
85*49c04938SLisandro Dalcin    PetscDrawSetSaveMovie - Saves a movie produced from a PetscDraw into a file
86*49c04938SLisandro Dalcin 
87*49c04938SLisandro Dalcin    Collective on PetscDraw
88*49c04938SLisandro Dalcin 
89*49c04938SLisandro Dalcin    Input Parameter:
90*49c04938SLisandro Dalcin +  draw      - the graphics context
91*49c04938SLisandro Dalcin -  movieext  - optional extension defining the movie format
92*49c04938SLisandro Dalcin 
93*49c04938SLisandro Dalcin    Options Database Command:
94*49c04938SLisandro Dalcin .  -draw_save_movie <.ext> - saves a movie with extension .ext
95*49c04938SLisandro Dalcin 
96*49c04938SLisandro Dalcin    Level: intermediate
97*49c04938SLisandro Dalcin 
98*49c04938SLisandro Dalcin    Concepts: X windows^graphics
99*49c04938SLisandro Dalcin 
100*49c04938SLisandro Dalcin    Notes: You should call this AFTER calling PetscDrawSetSave() and BEFORE creating your image with PetscDrawSave().
101*49c04938SLisandro Dalcin    The ffmpeg utility must be in your path to make the movie.
102*49c04938SLisandro Dalcin 
103*49c04938SLisandro Dalcin .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
104*49c04938SLisandro Dalcin @*/
105*49c04938SLisandro Dalcin PetscErrorCode  PetscDrawSetSaveMovie(PetscDraw draw,const char movieext[])
106*49c04938SLisandro Dalcin {
107*49c04938SLisandro Dalcin 
108*49c04938SLisandro Dalcin   PetscErrorCode ierr;
109*49c04938SLisandro Dalcin 
110*49c04938SLisandro Dalcin   PetscFunctionBegin;
111*49c04938SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
112*49c04938SLisandro Dalcin   if (movieext) PetscValidCharPointer(movieext,2);
113*49c04938SLisandro Dalcin 
114*49c04938SLisandro Dalcin   if (!draw->savefilename) {ierr = PetscDrawSetSave(draw,"");CHKERRQ(ierr);}
115*49c04938SLisandro Dalcin   ierr = PetscDrawMovieCheckFormat(&movieext);CHKERRQ(ierr);
1168067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(movieext,&draw->savemovieext);CHKERRQ(ierr);
117*49c04938SLisandro Dalcin   draw->savesinglefile = PETSC_FALSE; /* otherwise we cannot generage movies */
118*49c04938SLisandro Dalcin 
119*49c04938SLisandro Dalcin   ierr = PetscInfo2(NULL,"Will save movie to file %s%s\n",draw->savefilename,draw->savemovieext);CHKERRQ(ierr);
1205b399a63SLisandro Dalcin   PetscFunctionReturn(0);
1215b399a63SLisandro Dalcin }
1225b399a63SLisandro Dalcin 
1235b399a63SLisandro Dalcin #undef __FUNCT__
1245b399a63SLisandro Dalcin #define __FUNCT__ "PetscDrawSetSaveFinalImage"
1255b399a63SLisandro Dalcin /*@C
1268067a7d5SLisandro Dalcin    PetscDrawSetSaveFinalImage - Saves the final image produced in a PetscDraw into a file
1275b399a63SLisandro Dalcin 
1285b399a63SLisandro Dalcin    Collective on PetscDraw
1295b399a63SLisandro Dalcin 
1305b399a63SLisandro Dalcin    Input Parameter:
1315b399a63SLisandro Dalcin +  draw      - the graphics context
1328067a7d5SLisandro Dalcin -  filename  - name of the file, if NULL or empty uses name set with PetscDrawSetSave() or name of draw object
1335b399a63SLisandro Dalcin 
1345b399a63SLisandro Dalcin    Options Database Command:
1358067a7d5SLisandro Dalcin .  -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)
1365b399a63SLisandro Dalcin 
1375b399a63SLisandro Dalcin    Level: intermediate
1385b399a63SLisandro Dalcin 
1395b399a63SLisandro Dalcin    Concepts: X windows^graphics
1405b399a63SLisandro Dalcin 
1418067a7d5SLisandro Dalcin    Notes: You should call this BEFORE creating your image and calling PetscDrawSave().
1428067a7d5SLisandro Dalcin    The supported image types are .png, .gif, and .ppm (PETSc chooses the default in that order).
1438067a7d5SLisandro Dalcin    Support for .png images requires configure --with-libpng.
1448067a7d5SLisandro Dalcin    Support for .gif images requires configure --with-giflib.
1458067a7d5SLisandro Dalcin    Support for .jpg images requires configure --with-libjpeg.
1468067a7d5SLisandro Dalcin    Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).
1475b399a63SLisandro Dalcin 
148*49c04938SLisandro Dalcin .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
1495b399a63SLisandro Dalcin @*/
1508067a7d5SLisandro Dalcin PetscErrorCode  PetscDrawSetSaveFinalImage(PetscDraw draw,const char filename[])
1515b399a63SLisandro Dalcin {
1528067a7d5SLisandro Dalcin   char           buf[PETSC_MAX_PATH_LEN];
1535b399a63SLisandro Dalcin   PetscErrorCode ierr;
1545b399a63SLisandro Dalcin 
1555b399a63SLisandro Dalcin   PetscFunctionBegin;
1565b399a63SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
1578067a7d5SLisandro Dalcin   if (!filename || !filename[0]) {
1588067a7d5SLisandro Dalcin     if (!draw->savefilename) {
1598067a7d5SLisandro Dalcin       ierr = PetscObjectGetName((PetscObject)draw,&filename);CHKERRQ(ierr);
1605b399a63SLisandro Dalcin     } else {
1618067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(buf,sizeof(buf),"%s%s",draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
1628067a7d5SLisandro Dalcin       filename = buf;
1635b399a63SLisandro Dalcin     }
1648067a7d5SLisandro Dalcin   }
1658067a7d5SLisandro Dalcin   ierr = PetscFree(draw->savefinalfilename);CHKERRQ(ierr);
1668067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(filename,&draw->savefinalfilename);CHKERRQ(ierr);
1675b399a63SLisandro Dalcin   PetscFunctionReturn(0);
1685b399a63SLisandro Dalcin }
1695b399a63SLisandro Dalcin 
1705b399a63SLisandro Dalcin #undef __FUNCT__
1715b399a63SLisandro Dalcin #define __FUNCT__ "PetscDrawSave"
1725b399a63SLisandro Dalcin /*@
1735b399a63SLisandro Dalcin    PetscDrawSave - Saves a drawn image
1745b399a63SLisandro Dalcin 
1755b399a63SLisandro Dalcin    Collective on PetscDraw
1765b399a63SLisandro Dalcin 
1775b399a63SLisandro Dalcin    Input Parameters:
1785b399a63SLisandro Dalcin .  draw - the drawing context
1795b399a63SLisandro Dalcin 
1805b399a63SLisandro Dalcin    Level: advanced
1815b399a63SLisandro Dalcin 
182*49c04938SLisandro Dalcin    Notes: this is not normally called by the user.
1835b399a63SLisandro Dalcin 
1845b399a63SLisandro Dalcin .seealso: PetscDrawSetSave()
1855b399a63SLisandro Dalcin 
1865b399a63SLisandro Dalcin @*/
1875b399a63SLisandro Dalcin PetscErrorCode  PetscDrawSave(PetscDraw draw)
1885b399a63SLisandro Dalcin {
189*49c04938SLisandro Dalcin   PetscInt       saveindex;
1908067a7d5SLisandro Dalcin   char           basename[PETSC_MAX_PATH_LEN];
1918067a7d5SLisandro Dalcin   unsigned char  palette[256][3];
1928067a7d5SLisandro Dalcin   unsigned int   w,h;
1938067a7d5SLisandro Dalcin   unsigned char  *pixels = NULL;
1948067a7d5SLisandro Dalcin   PetscMPIInt    rank;
1955b399a63SLisandro Dalcin   PetscErrorCode ierr;
1965b399a63SLisandro Dalcin 
1975b399a63SLisandro Dalcin   PetscFunctionBegin;
1985b399a63SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
199*49c04938SLisandro Dalcin   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
2008067a7d5SLisandro Dalcin   if (draw->ops->save) {ierr = (*draw->ops->save)(draw);CHKERRQ(ierr); goto finally;}
201*49c04938SLisandro Dalcin   if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0);
2028067a7d5SLisandro Dalcin   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
2038067a7d5SLisandro Dalcin 
204*49c04938SLisandro Dalcin   saveindex = draw->savefilecount++;
2058067a7d5SLisandro Dalcin 
206*49c04938SLisandro Dalcin   if (!rank && !saveindex) {
2078067a7d5SLisandro Dalcin     char path[PETSC_MAX_PATH_LEN];
2088067a7d5SLisandro Dalcin     if (draw->savesinglefile) {
2098067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
2108067a7d5SLisandro Dalcin       (void)remove(path);
2118067a7d5SLisandro Dalcin     } else {
2128067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(path,sizeof(path),"%s",draw->savefilename);CHKERRQ(ierr);
2138067a7d5SLisandro Dalcin       ierr = PetscRMTree(path);CHKERRQ(ierr);
2148067a7d5SLisandro Dalcin       ierr = PetscMkdir(path);CHKERRQ(ierr);
2158067a7d5SLisandro Dalcin     }
2168067a7d5SLisandro Dalcin     if (draw->savemovieext) {
2178067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->savemovieext);CHKERRQ(ierr);
2188067a7d5SLisandro Dalcin       (void)remove(path);
2198067a7d5SLisandro Dalcin     }
2208067a7d5SLisandro Dalcin   }
2218067a7d5SLisandro Dalcin   if (draw->savesinglefile) {
2228067a7d5SLisandro Dalcin     ierr = PetscSNPrintf(basename,sizeof(basename),"%s",draw->savefilename);CHKERRQ(ierr);
2238067a7d5SLisandro Dalcin   } else {
224*49c04938SLisandro Dalcin     ierr = PetscSNPrintf(basename,sizeof(basename),"%s/%s_%d",draw->savefilename,draw->savefilename,(int)saveindex);CHKERRQ(ierr);
2258067a7d5SLisandro Dalcin   }
2268067a7d5SLisandro Dalcin 
2278067a7d5SLisandro Dalcin   /* this call is collective, only the first process gets the image data */
2288067a7d5SLisandro Dalcin   ierr = (*draw->ops->getimage)(draw,palette,&w,&h,&pixels);CHKERRQ(ierr);
2298067a7d5SLisandro Dalcin   /* only the first process handles the saving business */
2308067a7d5SLisandro Dalcin   if (!rank) {ierr = PetscDrawImageSave(basename,draw->saveimageext,palette,w,h,pixels);CHKERRQ(ierr);}
2318067a7d5SLisandro Dalcin   ierr = PetscFree(pixels);CHKERRQ(ierr);
2328067a7d5SLisandro Dalcin   ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
2338067a7d5SLisandro Dalcin 
2348067a7d5SLisandro Dalcin finally:
2358067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS)
2368067a7d5SLisandro Dalcin   ierr = PetscDrawSave_SAWs(draw);CHKERRQ(ierr);
2378067a7d5SLisandro Dalcin #endif
2388067a7d5SLisandro Dalcin   PetscFunctionReturn(0);
2398067a7d5SLisandro Dalcin }
2408067a7d5SLisandro Dalcin 
241*49c04938SLisandro Dalcin #undef __FUNCT__
242*49c04938SLisandro Dalcin #define __FUNCT__ "PetscDrawSaveMovie"
243*49c04938SLisandro Dalcin /*@
244*49c04938SLisandro Dalcin    PetscDrawSaveMovie - Saves a movie from previously saved images
245*49c04938SLisandro Dalcin 
246*49c04938SLisandro Dalcin    Collective on PetscDraw
247*49c04938SLisandro Dalcin 
248*49c04938SLisandro Dalcin    Input Parameters:
249*49c04938SLisandro Dalcin .  draw - the drawing context
250*49c04938SLisandro Dalcin 
251*49c04938SLisandro Dalcin    Level: advanced
252*49c04938SLisandro Dalcin 
253*49c04938SLisandro Dalcin    Notes: this is not normally called by the user.
254*49c04938SLisandro Dalcin    The ffmpeg utility must be in your path to make the movie.
255*49c04938SLisandro Dalcin 
256*49c04938SLisandro Dalcin .seealso: PetscDrawSetSave(), PetscDrawSetSaveMovie()
257*49c04938SLisandro Dalcin 
258*49c04938SLisandro Dalcin @*/
259*49c04938SLisandro Dalcin PetscErrorCode PetscDrawSaveMovie(PetscDraw draw)
260*49c04938SLisandro Dalcin {
261*49c04938SLisandro Dalcin   PetscMPIInt    rank;
262*49c04938SLisandro Dalcin   PetscErrorCode ierr;
263*49c04938SLisandro Dalcin 
264*49c04938SLisandro Dalcin   PetscFunctionBegin;
265*49c04938SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
266*49c04938SLisandro Dalcin   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
267*49c04938SLisandro Dalcin   if (!draw->savefilename || !draw->savemovieext || draw->savesinglefile) PetscFunctionReturn(0);
268*49c04938SLisandro Dalcin   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
269*49c04938SLisandro Dalcin   {
270*49c04938SLisandro Dalcin     const char *fname = draw->savefilename;
271*49c04938SLisandro Dalcin     const char *imext = draw->saveimageext;
272*49c04938SLisandro Dalcin     const char *mvext = draw->savemovieext;
273*49c04938SLisandro Dalcin     if (!rank) {ierr = PetscDrawMovieSave(fname,draw->savefilecount,imext,draw->savemoviefps,mvext);CHKERRQ(ierr);}
274*49c04938SLisandro Dalcin     ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
275*49c04938SLisandro Dalcin   }
276*49c04938SLisandro Dalcin   PetscFunctionReturn(0);
277*49c04938SLisandro Dalcin }
278*49c04938SLisandro Dalcin 
279*49c04938SLisandro Dalcin 
2808067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS)
2818067a7d5SLisandro Dalcin #include <petscviewersaws.h>
2828067a7d5SLisandro Dalcin /*
2838067a7d5SLisandro Dalcin   The PetscImageList object and functions are used to maintain a list of file images
2848067a7d5SLisandro Dalcin   that can be displayed by the SAWs webserver.
2858067a7d5SLisandro Dalcin */
2868067a7d5SLisandro Dalcin typedef struct _P_PetscImageList *PetscImageList;
2878067a7d5SLisandro Dalcin struct _P_PetscImageList {
2888067a7d5SLisandro Dalcin   PetscImageList next;
2898067a7d5SLisandro Dalcin   char           *filename;
2908067a7d5SLisandro Dalcin   char           *ext;
2918067a7d5SLisandro Dalcin   PetscInt       count;
2928067a7d5SLisandro Dalcin } ;
2938067a7d5SLisandro Dalcin 
2948067a7d5SLisandro Dalcin static PetscImageList SAWs_images = NULL;
2958067a7d5SLisandro Dalcin 
2968067a7d5SLisandro Dalcin #undef __FUNCT__
2978067a7d5SLisandro Dalcin #define __FUNCT__ "PetscImageListDestroy"
2988067a7d5SLisandro Dalcin static PetscErrorCode PetscImageListDestroy(void)
2998067a7d5SLisandro Dalcin {
3008067a7d5SLisandro Dalcin   PetscErrorCode ierr;
3018067a7d5SLisandro Dalcin   PetscImageList image = SAWs_images;
3028067a7d5SLisandro Dalcin 
3038067a7d5SLisandro Dalcin   PetscFunctionBegin;
3048067a7d5SLisandro Dalcin   while (image) {
3058067a7d5SLisandro Dalcin     PetscImageList next = image->next;
3068067a7d5SLisandro Dalcin     ierr = PetscFree(image->filename);CHKERRQ(ierr);
3078067a7d5SLisandro Dalcin     ierr = PetscFree(image->ext);CHKERRQ(ierr);
3088067a7d5SLisandro Dalcin     ierr = PetscFree(image);CHKERRQ(ierr);
3098067a7d5SLisandro Dalcin     image = next;
3105b399a63SLisandro Dalcin   }
3115b399a63SLisandro Dalcin   PetscFunctionReturn(0);
3125b399a63SLisandro Dalcin }
3138067a7d5SLisandro Dalcin 
3148067a7d5SLisandro Dalcin #undef __FUNCT__
3158067a7d5SLisandro Dalcin #define __FUNCT__ "PetscImageListAdd"
3168067a7d5SLisandro Dalcin static PetscErrorCode PetscImageListAdd(const char filename[],const char ext[],PetscInt count)
3178067a7d5SLisandro Dalcin {
3188067a7d5SLisandro Dalcin   PetscErrorCode  ierr;
3198067a7d5SLisandro Dalcin   PetscImageList  image,oimage = SAWs_images;
3208067a7d5SLisandro Dalcin   PetscBool       flg;
3218067a7d5SLisandro Dalcin 
3228067a7d5SLisandro Dalcin   PetscFunctionBegin;
3238067a7d5SLisandro Dalcin   if (oimage) {
3248067a7d5SLisandro Dalcin     ierr = PetscStrcmp(filename,oimage->filename,&flg);CHKERRQ(ierr);
3258067a7d5SLisandro Dalcin     if (flg) {
3268067a7d5SLisandro Dalcin       oimage->count = count;
3278067a7d5SLisandro Dalcin       PetscFunctionReturn(0);
3288067a7d5SLisandro Dalcin     }
3298067a7d5SLisandro Dalcin     while (oimage->next) {
3308067a7d5SLisandro Dalcin       oimage = oimage->next;
3318067a7d5SLisandro Dalcin       ierr = PetscStrcmp(filename,oimage->filename,&flg);CHKERRQ(ierr);
3328067a7d5SLisandro Dalcin       if (flg) {
3338067a7d5SLisandro Dalcin         oimage->count = count;
3348067a7d5SLisandro Dalcin         PetscFunctionReturn(0);
3358067a7d5SLisandro Dalcin       }
3368067a7d5SLisandro Dalcin     }
3378067a7d5SLisandro Dalcin     ierr = PetscNew(&image);CHKERRQ(ierr);
3388067a7d5SLisandro Dalcin     oimage->next = image;
3398067a7d5SLisandro Dalcin   } else {
3408067a7d5SLisandro Dalcin     ierr = PetscRegisterFinalize(PetscImageListDestroy);CHKERRQ(ierr);
3418067a7d5SLisandro Dalcin     ierr = PetscNew(&image);CHKERRQ(ierr);
3428067a7d5SLisandro Dalcin     SAWs_images = image;
3438067a7d5SLisandro Dalcin   }
3448067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(filename,&image->filename);CHKERRQ(ierr);
3458067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(ext,&image->ext);CHKERRQ(ierr);
3468067a7d5SLisandro Dalcin   image->count = count;
3478067a7d5SLisandro Dalcin   PetscFunctionReturn(0);
3488067a7d5SLisandro Dalcin }
3498067a7d5SLisandro Dalcin 
3508067a7d5SLisandro Dalcin #undef __FUNCT__
3518067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawSave_SAWs"
3528067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawSave_SAWs(PetscDraw draw)
3538067a7d5SLisandro Dalcin {
3548067a7d5SLisandro Dalcin   PetscImageList image;
3558067a7d5SLisandro Dalcin   char           body[4096];
3568067a7d5SLisandro Dalcin   size_t         len = 0;
3578067a7d5SLisandro Dalcin   PetscErrorCode ierr;
3588067a7d5SLisandro Dalcin 
3598067a7d5SLisandro Dalcin   PetscFunctionBegin;
360*49c04938SLisandro Dalcin   if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0);
3618067a7d5SLisandro Dalcin   ierr = PetscImageListAdd(draw->savefilename,draw->saveimageext,draw->savefilecount-1);CHKERRQ(ierr);
3628067a7d5SLisandro Dalcin   image = SAWs_images;
3638067a7d5SLisandro Dalcin   while (image) {
3648067a7d5SLisandro Dalcin     const char *name = image->filename;
3658067a7d5SLisandro Dalcin     const char *ext  = image->ext;
3668067a7d5SLisandro Dalcin     if (draw->savesinglefile) {
3678067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s%s\" alt=\"None\">",name,ext);CHKERRQ(ierr);
3688067a7d5SLisandro Dalcin     } else {
3698067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s_%d%s\" alt=\"None\">",name,name,image->count,ext);CHKERRQ(ierr);
3708067a7d5SLisandro Dalcin     }
3718067a7d5SLisandro Dalcin     ierr = PetscStrlen(body,&len);CHKERRQ(ierr);
3728067a7d5SLisandro Dalcin     image = image->next;
3738067a7d5SLisandro Dalcin   }
3748067a7d5SLisandro Dalcin   ierr = PetscStrcat(body,"<br>\n");CHKERRQ(ierr);
3758067a7d5SLisandro Dalcin   if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
3768067a7d5SLisandro Dalcin   PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
3778067a7d5SLisandro Dalcin   PetscFunctionReturn(0);
3788067a7d5SLisandro Dalcin }
3798067a7d5SLisandro Dalcin 
3808067a7d5SLisandro Dalcin #endif
381