Advanced Strategic Command
surface.cpp
Go to the documentation of this file.
1 
2 /*
3  This file is part of Advanced Strategic Command; http://www.asc-hq.de
4  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; see the file COPYING. If not, write to the
18  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19  Boston, MA 02111-1307 USA
20 */
21 
22 #include <SDL_image.h>
23 #include <cmath>
24 #include "../sdl/sdlstretch.h"
25 #include "surface.h"
26 #include "blitter.h"
27 #include "../basegfx.h"
28 #include "../basestrm.h"
29 #include "../misc.h"
30 #include "../util/messaginghub.h"
31 #include <iostream>
32 
34  r = 0;
35  g = 0;
36  b = 0;
37 }
38 
39 DI_Color::DI_Color(const SDL_Color& c) {
40  *this = c;
41 }
42 
43 DI_Color::DI_Color(Uint32 c) {
44  *this = c;
45 }
46 
47 DI_Color::DI_Color(Uint8 r, Uint8 g, Uint8 b) {
48  *this = (Uint32)((r << 16) | (g << 8) | b);
49 }
50 
51 DI_Color& DI_Color::operator=(const SDL_Color& c) {
52  r = c.r;
53  g = c.g;
54  b = c.b;
55 
56  return *this;
57 }
58 
60  r = (c >> 16) & 0xFF;
61  g = (c >> 8) & 0xFF;
62  b = c & 0xFF;
63 
64  return *this;
65 }
66 
67 /*
68 DI_Color::operator Uint32() const {
69  return (r << 16) | (g << 8) | b;
70 }
71 */
72 
73 
74 
75  SDLmm::PixelFormat* Surface::default8bit = NULL;
76  SDLmm::PixelFormat* Surface::default32bit = NULL;
77 
78 void Surface::SetScreen( SDL_Surface* screen )
79 {
80  if ( screen && screen->format->BitsPerPixel == 32 )
81  default32bit = new SDLmm::PixelFormat ( screen->format );
82 }
83 
84 
86 {
87  Surface new_surface(CreateSurface(*this));
88 
89  megaBlitter<ColorTransform_None, ColorMerger_PlainOverwrite, SourcePixelSelector_Plain, TargetPixelSelector_All>(*this, new_surface, SPoint(0,0), nullParam, nullParam, nullParam, nullParam);
90 
91  new_surface.Blit(*this);
92  return new_surface;
93 }
94 
95 
96  void writeDefaultPixelFormat ( SDLmm::PixelFormat pf, tnstream& stream )
97  {
98  stream.writeInt( 1 );
99  stream.writeInt(pf.BitsPerPixel()) ;
100  stream.writeInt(pf.BytesPerPixel()) ;
101  stream.writeInt(pf.Rmask()) ;
102  stream.writeInt(pf.Gmask()) ;
103  stream.writeInt(pf.Bmask()) ;
104  stream.writeInt(pf.Amask()) ;
105  stream.writeInt(pf.Rshift()) ;
106  stream.writeInt(pf.Gshift()) ;
107  stream.writeInt(pf.Bshift()) ;
108  stream.writeInt(pf.Ashift()) ;
109  stream.writeInt(pf.Rloss()) ;
110  stream.writeInt(pf.Gloss()) ;
111  stream.writeInt(pf.Bloss()) ;
112  stream.writeInt(pf.Aloss()) ;
113  stream.writeInt(pf.colorkey()) ;
114  stream.writeInt(pf.alpha()) ;
115  }
116 
117  SDL_PixelFormat* readSDLPixelFormat( tnstream& stream )
118  {
119  SDL_PixelFormat* pf = new SDL_PixelFormat;
120  int version = stream.readInt();
121  if ( version != 1 )
122  throw tinvalidversion( stream.getLocation(), 1, version );
123 
124  pf->BitsPerPixel = stream.readInt();
125  pf->BytesPerPixel = stream.readInt();
126  pf->Rmask = stream.readInt();
127  pf->Gmask = stream.readInt();
128  pf->Bmask = stream.readInt();
129  pf->Amask = stream.readInt();
130  pf->Rshift = stream.readInt();
131  pf->Gshift = stream.readInt();
132  pf->Bshift = stream.readInt();
133  pf->Ashift = stream.readInt();
134  pf->Rloss = stream.readInt();
135  pf->Gloss = stream.readInt();
136  pf->Bloss = stream.readInt();
137  pf->Aloss = stream.readInt();
138  pf->colorkey = stream.readInt();
139  pf->alpha = stream.readInt();
140  return pf;
141  }
142 
143 
144 
145 Surface::Surface( SDL_Surface *surface) : SDLmm::Surface ( surface ), pixelDataPointer(NULL)
146 {
147  if ( me )
148  convert();
149 }
150 
152 {
153  if ( GetPixelFormat().BitsPerPixel() == 24 ) {
154  Surface s = Surface::createSurface(w(), h(), 32 );
155  s.Blit( *this );
156  if ( flags() & SDL_SRCCOLORKEY )
157  s.SetColorKey( SDL_SRCCOLORKEY, GetPixelFormat().colorkey() );
158  *this = s;
159  }
160 
161  if ( default32bit && GetPixelFormat().BytesPerPixel() == 4 ) {
162  if ( default32bit->Rmask() != GetPixelFormat().Rmask() || default32bit->Gmask() != GetPixelFormat().Gmask() || default32bit->Bmask() != GetPixelFormat().Bmask() ) {
163  SDL_Surface *tmp;
164  if ( flags() & SDL_SRCALPHA )
165  tmp = SDL_DisplayFormatAlpha(me);
166  else
167  tmp = SDL_DisplayFormat(me);
168 
169  if ( !tmp )
170  return;
171 
172  SetSurface(tmp);
173  }
174  }
175 
176 }
177 
178 /*
179 SDLmm::ColorRGB Surface::GetRGB(SDLmm::Color pixel) const
180 {
181  if ( GetPixelFormat().BytesPerPixel() == 1 ) {
182  assert( pixel < 256 );
183  return SDLmm::ColorRGB( pal[pixel][0] * 4, pal[pixel][1] * 4, pal[pixel][2] * 4 );
184  } else
185  return GetPixelFormat().GetRGB( pixel );
186 }
187 
188 SDLmm::ColorRGBA Surface::GetRGBA(SDLmm::Color pixel) const
189 {
190  if ( GetPixelFormat().BytesPerPixel() == 1 ) {
191  assert( pixel < 256 );
192  return SDLmm::ColorRGBA( pal[pixel][0] * 4, pal[pixel][1] * 4, pal[pixel][2] * 4, opaque );
193  } else
194  return GetPixelFormat().GetRGBA( pixel );
195 }
196 */
197 
198 Surface::Surface(const SDLmm::Surface& other) : SDLmm::Surface ( other ), pixelDataPointer(NULL)
199 {
200  if ( me )
201  convert();
202 }
203 
204 
206  {
207  default8bit = new SDLmm::PixelFormat( readSDLPixelFormat( stream ) );
208  default32bit = new SDLmm::PixelFormat( readSDLPixelFormat( stream ) );
209  }
210 
212  {
213  ::writeDefaultPixelFormat( GetPixelFormat(),stream );
214  }
215 
216  const int surfaceVersion = 2;
217 
218 void Surface::write ( tnstream& stream ) const
219 {
220  if ( !valid() ) {
221  stream.writeWord( 16974 );
222  stream.writeWord ( 1 );
223  stream.writeUint8 ( 0 );
224  stream.writeWord ( 0 );
225  stream.writeWord ( 0 );
226  return;
227  }
228  stream.writeWord( 16974 );
229  stream.writeWord ( 1 );
230  stream.writeUint8 ( 0 );
231  stream.writeWord ( w() );
232  stream.writeWord ( h() );
233  stream.writeInt( surfaceVersion );
234 
235  SDLmm::PixelFormat pf = GetPixelFormat();
236 
237  stream.writeUint8 ( pf.BitsPerPixel() );
238  stream.writeUint8 ( pf.BytesPerPixel() );
239  stream.writeInt ( GetPixelFormat().colorkey());
240  stream.writeInt( flags() );
241  if ( pf.BytesPerPixel() == 1 ) {
242  for ( int y = 0; y < h(); ++y )
243  stream.writedata( ((Uint8*)me->pixels) + y*pitch(), w() );
244  /*
245  for ( int y = 0; y < h(); ++y )
246  for ( int x = 0; x < w(); ++x )
247  stream.writeUint8( GetPixel(x,y));
248  */
249  } else {
250  SDLmm::PixelFormat pf = GetPixelFormat();
251  stream.writeInt(pf.Rmask()) ;
252  stream.writeInt(pf.Gmask()) ;
253  stream.writeInt(pf.Bmask()) ;
254  stream.writeInt(pf.Amask()) ;
255  for ( int y = 0; y < h(); ++y ) {
256  for ( int x = 0; x < w(); ++x )
257  stream.writeInt( GetPixel(x,y));
258 
259  }
260  }
261 
262 }
263 
264 
265 void Surface::read ( tnstream& stream )
266 {
267  trleheader hd;
268 
269  hd.id = stream.readWord();
270  hd.size = stream.readWord();
271  hd.rle = stream.readUint8();
272  hd.x = stream.readWord();
273  hd.y = stream.readWord();
274 
275  if ( hd.x == 0 && hd.y == 0 ) {
276  SetSurface( NULL );
277  return;
278  }
279 
280  if (hd.id == 16973) {
281  Uint8 *pnter = new Uint8 [ hd.size + sizeof(hd) ];
282  memcpy( pnter, &hd, sizeof(hd));
283  Uint8* q = pnter + sizeof(hd);
284 
285  stream.readdata( q, hd.size); // endian ok ?
286 
287  Uint8* uncomp = (Uint8*) uncompress_rlepict ( pnter );
288  pixelDataPointer = uncomp;
289 
290  // TODO fix memory leak: uncomp will not be deleted
291  delete[] pnter;
292 
293  SDL_Surface* surface = SDL_CreateRGBSurface( SDL_SWSURFACE, hd.x+1, hd.y+1, 8, 0, 0, 0, 0 );
294  for ( int y = 0; y <= hd.y; ++y ) {
295  Uint8* dest = ((Uint8*)surface->pixels) + y * surface->pitch;
296  memcpy( dest, uncomp+4 + y * (hd.x+1), hd.x+1);
297  }
298  free ( uncomp );
299 
300  SetSurface( surface );
301  SetColorKey( SDL_SRCCOLORKEY, 255 );
303  }
304  else {
305  if (hd.id == 16974) {
306  int version = stream.readInt();
307  if ( version > surfaceVersion )
308  throw tinvalidversion( stream.getLocation(), version, surfaceVersion );
309 
310  stream.readUint8(); // int bitsPerPixel =
311  int bytesPerPixel = stream.readUint8();
312  int colorkey = stream.readInt();
313  int flags = stream.readInt();
314  if ( bytesPerPixel == 1 ) {
315  SDL_Surface* s = SDL_CreateRGBSurface ( SDL_SWSURFACE, hd.x, hd.y, 8, 0xff, 0xff, 0xff, 0xff );
316  Uint8* p = (Uint8*)( s->pixels );
317  for ( int y = 0; y < hd.y; ++y )
318  stream.readdata( p + y*s->pitch, hd.x );
319 
320  /*for ( int x = 0; x< hd.x; ++x )
321  *(p++) = stream.readUint8();*/
322 
323  SetSurface( s );
325 
326  } else {
327  int Rmask = stream.readInt();
328  int Gmask = stream.readInt();
329  int Bmask = stream.readInt();
330  int Amask = stream.readInt();
331 
332  SDL_Surface* s = SDL_CreateRGBSurface ( SDL_SWSURFACE, hd.x, hd.y, 32, Rmask, Gmask, Bmask, Amask );
333  Uint32* p = (Uint32*)( s->pixels );
334  for ( int y = 0; y < hd.y; ++y ) {
335  for ( int x = 0; x< hd.x; ++x )
336  *(p++) = stream.readInt();
337  }
338  SetSurface( s );
339  }
340  if ( flags & SDL_SRCCOLORKEY )
341  SetColorKey( SDL_SRCCOLORKEY, colorkey );
342 
343  if ( flags & SDL_SRCALPHA )
344  SetAlpha ( SDL_SRCALPHA, GetPixelFormat().alpha());
345  else
346  SetAlpha ( 0, SDL_ALPHA_OPAQUE);
347 
348  } else {
349  // int w = (hd.id + 1) * (hd.size + 1) ;
350 
351  SDL_Surface* s = SDL_CreateRGBSurface( SDL_SWSURFACE, hd.id+1, hd.size+1, 8, 0,0,0,0 );
352 
353  for ( int y = 0; y <= hd.size; ++y ) {
354  Uint8* pixeldata = (Uint8*)(s->pixels) + y * s->pitch;
355  if ( y == 0 ) {
356  memcpy ( pixeldata, ((Uint8*)&hd) + 4, sizeof ( hd ) - 4);
357  Uint8* q = pixeldata + sizeof(hd) - 4;
358  stream.readdata ( q, s->w - sizeof(hd) + 4 );
359  } else {
360  stream.readdata ( pixeldata, s->w );
361  }
362  }
363 /*
364 
365  Uint8* pntr = (Uint8*) asc_malloc( w );
366  stream.readdata ( q, w - sizeof(hd) + 4 ); // endian ok ?
367 
368  SDL_SWSURFACE
369  SDL_Surface* s = SDL_CreateRGBSurfaceFrom(pntr, hd.id+1, hd.size+1, 8, hd.id+1, 0, 0, 0, 0 );
370 // s->flags &= ~SDL_PREALLOC;
371  */
372  SetSurface( s );
373  SetColorKey( SDL_SRCCOLORKEY, 255 );
375  }
376  }
377  convert();
378 }
379 
381 {
382  SetSurface( IMG_Load_RW( SDL_RWFromStream ( &stream ), true ));
383  convert();
384 }
385 
386 
387 Surface Surface::createSurface( int width, int height, SDLmm::Color color )
388 {
389  Surface s = createSurface ( width, height, 8, color );
390  s.SetColorKey( SDL_SRCCOLORKEY, 255 );
391  return s;
392 }
393 
394 Surface Surface::createSurface( int width, int height, int depth, SDLmm::Color color )
395 {
396  assert ( depth == 32 || depth == 8 );
397 
398  SDL_Surface* surf = NULL;
399  if ( depth == 32 && default32bit ) {
400  int rmask = default32bit->Rmask();
401  int gmask = default32bit->Gmask();
402  int bmask = default32bit->Bmask();
403  int amask = ~(rmask | gmask | bmask );
404  surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, depth, rmask, gmask, bmask, amask );
405  } else
406  surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, depth, 0xff, 0xff00, 0xff0000, 0xff000000 );
407 
408  Surface s ( surf );
409  if ( depth == 32 )
410  s.Fill(color);
411  else {
412  s.Fill(color & 0xff );
414  }
415  // s.SetColorKey( SDL_SRCCOLORKEY, 255 );
416  return s;
417 }
418 
420 {
421  if ( GetPixelFormat().BitsPerPixel() == 32 ) {
422  Fill( 0 );
423  } else {
424  Fill( GetPixelFormat().colorkey() );
425  }
426 }
427 
428 
430 {
431  if ( me && GetPixelFormat().BytesPerPixel() == 1 ) {
432  SDL_Color spal[256];
433  memset ( spal, 0, 256* sizeof(SDL_Color));
434  for ( int i = 0; i < 256; i++ ) {
435  spal[i].r = pal[i][0] * 4;;
436  spal[i].g = pal[i][1] * 4;;
437  spal[i].b = pal[i][2] * 4;;
438  }
439  SDL_SetColors ( me, spal, 0, 256 );
440  }
441 }
442 
443 
444 void Surface::assignPalette(SDL_Color* colors, int startColor, int colorNum )
445 {
446  if ( me )
447  SDL_SetColors ( me, colors, startColor, colorNum );
448 }
449 
450 
451 /*
452 void SDL_StretchSurface(SDL_Surface* src_surface, int xs1, int ys1, int xs2, int ys2, SDL_Surface* dst_surface, int xd1, int yd1, int xd2, int yd2, Uint32* lutVOI)
453 {
454 }
455 */
456 
457 void Surface::strech ( int width, int height )
458 {
459  if ( width != w() || height != h() ) {
460  SDL_Surface* s;
461  if( GetPixelFormat().BytesPerPixel() == 1 )
462  s = SDL_CreateRGBSurface ( SDL_SWSURFACE, width, height, 8, 0,0,0,0 );
463  else
464  s = SDL_CreateRGBSurface ( SDL_SWSURFACE, width, height, 32, 0xff, 0xff00, 0xff0000, 0xff000000 );
465 
466  SDL_StretchSurface( me,0,0,w()-1,h()-1, s, 0,0,width-1, height-1);
467 
468  SetSurface(s);
469  if( GetPixelFormat().BytesPerPixel() == 1 ) {
471  detectColorKey();
472  }
473  }
474 }
475 
477 {
478  if ( GetPixelFormat().BitsPerPixel() > 8 ) {
479  for ( int y = 0; y < h(); ++y )
480  for ( int x = 0; x < w(); ++x )
481  if ( (GetPixel(x,y) >> GetPixelFormat().Ashift()) != SDL_ALPHA_OPAQUE ) {
482  // GetSurface()->flags |= SDL_SRCALPHA;
483  return true;
484  }
485 
486  // GetSurface()->flags &= ~SDL_SRCALPHA;
487  }
488  return false;
489 }
490 
491 
492 
493 void Surface::detectColorKey ( bool RLE )
494 {
495 
496  // detect if image has per pixel alpha - don't use ColorKey then
497  if ( GetPixelFormat().BitsPerPixel() > 8 )
498  if ( hasAlpha() )
499  return;
500 
501  int flags = SDL_SRCCOLORKEY;
502  if ( RLE )
503  flags |= SDL_RLEACCEL;
504 
505  SetAlpha ( 0, 0 );
506 
507  if ( GetPixelFormat().BitsPerPixel() > 8 ) {
508  SetColorKey( flags, GetPixel(0,0) & ( GetPixelFormat().Rmask() | GetPixelFormat().Gmask() | GetPixelFormat().Bmask()));
509  } else
510  SetColorKey( flags, GetPixel(0,0));
511  // SetColorKey( flags, 255 );
512 }
513 
514 
516 {
517  if ( flags() & SDL_SRCCOLORKEY )
518  return (col & (GetPixelFormat().Rmask() | GetPixelFormat().Gmask() | GetPixelFormat().Bmask())) == GetPixelFormat().colorkey();
519  else {
520  if ( GetPixelFormat().BitsPerPixel() == 8 )
521  return false;
522  else {
523  if ( ((col & GetPixelFormat().Amask()) >> GetPixelFormat().Ashift()) < opaque/2)
524  return true;
525  else
526  return false;
527  }
528  }
529 }
530 
532 {/*
533  if ( pixelDataPointer ) {
534  asc_free( pixelDataPointer );
535  pixelDataPointer = NULL;
536  }
537  */
538 }
539 
540 
541 
542 
544 {
545  static Surface* mask8 = NULL;
546  if ( !mask8 ) {
547  try {
548  tnfilestream st ( "largehex.pcx", tnstream::reading );
549  RWOPS_Handler rwo ( SDL_RWFromStream( &st ) );
550  mask8 = new Surface ( IMG_LoadPCX_RW ( rwo.Get() ));
551  rwo.Close();
552 
553  assert ( mask8->GetPixelFormat().BitsPerPixel() == 8);
554  mask8->SetColorKey( SDL_SRCCOLORKEY, 0 );
555  }
556  catch ( tfileerror err ) {
557  fatalError( "could not access " + err.getFileName() );
558  }
559 
560  }
561  return *mask8;
562 
563 }
564 
565 
566 template<int pixelsize>
568 {
569  int alphamask;
570  typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
571  protected:
572 
573  void init( const Surface& srf )
574  {
575  alphamask = ~(srf.GetPixelFormat().Amask());
577  }
578 
579 
580  void assign ( PixelType src, PixelType* dest )
581  {
582  if ( !this->isOpaque(src ) )
583  *dest &= alphamask;
584  };
585 
586  public:
588  {}
589  ;
590 };
591 
592 
593 void applyFieldMask( Surface& s, int x, int y, bool detecColorKey )
594 {
595  if ( s.GetPixelFormat().BitsPerPixel() == 8 ) {
596  // we don't want any transformations from one palette to another; we just assume that all 8-Bit images use the same colorspace
598  blitter.blit( getFieldMask(), s, SPoint(0,0) );
599  s.detectColorKey ( );
600  } else {
601  if ( detecColorKey ) {
602  s.Blit( getFieldMask() );
603  s.detectColorKey ( );
604  } else {
606  blitter.blit( getFieldMask(), s, SPoint(0,0) );
607  }
608  }
609 }
610 
611 void applyLegacyFieldMask( Surface& s, int x, int y, bool detectColorKey )
612 {
613  static Surface* mask32 = NULL;
614  if ( !mask32 ) {
615  Surface& mask8 = getFieldMask();
616 
617  mask32 = new Surface ( Surface::createSurface( mask8.w(), mask8.h(), 32 ));
618  for ( int y = 0; y < mask8.h(); ++y ) {
619  Uint8* s = ((Uint8*) mask8.pixels()) + mask8.pitch() * y;
620  Uint32* d = (Uint32*) ((Uint8*)(mask32->pixels()) + mask32->pitch() * y);
621  for ( int x = 0; x < mask8.w(); ++x, ++s, ++d)
622  if ( *s == 0 )
623  *d = 0;
624  else
625  *d = 0xfffefefe;
626  }
627 
628  mask32->SetColorKey( SDL_SRCCOLORKEY, 0 );
629 
630  }
631  if ( s.GetPixelFormat().BitsPerPixel() == 8 ) {
632  // we don't want any transformations from one palette to another; we just assume that all 8-Bit images use the same colorspace
634  blitter.blit( getFieldMask(), s, SPoint(0,0) );
635  s.detectColorKey ( );
636  } else {
637  if ( !detectColorKey || s.hasAlpha() ) {
639  blitter.blit( getFieldMask(), s, SPoint(0,0) );
640  } else {
641  s.Blit( *mask32 );
642  s.detectColorKey ( );
643  }
644  }
645 }
646 
647 /*
648 void colorShift ( Surface& s, int startcolor, int colNum, int shift )
649 {
650  if ( s.GetPixelFormat().BitsPerPixel() != 8)
651  fatalError ( "colorShift can only be done with 8 Bit surfaces");
652 
653  SDL_Color spal[256];
654  int col;
655  for ( int i = 0; i < 256; i++ ) {
656  int src;
657  if ( i >= startcolor && i < startcolor + colNum )
658  src = i + shift;
659  else
660  src = i;
661  for ( int c = 0; c < 3; c++ ) {
662  col = pal[src][c];
663  switch ( c ) {
664  case 0: spal[i].r = col * 4; break;
665  case 1: spal[i].g = col * 4; break;
666  case 2: spal[i].b = col * 4; break;
667  };
668  }
669  }
670  s.assignPalette( spal, 0, 256 );
671 }
672 */
673 
674 Surface rotateSurface( Surface& s, int degrees )
675 {
676  SurfaceLock sl1 ( s );
677 
678  Surface dest = s.Duplicate();
679 
680  SurfaceLock sl2( dest );
681 
682  if ( s.GetPixelFormat().BitsPerPixel() == 8 )
683  dest.Fill ( 255 );
684  else {
685  dest.Fill(0xfefefe);
686  }
687  dest.detectColorKey();
688 
689  for ( int y = 0; y < s.h(); y++ ) {
690  for ( int x = 0; x < s.w(); x++ ) {
691  SPoint newpos = getPixelRotationLocation( SPoint(x,y), s.w(),s.h(), degrees );
692 
693  if ( newpos.x >= 0 && newpos.y >= 0 && newpos.x < s.w() && newpos.y < s.h() )
694  dest.SetPixel( x, y, s.GetPixel ( newpos ));
695  }
696  }
697 
698  return dest;
699 }
700 
701 
702 void* Surface::toBGI() const
703 {
704  void* p = malloc( imagesize(1,1,w(),h()) );
705  Uint8* c = (Uint8*) p;
706  Uint16* ww = (Uint16*) p;
707  ww[0] = w()-1;
708  ww[1] = h()-1;
709  c += 4;
710  for ( int y = 0; y < h(); ++y )
711  for ( int x = 0; x < w(); ++x )
712  *c++ = GetPixel(x,y);
713  return p;
714 }
715 
717 {
718  int size = sizeof(*this);
719 
720  const SDL_Surface* s = getBaseSurface();
721  if ( s ) {
722  size += sizeof( SDL_Surface );
723  if ( s->format ) {
724  size += sizeof( SDL_PixelFormat );
725  if ( s->format->palette )
726  size += sizeof ( SDL_Palette ) + s->format->palette->ncolors * sizeof(SDL_Color);
727  }
728  size += s->h * s->pitch;
729  }
730  return size;
731 }
732 
733 
735 {
736  Lock();
737  for ( int y = 0; y < h(); ++y ) {
738  Uint8* cp = (Uint8*) pixels();
739  cp += y * pitch();
740  int* ip = (int*) cp;
741  for ( int x = 0; x < w(); ++x, ++ip )
742  if ( (*ip & ~(0xff << GetPixelFormat().Ashift())) == GetPixelFormat().colorkey())
743  *ip &= ~(Surface::transparent << GetPixelFormat().Ashift());
744  }
745  GetSurface()->flags &= ~SDL_SRCCOLORKEY;
746  Unlock();
747 }
748 
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
A Device Independent color. Shamelessly pinched from Paragui to reduce coupling.
Definition: surface.h:30
const ASCString & getFileName() const
Definition: simplestream.h:80
virtual ASCString getLocation()
returns the location of the stream.
Definition: basestrm.cpp:274
void blit(const Surface &src, Surface &dst, SPoint dstPos)
Definition: blitter.h:349
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
NullParamType nullParam
Definition: blitter.cpp:30
void Close()
Definition: basestrm.h:55
static const Uint32 transparent
Definition: surface.h:65
bool isOpaque(PixelType src)
Definition: blitter.h:671
virtual int readWord(void)
Reads a 16 bit unsigned Integer. In the stream little-endian byte order is used and a translation is ...
Definition: basestrm.cpp:291
static void readDefaultPixelFormat(tnstream &stream)
Definition: surface.cpp:205
void SDL_StretchSurface(SDL_Surface *src_surface, int xs1, int ys1, int xs2, int ys2, SDL_Surface *dst_surface, int xd1, int yd1, int xd2, int yd2, Uint32 *lutVOI)
Definition: sdlstretch.cpp:146
static Surface createSurface(int width, int height, SDLmm::Color color=255)
Definition: surface.cpp:387
void init(const Surface &srf)
Definition: blitter.h:658
void FillTransparent()
Definition: surface.cpp:419
Surface rotateSurface(Surface &s, int degrees)
Definition: surface.cpp:674
The interface for all kinds of IO stream.
void convert()
Definition: surface.cpp:151
void strech(int width, int height)
Definition: surface.cpp:457
SDL_Surface * getBaseSurface()
Definition: surface.h:116
Surface & getFieldMask()
Definition: surface.cpp:543
void ColorKey2AlphaChannel()
Definition: surface.cpp:734
virtual Uint8 readUint8(void)
Reads a 8 bit unsigned Integer.
Definition: basestrm.cpp:305
char * malloc(int)
void read(tnstream &stream)
Definition: surface.cpp:265
void write(tnstream &stream) const
Definition: surface.cpp:218
Uint16 x
Definition: basegfx.h:83
void writeDefaultPixelFormat(SDLmm::PixelFormat pf, tnstream &stream)
Definition: surface.cpp:96
void applyFieldMask(Surface &s, int x, int y, bool detecColorKey)
Definition: surface.cpp:593
void assign(PixelType src, PixelType *dest)
Definition: surface.cpp:580
static void SetScreen(SDL_Surface *screen)
Definition: surface.cpp:78
void applyLegacyFieldMask(Surface &s, int x, int y, bool detectColorKey)
applies a field mask that uses FEFEFE Color as Colorkey to load old images
Definition: surface.cpp:611
~Surface()
Definition: surface.cpp:531
static const Uint32 opaque
Definition: surface.h:66
virtual void writeUint8(Uint8 c)
Writes a 8 bit unsigned Integer.
Definition: basestrm.cpp:380
Uint16 y
Definition: basegfx.h:84
virtual int readdata(void *buf, int size, bool excpt=true)=0
Reads data from the stream.
SDL_PixelFormat * readSDLPixelFormat(tnstream &stream)
Definition: surface.cpp:117
bool hasAlpha()
Definition: surface.cpp:476
SDLmm::Color Color
Definition: blitter.h:35
SDL_RWops * Get()
Definition: basestrm.h:54
Uint16 size
Definition: basegfx.h:81
SDLmm::SPoint SPoint
Definition: surface.h:27
ColorMerger_MaskApply(NullParamType npt=nullParam)
Definition: surface.cpp:587
Uint16 id
Definition: basegfx.h:80
bool isTransparent(SDLmm::Color col) const
Definition: surface.cpp:515
dacpalette256 pal
Definition: palette.cpp:33
void assignDefaultPalette()
assigns the default ASC palette to the surface (only for 8 Bit surfaces)
Definition: surface.cpp:429
int imagesize(int x1, int y1, int x2, int y2)
returns the size for a buffer that can contain an image of the given size.
Definition: basegfx.cpp:896
DI_Color & operator=(const SDL_Color &c)
Definition: surface.cpp:51
void * uncompress_rlepict(void *pict)
uncompresses the RLE-compressed image pict.
Definition: basegfx.cpp:1001
virtual void writeWord(int w)
Writes a 16 bit unsigned Integer. In the stream little-endian byte order is used and a translation is...
Definition: basestrm.cpp:369
void * toBGI() const
Definition: surface.cpp:702
Surface()
Definition: surface.h:69
DI_Color()
Definition: surface.cpp:33
SDL_RWops * SDL_RWFromStream(tnstream *stream)
Definition: basestrm.cpp:693
void readImageFile(tnstream &stream)
Definition: surface.cpp:380
void assignPalette(SDL_Color *colors, int startColor=0, int colorNum=256)
Definition: surface.cpp:444
int getMemoryFootprint() const
Definition: surface.cpp:716
void writeDefaultPixelFormat(tnstream &stream)
Definition: surface.cpp:211
SPoint getPixelRotationLocation(SPoint pos, int width, int height, int degrees)
transforms the coordinate for an image rotation
Definition: basegfx.cpp:1999
void fatalError(const ASCString &string)
SDL_Surface * screen
Definition: graphics.cpp:31
void detectColorKey(bool RLE=false)
tries to automatically detect the color key of the surface
Definition: surface.cpp:493
Uint8 rle
Definition: basegfx.h:82
const int surfaceVersion
Definition: surface.cpp:216
Surface Duplicate() const
Definition: surface.cpp:85
virtual void writedata(const void *buf, int size)=0
writes data to the stream
void init(const Surface &srf)
Definition: surface.cpp:573