Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

surface2png.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00004     Copyright (C) 1994-2003  Martin Bickel  and  Marc Schellenberger
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; see the file COPYING. If not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00019     Boston, MA  02111-1307  USA
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 

Generated on Tue Jun 24 01:27:52 2008 for Advanced Strategic Command by  doxygen 1.4.2