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 13*811af0c4SBarry Smith PetscDrawSetSave - Saves images produced in a `PetscDraw` into a file 145b399a63SLisandro Dalcin 15*811af0c4SBarry Smith Collective on draw 165b399a63SLisandro Dalcin 17d8d19677SJose E. Roman Input Parameters: 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 28*811af0c4SBarry Smith Note: 29*811af0c4SBarry Smith You should call this BEFORE creating your image and calling `PetscDrawSave()`. 308067a7d5SLisandro Dalcin The supported image types are .png, .gif, .jpg, and .ppm (PETSc chooses the default in that order). 318067a7d5SLisandro Dalcin Support for .png images requires configure --with-libpng. 328067a7d5SLisandro Dalcin Support for .gif images requires configure --with-giflib. 338067a7d5SLisandro Dalcin Support for .jpg images requires configure --with-libjpeg. 348067a7d5SLisandro Dalcin Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB). 355b399a63SLisandro Dalcin 36*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`, `PetscDrawSetSaveFinalImage()` 375b399a63SLisandro Dalcin @*/ 389371c9d4SSatish Balay PetscErrorCode PetscDrawSetSave(PetscDraw draw, const char filename[]) { 398067a7d5SLisandro Dalcin const char *savename = NULL; 408067a7d5SLisandro Dalcin const char *imageext = NULL; 4171ed57bfSLisandro Dalcin char buf[PETSC_MAX_PATH_LEN]; 425b399a63SLisandro Dalcin 435b399a63SLisandro Dalcin PetscFunctionBegin; 445b399a63SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 4571ed57bfSLisandro Dalcin if (filename) PetscValidCharPointer(filename, 2); 465b399a63SLisandro Dalcin 478067a7d5SLisandro Dalcin /* determine save filename and image extension */ 485b399a63SLisandro Dalcin if (filename && filename[0]) { 499566063dSJacob Faibussowitsch PetscCall(PetscStrchr(filename, '.', (char **)&imageext)); 508067a7d5SLisandro Dalcin if (!imageext) savename = filename; 518067a7d5SLisandro Dalcin else if (imageext != filename) { 5271ed57bfSLisandro Dalcin size_t l1 = 0, l2 = 0; 539566063dSJacob Faibussowitsch PetscCall(PetscStrlen(filename, &l1)); 549566063dSJacob Faibussowitsch PetscCall(PetscStrlen(imageext, &l2)); 559566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(buf, filename, l1 - l2 + 1)); 568067a7d5SLisandro Dalcin savename = buf; 575b399a63SLisandro Dalcin } 5871ed57bfSLisandro Dalcin } 5971ed57bfSLisandro Dalcin 609566063dSJacob Faibussowitsch if (!savename) PetscCall(PetscObjectGetName((PetscObject)draw, &savename)); 619566063dSJacob Faibussowitsch PetscCall(PetscDrawImageCheckFormat(&imageext)); 628067a7d5SLisandro Dalcin 638067a7d5SLisandro Dalcin draw->savefilecount = 0; 649566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->savefilename)); 659566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->saveimageext)); 669566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(savename, &draw->savefilename)); 679566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(imageext, &draw->saveimageext)); 6849c04938SLisandro Dalcin 6949c04938SLisandro Dalcin if (draw->savesinglefile) { 709566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Will save image to file %s%s\n", draw->savefilename, draw->saveimageext)); 7149c04938SLisandro Dalcin } else { 729566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Will save images to file %s/%s_%%d%s\n", draw->savefilename, draw->savefilename, draw->saveimageext)); 7349c04938SLisandro Dalcin } 7449c04938SLisandro Dalcin PetscFunctionReturn(0); 7549c04938SLisandro Dalcin } 7649c04938SLisandro Dalcin 7749c04938SLisandro Dalcin /*@C 78*811af0c4SBarry Smith PetscDrawSetSaveMovie - Saves a movie produced from a `PetscDraw` into a file 7949c04938SLisandro Dalcin 80*811af0c4SBarry Smith Collective on draw 8149c04938SLisandro Dalcin 82d8d19677SJose E. Roman Input Parameters: 8349c04938SLisandro Dalcin + draw - the graphics context 8449c04938SLisandro Dalcin - movieext - optional extension defining the movie format 8549c04938SLisandro Dalcin 8649c04938SLisandro Dalcin Options Database Command: 8749c04938SLisandro Dalcin . -draw_save_movie <.ext> - saves a movie with extension .ext 8849c04938SLisandro Dalcin 8949c04938SLisandro Dalcin Level: intermediate 9049c04938SLisandro Dalcin 91*811af0c4SBarry Smith Note: 92*811af0c4SBarry Smith You should call this AFTER calling `PetscDrawSetSave()` and BEFORE creating your image with `PetscDrawSave()`. 9349c04938SLisandro Dalcin The ffmpeg utility must be in your path to make the movie. 9449c04938SLisandro Dalcin 95*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()` 9649c04938SLisandro Dalcin @*/ 979371c9d4SSatish Balay PetscErrorCode PetscDrawSetSaveMovie(PetscDraw draw, const char movieext[]) { 9849c04938SLisandro Dalcin PetscFunctionBegin; 9949c04938SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 10049c04938SLisandro Dalcin if (movieext) PetscValidCharPointer(movieext, 2); 10149c04938SLisandro Dalcin 1029566063dSJacob Faibussowitsch if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, "")); 1039566063dSJacob Faibussowitsch PetscCall(PetscDrawMovieCheckFormat(&movieext)); 1049566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(movieext, &draw->savemovieext)); 10549c04938SLisandro Dalcin draw->savesinglefile = PETSC_FALSE; /* otherwise we cannot generage movies */ 10649c04938SLisandro Dalcin 1079566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Will save movie to file %s%s\n", draw->savefilename, draw->savemovieext)); 1085b399a63SLisandro Dalcin PetscFunctionReturn(0); 1095b399a63SLisandro Dalcin } 1105b399a63SLisandro Dalcin 1115b399a63SLisandro Dalcin /*@C 112*811af0c4SBarry Smith PetscDrawSetSaveFinalImage - Saves the final image produced in a `PetscDraw` into a file 1135b399a63SLisandro Dalcin 114*811af0c4SBarry Smith Collective on draw 1155b399a63SLisandro Dalcin 116d8d19677SJose E. Roman Input Parameters: 1175b399a63SLisandro Dalcin + draw - the graphics context 118*811af0c4SBarry Smith - filename - name of the file, if NULL or empty uses name set with `PetscDrawSetSave()` or the name of the draw object 1195b399a63SLisandro Dalcin 1205b399a63SLisandro Dalcin Options Database Command: 1218067a7d5SLisandro 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) 1225b399a63SLisandro Dalcin 1235b399a63SLisandro Dalcin Level: intermediate 1245b399a63SLisandro Dalcin 12595452b02SPatrick Sanan Notes: 126*811af0c4SBarry Smith You should call this BEFORE creating your image and calling `PetscDrawSave()`. 127*811af0c4SBarry Smith 1288067a7d5SLisandro Dalcin The supported image types are .png, .gif, and .ppm (PETSc chooses the default in that order). 129*811af0c4SBarry Smith .vb 1308067a7d5SLisandro Dalcin Support for .png images requires configure --with-libpng. 1318067a7d5SLisandro Dalcin Support for .gif images requires configure --with-giflib. 1328067a7d5SLisandro Dalcin Support for .jpg images requires configure --with-libjpeg. 1338067a7d5SLisandro Dalcin Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB). 134*811af0c4SBarry Smith .ve 1355b399a63SLisandro Dalcin 136*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()` 1375b399a63SLisandro Dalcin @*/ 1389371c9d4SSatish Balay PetscErrorCode PetscDrawSetSaveFinalImage(PetscDraw draw, const char filename[]) { 1398067a7d5SLisandro Dalcin char buf[PETSC_MAX_PATH_LEN]; 1405b399a63SLisandro Dalcin 1415b399a63SLisandro Dalcin PetscFunctionBegin; 1425b399a63SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 1438067a7d5SLisandro Dalcin if (!filename || !filename[0]) { 1448067a7d5SLisandro Dalcin if (!draw->savefilename) { 1459566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)draw, &filename)); 1465b399a63SLisandro Dalcin } else { 1479566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, sizeof(buf), "%s%s", draw->savefilename, draw->saveimageext)); 1488067a7d5SLisandro Dalcin filename = buf; 1495b399a63SLisandro Dalcin } 1508067a7d5SLisandro Dalcin } 1519566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->savefinalfilename)); 1529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(filename, &draw->savefinalfilename)); 1535b399a63SLisandro Dalcin PetscFunctionReturn(0); 1545b399a63SLisandro Dalcin } 1555b399a63SLisandro Dalcin 1565b399a63SLisandro Dalcin /*@ 1575b399a63SLisandro Dalcin PetscDrawSave - Saves a drawn image 1585b399a63SLisandro Dalcin 159*811af0c4SBarry Smith Collective on draw 1605b399a63SLisandro Dalcin 1615b399a63SLisandro Dalcin Input Parameters: 1625b399a63SLisandro Dalcin . draw - the drawing context 1635b399a63SLisandro Dalcin 1645b399a63SLisandro Dalcin Level: advanced 1655b399a63SLisandro Dalcin 166*811af0c4SBarry Smith Note: 16795452b02SPatrick Sanan this is not normally called by the user. 1685b399a63SLisandro Dalcin 169*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()` 1705b399a63SLisandro Dalcin @*/ 1719371c9d4SSatish Balay PetscErrorCode PetscDrawSave(PetscDraw draw) { 17249c04938SLisandro Dalcin PetscInt saveindex; 1738067a7d5SLisandro Dalcin char basename[PETSC_MAX_PATH_LEN]; 1748067a7d5SLisandro Dalcin unsigned char palette[256][3]; 1758067a7d5SLisandro Dalcin unsigned int w, h; 1768067a7d5SLisandro Dalcin unsigned char *pixels = NULL; 1778067a7d5SLisandro Dalcin PetscMPIInt rank; 1785b399a63SLisandro Dalcin 1795b399a63SLisandro Dalcin PetscFunctionBegin; 1805b399a63SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 18149c04938SLisandro Dalcin if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 1829371c9d4SSatish Balay if (draw->ops->save) { 1839371c9d4SSatish Balay PetscUseTypeMethod(draw, save); 1849371c9d4SSatish Balay goto finally; 1859371c9d4SSatish Balay } 18649c04938SLisandro Dalcin if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0); 1879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank)); 1888067a7d5SLisandro Dalcin 18949c04938SLisandro Dalcin saveindex = draw->savefilecount++; 1908067a7d5SLisandro Dalcin 191dd400576SPatrick Sanan if (rank == 0 && !saveindex) { 1928067a7d5SLisandro Dalcin char path[PETSC_MAX_PATH_LEN]; 1938067a7d5SLisandro Dalcin if (draw->savesinglefile) { 1949566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(path, sizeof(path), "%s%s", draw->savefilename, draw->saveimageext)); 1958067a7d5SLisandro Dalcin (void)remove(path); 1968067a7d5SLisandro Dalcin } else { 1979566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(path, sizeof(path), "%s", draw->savefilename)); 1989566063dSJacob Faibussowitsch PetscCall(PetscRMTree(path)); 1999566063dSJacob Faibussowitsch PetscCall(PetscMkdir(path)); 2008067a7d5SLisandro Dalcin } 2018067a7d5SLisandro Dalcin if (draw->savemovieext) { 2029566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(path, sizeof(path), "%s%s", draw->savefilename, draw->savemovieext)); 2038067a7d5SLisandro Dalcin (void)remove(path); 2048067a7d5SLisandro Dalcin } 2058067a7d5SLisandro Dalcin } 2068067a7d5SLisandro Dalcin if (draw->savesinglefile) { 2079566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(basename, sizeof(basename), "%s", draw->savefilename)); 2088067a7d5SLisandro Dalcin } else { 20980603804SMatthew G. Knepley char *basefilename; 21080603804SMatthew G. Knepley 2119566063dSJacob Faibussowitsch PetscCall(PetscStrrchr(draw->savefilename, '/', (char **)&basefilename)); 21280603804SMatthew G. Knepley if (basefilename != draw->savefilename) { 2139566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(basename, sizeof(basename), "%s_%d", draw->savefilename, (int)saveindex)); 21480603804SMatthew G. Knepley } else { 2159566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(basename, sizeof(basename), "%s/%s_%d", draw->savefilename, draw->savefilename, (int)saveindex)); 2168067a7d5SLisandro Dalcin } 21780603804SMatthew G. Knepley } 2188067a7d5SLisandro Dalcin 2198067a7d5SLisandro Dalcin /* this call is collective, only the first process gets the image data */ 220dbbe0bcdSBarry Smith PetscUseTypeMethod(draw, getimage, palette, &w, &h, &pixels); 2218067a7d5SLisandro Dalcin /* only the first process handles the saving business */ 2229566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscDrawImageSave(basename, draw->saveimageext, palette, w, h, pixels)); 2239566063dSJacob Faibussowitsch PetscCall(PetscFree(pixels)); 2249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PetscObjectComm((PetscObject)draw))); 2258067a7d5SLisandro Dalcin 2268067a7d5SLisandro Dalcin finally: 2278067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS) 2289566063dSJacob Faibussowitsch PetscCall(PetscDrawSave_SAWs(draw)); 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 236*811af0c4SBarry Smith Collective on draw 23749c04938SLisandro Dalcin 23849c04938SLisandro Dalcin Input Parameters: 23949c04938SLisandro Dalcin . draw - the drawing context 24049c04938SLisandro Dalcin 24149c04938SLisandro Dalcin Level: advanced 24249c04938SLisandro Dalcin 24395452b02SPatrick Sanan Notes: 244*811af0c4SBarry Smith This is not normally called by the user. 245*811af0c4SBarry Smith 24649c04938SLisandro Dalcin The ffmpeg utility must be in your path to make the movie. 24749c04938SLisandro Dalcin 248*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()`, `PetscDrawSetSaveMovie()` 24949c04938SLisandro Dalcin @*/ 2509371c9d4SSatish Balay PetscErrorCode PetscDrawSaveMovie(PetscDraw draw) { 25149c04938SLisandro Dalcin PetscMPIInt rank; 25249c04938SLisandro Dalcin 25349c04938SLisandro Dalcin PetscFunctionBegin; 25449c04938SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 25549c04938SLisandro Dalcin if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 25649c04938SLisandro Dalcin if (!draw->savefilename || !draw->savemovieext || draw->savesinglefile) PetscFunctionReturn(0); 2579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank)); 25849c04938SLisandro Dalcin { 25949c04938SLisandro Dalcin const char *fname = draw->savefilename; 26049c04938SLisandro Dalcin const char *imext = draw->saveimageext; 26149c04938SLisandro Dalcin const char *mvext = draw->savemovieext; 2629566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscDrawMovieSave(fname, draw->savefilecount, imext, draw->savemoviefps, mvext)); 2639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PetscObjectComm((PetscObject)draw))); 26449c04938SLisandro Dalcin } 26549c04938SLisandro Dalcin PetscFunctionReturn(0); 26649c04938SLisandro Dalcin } 26749c04938SLisandro Dalcin 2688067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS) 2698067a7d5SLisandro Dalcin #include <petscviewersaws.h> 2708067a7d5SLisandro Dalcin /* 2718067a7d5SLisandro Dalcin The PetscImageList object and functions are used to maintain a list of file images 2728067a7d5SLisandro Dalcin that can be displayed by the SAWs webserver. 2738067a7d5SLisandro Dalcin */ 2748067a7d5SLisandro Dalcin typedef struct _P_PetscImageList *PetscImageList; 2758067a7d5SLisandro Dalcin struct _P_PetscImageList { 2768067a7d5SLisandro Dalcin PetscImageList next; 2778067a7d5SLisandro Dalcin char *filename; 2788067a7d5SLisandro Dalcin char *ext; 2798067a7d5SLisandro Dalcin PetscInt count; 2808067a7d5SLisandro Dalcin }; 2818067a7d5SLisandro Dalcin 2828067a7d5SLisandro Dalcin static PetscImageList SAWs_images = NULL; 2838067a7d5SLisandro Dalcin 2849371c9d4SSatish Balay static PetscErrorCode PetscImageListDestroy(void) { 2858067a7d5SLisandro Dalcin PetscImageList image = SAWs_images; 2868067a7d5SLisandro Dalcin 2878067a7d5SLisandro Dalcin PetscFunctionBegin; 2888067a7d5SLisandro Dalcin while (image) { 2898067a7d5SLisandro Dalcin PetscImageList next = image->next; 2909566063dSJacob Faibussowitsch PetscCall(PetscFree(image->filename)); 2919566063dSJacob Faibussowitsch PetscCall(PetscFree(image->ext)); 2929566063dSJacob Faibussowitsch PetscCall(PetscFree(image)); 2938067a7d5SLisandro Dalcin image = next; 2945b399a63SLisandro Dalcin } 2955b399a63SLisandro Dalcin PetscFunctionReturn(0); 2965b399a63SLisandro Dalcin } 2978067a7d5SLisandro Dalcin 2989371c9d4SSatish Balay static PetscErrorCode PetscImageListAdd(const char filename[], const char ext[], PetscInt count) { 2998067a7d5SLisandro Dalcin PetscImageList image, oimage = SAWs_images; 3008067a7d5SLisandro Dalcin PetscBool flg; 3018067a7d5SLisandro Dalcin 3028067a7d5SLisandro Dalcin PetscFunctionBegin; 3038067a7d5SLisandro Dalcin if (oimage) { 3049566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(filename, oimage->filename, &flg)); 3058067a7d5SLisandro Dalcin if (flg) { 3068067a7d5SLisandro Dalcin oimage->count = count; 3078067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3088067a7d5SLisandro Dalcin } 3098067a7d5SLisandro Dalcin while (oimage->next) { 3108067a7d5SLisandro Dalcin oimage = oimage->next; 3119566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(filename, oimage->filename, &flg)); 3128067a7d5SLisandro Dalcin if (flg) { 3138067a7d5SLisandro Dalcin oimage->count = count; 3148067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3158067a7d5SLisandro Dalcin } 3168067a7d5SLisandro Dalcin } 3179566063dSJacob Faibussowitsch PetscCall(PetscNew(&image)); 3188067a7d5SLisandro Dalcin oimage->next = image; 3198067a7d5SLisandro Dalcin } else { 3209566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscImageListDestroy)); 3219566063dSJacob Faibussowitsch PetscCall(PetscNew(&image)); 3228067a7d5SLisandro Dalcin SAWs_images = image; 3238067a7d5SLisandro Dalcin } 3249566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(filename, &image->filename)); 3259566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ext, &image->ext)); 3268067a7d5SLisandro Dalcin image->count = count; 3278067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3288067a7d5SLisandro Dalcin } 3298067a7d5SLisandro Dalcin 3309371c9d4SSatish Balay static PetscErrorCode PetscDrawSave_SAWs(PetscDraw draw) { 3318067a7d5SLisandro Dalcin PetscImageList image; 3328067a7d5SLisandro Dalcin char body[4096]; 3338067a7d5SLisandro Dalcin size_t len = 0; 3348067a7d5SLisandro Dalcin 3358067a7d5SLisandro Dalcin PetscFunctionBegin; 33649c04938SLisandro Dalcin if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0); 3379566063dSJacob Faibussowitsch PetscCall(PetscImageListAdd(draw->savefilename, draw->saveimageext, draw->savefilecount - 1)); 3388067a7d5SLisandro Dalcin image = SAWs_images; 3398067a7d5SLisandro Dalcin while (image) { 3408067a7d5SLisandro Dalcin const char *name = image->filename; 3418067a7d5SLisandro Dalcin const char *ext = image->ext; 3428067a7d5SLisandro Dalcin if (draw->savesinglefile) { 3439566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(body + len, 4086 - len, "<img src=\"%s%s\" alt=\"None\">", name, ext)); 3448067a7d5SLisandro Dalcin } else { 3459566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(body + len, 4086 - len, "<img src=\"%s/%s_%d%s\" alt=\"None\">", name, name, image->count, ext)); 3468067a7d5SLisandro Dalcin } 3479566063dSJacob Faibussowitsch PetscCall(PetscStrlen(body, &len)); 3488067a7d5SLisandro Dalcin image = image->next; 3498067a7d5SLisandro Dalcin } 3509566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(body, "<br>\n", sizeof(body))); 351792fecdfSBarry Smith if (draw->savefilecount > 0) PetscCallSAWs(SAWs_Pop_Body, ("index.html", 1)); 352792fecdfSBarry Smith PetscCallSAWs(SAWs_Push_Body, ("index.html", 1, body)); 3538067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3548067a7d5SLisandro Dalcin } 3558067a7d5SLisandro Dalcin 3568067a7d5SLisandro Dalcin #endif 357