00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef NO_INTERNAL_PNG
00023 #include <SDL_image.h>
00024 #else
00025 #include <png.h>
00026 #endif
00027
00028 #include "surface2png.h"
00029 #include "../messaginghub.h"
00030
00031 void writePNG( const ASCString& filename, const Surface& s )
00032 {
00033 writePNG( filename, s, 0,0, s.w(), s.h());
00034 }
00035
00036 void writePNGtrim( const ASCString& filename, const Surface& s )
00037 {
00038 int x2 = 0;
00039 int y2 = 0;
00040 int x1 = s.w();
00041 int y1 = s.h();
00042
00043 for ( int y = 0; y < s.h(); ++y )
00044 for ( int x = 0; x < s.w(); ++x )
00045 if ( s.GetPixelFormat().GetRGBA( s.GetPixel(x,y)).a != Surface::transparent ) {
00046 x1 = min(x1, x);
00047 y1 = min(y1, y);
00048 x2 = max(x2, x);
00049 y2 = max(y2, y);
00050 }
00051
00052 writePNG( filename, s, x1,y1, x2-x1+1, y2-y1+1);
00053 }
00054
00055 void writePNG( const ASCString& filename, const Surface& s, const SDLmm::SRect& rect )
00056 {
00057 writePNG( filename, s, rect.x, rect.y, rect.w, rect.h);
00058 }
00059
00060
00061 #ifdef NO_INTERNAL_PNG
00062
00063 void writePNG( const ASCString& filename, const Surface& s, int x1, int y1, int w, int h )
00064 {
00065 if ( s.GetPixelFormat().BytesPerPixel () != 4 ) {
00066 errorMessage("Only 32 Bit images are supported for PNG writing");
00067 return;
00068 }
00069
00070 SDL_RWops *rw=SDL_RWFromFile( filename.c_str(),"wb");
00071 if(rw==NULL) {
00072 errorMessage("Could not open " + filename + " for writing");
00073 return;
00074 }
00075
00076 IMG_WritePNG_RW( rw, s.GetSurface(), x1,y1,w,h);
00077
00078 SDL_RWclose(rw);
00079
00080 }
00081
00082 #else
00083
00084 void writePNG( const ASCString& filename, const Surface& s, int x1, int y1, int w, int h )
00085 {
00086
00087 if ( x1 < 0 )
00088 x1 = 0;
00089 if ( y1 < 0 )
00090 y1 = 0;
00091 if ( w >= s.w()-x1 )
00092 w = s.w() -x1 ;
00093 if ( h >= s.h()-y1 )
00094 h = s.h() -y1 ;
00095
00096 if ( s.GetPixelFormat().BytesPerPixel() != 4 && s.GetPixelFormat().BytesPerPixel() != 1 ) {
00097 errorMessage("Only 8 Bit and 32 Bit images are supported for PNG writing");
00098 return;
00099 }
00100
00101
00102 FILE* fp = fopen(filename.c_str(), "wb");
00103 if( fp == NULL)
00104 {
00105 errorMessage("Could not open " + filename + " for writing");
00106 return;
00107 }
00108
00109 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00110 png_infop info_ptr = png_create_info_struct(png_ptr);
00111 png_init_io(png_ptr, fp);
00112
00113 png_color my_palette[256];
00114
00115 if ( s.GetPixelFormat().BytesPerPixel() == 4 ){
00116 png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00117 } else {
00118 png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
00119
00120 SDL_Palette* sdlpal = s.GetPixelFormat().palette();
00121 if ( sdlpal->ncolors > 256 ) {
00122 errorMessage("A palettes with more than 256 colors is not supported");
00123 return;
00124 }
00125
00126 for ( int c = 0; c < sdlpal->ncolors; ++c ) {
00127 my_palette[c].red = sdlpal->colors[c].r;
00128 my_palette[c].green = sdlpal->colors[c].g;
00129 my_palette[c].blue = sdlpal->colors[c].b;
00130 }
00131
00132 png_set_PLTE(png_ptr, info_ptr, my_palette, sdlpal->ncolors);
00133 }
00134
00135 time_t gmt;
00136 png_time mod_time;
00137 time(&gmt);
00138 png_convert_from_time_t(&mod_time, gmt);
00139 png_set_tIME(png_ptr, info_ptr, &mod_time);
00140
00141
00142 png_text text_ptr[1];
00143 text_ptr[0].key = const_cast<char*>("Title");
00144 text_ptr[0].text = const_cast<char*>("Advanced Strategic Command");
00145 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
00146 png_set_text(png_ptr, info_ptr, text_ptr, 1);
00147
00148
00149 Uint8* linebuf = new Uint8[w*4];
00150
00151 png_write_info(png_ptr, info_ptr);
00152
00153
00154 int iii = 0;
00155 char* pix = (char*)s.pixels();
00156 for ( int y = y1; y < y1 + h; ++y ) {
00157 Uint32* srcpix32 = (Uint32*)(pix + y * s.pitch());
00158 srcpix32 += x1;
00159 Uint8* srcpix8 = (Uint8*)(pix + y * s.pitch());
00160 srcpix8 += x1;
00161 if ( s.GetPixelFormat().BytesPerPixel() == 4) {
00162 for ( int x = 0; x < w; ++x )
00163 s.GetPixelFormat().GetRGBA( srcpix32[x], linebuf[x*4],linebuf[x*4+1],linebuf[x*4+2],linebuf[x*4+3] );
00164 } else {
00165 if ( s.GetPixelFormat().BytesPerPixel() == 1)
00166 for ( int x = 0; x < w; ++x ) {
00167 linebuf[x] = srcpix8[x];
00168 if ( linebuf[x] )
00169 ++iii;
00170 }
00171 }
00172 png_write_row(png_ptr, (png_bytep) linebuf);
00173 }
00174 delete[] linebuf;
00175
00176 png_write_end(png_ptr, info_ptr);
00177 png_destroy_write_struct(&png_ptr, &info_ptr);
00178 fclose(fp);
00179 }
00180 #endif
00181
00182