#include "PngFunctions.h" int PngColortypeFromSurface(SDL_Surface *surface) { int colortype = PNG_COLOR_TYPE_RGB; // grayscale not supported if (surface->format->palette) colortype |= PNG_COLOR_TYPE_PALETTE; else if (surface->format->Amask) colortype |= PNG_COLOR_TYPE_RGB_ALPHA; return colortype; } void PngUserWarn(png_structp ctx, png_const_charp str) { fprintf(stderr, "libpng: warning: %s\n", str); } void PngUserError(png_structp ctx, png_const_charp str) { fprintf(stderr, "libpng: error: %s\n", str); } int PngSaveSurface(const char * filename, SDL_Surface *surf) { FILE *fp; png_structp png_ptr; png_infop info_ptr; int i, colortype; png_bytep *row_pointers; // Opening output file if((fp = fopen(filename, "wb")) == NULL) { throw Exception("Screen", "fopen error"); return -1; } // Initializing png structures and callbacks if((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PngUserError, PngUserWarn)) == NULL) { throw Exception("Screen", "png_create_write_struct error!"); return -1; } if((info_ptr = png_create_info_struct(png_ptr)) == NULL) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); throw Exception("Screen", "png_create_info_struct error!"); return -1; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); throw Exception("Screen", "??"); return -1; } png_init_io(png_ptr, fp); colortype = PngColortypeFromSurface(surf); png_set_IHDR(png_ptr, info_ptr, surf->w, surf->h, 8, colortype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // Writing the image png_write_info(png_ptr, info_ptr); png_set_packing(png_ptr); row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surf->h); for (i = 0; i < surf->h; i++) row_pointers[i] = (png_bytep)(Uint8 *)surf->pixels + i*surf->pitch; png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); // Cleaning out... free(row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return 0; }