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 13811af0c4SBarry Smith PetscDrawSetSave - Saves images produced in a `PetscDraw` into a file 145b399a63SLisandro Dalcin 15*c3339decSBarry Smith Collective 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 213c7db156SBarry Smith Options Database Keys: 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 28811af0c4SBarry Smith Note: 29811af0c4SBarry 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 36811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawOpenX()`, `PetscDrawOpenImage()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()`, `PetscDrawSetSaveFinalImage()` 375b399a63SLisandro Dalcin @*/ 38d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawSetSave(PetscDraw draw, const char filename[]) 39d71ae5a4SJacob Faibussowitsch { 408067a7d5SLisandro Dalcin const char *savename = NULL; 418067a7d5SLisandro Dalcin const char *imageext = NULL; 4271ed57bfSLisandro Dalcin char buf[PETSC_MAX_PATH_LEN]; 435b399a63SLisandro Dalcin 445b399a63SLisandro Dalcin PetscFunctionBegin; 455b399a63SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 4671ed57bfSLisandro Dalcin if (filename) PetscValidCharPointer(filename, 2); 475b399a63SLisandro Dalcin 488067a7d5SLisandro Dalcin /* determine save filename and image extension */ 495b399a63SLisandro Dalcin if (filename && filename[0]) { 509566063dSJacob Faibussowitsch PetscCall(PetscStrchr(filename, '.', (char **)&imageext)); 518067a7d5SLisandro Dalcin if (!imageext) savename = filename; 528067a7d5SLisandro Dalcin else if (imageext != filename) { 5371ed57bfSLisandro Dalcin size_t l1 = 0, l2 = 0; 549566063dSJacob Faibussowitsch PetscCall(PetscStrlen(filename, &l1)); 559566063dSJacob Faibussowitsch PetscCall(PetscStrlen(imageext, &l2)); 569566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(buf, filename, l1 - l2 + 1)); 578067a7d5SLisandro Dalcin savename = buf; 585b399a63SLisandro Dalcin } 5971ed57bfSLisandro Dalcin } 6071ed57bfSLisandro Dalcin 619566063dSJacob Faibussowitsch if (!savename) PetscCall(PetscObjectGetName((PetscObject)draw, &savename)); 629566063dSJacob Faibussowitsch PetscCall(PetscDrawImageCheckFormat(&imageext)); 638067a7d5SLisandro Dalcin 648067a7d5SLisandro Dalcin draw->savefilecount = 0; 659566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->savefilename)); 669566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->saveimageext)); 679566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(savename, &draw->savefilename)); 689566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(imageext, &draw->saveimageext)); 6949c04938SLisandro Dalcin 7049c04938SLisandro Dalcin if (draw->savesinglefile) { 719566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Will save image to file %s%s\n", draw->savefilename, draw->saveimageext)); 7249c04938SLisandro Dalcin } else { 739566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Will save images to file %s/%s_%%d%s\n", draw->savefilename, draw->savefilename, draw->saveimageext)); 7449c04938SLisandro Dalcin } 7549c04938SLisandro Dalcin PetscFunctionReturn(0); 7649c04938SLisandro Dalcin } 7749c04938SLisandro Dalcin 7849c04938SLisandro Dalcin /*@C 79811af0c4SBarry Smith PetscDrawSetSaveMovie - Saves a movie produced from a `PetscDraw` into a file 8049c04938SLisandro Dalcin 81*c3339decSBarry Smith Collective 8249c04938SLisandro Dalcin 83d8d19677SJose E. Roman Input Parameters: 8449c04938SLisandro Dalcin + draw - the graphics context 8549c04938SLisandro Dalcin - movieext - optional extension defining the movie format 8649c04938SLisandro Dalcin 873c7db156SBarry Smith Options Database Key: 8849c04938SLisandro Dalcin . -draw_save_movie <.ext> - saves a movie with extension .ext 8949c04938SLisandro Dalcin 9049c04938SLisandro Dalcin Level: intermediate 9149c04938SLisandro Dalcin 92811af0c4SBarry Smith Note: 93811af0c4SBarry Smith You should call this AFTER calling `PetscDrawSetSave()` and BEFORE creating your image with `PetscDrawSave()`. 9449c04938SLisandro Dalcin The ffmpeg utility must be in your path to make the movie. 9549c04938SLisandro Dalcin 96811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()` 9749c04938SLisandro Dalcin @*/ 98d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawSetSaveMovie(PetscDraw draw, const char movieext[]) 99d71ae5a4SJacob Faibussowitsch { 10049c04938SLisandro Dalcin PetscFunctionBegin; 10149c04938SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 10249c04938SLisandro Dalcin if (movieext) PetscValidCharPointer(movieext, 2); 10349c04938SLisandro Dalcin 1049566063dSJacob Faibussowitsch if (!draw->savefilename) PetscCall(PetscDrawSetSave(draw, "")); 1059566063dSJacob Faibussowitsch PetscCall(PetscDrawMovieCheckFormat(&movieext)); 1069566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(movieext, &draw->savemovieext)); 10749c04938SLisandro Dalcin draw->savesinglefile = PETSC_FALSE; /* otherwise we cannot generage movies */ 10849c04938SLisandro Dalcin 1099566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Will save movie to file %s%s\n", draw->savefilename, draw->savemovieext)); 1105b399a63SLisandro Dalcin PetscFunctionReturn(0); 1115b399a63SLisandro Dalcin } 1125b399a63SLisandro Dalcin 1135b399a63SLisandro Dalcin /*@C 114811af0c4SBarry Smith PetscDrawSetSaveFinalImage - Saves the final image produced in a `PetscDraw` into a file 1155b399a63SLisandro Dalcin 116*c3339decSBarry Smith Collective 1175b399a63SLisandro Dalcin 118d8d19677SJose E. Roman Input Parameters: 1195b399a63SLisandro Dalcin + draw - the graphics context 120811af0c4SBarry Smith - filename - name of the file, if NULL or empty uses name set with `PetscDrawSetSave()` or the name of the draw object 1215b399a63SLisandro Dalcin 1223c7db156SBarry Smith Options Database Key: 1238067a7d5SLisandro 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) 1245b399a63SLisandro Dalcin 1255b399a63SLisandro Dalcin Level: intermediate 1265b399a63SLisandro Dalcin 12795452b02SPatrick Sanan Notes: 128811af0c4SBarry Smith You should call this BEFORE creating your image and calling `PetscDrawSave()`. 129811af0c4SBarry Smith 1308067a7d5SLisandro Dalcin The supported image types are .png, .gif, and .ppm (PETSc chooses the default in that order). 131811af0c4SBarry Smith .vb 1328067a7d5SLisandro Dalcin Support for .png images requires configure --with-libpng. 1338067a7d5SLisandro Dalcin Support for .gif images requires configure --with-giflib. 1348067a7d5SLisandro Dalcin Support for .jpg images requires configure --with-libjpeg. 1358067a7d5SLisandro Dalcin Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB). 136811af0c4SBarry Smith .ve 1375b399a63SLisandro Dalcin 138811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()`, `PetscDrawSetFromOptions()`, `PetscDrawCreate()`, `PetscDrawDestroy()` 1395b399a63SLisandro Dalcin @*/ 140d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawSetSaveFinalImage(PetscDraw draw, const char filename[]) 141d71ae5a4SJacob Faibussowitsch { 1428067a7d5SLisandro Dalcin char buf[PETSC_MAX_PATH_LEN]; 1435b399a63SLisandro Dalcin 1445b399a63SLisandro Dalcin PetscFunctionBegin; 1455b399a63SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 1468067a7d5SLisandro Dalcin if (!filename || !filename[0]) { 1478067a7d5SLisandro Dalcin if (!draw->savefilename) { 1489566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)draw, &filename)); 1495b399a63SLisandro Dalcin } else { 1509566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(buf, sizeof(buf), "%s%s", draw->savefilename, draw->saveimageext)); 1518067a7d5SLisandro Dalcin filename = buf; 1525b399a63SLisandro Dalcin } 1538067a7d5SLisandro Dalcin } 1549566063dSJacob Faibussowitsch PetscCall(PetscFree(draw->savefinalfilename)); 1559566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(filename, &draw->savefinalfilename)); 1565b399a63SLisandro Dalcin PetscFunctionReturn(0); 1575b399a63SLisandro Dalcin } 1585b399a63SLisandro Dalcin 1595b399a63SLisandro Dalcin /*@ 1605b399a63SLisandro Dalcin PetscDrawSave - Saves a drawn image 1615b399a63SLisandro Dalcin 162*c3339decSBarry Smith Collective 1635b399a63SLisandro Dalcin 1645b399a63SLisandro Dalcin Input Parameters: 1655b399a63SLisandro Dalcin . draw - the drawing context 1665b399a63SLisandro Dalcin 1675b399a63SLisandro Dalcin Level: advanced 1685b399a63SLisandro Dalcin 169811af0c4SBarry Smith Note: 17095452b02SPatrick Sanan this is not normally called by the user. 1715b399a63SLisandro Dalcin 172811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()` 1735b399a63SLisandro Dalcin @*/ 174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawSave(PetscDraw draw) 175d71ae5a4SJacob Faibussowitsch { 17649c04938SLisandro Dalcin PetscInt saveindex; 1778067a7d5SLisandro Dalcin char basename[PETSC_MAX_PATH_LEN]; 1788067a7d5SLisandro Dalcin unsigned char palette[256][3]; 1798067a7d5SLisandro Dalcin unsigned int w, h; 1808067a7d5SLisandro Dalcin unsigned char *pixels = NULL; 1818067a7d5SLisandro Dalcin PetscMPIInt rank; 1825b399a63SLisandro Dalcin 1835b399a63SLisandro Dalcin PetscFunctionBegin; 1845b399a63SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 18549c04938SLisandro Dalcin if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 1869371c9d4SSatish Balay if (draw->ops->save) { 1879371c9d4SSatish Balay PetscUseTypeMethod(draw, save); 1889371c9d4SSatish Balay goto finally; 1899371c9d4SSatish Balay } 19049c04938SLisandro Dalcin if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0); 1919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank)); 1928067a7d5SLisandro Dalcin 19349c04938SLisandro Dalcin saveindex = draw->savefilecount++; 1948067a7d5SLisandro Dalcin 195dd400576SPatrick Sanan if (rank == 0 && !saveindex) { 1968067a7d5SLisandro Dalcin char path[PETSC_MAX_PATH_LEN]; 1978067a7d5SLisandro Dalcin if (draw->savesinglefile) { 1989566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(path, sizeof(path), "%s%s", draw->savefilename, draw->saveimageext)); 1998067a7d5SLisandro Dalcin (void)remove(path); 2008067a7d5SLisandro Dalcin } else { 2019566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(path, sizeof(path), "%s", draw->savefilename)); 2029566063dSJacob Faibussowitsch PetscCall(PetscRMTree(path)); 2039566063dSJacob Faibussowitsch PetscCall(PetscMkdir(path)); 2048067a7d5SLisandro Dalcin } 2058067a7d5SLisandro Dalcin if (draw->savemovieext) { 2069566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(path, sizeof(path), "%s%s", draw->savefilename, draw->savemovieext)); 2078067a7d5SLisandro Dalcin (void)remove(path); 2088067a7d5SLisandro Dalcin } 2098067a7d5SLisandro Dalcin } 2108067a7d5SLisandro Dalcin if (draw->savesinglefile) { 2119566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(basename, sizeof(basename), "%s", draw->savefilename)); 2128067a7d5SLisandro Dalcin } else { 21380603804SMatthew G. Knepley char *basefilename; 21480603804SMatthew G. Knepley 2159566063dSJacob Faibussowitsch PetscCall(PetscStrrchr(draw->savefilename, '/', (char **)&basefilename)); 21680603804SMatthew G. Knepley if (basefilename != draw->savefilename) { 2179566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(basename, sizeof(basename), "%s_%d", draw->savefilename, (int)saveindex)); 21880603804SMatthew G. Knepley } else { 2199566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(basename, sizeof(basename), "%s/%s_%d", draw->savefilename, draw->savefilename, (int)saveindex)); 2208067a7d5SLisandro Dalcin } 22180603804SMatthew G. Knepley } 2228067a7d5SLisandro Dalcin 2238067a7d5SLisandro Dalcin /* this call is collective, only the first process gets the image data */ 224dbbe0bcdSBarry Smith PetscUseTypeMethod(draw, getimage, palette, &w, &h, &pixels); 2258067a7d5SLisandro Dalcin /* only the first process handles the saving business */ 2269566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscDrawImageSave(basename, draw->saveimageext, palette, w, h, pixels)); 2279566063dSJacob Faibussowitsch PetscCall(PetscFree(pixels)); 2289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PetscObjectComm((PetscObject)draw))); 2298067a7d5SLisandro Dalcin 2308067a7d5SLisandro Dalcin finally: 2318067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS) 2329566063dSJacob Faibussowitsch PetscCall(PetscDrawSave_SAWs(draw)); 2338067a7d5SLisandro Dalcin #endif 2348067a7d5SLisandro Dalcin PetscFunctionReturn(0); 2358067a7d5SLisandro Dalcin } 2368067a7d5SLisandro Dalcin 23749c04938SLisandro Dalcin /*@ 23849c04938SLisandro Dalcin PetscDrawSaveMovie - Saves a movie from previously saved images 23949c04938SLisandro Dalcin 240*c3339decSBarry Smith Collective 24149c04938SLisandro Dalcin 24249c04938SLisandro Dalcin Input Parameters: 24349c04938SLisandro Dalcin . draw - the drawing context 24449c04938SLisandro Dalcin 24549c04938SLisandro Dalcin Level: advanced 24649c04938SLisandro Dalcin 24795452b02SPatrick Sanan Notes: 248811af0c4SBarry Smith This is not normally called by the user. 249811af0c4SBarry Smith 25049c04938SLisandro Dalcin The ffmpeg utility must be in your path to make the movie. 25149c04938SLisandro Dalcin 252811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawSetSave()`, `PetscDrawSetSaveMovie()` 25349c04938SLisandro Dalcin @*/ 254d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawSaveMovie(PetscDraw draw) 255d71ae5a4SJacob Faibussowitsch { 25649c04938SLisandro Dalcin PetscMPIInt rank; 25749c04938SLisandro Dalcin 25849c04938SLisandro Dalcin PetscFunctionBegin; 25949c04938SLisandro Dalcin PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 26049c04938SLisandro Dalcin if (!draw->ops->save && !draw->ops->getimage) PetscFunctionReturn(0); 26149c04938SLisandro Dalcin if (!draw->savefilename || !draw->savemovieext || draw->savesinglefile) PetscFunctionReturn(0); 2629566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)draw), &rank)); 26349c04938SLisandro Dalcin { 26449c04938SLisandro Dalcin const char *fname = draw->savefilename; 26549c04938SLisandro Dalcin const char *imext = draw->saveimageext; 26649c04938SLisandro Dalcin const char *mvext = draw->savemovieext; 2679566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscDrawMovieSave(fname, draw->savefilecount, imext, draw->savemoviefps, mvext)); 2689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(PetscObjectComm((PetscObject)draw))); 26949c04938SLisandro Dalcin } 27049c04938SLisandro Dalcin PetscFunctionReturn(0); 27149c04938SLisandro Dalcin } 27249c04938SLisandro Dalcin 2738067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SAWS) 2748067a7d5SLisandro Dalcin #include <petscviewersaws.h> 2758067a7d5SLisandro Dalcin /* 2768067a7d5SLisandro Dalcin The PetscImageList object and functions are used to maintain a list of file images 2778067a7d5SLisandro Dalcin that can be displayed by the SAWs webserver. 2788067a7d5SLisandro Dalcin */ 2798067a7d5SLisandro Dalcin typedef struct _P_PetscImageList *PetscImageList; 2808067a7d5SLisandro Dalcin struct _P_PetscImageList { 2818067a7d5SLisandro Dalcin PetscImageList next; 2828067a7d5SLisandro Dalcin char *filename; 2838067a7d5SLisandro Dalcin char *ext; 2848067a7d5SLisandro Dalcin PetscInt count; 2858067a7d5SLisandro Dalcin }; 2868067a7d5SLisandro Dalcin 2878067a7d5SLisandro Dalcin static PetscImageList SAWs_images = NULL; 2888067a7d5SLisandro Dalcin 289d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscImageListDestroy(void) 290d71ae5a4SJacob Faibussowitsch { 2918067a7d5SLisandro Dalcin PetscImageList image = SAWs_images; 2928067a7d5SLisandro Dalcin 2938067a7d5SLisandro Dalcin PetscFunctionBegin; 2948067a7d5SLisandro Dalcin while (image) { 2958067a7d5SLisandro Dalcin PetscImageList next = image->next; 2969566063dSJacob Faibussowitsch PetscCall(PetscFree(image->filename)); 2979566063dSJacob Faibussowitsch PetscCall(PetscFree(image->ext)); 2989566063dSJacob Faibussowitsch PetscCall(PetscFree(image)); 2998067a7d5SLisandro Dalcin image = next; 3005b399a63SLisandro Dalcin } 3015b399a63SLisandro Dalcin PetscFunctionReturn(0); 3025b399a63SLisandro Dalcin } 3038067a7d5SLisandro Dalcin 304d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscImageListAdd(const char filename[], const char ext[], PetscInt count) 305d71ae5a4SJacob Faibussowitsch { 3068067a7d5SLisandro Dalcin PetscImageList image, oimage = SAWs_images; 3078067a7d5SLisandro Dalcin PetscBool flg; 3088067a7d5SLisandro Dalcin 3098067a7d5SLisandro Dalcin PetscFunctionBegin; 3108067a7d5SLisandro Dalcin if (oimage) { 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 while (oimage->next) { 3178067a7d5SLisandro Dalcin oimage = oimage->next; 3189566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(filename, oimage->filename, &flg)); 3198067a7d5SLisandro Dalcin if (flg) { 3208067a7d5SLisandro Dalcin oimage->count = count; 3218067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3228067a7d5SLisandro Dalcin } 3238067a7d5SLisandro Dalcin } 3249566063dSJacob Faibussowitsch PetscCall(PetscNew(&image)); 3258067a7d5SLisandro Dalcin oimage->next = image; 3268067a7d5SLisandro Dalcin } else { 3279566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(PetscImageListDestroy)); 3289566063dSJacob Faibussowitsch PetscCall(PetscNew(&image)); 3298067a7d5SLisandro Dalcin SAWs_images = image; 3308067a7d5SLisandro Dalcin } 3319566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(filename, &image->filename)); 3329566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ext, &image->ext)); 3338067a7d5SLisandro Dalcin image->count = count; 3348067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3358067a7d5SLisandro Dalcin } 3368067a7d5SLisandro Dalcin 337d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawSave_SAWs(PetscDraw draw) 338d71ae5a4SJacob Faibussowitsch { 3398067a7d5SLisandro Dalcin PetscImageList image; 3408067a7d5SLisandro Dalcin char body[4096]; 3418067a7d5SLisandro Dalcin size_t len = 0; 3428067a7d5SLisandro Dalcin 3438067a7d5SLisandro Dalcin PetscFunctionBegin; 34449c04938SLisandro Dalcin if (!draw->savefilename || !draw->saveimageext) PetscFunctionReturn(0); 3459566063dSJacob Faibussowitsch PetscCall(PetscImageListAdd(draw->savefilename, draw->saveimageext, draw->savefilecount - 1)); 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) { 3519566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(body + len, 4086 - len, "<img src=\"%s%s\" alt=\"None\">", name, ext)); 3528067a7d5SLisandro Dalcin } else { 3539566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(body + len, 4086 - len, "<img src=\"%s/%s_%d%s\" alt=\"None\">", name, name, image->count, ext)); 3548067a7d5SLisandro Dalcin } 3559566063dSJacob Faibussowitsch PetscCall(PetscStrlen(body, &len)); 3568067a7d5SLisandro Dalcin image = image->next; 3578067a7d5SLisandro Dalcin } 3589566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(body, "<br>\n", sizeof(body))); 359792fecdfSBarry Smith if (draw->savefilecount > 0) PetscCallSAWs(SAWs_Pop_Body, ("index.html", 1)); 360792fecdfSBarry Smith PetscCallSAWs(SAWs_Push_Body, ("index.html", 1, body)); 3618067a7d5SLisandro Dalcin PetscFunctionReturn(0); 3628067a7d5SLisandro Dalcin } 3638067a7d5SLisandro Dalcin 3648067a7d5SLisandro Dalcin #endif 365