fieldimageloader.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           textfile_evaluation.cpp  -  description
00003                              -------------------
00004     begin                : Thu Oct 06 2002
00005     copyright            : (C) 2002 by Martin Bickel
00006     email                : bickel@asc-hq.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <vector>
00019 #include <algorithm>
00020 #include <iostream>
00021 #include <SDL_image.h>
00022 #include <boost/regex.hpp>
00023 
00024 #include "global.h"
00025 #include "ascstring.h"
00026 #include "fieldimageloader.h"
00027 #include "typen.h"
00028 #include "graphics/blitter.h"
00029 
00030 #include "basestreaminterface.h"
00031 #include "stringtokenizer.h"
00032 #include "graphics/surface2png.h"
00033 
00034 
00035 const char* fileNameDelimitter = " =*/+<>,";
00036 
00037 
00038 void snowify( Surface& s, bool adaptive )
00039 {
00040    if ( !s.valid() )
00041       return;
00042    
00043    if ( s.GetPixelFormat().BitsPerPixel() != 32 )
00044       return;
00045 
00046 
00047    const int targetWhite = 210;
00048 
00049    float avg = 0;
00050    if ( adaptive ) {
00051       for ( int y = 0; y < s.h(); ++y ) {
00052          const char* c = (char*) s.pixels();
00053          c += y * s.pitch();
00054          for ( int x = 0; x < s.w(); ++x ) {
00055             uint32_t* i = (uint32_t*) c;
00056             avg +=  ((*i >> s.GetPixelFormat().Rshift()) & 0xff ) 
00057                   + ((*i >> s.GetPixelFormat().Gshift()) & 0xff ) 
00058                   + ((*i >> s.GetPixelFormat().Bshift()) & 0xff ) ;
00059             c += 4;
00060          }
00061       }
00062 
00063       avg /= float(s.h() * s.w() * 3);
00064    } else
00065       avg = 150;
00066 
00067    for ( int y = 0; y < s.h(); ++y ) {
00068       char* c = (char*) s.pixels();
00069       c += y * s.pitch();
00070       for ( int x = 0; x < s.w(); ++x ) {
00071          uint32_t* i = (uint32_t*) c;
00072          if ( ((*i >> s.GetPixelFormat().Ashift()) & 0xff ) != Surface::transparent ) {
00073             int v =  ((*i >> s.GetPixelFormat().Rshift()) & 0xff ) 
00074                   + ((*i >> s.GetPixelFormat().Gshift()) & 0xff ) 
00075                   + ((*i >> s.GetPixelFormat().Bshift()) & 0xff ) ;
00076             v /= 3;
00077             
00078             int nv = targetWhite + ( v - int(avg)) * (255-targetWhite) / 64;
00079             if ( nv > 255)
00080                nv = 255;
00081             if ( nv < 0 )
00082                nv = 0;
00083             
00084             *i = (nv << s.GetPixelFormat().Rshift()) | (nv << s.GetPixelFormat().Gshift() ) | (nv << s.GetPixelFormat().Bshift()) | (*i & s.GetPixelFormat().Amask() );
00085          }
00086          c += 4;
00087       }
00088    }
00089 }
00090 
00091 bool imageEmpty( const Surface&  s ) 
00092 {
00093    bool allWhite = true;
00094    bool allTransparent = true;
00095    int amask = s.GetPixelFormat().Amask();
00096    int areference = Surface::transparent << s.GetPixelFormat().Ashift();
00097    
00098    int colmask = s.GetPixelFormat().Rmask() | s.GetPixelFormat().Gmask() | s.GetPixelFormat().Bmask();
00099    int colref = (0xff << s.GetPixelFormat().Rshift()) | (0xff << s.GetPixelFormat().Gshift()) | (0xff << s.GetPixelFormat().Bshift());
00100    
00101    for ( int y = 0; y < s.h(); ++y ) {
00102       const char* c = (char*) s.pixels();
00103       c += y * s.pitch();
00104       for ( int x = 0; x < s.w(); ++x ) {
00105          const uint32_t* i = (uint32_t*) c;
00106          if( (*i & amask) != areference )
00107             allTransparent  = false;
00108 
00109          if ( (*i & colmask) != colref )
00110             allWhite = false;
00111          
00112          c += 4;
00113       }
00114       if ( !allWhite && !allTransparent )
00115          return false;
00116    }
00117    return allWhite || allTransparent;
00118 }
00119 
00120 vector<Surface> loadASCFieldImageArray ( const ASCString& file, int num )
00121 {
00122    vector<Surface> images;
00123 
00124    int xsize;
00125    if ( num <= 10)
00126       xsize = (num+1)* 100;
00127    else
00128       xsize = 1100;
00129 
00130    
00131    tnfilestream fs ( file, tnstream::reading );
00132    
00133    Surface s ( IMG_Load_RW ( SDL_RWFromStream( &fs ), 1));
00134    if ( !s.valid() )
00135       fatalError("could not read image " + file );
00136    
00137    if ( s.GetPixelFormat().BitsPerPixel() == 8 )
00138       s.assignDefaultPalette();
00139 
00140       
00141    int depth = s.GetPixelFormat().BitsPerPixel();
00142    
00143    for ( int i = 0; i < num; i++ ) {
00144       int x1 = (i % 10) * 100;
00145       int y1 = (i / 10) * 100;
00146       if ( depth > 8 && depth < 32 )
00147          depth = 32;
00148          
00149       Surface s2 = Surface::createSurface(fieldsizex,fieldsizey, depth );
00150       
00151       if ( s2.GetPixelFormat().BitsPerPixel() != 8 || s.GetPixelFormat().BitsPerPixel() != 8 ) {
00152          
00153          bool colorKeyAllowed = false;
00154          static boost::regex pcx( ".*\\.pcx$");
00155          boost::smatch what;
00156          if( boost::regex_match( copytoLower(file) , what, pcx)) {
00157             // warningMessage("Truecolor PCX image detected: " + file);
00158             colorKeyAllowed = true;
00159          }
00160          
00161          if ( s.GetPixelFormat().BitsPerPixel() == 32 ) {
00162             MegaBlitter<4,4,ColorTransform_None,ColorMerger_PlainOverwrite,SourcePixelSelector_Rectangle > blitter;
00163             blitter.setSrcRectangle(SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey));
00164             blitter.blit( s, s2, SPoint(0,0)  );
00165          } else {
00166             s2.Blit( s, SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey), SPoint(0,0));
00167          }
00168          applyLegacyFieldMask(s2,0,0, colorKeyAllowed);
00169          if ( colorKeyAllowed ) 
00170             s2.ColorKey2AlphaChannel();
00171          
00172          s2.detectColorKey();
00173          if ( depth != 32 || imageEmpty(s2))
00174             images.push_back( Surface() );
00175          else
00176             images.push_back ( s2 );
00177          
00178        } else {
00179           // we don't want any transformations from one palette to another; we just assume that all 8-Bit images use the same colorspace
00180           MegaBlitter<1,1,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_Rectangle > blitter;
00181           blitter.setSrcRectangle(SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey));
00182           blitter.blit( s, s2, SPoint(0,0)  );
00183           applyFieldMask(s2);
00184           s2.detectColorKey();
00185           images.push_back ( s2 );
00186        }
00187    }
00188    return images;
00189 }
00190 
00191 Surface loadASCFieldImage ( const ASCString& file, bool applyFieldMaskToImage )
00192 {
00193    StringTokenizer st ( file, fileNameDelimitter );
00194    FileName fn = st.getNextToken();
00195    fn.toLower();
00196 
00197    displayLogMessage ( 6, "loading file " + file + "\n" );
00198 
00199    if ( fn.suffix() == "png" ) {
00200       SDLmm::Surface* s = NULL;
00201       do {
00202          tnfilestream fs ( fn, tnstream::reading );
00203          RWOPS_Handler rwo( SDL_RWFromStream( &fs ) );
00204          SDLmm::Surface s2 ( IMG_LoadPNG_RW ( rwo.Get() ));
00205          rwo.Close();
00206          // s2.SetAlpha ( SDL_SRCALPHA, SDL_ALPHA_OPAQUE );
00207          if ( !s )
00208             s = new SDLmm::Surface ( s2 );
00209          else {
00210             int res = s->Blit ( s2 );
00211             if ( res < 0 )
00212                warningMessage ( "ImageProperty::operation_eq - couldn't blit surface "+fn);
00213          }
00214 
00215          fn = st.getNextToken();
00216       } while ( !fn.empty() );
00217       if ( s )  {
00218          Surface s3( *s );
00219          if ( applyFieldMaskToImage )
00220             applyFieldMask(s3,0,0,false);
00221 
00222          delete s;
00223          return s3;
00224       } else
00225          return Surface();
00226 
00227    } else
00228       if ( fn.suffix() == "pcx" ) {
00229          SDL_Surface* surface;
00230          {
00231             tnfilestream fs ( fn, tnstream::reading );
00232 
00233             RWOPS_Handler rwo ( SDL_RWFromStream( &fs ));
00234             surface = IMG_LoadPCX_RW ( rwo.Get() );
00235             rwo.Close();
00236          }
00237 
00238          if ( !surface )
00239             errorMessage( "error loading file " + fn );
00240             
00241          Surface s ( surface );
00242 
00243          if ( s.GetPixelFormat().BitsPerPixel() == 8)
00244             s.SetColorKey( SDL_SRCCOLORKEY, 255 );
00245          /*
00246          else 
00247             s.SetColorKey( SDL_SRCCOLORKEY, 0xfefefe );
00248          s.SetAlpha(SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
00249          */
00250 
00251          fn = st.getNextToken();
00252          while ( !fn.empty() ) {
00253             tnfilestream fs ( fn, tnstream::reading );
00254             RWOPS_Handler rwo( SDL_RWFromStream( &fs ) );
00255             SDLmm::Surface s2 ( IMG_LoadPNG_RW ( rwo.Get() ));
00256             rwo.Close();
00257             int res = s.Blit ( s2 );
00258             if ( res < 0 )
00259                warningMessage ( "ImageProperty::operation_eq - couldn't blit surface "+fn);
00260 
00261             fn = st.getNextToken();
00262          }
00263 
00264 
00265          if ( applyFieldMaskToImage )
00266             if ( s.w() >= fieldsizex && s.h() >= fieldsizey )
00267                applyFieldMask(s,0,0,false);
00268 
00269          return s;
00270       }
00271    throw ASCexception();
00272 }
00273 
00274 

Generated on Mon May 21 01:26:32 2012 for Advanced Strategic Command by  doxygen 1.5.1