ManaPlus
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Attributes | Friends
SDLImageHelper Class Reference

#include <sdlimagehelper.h>

Inheritance diagram for SDLImageHelper:
ImageHelper

Public Member Functions

 SDLImageHelper ()
 
 ~SDLImageHelper ()
 
Imageload (SDL_RWops *const rw, Dye const &dye)
 
ImageloadSurface (SDL_Surface *const tmpImage)
 
ImagecreateTextSurface (SDL_Surface *const tmpImage, const int width, const int height, const float alpha)
 
void copySurfaceToImage (const Image *const image, const int x, const int y, SDL_Surface *const surface) const
 
- Public Member Functions inherited from ImageHelper
virtual ~ImageHelper ()
 
Imageload (SDL_RWops *const rw)
 
virtual ImagecreateTextSurface (SDL_Surface *const tmpImage, const int width, const int height, const float alpha) const
 
virtual SDL_Surface * create32BitSurface (int width, int height) const
 
virtual RenderType useOpenGL () const
 
virtual void postInit ()
 

Static Public Member Functions

static void SDLSetEnableAlphaCache (const bool n)
 
static bool SDLGetEnableAlphaCache ()
 
static SDL_Surface * SDLDuplicateSurface (SDL_Surface *const tmpImage)
 
static int combineSurface (SDL_Surface *const src, SDL_Rect *const srcrect, SDL_Surface *const dst, SDL_Rect *const dstrect)
 
- Static Public Member Functions inherited from ImageHelper
static SDL_Surface * convertTo32Bit (SDL_Surface *const tmpImage)
 
static void dumpSurfaceFormat (const SDL_Surface *const image)
 
static void setEnableAlpha (const bool n)
 
static SDL_Surface * loadPng (SDL_RWops *const rw)
 
static void setOpenGlMode (const RenderType useOpenGL)
 

Protected Member Functions

Image_SDLload (SDL_Surface *tmpImage)
 
- Protected Member Functions inherited from ImageHelper
 ImageHelper ()
 

Static Protected Attributes

static bool mEnableAlphaCache = false
 
- Static Protected Attributes inherited from ImageHelper
static bool mEnableAlpha = true
 
static RenderType mUseOpenGL = RENDER_SOFTWARE
 

Friends

class Image
 

Detailed Description

Defines a class for loading and storing images.

Definition at line 42 of file sdlimagehelper.h.

Constructor & Destructor Documentation

◆ SDLImageHelper()

SDLImageHelper::SDLImageHelper ( )
inline

Definition at line 47 of file sdlimagehelper.h.

References A_DELETE_COPY.

47  :
48  ImageHelper()
49  { }

◆ ~SDLImageHelper()

SDLImageHelper::~SDLImageHelper ( )
inline

Member Function Documentation

◆ _SDLload()

Image * SDLImageHelper::_SDLload ( SDL_Surface *  tmpImage)
protected

SDL_Surface to SDL_Surface Image loader

Definition at line 217 of file sdlimagehelper.cpp.

References ImageHelper::convertTo32Bit(), ifconstexpr, Image, MSDL_DisplayFormat, MSDL_DisplayFormatAlpha, MSDL_FreeSurface, and reportAlways.

Referenced by loadSurface(), and SDLGetEnableAlphaCache().

218 {
219  if (tmpImage == nullptr)
220  return nullptr;
221 
222  bool hasAlpha = false;
223  bool converted = false;
224 
225  if (tmpImage->format->BitsPerPixel != 32)
226  {
227  reportAlways("Non 32 bit image detected");
228  tmpImage = convertTo32Bit(tmpImage);
229 
230  if (tmpImage == nullptr)
231  return nullptr;
232  converted = true;
233  }
234 
235  const size_t sz = tmpImage->w * tmpImage->h;
236 
237  // The alpha channel to be filled with alpha values
238  uint8_t *alphaChannel = new uint8_t[sz];
239 
240  // Figure out whether the image uses its alpha layer
241  if (tmpImage->format->palette == nullptr)
242  {
243  const SDL_PixelFormat *const fmt = tmpImage->format;
244  if (fmt->Amask != 0u)
245  {
246  const uint32_t amask = fmt->Amask;
247  const uint8_t ashift = fmt->Ashift;
248  const uint8_t aloss = fmt->Aloss;
249  const uint32_t *pixels = static_cast<uint32_t*>(tmpImage->pixels);
250  cilk_for (size_t i = 0; i < sz; ++ i)
251  {
252  const unsigned v = (pixels[i] & amask) >> ashift;
253  const uint8_t a = static_cast<uint8_t>((v << aloss)
254  + (v >> (8 - (aloss << 1))));
255 
256  if (a != 255)
257  hasAlpha = true;
258 
259  alphaChannel[i] = a;
260  }
261  }
262  else
263  {
264  ifconstexpr (SDL_ALPHA_OPAQUE != 255)
265  {
266  hasAlpha = true;
267  memset(alphaChannel, SDL_ALPHA_OPAQUE, sz);
268  }
269  }
270  }
271  else
272  {
273  ifconstexpr (SDL_ALPHA_OPAQUE != 255)
274  {
275  hasAlpha = true;
276  memset(alphaChannel, SDL_ALPHA_OPAQUE, sz);
277  }
278  }
279 
280  SDL_Surface *image;
281 
282  // Convert the surface to the current display format
283  if (hasAlpha)
284  {
285  image = MSDL_DisplayFormatAlpha(tmpImage);
286  }
287  else
288  {
289  image = MSDL_DisplayFormat(tmpImage);
290 
291  // We also delete the alpha channel since
292  // it's not used.
293  delete [] alphaChannel;
294  alphaChannel = nullptr;
295  }
296 
297  if (image == nullptr)
298  {
299  reportAlways("Error: Image convert failed.");
300  delete [] alphaChannel;
301  return nullptr;
302  }
303 
304  if (converted)
305  MSDL_FreeSurface(tmpImage);
306  return new Image(image, hasAlpha, alphaChannel);
307 }
#define MSDL_DisplayFormat(surface)
Definition: debug.h:62
#define MSDL_DisplayFormatAlpha(surface)
Definition: debug.h:61
friend class Image
#define MSDL_FreeSurface(surface)
Definition: debug.h:53
static SDL_Surface * convertTo32Bit(SDL_Surface *const tmpImage)
#define ifconstexpr
Definition: localconsts.h:312
#define reportAlways(...)
Definition: checkutils.h:252

◆ combineSurface()

int SDLImageHelper::combineSurface ( SDL_Surface *const  src,
SDL_Rect *const  srcrect,
SDL_Surface *const  dst,
SDL_Rect *const  dstrect 
)
static

Definition at line 309 of file sdlimagehelper.cpp.

References SDLgfxBlitRGBA().

Referenced by SDLGetEnableAlphaCache().

313 {
314 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
315  return SDLgfxBlitRGBA(src, srcrect, dst, dstrect);
316 #else // SDL_BYTEORDER == SDL_LIL_ENDIAN
317 
318  return SDL_gfxBlitRGBA(src, srcrect, dst, dstrect);
319 #endif // SDL_BYTEORDER == SDL_LIL_ENDIAN
320 }
int SDLgfxBlitRGBA(SDL_Surface *const src, const SDL_Rect *const srcrect, SDL_Surface *const dst, const SDL_Rect *const dstrect)

◆ copySurfaceToImage()

void SDLImageHelper::copySurfaceToImage ( const Image *const  image,
const int  x,
const int  y,
SDL_Surface *const  surface 
) const
virtual

Reimplemented from ImageHelper.

Definition at line 322 of file sdlimagehelper.cpp.

References CAST_S16, CAST_U16, and Image::mSDLSurface.

Referenced by ~SDLImageHelper().

325 {
326  if ((image == nullptr) || (surface == nullptr))
327  return;
328 
329  SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
330  SDL_Rect rect =
331  {
332  CAST_S16(x), CAST_S16(y),
333  CAST_U16(surface->w), static_cast<uint16_t>(surface->h)
334  };
335 
336  SDL_BlitSurface(surface, nullptr, image->mSDLSurface, &rect);
337 }
#define CAST_U16
Definition: cast.h:28
SDL_Surface * mSDLSurface
Definition: image.h:230
#define CAST_S16
Definition: cast.h:27

◆ createTextSurface()

Image * SDLImageHelper::createTextSurface ( SDL_Surface *const  tmpImage,
const int  width,
const int  height,
const float  alpha 
)

Definition at line 141 of file sdlimagehelper.cpp.

References CAST_U8, Image, Image::mAlpha, MSDL_DisplayFormat, MSDL_DisplayFormatAlpha, and reportAlways.

Referenced by ~SDLImageHelper().

145 {
146  if (tmpImage == nullptr)
147  return nullptr;
148 
149  bool hasAlpha = false;
150  const size_t sz = tmpImage->w * tmpImage->h;
151 
152  // The alpha channel to be filled with alpha values
153  uint8_t *alphaChannel = new uint8_t[sz];
154 
155  const SDL_PixelFormat *const fmt = tmpImage->format;
156  if (fmt->Amask != 0u)
157  {
158  for (size_t i = 0; i < sz; ++ i)
159  {
160  uint32_t c = (static_cast<uint32_t*>(tmpImage->pixels))[i];
161 
162  const unsigned v = (c & fmt->Amask) >> fmt->Ashift;
163  const uint8_t a = static_cast<uint8_t>((v << fmt->Aloss)
164  + (v >> (8 - (fmt->Aloss << 1))));
165 
166  const uint8_t a2 = CAST_U8(
167  static_cast<float>(a) * alpha);
168 
169  c &= ~fmt->Amask;
170  c |= ((a2 >> fmt->Aloss) << fmt->Ashift & fmt->Amask);
171  (static_cast<uint32_t*>(tmpImage->pixels))[i] = c;
172 
173  if (a != 255)
174  hasAlpha = true;
175 
176  alphaChannel[i] = a;
177  }
178  }
179 
180  SDL_Surface *image;
181 
182  // Convert the surface to the current display format
183  if (hasAlpha)
184  {
185  image = MSDL_DisplayFormatAlpha(tmpImage);
186  }
187  else
188  {
189  image = MSDL_DisplayFormat(tmpImage);
190 
191  // We also delete the alpha channel since
192  // it's not used.
193  delete [] alphaChannel;
194  alphaChannel = nullptr;
195  }
196 
197  if (image == nullptr)
198  {
199  reportAlways("Error: Image convert failed.");
200  delete [] alphaChannel;
201  return nullptr;
202  }
203 
204  Image *const img = new Image(image, hasAlpha, alphaChannel);
205  img->mAlpha = alpha;
206  return img;
207 }
#define MSDL_DisplayFormat(surface)
Definition: debug.h:62
#define CAST_U8
Definition: cast.h:26
#define MSDL_DisplayFormatAlpha(surface)
Definition: debug.h:61
friend class Image
float mAlpha
Definition: image.h:212
Definition: image.h:61
#define reportAlways(...)
Definition: checkutils.h:252

◆ load()

Image * SDLImageHelper::load ( SDL_RWops *const  rw,
Dye const &  dye 
)
virtual

Loads an image from an SDL_RWops structure and recolors it.

Parameters
rwThe SDL_RWops to load the image from.
dyeThe dye used to recolor the image.
Returns
NULL if an error occurred, a valid pointer otherwise.

< Surface is in system memory

Reimplemented from ImageHelper.

Definition at line 54 of file sdlimagehelper.cpp.

References DYEPALETTEP, Dye::getAPalete(), Dye::getSPalete(), Dye::getType(), ImageHelper::loadPng(), loadSurface(), MSDL_ConvertSurface, MSDL_FreeSurface, Dye::normalDye(), and reportAlways.

Referenced by ~SDLImageHelper().

55 {
56  SDL_Surface *const tmpImage = loadPng(rw);
57  if (tmpImage == nullptr)
58  {
59  reportAlways("Error, image load failed: %s",
60  SDL_GetError());
61  return nullptr;
62  }
63 
64  SDL_PixelFormat rgba;
65  rgba.palette = nullptr;
66  rgba.BitsPerPixel = 32;
67  rgba.BytesPerPixel = 4;
68  rgba.colorkey = 0;
69  rgba.alpha = 255;
70  rgba.Rloss = 0;
71  rgba.Gloss = 0;
72  rgba.Bloss = 0;
73  rgba.Aloss = 0;
74 
75 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
76  rgba.Rmask = 0x000000FF;
77  rgba.Rshift = 24;
78  rgba.Gmask = 0x0000FF00;
79  rgba.Gshift = 16;
80  rgba.Bmask = 0x00FF0000;
81  rgba.Bshift = 8;
82  rgba.Amask = 0xFF000000;
83  rgba.Ashift = 0;
84 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
85 
86  rgba.Rmask = 0xFF000000;
87  rgba.Rshift = 0;
88  rgba.Gmask = 0x00FF0000;
89  rgba.Gshift = 8;
90  rgba.Bmask = 0x0000FF00;
91  rgba.Bshift = 16;
92  rgba.Amask = 0x000000FF;
93  rgba.Ashift = 24;
94 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
95 
96  // +++ here is bug on ppc64le
97  SDL_Surface *const surf = MSDL_ConvertSurface(
98  tmpImage, &rgba, SDL_SWSURFACE);
99 
100  MSDL_FreeSurface(tmpImage);
101  if (surf == nullptr)
102  return nullptr;
103 
104  uint32_t *pixels = static_cast<uint32_t *>(surf->pixels);
105  const int type = dye.getType();
106 
107  switch (type)
108  {
109  case 1:
110  {
111  const DyePalette *const pal = dye.getSPalete();
112  if (pal != nullptr)
113  DYEPALETTEP(pal, SColor)(pixels, surf->w * surf->h);
114  break;
115  }
116  case 2:
117  {
118  const DyePalette *const pal = dye.getAPalete();
119  if (pal != nullptr)
120  DYEPALETTEP(pal, AColor)(pixels, surf->w * surf->h);
121  break;
122  }
123  case 0:
124  default:
125  {
126  dye.normalDye(pixels, surf->w * surf->h);
127  break;
128  }
129  }
130 
131  Image *const image = loadSurface(surf);
132  MSDL_FreeSurface(surf);
133  return image;
134 }
static SDL_Surface * loadPng(SDL_RWops *const rw)
#define MSDL_FreeSurface(surface)
Definition: debug.h:53
Image * loadSurface(SDL_Surface *const tmpImage)
#define DYEPALETTEP(palette, color)
Definition: dyepalette.h:39
#define MSDL_ConvertSurface(src, fmt, flags)
Definition: debug.h:56
Definition: image.h:61
#define reportAlways(...)
Definition: checkutils.h:252

◆ loadSurface()

Image * SDLImageHelper::loadSurface ( SDL_Surface *const  tmpImage)
virtual

Loads an image from an SDL surface.

Reimplemented from ImageHelper.

Definition at line 136 of file sdlimagehelper.cpp.

References _SDLload().

Referenced by load(), and ~SDLImageHelper().

137 {
138  return _SDLload(tmpImage);
139 }
Image * _SDLload(SDL_Surface *tmpImage)

◆ SDLDuplicateSurface()

SDL_Surface * SDLImageHelper::SDLDuplicateSurface ( SDL_Surface *const  tmpImage)
static

< Surface is in system memory

Definition at line 209 of file sdlimagehelper.cpp.

References MSDL_ConvertSurface.

Referenced by SDLGetEnableAlphaCache(), and Image::setAlpha().

210 {
211  if ((tmpImage == nullptr) || (tmpImage->format == nullptr))
212  return nullptr;
213 
214  return MSDL_ConvertSurface(tmpImage, tmpImage->format, SDL_SWSURFACE);
215 }
#define MSDL_ConvertSurface(src, fmt, flags)
Definition: debug.h:56

◆ SDLGetEnableAlphaCache()

static bool SDLImageHelper::SDLGetEnableAlphaCache ( )
inlinestatic

Definition at line 87 of file sdlimagehelper.h.

References _SDLload(), A_WARN_UNUSED, combineSurface(), mEnableAlphaCache, restrict, and SDLDuplicateSurface().

88  { return mEnableAlphaCache; }
static bool mEnableAlphaCache

◆ SDLSetEnableAlphaCache()

static void SDLImageHelper::SDLSetEnableAlphaCache ( const bool  n)
inlinestatic

Definition at line 84 of file sdlimagehelper.h.

References mEnableAlphaCache.

85  { mEnableAlphaCache = n; }
static bool mEnableAlphaCache

Friends And Related Function Documentation

◆ Image

friend class Image
friend

Definition at line 44 of file sdlimagehelper.h.

Referenced by _SDLload(), and createTextSurface().

Field Documentation

◆ mEnableAlphaCache

bool SDLImageHelper::mEnableAlphaCache = false
staticprotected

Definition at line 102 of file sdlimagehelper.h.

Referenced by SDLGetEnableAlphaCache(), and SDLSetEnableAlphaCache().


The documentation for this class was generated from the following files: