Actual source code: dsave.c
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 Parameters:
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: Notes:
29: You should call this BEFORE creating your image and calling PetscDrawSave().
30: The supported image types are .png, .gif, .jpg, and .ppm (PETSc chooses the default in that order).
31: Support for .png images requires configure --with-libpng.
32: Support for .gif images requires configure --with-giflib.
33: Support for .jpg images requires configure --with-libjpeg.
34: Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).
36: .seealso: PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy(), PetscDrawSetSaveFinalImage()
37: @*/
38: PetscErrorCode PetscDrawSetSave(PetscDraw draw,const char filename[])
39: {
40: const char *savename = NULL;
41: const char *imageext = NULL;
42: char buf[PETSC_MAX_PATH_LEN];
47: /* determine save filename and image extension */
48: if (filename && filename[0]) {
49: PetscStrchr(filename,'.',(char **)&imageext);
50: if (!imageext) savename = filename;
51: else if (imageext != filename) {
52: size_t l1 = 0,l2 = 0;
53: PetscStrlen(filename,&l1);
54: PetscStrlen(imageext,&l2);
55: PetscStrncpy(buf,filename,l1-l2+1);
56: savename = buf;
57: }
58: }
60: if (!savename) PetscObjectGetName((PetscObject)draw,&savename);
61: PetscDrawImageCheckFormat(&imageext);
63: draw->savefilecount = 0;
64: PetscFree(draw->savefilename);
65: PetscFree(draw->saveimageext);
66: PetscStrallocpy(savename,&draw->savefilename);
67: PetscStrallocpy(imageext,&draw->saveimageext);
69: if (draw->savesinglefile) {
70: PetscInfo(NULL,"Will save image to file %s%s\n",draw->savefilename,draw->saveimageext);
71: } else {
72: PetscInfo(NULL,"Will save images to file %s/%s_%%d%s\n",draw->savefilename,draw->savefilename,draw->saveimageext);
73: }
74: return 0;
75: }
77: /*@C
78: PetscDrawSetSaveMovie - Saves a movie produced from a PetscDraw into a file
80: Collective on PetscDraw
82: Input Parameters:
83: + draw - the graphics context
84: - movieext - optional extension defining the movie format
86: Options Database Command:
87: . -draw_save_movie <.ext> - saves a movie with extension .ext
89: Level: intermediate
91: Notes:
92: You should call this AFTER calling PetscDrawSetSave() and BEFORE creating your image with PetscDrawSave().
93: The ffmpeg utility must be in your path to make the movie.
95: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
96: @*/
97: PetscErrorCode PetscDrawSetSaveMovie(PetscDraw draw,const char movieext[])
98: {
102: if (!draw->savefilename) PetscDrawSetSave(draw,"");
103: PetscDrawMovieCheckFormat(&movieext);
104: PetscStrallocpy(movieext,&draw->savemovieext);
105: draw->savesinglefile = PETSC_FALSE; /* otherwise we cannot generage movies */
107: PetscInfo(NULL,"Will save movie to file %s%s\n",draw->savefilename,draw->savemovieext);
108: return 0;
109: }
111: /*@C
112: PetscDrawSetSaveFinalImage - Saves the final image produced in a PetscDraw into a file
114: Collective on PetscDraw
116: Input Parameters:
117: + draw - the graphics context
118: - filename - name of the file, if NULL or empty uses name set with PetscDrawSetSave() or name of draw object
120: Options Database Command:
121: . -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)
123: Level: intermediate
125: Notes:
126: You should call this BEFORE creating your image and calling PetscDrawSave().
127: The supported image types are .png, .gif, and .ppm (PETSc chooses the default in that order).
128: Support for .png images requires configure --with-libpng.
129: Support for .gif images requires configure --with-giflib.
130: Support for .jpg images requires configure --with-libjpeg.
131: Support for .ppm images is built-in. The PPM format has no compression (640x480 pixels ~ 900 KiB).
133: .seealso: PetscDrawSetSave(), PetscDrawSetFromOptions(), PetscDrawCreate(), PetscDrawDestroy()
134: @*/
135: PetscErrorCode PetscDrawSetSaveFinalImage(PetscDraw draw,const char filename[])
136: {
137: char buf[PETSC_MAX_PATH_LEN];
140: if (!filename || !filename[0]) {
141: if (!draw->savefilename) {
142: PetscObjectGetName((PetscObject)draw,&filename);
143: } else {
144: PetscSNPrintf(buf,sizeof(buf),"%s%s",draw->savefilename,draw->saveimageext);
145: filename = buf;
146: }
147: }
148: PetscFree(draw->savefinalfilename);
149: PetscStrallocpy(filename,&draw->savefinalfilename);
150: return 0;
151: }
153: /*@
154: PetscDrawSave - Saves a drawn image
156: Collective on PetscDraw
158: Input Parameters:
159: . draw - the drawing context
161: Level: advanced
163: Notes:
164: this is not normally called by the user.
166: .seealso: PetscDrawSetSave()
168: @*/
169: PetscErrorCode PetscDrawSave(PetscDraw draw)
170: {
171: PetscInt saveindex;
172: char basename[PETSC_MAX_PATH_LEN];
173: unsigned char palette[256][3];
174: unsigned int w,h;
175: unsigned char *pixels = NULL;
176: PetscMPIInt rank;
179: if (!draw->ops->save && !draw->ops->getimage) return 0;
180: if (draw->ops->save) {(*draw->ops->save)(draw); goto finally;}
181: if (!draw->savefilename || !draw->saveimageext) return 0;
182: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
184: saveindex = draw->savefilecount++;
186: if (rank == 0 && !saveindex) {
187: char path[PETSC_MAX_PATH_LEN];
188: if (draw->savesinglefile) {
189: PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->saveimageext);
190: (void)remove(path);
191: } else {
192: PetscSNPrintf(path,sizeof(path),"%s",draw->savefilename);
193: PetscRMTree(path);
194: PetscMkdir(path);
195: }
196: if (draw->savemovieext) {
197: PetscSNPrintf(path,sizeof(path),"%s%s",draw->savefilename,draw->savemovieext);
198: (void)remove(path);
199: }
200: }
201: if (draw->savesinglefile) {
202: PetscSNPrintf(basename,sizeof(basename),"%s",draw->savefilename);
203: } else {
204: char *basefilename;
206: PetscStrrchr(draw->savefilename, '/', (char **) &basefilename);
207: if (basefilename != draw->savefilename) {
208: PetscSNPrintf(basename,sizeof(basename),"%s_%d",draw->savefilename,(int)saveindex);
209: } else {
210: PetscSNPrintf(basename,sizeof(basename),"%s/%s_%d",draw->savefilename,draw->savefilename,(int)saveindex);
211: }
212: }
214: /* this call is collective, only the first process gets the image data */
215: (*draw->ops->getimage)(draw,palette,&w,&h,&pixels);
216: /* only the first process handles the saving business */
217: if (rank == 0) PetscDrawImageSave(basename,draw->saveimageext,palette,w,h,pixels);
218: PetscFree(pixels);
219: MPI_Barrier(PetscObjectComm((PetscObject)draw));
221: finally:
222: #if defined(PETSC_HAVE_SAWS)
223: PetscDrawSave_SAWs(draw);
224: #endif
225: return 0;
226: }
228: /*@
229: PetscDrawSaveMovie - Saves a movie from previously saved images
231: Collective on PetscDraw
233: Input Parameters:
234: . draw - the drawing context
236: Level: advanced
238: Notes:
239: this is not normally called by the user.
240: The ffmpeg utility must be in your path to make the movie.
242: .seealso: PetscDrawSetSave(), PetscDrawSetSaveMovie()
244: @*/
245: PetscErrorCode PetscDrawSaveMovie(PetscDraw draw)
246: {
247: PetscMPIInt rank;
250: if (!draw->ops->save && !draw->ops->getimage) return 0;
251: if (!draw->savefilename || !draw->savemovieext || draw->savesinglefile) return 0;
252: MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);
253: {
254: const char *fname = draw->savefilename;
255: const char *imext = draw->saveimageext;
256: const char *mvext = draw->savemovieext;
257: if (rank == 0) PetscDrawMovieSave(fname,draw->savefilecount,imext,draw->savemoviefps,mvext);
258: MPI_Barrier(PetscObjectComm((PetscObject)draw));
259: }
260: return 0;
261: }
263: #if defined(PETSC_HAVE_SAWS)
264: #include <petscviewersaws.h>
265: /*
266: The PetscImageList object and functions are used to maintain a list of file images
267: that can be displayed by the SAWs webserver.
268: */
269: typedef struct _P_PetscImageList *PetscImageList;
270: struct _P_PetscImageList {
271: PetscImageList next;
272: char *filename;
273: char *ext;
274: PetscInt count;
275: } ;
277: static PetscImageList SAWs_images = NULL;
279: static PetscErrorCode PetscImageListDestroy(void)
280: {
281: PetscImageList image = SAWs_images;
283: while (image) {
284: PetscImageList next = image->next;
285: PetscFree(image->filename);
286: PetscFree(image->ext);
287: PetscFree(image);
288: image = next;
289: }
290: return 0;
291: }
293: static PetscErrorCode PetscImageListAdd(const char filename[],const char ext[],PetscInt count)
294: {
295: PetscImageList image,oimage = SAWs_images;
296: PetscBool flg;
298: if (oimage) {
299: PetscStrcmp(filename,oimage->filename,&flg);
300: if (flg) {
301: oimage->count = count;
302: return 0;
303: }
304: while (oimage->next) {
305: oimage = oimage->next;
306: PetscStrcmp(filename,oimage->filename,&flg);
307: if (flg) {
308: oimage->count = count;
309: return 0;
310: }
311: }
312: PetscNew(&image);
313: oimage->next = image;
314: } else {
315: PetscRegisterFinalize(PetscImageListDestroy);
316: PetscNew(&image);
317: SAWs_images = image;
318: }
319: PetscStrallocpy(filename,&image->filename);
320: PetscStrallocpy(ext,&image->ext);
321: image->count = count;
322: return 0;
323: }
325: static PetscErrorCode PetscDrawSave_SAWs(PetscDraw draw)
326: {
327: PetscImageList image;
328: char body[4096];
329: size_t len = 0;
331: if (!draw->savefilename || !draw->saveimageext) return 0;
332: PetscImageListAdd(draw->savefilename,draw->saveimageext,draw->savefilecount-1);
333: image = SAWs_images;
334: while (image) {
335: const char *name = image->filename;
336: const char *ext = image->ext;
337: if (draw->savesinglefile) {
338: PetscSNPrintf(body+len,4086-len,"<img src=\"%s%s\" alt=\"None\">",name,ext);
339: } else {
340: PetscSNPrintf(body+len,4086-len,"<img src=\"%s/%s_%d%s\" alt=\"None\">",name,name,image->count,ext);
341: }
342: PetscStrlen(body,&len);
343: image = image->next;
344: }
345: PetscStrlcat(body,"<br>\n",sizeof(body));
346: if (draw->savefilecount > 0) PetscStackCallSAWs(SAWs_Pop_Body,("index.html",1));
347: PetscStackCallSAWs(SAWs_Push_Body,("index.html",1,body));
348: return 0;
349: }
351: #endif