xref: /petsc/src/sys/classes/draw/interface/dsave.c (revision a126751eb7c22282655f26917f2fb121ff6a923a)
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[]);
449c04938SLisandro 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 /*@C
138067a7d5SLisandro Dalcin    PetscDrawSetSave - Saves images produced in a PetscDraw into a file
145b399a63SLisandro Dalcin 
155b399a63SLisandro Dalcin    Collective on PetscDraw
165b399a63SLisandro Dalcin 
175b399a63SLisandro Dalcin    Input Parameter:
185b399a63SLisandro Dalcin +  draw      - the graphics context
1949c04938SLisandro Dalcin -  filename  - name of the file, if .ext then uses name of draw object plus .ext using .ext to determine the image type
205b399a63SLisandro Dalcin 
215b399a63SLisandro Dalcin    Options Database Command:
228067a7d5SLisandro Dalcin +  -draw_save <filename>  - filename could be name.ext or .ext (where .ext determines the type of graphics file to save, for example .png)
238067a7d5SLisandro Dalcin .  -draw_save_final_image [optional filename] - saves the final image displayed in a window
248067a7d5SLisandro 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
255b399a63SLisandro Dalcin 
265b399a63SLisandro Dalcin    Level: intermediate
275b399a63SLisandro Dalcin 
285b399a63SLisandro Dalcin    Concepts: X windows^graphics
295b399a63SLisandro Dalcin 
308067a7d5SLisandro Dalcin    Notes: You should call this BEFORE creating your image and calling PetscDrawSave().
318067a7d5SLisandro Dalcin    The supported image types are .png, .gif, .jpg, and .ppm (PETSc chooses the default in that order).
328067a7d5SLisandro Dalcin    Support for .png images requires configure --with-libpng.
338067a7d5SLisandro Dalcin    Support for .gif images requires configure --with-giflib.
348067a7d5SLisandro Dalcin    Support for .jpg images requires configure --with-libjpeg.
358067a7d5SLisandro Dalcin    Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).
365b399a63SLisandro Dalcin 
375b399a63SLisandro Dalcin .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawSetSaveFinalImage()
385b399a63SLisandro Dalcin @*/
3949c04938SLisandro Dalcin PetscErrorCode  PetscDrawSetSave(PetscDraw draw,const char filename[])
405b399a63SLisandro Dalcin {
418067a7d5SLisandro Dalcin   const char     *savename = NULL;
428067a7d5SLisandro Dalcin   const char     *imageext = NULL;
4371ed57bfSLisandro Dalcin   char           buf[PETSC_MAX_PATH_LEN];
445b399a63SLisandro Dalcin   PetscErrorCode ierr;
455b399a63SLisandro Dalcin 
465b399a63SLisandro Dalcin   PetscFunctionBegin;
475b399a63SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
4871ed57bfSLisandro Dalcin   if (filename) PetscValidCharPointer(filename,2);
495b399a63SLisandro Dalcin 
508067a7d5SLisandro Dalcin   /* determine save filename and image extension */
515b399a63SLisandro Dalcin   if (filename && filename[0]) {
528067a7d5SLisandro Dalcin     ierr = PetscStrchr(filename,'.',(char **)&imageext);CHKERRQ(ierr);
538067a7d5SLisandro Dalcin     if (!imageext) savename = filename;
548067a7d5SLisandro Dalcin     else if (imageext != filename) {
5571ed57bfSLisandro Dalcin       size_t l1 = 0,l2 = 0;
565b399a63SLisandro Dalcin       ierr = PetscStrlen(filename,&l1);CHKERRQ(ierr);
578067a7d5SLisandro Dalcin       ierr = PetscStrlen(imageext,&l2);CHKERRQ(ierr);
5871ed57bfSLisandro Dalcin       ierr = PetscStrncpy(buf,filename,l1-l2+1);CHKERRQ(ierr);
598067a7d5SLisandro Dalcin       savename = buf;
605b399a63SLisandro Dalcin     }
6171ed57bfSLisandro Dalcin   }
6271ed57bfSLisandro Dalcin 
638067a7d5SLisandro Dalcin   if (!savename) {ierr = PetscObjectGetName((PetscObject)draw,&savename);CHKERRQ(ierr);}
648067a7d5SLisandro Dalcin   ierr = PetscDrawImageCheckFormat(&imageext);CHKERRQ(ierr);
658067a7d5SLisandro Dalcin 
668067a7d5SLisandro Dalcin   draw->savefilecount = 0;
678067a7d5SLisandro Dalcin   ierr = PetscFree(draw->savefilename);CHKERRQ(ierr);
688067a7d5SLisandro Dalcin   ierr = PetscFree(draw->saveimageext);CHKERRQ(ierr);
698067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(savename,&draw->savefilename);CHKERRQ(ierr);
708067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(imageext,&draw->saveimageext);CHKERRQ(ierr);
7149c04938SLisandro Dalcin 
7249c04938SLisandro Dalcin   if (draw->savesinglefile) {
7349c04938SLisandro Dalcin     ierr = PetscInfo2(NULL,"Will save image to file %s%s\n",draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
7449c04938SLisandro Dalcin   } else {
7549c04938SLisandro Dalcin     ierr = PetscInfo3(NULL,"Will save images to file %s/%s_%%d%s\n",draw->savefilename,draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
7649c04938SLisandro Dalcin   }
7749c04938SLisandro Dalcin   PetscFunctionReturn(0);
7849c04938SLisandro Dalcin }
7949c04938SLisandro Dalcin 
8049c04938SLisandro Dalcin /*@C
8149c04938SLisandro Dalcin    PetscDrawSetSaveMovie - Saves a movie produced from a PetscDraw into a file
8249c04938SLisandro Dalcin 
8349c04938SLisandro Dalcin    Collective on PetscDraw
8449c04938SLisandro Dalcin 
8549c04938SLisandro Dalcin    Input Parameter:
8649c04938SLisandro Dalcin +  draw      - the graphics context
8749c04938SLisandro Dalcin -  movieext  - optional extension defining the movie format
8849c04938SLisandro Dalcin 
8949c04938SLisandro Dalcin    Options Database Command:
9049c04938SLisandro Dalcin .  -draw_save_movie <.ext> - saves a movie with extension .ext
9149c04938SLisandro Dalcin 
9249c04938SLisandro Dalcin    Level: intermediate
9349c04938SLisandro Dalcin 
9449c04938SLisandro Dalcin    Concepts: X windows^graphics
9549c04938SLisandro Dalcin 
9649c04938SLisandro Dalcin    Notes: You should call this AFTER calling PetscDrawSetSave() and BEFORE creating your image with PetscDrawSave().
9749c04938SLisandro Dalcin    The ffmpeg utility must be in your path to make the movie.
9849c04938SLisandro Dalcin 
9949c04938SLisandro Dalcin .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
10049c04938SLisandro Dalcin @*/
10149c04938SLisandro Dalcin PetscErrorCode  PetscDrawSetSaveMovie(PetscDraw draw,const char movieext[])
10249c04938SLisandro Dalcin {
10349c04938SLisandro Dalcin 
10449c04938SLisandro Dalcin   PetscErrorCode ierr;
10549c04938SLisandro Dalcin 
10649c04938SLisandro Dalcin   PetscFunctionBegin;
10749c04938SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
10849c04938SLisandro Dalcin   if (movieext) PetscValidCharPointer(movieext,2);
10949c04938SLisandro Dalcin 
11049c04938SLisandro Dalcin   if (!draw->savefilename) {ierr = PetscDrawSetSave(draw,"");CHKERRQ(ierr);}
11149c04938SLisandro Dalcin   ierr = PetscDrawMovieCheckFormat(&movieext);CHKERRQ(ierr);
1128067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(movieext,&draw->savemovieext);CHKERRQ(ierr);
11349c04938SLisandro Dalcin   draw->savesinglefile = PETSC_FALSE; /* otherwise we cannot generage movies */
11449c04938SLisandro Dalcin 
11549c04938SLisandro Dalcin   ierr = PetscInfo2(NULL,"Will save movie to file %s%s\n",draw->savefilename,draw->savemovieext);CHKERRQ(ierr);
1165b399a63SLisandro Dalcin   PetscFunctionReturn(0);
1175b399a63SLisandro Dalcin }
1185b399a63SLisandro Dalcin 
1195b399a63SLisandro Dalcin /*@C
1208067a7d5SLisandro Dalcin    PetscDrawSetSaveFinalImage - Saves the final image produced in a PetscDraw into a file
1215b399a63SLisandro Dalcin 
1225b399a63SLisandro Dalcin    Collective on PetscDraw
1235b399a63SLisandro Dalcin 
1245b399a63SLisandro Dalcin    Input Parameter:
1255b399a63SLisandro Dalcin +  draw      - the graphics context
1268067a7d5SLisandro Dalcin -  filename  - name of the file, if NULL or empty uses name set with PetscDrawSetSave() or name of draw object
1275b399a63SLisandro Dalcin 
1285b399a63SLisandro Dalcin    Options Database Command:
1298067a7d5SLisandro 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)
1305b399a63SLisandro Dalcin 
1315b399a63SLisandro Dalcin    Level: intermediate
1325b399a63SLisandro Dalcin 
1335b399a63SLisandro Dalcin    Concepts: X windows^graphics
1345b399a63SLisandro Dalcin 
1358067a7d5SLisandro Dalcin    Notes: You should call this BEFORE creating your image and calling PetscDrawSave().
1368067a7d5SLisandro Dalcin    The supported image types are .png, .gif, and .ppm (PETSc chooses the default in that order).
1378067a7d5SLisandro Dalcin    Support for .png images requires configure --with-libpng.
1388067a7d5SLisandro Dalcin    Support for .gif images requires configure --with-giflib.
1398067a7d5SLisandro Dalcin    Support for .jpg images requires configure --with-libjpeg.
1408067a7d5SLisandro Dalcin    Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).
1415b399a63SLisandro Dalcin 
14249c04938SLisandro Dalcin .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
1435b399a63SLisandro Dalcin @*/
1448067a7d5SLisandro Dalcin PetscErrorCode  PetscDrawSetSaveFinalImage(PetscDraw draw,const char filename[])
1455b399a63SLisandro Dalcin {
1468067a7d5SLisandro Dalcin   char           buf[PETSC_MAX_PATH_LEN];
1475b399a63SLisandro Dalcin   PetscErrorCode ierr;
1485b399a63SLisandro Dalcin 
1495b399a63SLisandro Dalcin   PetscFunctionBegin;
1505b399a63SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
1518067a7d5SLisandro Dalcin   if (!filename || !filename[0]) {
1528067a7d5SLisandro Dalcin     if (!draw->savefilename) {
1538067a7d5SLisandro Dalcin       ierr = PetscObjectGetName((PetscObject)draw,&filename);CHKERRQ(ierr);
1545b399a63SLisandro Dalcin     } else {
1558067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(buf,sizeof(buf),"%s%s",draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
1568067a7d5SLisandro Dalcin       filename = buf;
1575b399a63SLisandro Dalcin     }
1588067a7d5SLisandro Dalcin   }
1598067a7d5SLisandro Dalcin   ierr = PetscFree(draw->savefinalfilename);CHKERRQ(ierr);
1608067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(filename,&draw->savefinalfilename);CHKERRQ(ierr);
1615b399a63SLisandro Dalcin   PetscFunctionReturn(0);
1625b399a63SLisandro Dalcin }
1635b399a63SLisandro Dalcin 
1645b399a63SLisandro Dalcin /*@
1655b399a63SLisandro Dalcin    PetscDrawSave - Saves a drawn image
1665b399a63SLisandro Dalcin 
1675b399a63SLisandro Dalcin    Collective on PetscDraw
1685b399a63SLisandro Dalcin 
1695b399a63SLisandro Dalcin    Input Parameters:
1705b399a63SLisandro Dalcin .  draw - the drawing context
1715b399a63SLisandro Dalcin 
1725b399a63SLisandro Dalcin    Level: advanced
1735b399a63SLisandro Dalcin 
17449c04938SLisandro Dalcin    Notes: this is not normally called by the user.
1755b399a63SLisandro Dalcin 
1765b399a63SLisandro Dalcin .seealso: PetscDrawSetSave()
1775b399a63SLisandro Dalcin 
1785b399a63SLisandro Dalcin @*/
1795b399a63SLisandro Dalcin PetscErrorCode  PetscDrawSave(PetscDraw draw)
1805b399a63SLisandro Dalcin {
18149c04938SLisandro Dalcin   PetscInt       saveindex;
1828067a7d5SLisandro Dalcin   char           basename[PETSC_MAX_PATH_LEN];
1838067a7d5SLisandro Dalcin   unsigned char  palette[256][3];
1848067a7d5SLisandro Dalcin   unsigned int   w,h;
1858067a7d5SLisandro Dalcin   unsigned char  *pixels = NULL;
1868067a7d5SLisandro Dalcin   PetscMPIInt    rank;
1875b399a63SLisandro Dalcin   PetscErrorCode ierr;
1885b399a63SLisandro Dalcin 
1895b399a63SLisandro Dalcin   PetscFunctionBegin;
1905b399a63SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
19149c04938SLisandro Dalcin   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
1928067a7d5SLisandro Dalcin   if (draw->ops->save) {ierr = (*draw->ops->save)(draw);CHKERRQ(ierr); goto finally;}
19349c04938SLisandro Dalcin   if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0);
1948067a7d5SLisandro Dalcin   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
1958067a7d5SLisandro Dalcin 
19649c04938SLisandro Dalcin   saveindex = draw->savefilecount++;
1978067a7d5SLisandro Dalcin 
19849c04938SLisandro Dalcin   if (!rank && !saveindex) {
1998067a7d5SLisandro Dalcin     char path[PETSC_MAX_PATH_LEN];
2008067a7d5SLisandro Dalcin     if (draw->savesinglefile) {
2018067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->saveimageext);CHKERRQ(ierr);
2028067a7d5SLisandro Dalcin       (void)remove(path);
2038067a7d5SLisandro Dalcin     } else {
2048067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(path,sizeof(path),"%s",draw->savefilename);CHKERRQ(ierr);
2058067a7d5SLisandro Dalcin       ierr = PetscRMTree(path);CHKERRQ(ierr);
2068067a7d5SLisandro Dalcin       ierr = PetscMkdir(path);CHKERRQ(ierr);
2078067a7d5SLisandro Dalcin     }
2088067a7d5SLisandro Dalcin     if (draw->savemovieext) {
2098067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->savemovieext);CHKERRQ(ierr);
2108067a7d5SLisandro Dalcin       (void)remove(path);
2118067a7d5SLisandro Dalcin     }
2128067a7d5SLisandro Dalcin   }
2138067a7d5SLisandro Dalcin   if (draw->savesinglefile) {
2148067a7d5SLisandro Dalcin     ierr = PetscSNPrintf(basename,sizeof(basename),"%s",draw->savefilename);CHKERRQ(ierr);
2158067a7d5SLisandro Dalcin   } else {
21649c04938SLisandro Dalcin     ierr = PetscSNPrintf(basename,sizeof(basename),"%s/%s_%d",draw->savefilename,draw->savefilename,(int)saveindex);CHKERRQ(ierr);
2178067a7d5SLisandro Dalcin   }
2188067a7d5SLisandro Dalcin 
2198067a7d5SLisandro Dalcin   /* this call is collective, only the first process gets the image data */
2208067a7d5SLisandro Dalcin   ierr = (*draw->ops->getimage)(draw,palette,&w,&h,&pixels);CHKERRQ(ierr);
2218067a7d5SLisandro Dalcin   /* only the first process handles the saving business */
2228067a7d5SLisandro Dalcin   if (!rank) {ierr = PetscDrawImageSave(basename,draw->saveimageext,palette,w,h,pixels);CHKERRQ(ierr);}
2238067a7d5SLisandro Dalcin   ierr = PetscFree(pixels);CHKERRQ(ierr);
2248067a7d5SLisandro Dalcin   ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
2258067a7d5SLisandro Dalcin 
2268067a7d5SLisandro Dalcin finally:
2278067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS)
2288067a7d5SLisandro Dalcin   ierr = PetscDrawSave_SAWs(draw);CHKERRQ(ierr);
2298067a7d5SLisandro Dalcin #endif
2308067a7d5SLisandro Dalcin   PetscFunctionReturn(0);
2318067a7d5SLisandro Dalcin }
2328067a7d5SLisandro Dalcin 
23349c04938SLisandro Dalcin /*@
23449c04938SLisandro Dalcin    PetscDrawSaveMovie - Saves a movie from previously saved images
23549c04938SLisandro Dalcin 
23649c04938SLisandro Dalcin    Collective on PetscDraw
23749c04938SLisandro Dalcin 
23849c04938SLisandro Dalcin    Input Parameters:
23949c04938SLisandro Dalcin .  draw - the drawing context
24049c04938SLisandro Dalcin 
24149c04938SLisandro Dalcin    Level: advanced
24249c04938SLisandro Dalcin 
24349c04938SLisandro Dalcin    Notes: this is not normally called by the user.
24449c04938SLisandro Dalcin    The ffmpeg utility must be in your path to make the movie.
24549c04938SLisandro Dalcin 
24649c04938SLisandro Dalcin .seealso: PetscDrawSetSave(), PetscDrawSetSaveMovie()
24749c04938SLisandro Dalcin 
24849c04938SLisandro Dalcin @*/
24949c04938SLisandro Dalcin PetscErrorCode PetscDrawSaveMovie(PetscDraw draw)
25049c04938SLisandro Dalcin {
25149c04938SLisandro Dalcin   PetscMPIInt    rank;
25249c04938SLisandro Dalcin   PetscErrorCode ierr;
25349c04938SLisandro Dalcin 
25449c04938SLisandro Dalcin   PetscFunctionBegin;
25549c04938SLisandro Dalcin   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
25649c04938SLisandro Dalcin   if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0);
25749c04938SLisandro Dalcin   if (!draw->savefilename || !draw->savemovieext || draw->savesinglefile) PetscFunctionReturn(0);
25849c04938SLisandro Dalcin   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr);
25949c04938SLisandro Dalcin   {
26049c04938SLisandro Dalcin     const char *fname = draw->savefilename;
26149c04938SLisandro Dalcin     const char *imext = draw->saveimageext;
26249c04938SLisandro Dalcin     const char *mvext = draw->savemovieext;
26349c04938SLisandro Dalcin     if (!rank) {ierr = PetscDrawMovieSave(fname,draw->savefilecount,imext,draw->savemoviefps,mvext);CHKERRQ(ierr);}
26449c04938SLisandro Dalcin     ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr);
26549c04938SLisandro Dalcin   }
26649c04938SLisandro Dalcin   PetscFunctionReturn(0);
26749c04938SLisandro Dalcin }
26849c04938SLisandro Dalcin 
26949c04938SLisandro Dalcin 
2708067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS)
2718067a7d5SLisandro Dalcin #include <petscviewersaws.h>
2728067a7d5SLisandro Dalcin /*
2738067a7d5SLisandro Dalcin   The PetscImageList object and functions are used to maintain a list of file images
2748067a7d5SLisandro Dalcin   that can be displayed by the SAWs webserver.
2758067a7d5SLisandro Dalcin */
2768067a7d5SLisandro Dalcin typedef struct _P_PetscImageList *PetscImageList;
2778067a7d5SLisandro Dalcin struct _P_PetscImageList {
2788067a7d5SLisandro Dalcin   PetscImageList next;
2798067a7d5SLisandro Dalcin   char           *filename;
2808067a7d5SLisandro Dalcin   char           *ext;
2818067a7d5SLisandro Dalcin   PetscInt       count;
2828067a7d5SLisandro Dalcin } ;
2838067a7d5SLisandro Dalcin 
2848067a7d5SLisandro Dalcin static PetscImageList SAWs_images = NULL;
2858067a7d5SLisandro Dalcin 
2868067a7d5SLisandro Dalcin static PetscErrorCode PetscImageListDestroy(void)
2878067a7d5SLisandro Dalcin {
2888067a7d5SLisandro Dalcin   PetscErrorCode ierr;
2898067a7d5SLisandro Dalcin   PetscImageList image = SAWs_images;
2908067a7d5SLisandro Dalcin 
2918067a7d5SLisandro Dalcin   PetscFunctionBegin;
2928067a7d5SLisandro Dalcin   while (image) {
2938067a7d5SLisandro Dalcin     PetscImageList next = image->next;
2948067a7d5SLisandro Dalcin     ierr = PetscFree(image->filename);CHKERRQ(ierr);
2958067a7d5SLisandro Dalcin     ierr = PetscFree(image->ext);CHKERRQ(ierr);
2968067a7d5SLisandro Dalcin     ierr = PetscFree(image);CHKERRQ(ierr);
2978067a7d5SLisandro Dalcin     image = next;
2985b399a63SLisandro Dalcin   }
2995b399a63SLisandro Dalcin   PetscFunctionReturn(0);
3005b399a63SLisandro Dalcin }
3018067a7d5SLisandro Dalcin 
3028067a7d5SLisandro Dalcin static PetscErrorCode PetscImageListAdd(const char filename[],const char ext[],PetscInt count)
3038067a7d5SLisandro Dalcin {
3048067a7d5SLisandro Dalcin   PetscErrorCode  ierr;
3058067a7d5SLisandro Dalcin   PetscImageList  image,oimage = SAWs_images;
3068067a7d5SLisandro Dalcin   PetscBool       flg;
3078067a7d5SLisandro Dalcin 
3088067a7d5SLisandro Dalcin   PetscFunctionBegin;
3098067a7d5SLisandro Dalcin   if (oimage) {
3108067a7d5SLisandro Dalcin     ierr = PetscStrcmp(filename,oimage->filename,&flg);CHKERRQ(ierr);
3118067a7d5SLisandro Dalcin     if (flg) {
3128067a7d5SLisandro Dalcin       oimage->count = count;
3138067a7d5SLisandro Dalcin       PetscFunctionReturn(0);
3148067a7d5SLisandro Dalcin     }
3158067a7d5SLisandro Dalcin     while (oimage->next) {
3168067a7d5SLisandro Dalcin       oimage = oimage->next;
3178067a7d5SLisandro Dalcin       ierr = PetscStrcmp(filename,oimage->filename,&flg);CHKERRQ(ierr);
3188067a7d5SLisandro Dalcin       if (flg) {
3198067a7d5SLisandro Dalcin         oimage->count = count;
3208067a7d5SLisandro Dalcin         PetscFunctionReturn(0);
3218067a7d5SLisandro Dalcin       }
3228067a7d5SLisandro Dalcin     }
3238067a7d5SLisandro Dalcin     ierr = PetscNew(&image);CHKERRQ(ierr);
3248067a7d5SLisandro Dalcin     oimage->next = image;
3258067a7d5SLisandro Dalcin   } else {
3268067a7d5SLisandro Dalcin     ierr = PetscRegisterFinalize(PetscImageListDestroy);CHKERRQ(ierr);
3278067a7d5SLisandro Dalcin     ierr = PetscNew(&image);CHKERRQ(ierr);
3288067a7d5SLisandro Dalcin     SAWs_images = image;
3298067a7d5SLisandro Dalcin   }
3308067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(filename,&image->filename);CHKERRQ(ierr);
3318067a7d5SLisandro Dalcin   ierr = PetscStrallocpy(ext,&image->ext);CHKERRQ(ierr);
3328067a7d5SLisandro Dalcin   image->count = count;
3338067a7d5SLisandro Dalcin   PetscFunctionReturn(0);
3348067a7d5SLisandro Dalcin }
3358067a7d5SLisandro Dalcin 
3368067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawSave_SAWs(PetscDraw draw)
3378067a7d5SLisandro Dalcin {
3388067a7d5SLisandro Dalcin   PetscImageList image;
3398067a7d5SLisandro Dalcin   char           body[4096];
3408067a7d5SLisandro Dalcin   size_t         len = 0;
3418067a7d5SLisandro Dalcin   PetscErrorCode ierr;
3428067a7d5SLisandro Dalcin 
3438067a7d5SLisandro Dalcin   PetscFunctionBegin;
34449c04938SLisandro Dalcin   if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0);
3458067a7d5SLisandro Dalcin   ierr = PetscImageListAdd(draw->savefilename,draw->saveimageext,draw->savefilecount-1);CHKERRQ(ierr);
3468067a7d5SLisandro Dalcin   image = SAWs_images;
3478067a7d5SLisandro Dalcin   while (image) {
3488067a7d5SLisandro Dalcin     const char *name = image->filename;
3498067a7d5SLisandro Dalcin     const char *ext  = image->ext;
3508067a7d5SLisandro Dalcin     if (draw->savesinglefile) {
3518067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s%s\" alt=\"None\">",name,ext);CHKERRQ(ierr);
3528067a7d5SLisandro Dalcin     } else {
3538067a7d5SLisandro Dalcin       ierr = PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s_%d%s\" alt=\"None\">",name,name,image->count,ext);CHKERRQ(ierr);
3548067a7d5SLisandro Dalcin     }
3558067a7d5SLisandro Dalcin     ierr = PetscStrlen(body,&len);CHKERRQ(ierr);
3568067a7d5SLisandro Dalcin     image = image->next;
3578067a7d5SLisandro Dalcin   }
358*a126751eSBarry Smith   ierr = PetscStrlcat(body,"<br>\n",sizeof(body));CHKERRQ(ierr);
3598067a7d5SLisandro Dalcin   if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
3608067a7d5SLisandro Dalcin   PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
3618067a7d5SLisandro Dalcin   PetscFunctionReturn(0);
3628067a7d5SLisandro Dalcin }
3638067a7d5SLisandro Dalcin 
3648067a7d5SLisandro Dalcin #endif
365