1*8067a7d5SLisandro Dalcin #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 2*8067a7d5SLisandro Dalcin 3*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageSave(const char[],const char[],unsigned char[][3],unsigned int,unsigned int,const unsigned char[]); 4*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawMovieSave(const char[],PetscInt,const char[],const char[]); 5*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageCheckFormat(const char *[]); 6*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawMovieCheckFormat(const char *[]); 7*8067a7d5SLisandro Dalcin 8*8067a7d5SLisandro Dalcin /* 9*8067a7d5SLisandro Dalcin Code to write images in PPM format 10*8067a7d5SLisandro Dalcin */ 11*8067a7d5SLisandro Dalcin #undef __FUNCT__ 12*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawImageSavePPM" 13*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageSavePPM(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 14*8067a7d5SLisandro Dalcin { 15*8067a7d5SLisandro Dalcin int fd; 16*8067a7d5SLisandro Dalcin char header[32]; 17*8067a7d5SLisandro Dalcin size_t hdrlen; 18*8067a7d5SLisandro Dalcin unsigned char *rgb; 19*8067a7d5SLisandro Dalcin PetscErrorCode ierr; 20*8067a7d5SLisandro Dalcin 21*8067a7d5SLisandro Dalcin PetscFunctionBegin; 22*8067a7d5SLisandro Dalcin PetscValidCharPointer(filename,1); 23*8067a7d5SLisandro Dalcin if (palette) PetscValidCharPointer(palette,2); 24*8067a7d5SLisandro Dalcin PetscValidCharPointer(pixels,5); 25*8067a7d5SLisandro Dalcin /* map pixels to RGB colors */ 26*8067a7d5SLisandro Dalcin if (palette) { 27*8067a7d5SLisandro Dalcin int k,p,n = (int)(w*h); 28*8067a7d5SLisandro Dalcin const unsigned char *colordef; 29*8067a7d5SLisandro Dalcin ierr = PetscMalloc1(3*w*h,&rgb);CHKERRQ(ierr); 30*8067a7d5SLisandro Dalcin for (k=p=0; k<n; k++) { 31*8067a7d5SLisandro Dalcin colordef = palette[pixels[k]]; 32*8067a7d5SLisandro Dalcin rgb[p++] = colordef[0]; 33*8067a7d5SLisandro Dalcin rgb[p++] = colordef[1]; 34*8067a7d5SLisandro Dalcin rgb[p++] = colordef[2]; 35*8067a7d5SLisandro Dalcin } 36*8067a7d5SLisandro Dalcin } else { /* assume pixels are RGB colors */ 37*8067a7d5SLisandro Dalcin rgb = (unsigned char*)pixels; 38*8067a7d5SLisandro Dalcin } 39*8067a7d5SLisandro Dalcin /* open file and write PPM header */ 40*8067a7d5SLisandro Dalcin ierr = PetscBinaryOpen(filename,FILE_MODE_WRITE,&fd);CHKERRQ(ierr); 41*8067a7d5SLisandro Dalcin ierr = PetscSNPrintf(header,sizeof(header),"P6\n%d %d\n255\n\0",(int)w,(int)h);CHKERRQ(ierr); 42*8067a7d5SLisandro Dalcin ierr = PetscStrlen(header,&hdrlen);CHKERRQ(ierr); 43*8067a7d5SLisandro Dalcin ierr = PetscBinaryWrite(fd,header,hdrlen,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 44*8067a7d5SLisandro Dalcin /* write image data and close file */ 45*8067a7d5SLisandro Dalcin ierr = PetscBinaryWrite(fd,rgb,3*w*h,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 46*8067a7d5SLisandro Dalcin ierr = PetscBinaryClose(fd);CHKERRQ(ierr); 47*8067a7d5SLisandro Dalcin if (palette) {ierr = PetscFree(rgb);CHKERRQ(ierr);} 48*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 49*8067a7d5SLisandro Dalcin } 50*8067a7d5SLisandro Dalcin 51*8067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawImageSave_PPM(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 52*8067a7d5SLisandro Dalcin { return PetscDrawImageSavePPM(filename,palette,w,h,pixels); } 53*8067a7d5SLisandro Dalcin 54*8067a7d5SLisandro Dalcin 55*8067a7d5SLisandro Dalcin /* 56*8067a7d5SLisandro Dalcin Code to write images in PNG format 57*8067a7d5SLisandro Dalcin */ 58*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_LIBPNG) 59*8067a7d5SLisandro Dalcin 60*8067a7d5SLisandro Dalcin #include <png.h> 61*8067a7d5SLisandro Dalcin 62*8067a7d5SLisandro Dalcin #if defined(PNG_SETJMP_SUPPORTED) 63*8067a7d5SLisandro Dalcin # ifndef png_jmpbuf 64*8067a7d5SLisandro Dalcin # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 65*8067a7d5SLisandro Dalcin # endif 66*8067a7d5SLisandro Dalcin #endif 67*8067a7d5SLisandro Dalcin 68*8067a7d5SLisandro Dalcin #undef __FUNCT__ 69*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawImageSavePNG" 70*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageSavePNG(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 71*8067a7d5SLisandro Dalcin { 72*8067a7d5SLisandro Dalcin FILE *fp; 73*8067a7d5SLisandro Dalcin png_struct *png_ptr; 74*8067a7d5SLisandro Dalcin png_info *info_ptr; 75*8067a7d5SLisandro Dalcin unsigned int row, stride = palette ? w : 3*w; 76*8067a7d5SLisandro Dalcin PetscErrorCode ierr; 77*8067a7d5SLisandro Dalcin 78*8067a7d5SLisandro Dalcin PetscFunctionBegin; 79*8067a7d5SLisandro Dalcin PetscValidCharPointer(filename,1); 80*8067a7d5SLisandro Dalcin if (palette) PetscValidCharPointer(palette,2); 81*8067a7d5SLisandro Dalcin PetscValidCharPointer(pixels,5); 82*8067a7d5SLisandro Dalcin 83*8067a7d5SLisandro Dalcin /* open file and create libpng structures */ 84*8067a7d5SLisandro Dalcin ierr = PetscFOpen(PETSC_COMM_SELF,filename,"wb",&fp);CHKERRQ(ierr); 85*8067a7d5SLisandro Dalcin png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); 86*8067a7d5SLisandro Dalcin if (!png_ptr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot create PNG context"); 87*8067a7d5SLisandro Dalcin info_ptr = png_create_info_struct(png_ptr); 88*8067a7d5SLisandro Dalcin if (!info_ptr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot create PNG context"); 89*8067a7d5SLisandro Dalcin 90*8067a7d5SLisandro Dalcin /* setup libpng error handling */ 91*8067a7d5SLisandro Dalcin #if defined(PNG_SETJMP_SUPPORTED) 92*8067a7d5SLisandro Dalcin if (setjmp(png_jmpbuf(png_ptr))) { 93*8067a7d5SLisandro Dalcin png_destroy_write_struct(&png_ptr,&info_ptr); 94*8067a7d5SLisandro Dalcin (void)PetscFClose(PETSC_COMM_SELF,fp); 95*8067a7d5SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error writing PNG file %s",filename); 96*8067a7d5SLisandro Dalcin } 97*8067a7d5SLisandro Dalcin #endif 98*8067a7d5SLisandro Dalcin 99*8067a7d5SLisandro Dalcin /* setup PNG image metadata */ 100*8067a7d5SLisandro Dalcin png_init_io(png_ptr, fp); 101*8067a7d5SLisandro Dalcin png_set_IHDR(png_ptr, info_ptr, w, h, /*depth*/8, 102*8067a7d5SLisandro Dalcin palette ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_RGB, 103*8067a7d5SLisandro Dalcin PNG_INTERLACE_NONE, 104*8067a7d5SLisandro Dalcin PNG_COMPRESSION_TYPE_DEFAULT, 105*8067a7d5SLisandro Dalcin PNG_FILTER_TYPE_DEFAULT); 106*8067a7d5SLisandro Dalcin if (palette) 107*8067a7d5SLisandro Dalcin png_set_PLTE(png_ptr, info_ptr, (png_color*)palette, 256); 108*8067a7d5SLisandro Dalcin 109*8067a7d5SLisandro Dalcin /* write PNG image header and data */ 110*8067a7d5SLisandro Dalcin png_write_info(png_ptr, info_ptr); 111*8067a7d5SLisandro Dalcin for (row = 0; row < h; row++) 112*8067a7d5SLisandro Dalcin png_write_row(png_ptr, pixels + row*stride); 113*8067a7d5SLisandro Dalcin png_write_end(png_ptr, NULL); 114*8067a7d5SLisandro Dalcin 115*8067a7d5SLisandro Dalcin /* destroy libpng structures and close file */ 116*8067a7d5SLisandro Dalcin png_destroy_write_struct(&png_ptr, &info_ptr); 117*8067a7d5SLisandro Dalcin ierr = PetscFClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 118*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 119*8067a7d5SLisandro Dalcin } 120*8067a7d5SLisandro Dalcin 121*8067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawImageSave_PNG(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 122*8067a7d5SLisandro Dalcin { return PetscDrawImageSavePNG(filename,palette,w,h,pixels); } 123*8067a7d5SLisandro Dalcin 124*8067a7d5SLisandro Dalcin #endif/*!PETSC_HAVE_LIBPNG*/ 125*8067a7d5SLisandro Dalcin 126*8067a7d5SLisandro Dalcin 127*8067a7d5SLisandro Dalcin /* 128*8067a7d5SLisandro Dalcin Code to write images in GIF format 129*8067a7d5SLisandro Dalcin */ 130*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_GIFLIB) 131*8067a7d5SLisandro Dalcin 132*8067a7d5SLisandro Dalcin #include <gif_lib.h> 133*8067a7d5SLisandro Dalcin 134*8067a7d5SLisandro Dalcin #if !defined(GIFLIB_MAJOR) || GIFLIB_MAJOR < 5 135*8067a7d5SLisandro Dalcin #define GifMakeMapObject MakeMapObject 136*8067a7d5SLisandro Dalcin #define GifFreeMapObject FreeMapObject 137*8067a7d5SLisandro Dalcin #define EGifOpenFileName(n,b,err) EGifOpenFileName(n,b) 138*8067a7d5SLisandro Dalcin #define EGifOpenFileHandle(h,err) EGifOpenFileName(h) 139*8067a7d5SLisandro Dalcin #define EGifCloseFile(f,err) EGifCloseFile(f) 140*8067a7d5SLisandro Dalcin #endif 141*8067a7d5SLisandro Dalcin 142*8067a7d5SLisandro Dalcin #undef __FUNCT__ 143*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawImageSaveGIF" 144*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageSaveGIF(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 145*8067a7d5SLisandro Dalcin { 146*8067a7d5SLisandro Dalcin int Row, Error; 147*8067a7d5SLisandro Dalcin int Width = (int)w; 148*8067a7d5SLisandro Dalcin int Height = (int)h; 149*8067a7d5SLisandro Dalcin int ColorRes = 8; 150*8067a7d5SLisandro Dalcin int ColorCount = 256; 151*8067a7d5SLisandro Dalcin ColorMapObject *GifCMap = NULL; 152*8067a7d5SLisandro Dalcin GifFileType *GifFile = NULL; 153*8067a7d5SLisandro Dalcin # define SETERRGIF(msg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,msg", GIF file: %s",filename) 154*8067a7d5SLisandro Dalcin # define CHKERRGIF(msg) do {if (Error != GIF_OK) SETERRGIF(msg);} while(0) 155*8067a7d5SLisandro Dalcin 156*8067a7d5SLisandro Dalcin PetscFunctionBegin; 157*8067a7d5SLisandro Dalcin PetscValidCharPointer(filename,1); 158*8067a7d5SLisandro Dalcin PetscValidCharPointer(palette,2); 159*8067a7d5SLisandro Dalcin PetscValidCharPointer(pixels,5); 160*8067a7d5SLisandro Dalcin 161*8067a7d5SLisandro Dalcin GifCMap = GifMakeMapObject(ColorCount, (GifColorType*)palette); if (!GifCMap) SETERRGIF("Allocating colormap"); 162*8067a7d5SLisandro Dalcin GifFile = EGifOpenFileName(filename, 0, NULL); if (!GifFile) SETERRGIF("Opening"); 163*8067a7d5SLisandro Dalcin Error = EGifPutScreenDesc(GifFile, Width, Height, ColorRes, 0, GifCMap); CHKERRGIF("Writing screen descriptor"); 164*8067a7d5SLisandro Dalcin Error = EGifPutImageDesc(GifFile, 0, 0, Width, Height, 0, NULL); CHKERRGIF("Writing image descriptor"); 165*8067a7d5SLisandro Dalcin for (Row = 0; Row < Height; Row++) { 166*8067a7d5SLisandro Dalcin Error = EGifPutLine(GifFile, (GifPixelType*)pixels + Row*Width, Width); CHKERRGIF("Writing image pixels"); 167*8067a7d5SLisandro Dalcin } 168*8067a7d5SLisandro Dalcin Error = EGifCloseFile(GifFile, NULL); CHKERRGIF("Closing"); 169*8067a7d5SLisandro Dalcin GifFreeMapObject(GifCMap); GifCMap = NULL; 170*8067a7d5SLisandro Dalcin 171*8067a7d5SLisandro Dalcin # undef SETERRGIF 172*8067a7d5SLisandro Dalcin # undef CHKERRGIF 173*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 174*8067a7d5SLisandro Dalcin } 175*8067a7d5SLisandro Dalcin 176*8067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawImageSave_GIF(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 177*8067a7d5SLisandro Dalcin { return PetscDrawImageSaveGIF(filename,palette,w,h,pixels); } 178*8067a7d5SLisandro Dalcin 179*8067a7d5SLisandro Dalcin #endif/*!PETSC_HAVE_GIFLIB*/ 180*8067a7d5SLisandro Dalcin 181*8067a7d5SLisandro Dalcin /* 182*8067a7d5SLisandro Dalcin Code to write images in JPEG format 183*8067a7d5SLisandro Dalcin */ 184*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_LIBJPEG) 185*8067a7d5SLisandro Dalcin 186*8067a7d5SLisandro Dalcin #include <jpeglib.h> 187*8067a7d5SLisandro Dalcin 188*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H) 189*8067a7d5SLisandro Dalcin #include <setjmp.h> 190*8067a7d5SLisandro Dalcin static jmp_buf petsc_jpeg_jumpbuf; 191*8067a7d5SLisandro Dalcin static void petsc_jpeg_error_longjmp (j_common_ptr cinfo) { (void)cinfo; longjmp(petsc_jpeg_jumpbuf,1); } 192*8067a7d5SLisandro Dalcin #endif 193*8067a7d5SLisandro Dalcin 194*8067a7d5SLisandro Dalcin #undef __FUNCT__ 195*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawImageSaveJPG" 196*8067a7d5SLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscDrawImageSaveJPG(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 197*8067a7d5SLisandro Dalcin { 198*8067a7d5SLisandro Dalcin unsigned char *rgbpixels; 199*8067a7d5SLisandro Dalcin FILE *fp; 200*8067a7d5SLisandro Dalcin struct jpeg_compress_struct cinfo; 201*8067a7d5SLisandro Dalcin struct jpeg_error_mgr jerr; 202*8067a7d5SLisandro Dalcin PetscErrorCode ierr; 203*8067a7d5SLisandro Dalcin 204*8067a7d5SLisandro Dalcin PetscFunctionBegin; 205*8067a7d5SLisandro Dalcin PetscValidCharPointer(filename,1); 206*8067a7d5SLisandro Dalcin if (palette) PetscValidCharPointer(palette,2); 207*8067a7d5SLisandro Dalcin PetscValidCharPointer(pixels,5); 208*8067a7d5SLisandro Dalcin /* map pixels to RGB colors */ 209*8067a7d5SLisandro Dalcin if (palette) { 210*8067a7d5SLisandro Dalcin int k,p,n = (int)(w*h); 211*8067a7d5SLisandro Dalcin const unsigned char *colordef; 212*8067a7d5SLisandro Dalcin ierr = PetscMalloc1(3*w*h,&rgbpixels);CHKERRQ(ierr); 213*8067a7d5SLisandro Dalcin for (k=p=0; k<n; k++) { 214*8067a7d5SLisandro Dalcin colordef = palette[pixels[k]]; 215*8067a7d5SLisandro Dalcin rgbpixels[p++] = colordef[0]; 216*8067a7d5SLisandro Dalcin rgbpixels[p++] = colordef[1]; 217*8067a7d5SLisandro Dalcin rgbpixels[p++] = colordef[2]; 218*8067a7d5SLisandro Dalcin } 219*8067a7d5SLisandro Dalcin } else { /* assume pixels are RGB colors */ 220*8067a7d5SLisandro Dalcin rgbpixels = (unsigned char*)pixels; 221*8067a7d5SLisandro Dalcin } 222*8067a7d5SLisandro Dalcin ierr = PetscFOpen(PETSC_COMM_SELF,filename,"wb",&fp);CHKERRQ(ierr); 223*8067a7d5SLisandro Dalcin 224*8067a7d5SLisandro Dalcin cinfo.err = jpeg_std_error(&jerr); 225*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H) 226*8067a7d5SLisandro Dalcin jerr.error_exit = petsc_jpeg_error_longjmp; 227*8067a7d5SLisandro Dalcin if (setjmp(petsc_jpeg_jumpbuf)) { 228*8067a7d5SLisandro Dalcin char message[JMSG_LENGTH_MAX]; 229*8067a7d5SLisandro Dalcin jerr.format_message((j_common_ptr)&cinfo,message); 230*8067a7d5SLisandro Dalcin jpeg_destroy_compress(&cinfo); 231*8067a7d5SLisandro Dalcin (void)PetscFClose(PETSC_COMM_SELF,fp); 232*8067a7d5SLisandro Dalcin SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error writing JPEG file %s\n%s",filename,message); 233*8067a7d5SLisandro Dalcin } 234*8067a7d5SLisandro Dalcin #endif 235*8067a7d5SLisandro Dalcin jpeg_create_compress(&cinfo); 236*8067a7d5SLisandro Dalcin jpeg_stdio_dest(&cinfo,fp); 237*8067a7d5SLisandro Dalcin cinfo.image_width = w; 238*8067a7d5SLisandro Dalcin cinfo.image_height = h; 239*8067a7d5SLisandro Dalcin cinfo.input_components = 3; 240*8067a7d5SLisandro Dalcin cinfo.in_color_space = JCS_RGB; 241*8067a7d5SLisandro Dalcin jpeg_set_defaults(&cinfo); 242*8067a7d5SLisandro Dalcin jpeg_start_compress(&cinfo,TRUE); 243*8067a7d5SLisandro Dalcin while (cinfo.next_scanline < cinfo.image_height) { 244*8067a7d5SLisandro Dalcin unsigned char *rowptr = rgbpixels + cinfo.next_scanline * 3*w; 245*8067a7d5SLisandro Dalcin (void)jpeg_write_scanlines(&cinfo,&rowptr,1); 246*8067a7d5SLisandro Dalcin } 247*8067a7d5SLisandro Dalcin jpeg_finish_compress(&cinfo); 248*8067a7d5SLisandro Dalcin jpeg_destroy_compress(&cinfo); 249*8067a7d5SLisandro Dalcin 250*8067a7d5SLisandro Dalcin ierr = PetscFClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 251*8067a7d5SLisandro Dalcin if (palette) {ierr = PetscFree(rgbpixels);CHKERRQ(ierr);} 252*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 253*8067a7d5SLisandro Dalcin } 254*8067a7d5SLisandro Dalcin 255*8067a7d5SLisandro Dalcin static PetscErrorCode PetscDrawImageSave_JPG(const char filename[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 256*8067a7d5SLisandro Dalcin { return PetscDrawImageSaveJPG(filename,palette,w,h,pixels); } 257*8067a7d5SLisandro Dalcin 258*8067a7d5SLisandro Dalcin #endif/*!PETSC_HAVE_LIBJPEG*/ 259*8067a7d5SLisandro Dalcin 260*8067a7d5SLisandro Dalcin static struct { 261*8067a7d5SLisandro Dalcin const char *extension; 262*8067a7d5SLisandro Dalcin PetscErrorCode (*SaveImage)(const char[],unsigned char[][3],unsigned int,unsigned int,const unsigned char[]); 263*8067a7d5SLisandro Dalcin } PetscDrawImageSaveTable[] = { 264*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_LIBPNG) 265*8067a7d5SLisandro Dalcin {".png", PetscDrawImageSave_PNG}, 266*8067a7d5SLisandro Dalcin #endif 267*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_GIFLIB) 268*8067a7d5SLisandro Dalcin {".gif", PetscDrawImageSave_GIF}, 269*8067a7d5SLisandro Dalcin #endif 270*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_LIBJPEG) 271*8067a7d5SLisandro Dalcin {".jpg", PetscDrawImageSave_JPG}, 272*8067a7d5SLisandro Dalcin #endif 273*8067a7d5SLisandro Dalcin {".ppm", PetscDrawImageSave_PPM} 274*8067a7d5SLisandro Dalcin }; 275*8067a7d5SLisandro Dalcin 276*8067a7d5SLisandro Dalcin #undef __FUNCT__ 277*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawImageCheckFormat" 278*8067a7d5SLisandro Dalcin PetscErrorCode PetscDrawImageCheckFormat(const char *ext[]) 279*8067a7d5SLisandro Dalcin { 280*8067a7d5SLisandro Dalcin size_t k; 281*8067a7d5SLisandro Dalcin PetscBool match = PETSC_FALSE; 282*8067a7d5SLisandro Dalcin PetscErrorCode ierr; 283*8067a7d5SLisandro Dalcin 284*8067a7d5SLisandro Dalcin PetscFunctionBegin; 285*8067a7d5SLisandro Dalcin /* if extension is empty, return default format to caller */ 286*8067a7d5SLisandro Dalcin PetscValidPointer(ext,1); 287*8067a7d5SLisandro Dalcin if (!*ext || !**ext) { 288*8067a7d5SLisandro Dalcin *ext = PetscDrawImageSaveTable[0].extension; 289*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 290*8067a7d5SLisandro Dalcin } 291*8067a7d5SLisandro Dalcin /* check the extension mathes a supported format otherwise */ 292*8067a7d5SLisandro Dalcin PetscValidCharPointer(*ext,1); 293*8067a7d5SLisandro Dalcin for (k=0; k<sizeof(PetscDrawImageSaveTable)/sizeof(PetscDrawImageSaveTable[0]); k++) { 294*8067a7d5SLisandro Dalcin ierr = PetscStrcasecmp(*ext,PetscDrawImageSaveTable[k].extension,&match);CHKERRQ(ierr); 295*8067a7d5SLisandro Dalcin if (match && PetscDrawImageSaveTable[k].SaveImage) PetscFunctionReturn(0); 296*8067a7d5SLisandro Dalcin } 297*8067a7d5SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Image extension %s not supported, use .ppm",*ext); 298*8067a7d5SLisandro Dalcin PetscFunctionReturn(PETSC_ERR_SUP); 299*8067a7d5SLisandro Dalcin } 300*8067a7d5SLisandro Dalcin 301*8067a7d5SLisandro Dalcin #undef __FUNCT__ 302*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawImageSave" 303*8067a7d5SLisandro Dalcin PetscErrorCode PetscDrawImageSave(const char basename[],const char ext[],unsigned char palette[][3],unsigned int w,unsigned int h,const unsigned char pixels[]) 304*8067a7d5SLisandro Dalcin { 305*8067a7d5SLisandro Dalcin size_t k; 306*8067a7d5SLisandro Dalcin PetscBool match = PETSC_FALSE; 307*8067a7d5SLisandro Dalcin char filename[PETSC_MAX_PATH_LEN]; 308*8067a7d5SLisandro Dalcin PetscErrorCode ierr; 309*8067a7d5SLisandro Dalcin 310*8067a7d5SLisandro Dalcin PetscFunctionBegin; 311*8067a7d5SLisandro Dalcin PetscValidCharPointer(basename,1); 312*8067a7d5SLisandro Dalcin if (ext) PetscValidCharPointer(ext,2); 313*8067a7d5SLisandro Dalcin if (palette) PetscValidCharPointer(palette,3); 314*8067a7d5SLisandro Dalcin PetscValidCharPointer(pixels,6); 315*8067a7d5SLisandro Dalcin 316*8067a7d5SLisandro Dalcin ierr = PetscDrawImageCheckFormat(&ext);CHKERRQ(ierr); 317*8067a7d5SLisandro Dalcin ierr = PetscSNPrintf(filename,sizeof(filename),"%s%s",basename,ext);CHKERRQ(ierr); 318*8067a7d5SLisandro Dalcin for (k=0; k<sizeof(PetscDrawImageSaveTable)/sizeof(PetscDrawImageSaveTable[0]); k++) { 319*8067a7d5SLisandro Dalcin ierr = PetscStrcasecmp(ext,PetscDrawImageSaveTable[k].extension,&match);CHKERRQ(ierr); 320*8067a7d5SLisandro Dalcin if (match && PetscDrawImageSaveTable[k].SaveImage) { 321*8067a7d5SLisandro Dalcin ierr = PetscDrawImageSaveTable[k].SaveImage(filename,palette,w,h,pixels);CHKERRQ(ierr); 322*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 323*8067a7d5SLisandro Dalcin } 324*8067a7d5SLisandro Dalcin } 325*8067a7d5SLisandro Dalcin SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Image extension %s not supported, use .ppm",ext); 326*8067a7d5SLisandro Dalcin PetscFunctionReturn(PETSC_ERR_SUP); 327*8067a7d5SLisandro Dalcin } 328*8067a7d5SLisandro Dalcin 329*8067a7d5SLisandro Dalcin #undef __FUNCT__ 330*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawMovieCheckFormat" 331*8067a7d5SLisandro Dalcin PetscErrorCode PetscDrawMovieCheckFormat(const char *ext[]) 332*8067a7d5SLisandro Dalcin { 333*8067a7d5SLisandro Dalcin PetscFunctionBegin; 334*8067a7d5SLisandro Dalcin PetscValidPointer(ext,1); 335*8067a7d5SLisandro Dalcin if (!*ext || !**ext) *ext = ".m4v"; 336*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 337*8067a7d5SLisandro Dalcin } 338*8067a7d5SLisandro Dalcin 339*8067a7d5SLisandro Dalcin #undef __FUNCT__ 340*8067a7d5SLisandro Dalcin #define __FUNCT__ "PetscDrawMovieSave" 341*8067a7d5SLisandro Dalcin PetscErrorCode PetscDrawMovieSave(const char basename[],PetscInt count,const char imext[],const char mvext[]) 342*8067a7d5SLisandro Dalcin { 343*8067a7d5SLisandro Dalcin PetscBool imgif; 344*8067a7d5SLisandro Dalcin PetscErrorCode ierr; 345*8067a7d5SLisandro Dalcin 346*8067a7d5SLisandro Dalcin PetscFunctionBegin; 347*8067a7d5SLisandro Dalcin PetscValidCharPointer(basename,1); 348*8067a7d5SLisandro Dalcin PetscValidCharPointer(imext,3); 349*8067a7d5SLisandro Dalcin if (mvext) PetscValidCharPointer(mvext,4); 350*8067a7d5SLisandro Dalcin if (count < 1) PetscFunctionReturn(0); 351*8067a7d5SLisandro Dalcin 352*8067a7d5SLisandro Dalcin ierr = PetscStrcasecmp(imext,".gif",&imgif);CHKERRQ(ierr); 353*8067a7d5SLisandro Dalcin ierr = PetscDrawMovieCheckFormat(&mvext);CHKERRQ(ierr); 354*8067a7d5SLisandro Dalcin 355*8067a7d5SLisandro Dalcin #if defined(PETSC_HAVE_POPEN) 356*8067a7d5SLisandro Dalcin /* use ffmpeg to generate a movie */ 357*8067a7d5SLisandro Dalcin { 358*8067a7d5SLisandro Dalcin PetscInt i; 359*8067a7d5SLisandro Dalcin char filelist[PETSC_MAX_PATH_LEN]; 360*8067a7d5SLisandro Dalcin char command[64+PETSC_MAX_PATH_LEN*2]; 361*8067a7d5SLisandro Dalcin FILE *fd; 362*8067a7d5SLisandro Dalcin if (imgif) { 363*8067a7d5SLisandro Dalcin ierr = PetscSNPrintf(filelist,sizeof(filelist),"%s/%s.filelist",basename,basename);CHKERRQ(ierr); 364*8067a7d5SLisandro Dalcin ierr = PetscFOpen(PETSC_COMM_SELF,filelist,"w",&fd);CHKERRQ(ierr); 365*8067a7d5SLisandro Dalcin ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"# ffmpeg -f concat -i \"%s.filelist\" \"%s%s\"\n",basename,basename,mvext);CHKERRQ(ierr); 366*8067a7d5SLisandro Dalcin for (i=0; i<count; i++) {ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"file '%s_%d%s'\n",basename,i,imext);CHKERRQ(ierr);} 367*8067a7d5SLisandro Dalcin ierr = PetscFClose(PETSC_COMM_SELF,fd);CHKERRQ(ierr); 368*8067a7d5SLisandro Dalcin ierr = PetscSNPrintf(command,sizeof(command),"ffmpeg -loglevel error -f concat -i \"%s/%s.filelist\" \"%s%s\"",basename,basename,basename,mvext);CHKERRQ(ierr); 369*8067a7d5SLisandro Dalcin } else { 370*8067a7d5SLisandro Dalcin ierr = PetscSNPrintf(command,sizeof(command),"ffmpeg -loglevel error -i \"%s/%s_%%d%s\" \"%s%s\"",basename,basename,imext,basename,mvext);CHKERRQ(ierr); 371*8067a7d5SLisandro Dalcin } 372*8067a7d5SLisandro Dalcin ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",&fd);CHKERRQ(ierr); 373*8067a7d5SLisandro Dalcin ierr = PetscPClose(PETSC_COMM_SELF,fd,NULL);CHKERRQ(ierr); 374*8067a7d5SLisandro Dalcin } 375*8067a7d5SLisandro Dalcin #endif 376*8067a7d5SLisandro Dalcin PetscFunctionReturn(0); 377*8067a7d5SLisandro Dalcin } 378