00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "resources/imagewriter.h"
00023
00024 #include "log.h"
00025
00026 #include <png.h>
00027 #include <SDL.h>
00028 #include <string>
00029
00030 bool ImageWriter::writePNG(SDL_Surface *surface, const std::string &filename)
00031 {
00032
00033 FILE *fp = fopen(filename.c_str(), "wb");
00034 if (!fp)
00035 {
00036 logger->log("could not open file %s for writing", filename.c_str());
00037 return false;
00038 }
00039
00040 png_structp png_ptr;
00041 png_infop info_ptr;
00042 png_bytep *row_pointers;
00043 int colortype;
00044
00045 if (SDL_MUSTLOCK(surface)) {
00046 SDL_LockSurface(surface);
00047 }
00048
00049 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
00050 if (!png_ptr)
00051 {
00052 logger->log("Had trouble creating png_structp");
00053 return false;
00054 }
00055
00056 info_ptr = png_create_info_struct(png_ptr);
00057 if (!info_ptr)
00058 {
00059 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00060 logger->log("Could not create png_info");
00061 return false;
00062 }
00063
00064 if (setjmp(png_jmpbuf(png_ptr)))
00065 {
00066 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00067 logger->log("problem writing to %s", filename.c_str());
00068 return false;
00069 }
00070
00071 png_init_io(png_ptr, fp);
00072
00073 colortype = (surface->format->BitsPerPixel == 24) ?
00074 PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
00075
00076 png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype,
00077 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00078
00079 png_write_info(png_ptr, info_ptr);
00080
00081 png_set_packing(png_ptr);
00082
00083 row_pointers = new png_bytep[surface->h];
00084 if (!row_pointers)
00085 {
00086 logger->log("Had trouble converting surface to row pointers");
00087 return false;
00088 }
00089
00090 for (int i = 0; i < surface->h; i++)
00091 {
00092 row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels + i * surface->pitch;
00093 }
00094
00095 png_write_image(png_ptr, row_pointers);
00096 png_write_end(png_ptr, info_ptr);
00097
00098 fclose(fp);
00099
00100 delete [] row_pointers;
00101
00102 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00103
00104 if (SDL_MUSTLOCK(surface)) {
00105 SDL_UnlockSurface(surface);
00106 }
00107
00108 return true;
00109 }