ManaPlus
imagehelper.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "resources/imagehelper.h"
24 
25 #include "logger.h"
26 
27 #include "resources/dye/dye.h"
29 
30 #include "utils/sdlcheckutils.h"
31 
32 PRAGMA48(GCC diagnostic push)
33 PRAGMA48(GCC diagnostic ignored "-Wshadow")
34 #include <SDL_image.h>
35 PRAGMA48(GCC diagnostic pop)
36 
37 #include "debug.h"
38 
39 #ifndef SDL_BIG_ENDIAN
40 #error missing SDL_endian.h
41 #endif // SDL_BYTEORDER
42 
45 
46 bool ImageHelper::mEnableAlpha = true;
48 
49 Image *ImageHelper::load(SDL_RWops *const rw)
50 {
51  SDL_Surface *const tmpImage = loadPng(rw);
52  if (tmpImage == nullptr)
53  {
54  logger->log("Error, image load failed: %s", SDL_GetError());
55  return nullptr;
56  }
57 
58  Image *const image = loadSurface(tmpImage);
59 
60  MSDL_FreeSurface(tmpImage);
61  return image;
62 }
63 
64 Image *ImageHelper::load(SDL_RWops *const rw, Dye const &dye)
65 {
66  BLOCK_START("ImageHelper::load")
67  SDL_Surface *const tmpImage = loadPng(rw);
68  if (tmpImage == nullptr)
69  {
70  logger->log("Error, image load failed: %s", SDL_GetError());
71  BLOCK_END("ImageHelper::load")
72  return nullptr;
73  }
74 
75  SDL_PixelFormat rgba;
76  rgba.palette = nullptr;
77  rgba.BitsPerPixel = 32;
78  rgba.BytesPerPixel = 4;
79 
80 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
81  rgba.Rmask = 0x000000FF;
82  rgba.Gmask = 0x0000FF00;
83  rgba.Bmask = 0x00FF0000;
84  rgba.Amask = 0xFF000000;
85 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
86 
87  rgba.Rmask = 0xFF000000;
88  rgba.Gmask = 0x00FF0000;
89  rgba.Bmask = 0x0000FF00;
90  rgba.Amask = 0x000000FF;
91 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
92 
93  SDL_Surface *const surf = MSDL_ConvertSurface(
94  tmpImage, &rgba, SDL_SWSURFACE);
95  MSDL_FreeSurface(tmpImage);
96 
97  if (surf == nullptr)
98  return nullptr;
99 
100  uint32_t *const pixels = static_cast<uint32_t *>(surf->pixels);
101  const int type = dye.getType();
102 
103  switch (type)
104  {
105  case 1:
106  {
107  const DyePalette *const pal = dye.getSPalete();
108  if (pal != nullptr)
109  DYEPALETTEP(pal, SColor)(pixels, surf->w * surf->h);
110  break;
111  }
112  case 2:
113  {
114  const DyePalette *const pal = dye.getAPalete();
115  if (pal != nullptr)
116  DYEPALETTEP(pal, AColor)(pixels, surf->w * surf->h);
117  break;
118  }
119  case 0:
120  default:
121  {
122  dye.normalDye(pixels, surf->w * surf->h);
123  break;
124  }
125  }
126 
127  Image *const image = loadSurface(surf);
128  MSDL_FreeSurface(surf);
129  BLOCK_END("ImageHelper::load")
130  return image;
131 }
132 
133 SDL_Surface* ImageHelper::convertTo32Bit(SDL_Surface *const tmpImage)
134 {
135  if (tmpImage == nullptr)
136  return nullptr;
137  SDL_PixelFormat RGBAFormat;
138  RGBAFormat.palette = nullptr;
139 #ifndef USE_SDL2
140  RGBAFormat.colorkey = 0;
141  RGBAFormat.alpha = 0;
142 #endif // USE_SDL2
143 
144  RGBAFormat.BitsPerPixel = 32;
145  RGBAFormat.BytesPerPixel = 4;
146 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
147  RGBAFormat.Rmask = 0xFF000000;
148  RGBAFormat.Rshift = 0;
149  RGBAFormat.Rloss = 0;
150  RGBAFormat.Gmask = 0x00FF0000;
151  RGBAFormat.Gshift = 8;
152  RGBAFormat.Gloss = 0;
153  RGBAFormat.Bmask = 0x0000FF00;
154  RGBAFormat.Bshift = 16;
155  RGBAFormat.Bloss = 0;
156  RGBAFormat.Amask = 0x000000FF;
157  RGBAFormat.Ashift = 24;
158  RGBAFormat.Aloss = 0;
159 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
160 
161  RGBAFormat.Rmask = 0x000000FF;
162  RGBAFormat.Rshift = 24;
163  RGBAFormat.Rloss = 0;
164  RGBAFormat.Gmask = 0x0000FF00;
165  RGBAFormat.Gshift = 16;
166  RGBAFormat.Gloss = 0;
167  RGBAFormat.Bmask = 0x00FF0000;
168  RGBAFormat.Bshift = 8;
169  RGBAFormat.Bloss = 0;
170  RGBAFormat.Amask = 0xFF000000;
171  RGBAFormat.Ashift = 0;
172  RGBAFormat.Aloss = 0;
173 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
174 
175  return MSDL_ConvertSurface(tmpImage, &RGBAFormat, SDL_SWSURFACE);
176 }
177 
178 void ImageHelper::dumpSurfaceFormat(const SDL_Surface *const image)
179 {
180  if (image == nullptr)
181  return;
182  if (image->format != nullptr)
183  {
184  const SDL_PixelFormat * const format = image->format;
185  logger->log("Bytes per pixel: %d", format->BytesPerPixel);
186 #ifdef USE_SDL2
187  logger->log("Format: %u", format->format);
188 #else // USE_SDL2
189 
190  logger->log("Alpha: %d", format->alpha);
191  logger->log("Color key: %u", format->colorkey);
192 #endif // USE_SDL2
193 
194  logger->log("Loss: %02x, %02x, %02x, %02x",
195  CAST_U32(format->Rloss),
196  CAST_U32(format->Gloss),
197  CAST_U32(format->Bloss),
198  CAST_U32(format->Aloss));
199  logger->log("Shift: %02x, %02x, %02x, %02x",
200  CAST_U32(format->Rshift),
201  CAST_U32(format->Gshift),
202  CAST_U32(format->Bshift),
203  CAST_U32(format->Ashift));
204  logger->log("Mask: %08x, %08x, %08x, %08x", format->Rmask,
205  format->Gmask, format->Bmask, format->Amask);
206  }
207  logger->log("Flags: %u", image->flags);
208  logger->log("Pitch: %d", CAST_S32(image->pitch));
209 #ifndef USE_SDL2
210  logger->log("Offset: %d", image->offset);
211 #endif // USE_SDL2
212 }
213 
214 SDL_Surface *ImageHelper::loadPng(SDL_RWops *const rw)
215 {
216  if (rw == nullptr)
217  return nullptr;
218 
219  if (IMG_isPNG(rw) != 0)
220  {
221  SDL_Surface *const tmpImage = MIMG_LoadPNG_RW(rw);
222  SDL_RWclose(rw);
223  return tmpImage;
224  }
225 
226  if (IMG_isJPG(rw) != 0)
227  {
228  SDL_Surface *const tmpImage = MIMG_LoadJPG_RW(rw);
229  SDL_RWclose(rw);
230  return tmpImage;
231  }
232 
233  logger->log("Error, image is not png");
234  SDL_RWclose(rw);
235  return nullptr;
236 }
237 
238 SDL_Surface *ImageHelper::create32BitSurface(int width,
239  int height) const
240 {
241 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
242  const int rmask = 0xff000000;
243  const int gmask = 0x00ff0000;
244  const int bmask = 0x0000ff00;
245  const int amask = 0x000000ff;
246 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
247 
248  const int rmask = 0x000000ff;
249  const int gmask = 0x0000ff00;
250  const int bmask = 0x00ff0000;
251  const int amask = 0xff000000;
252 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
253 
254  return MSDL_CreateRGBSurface(SDL_SWSURFACE,
255  width, height, 32, rmask, gmask, bmask, amask);
256 }
#define CAST_U32
Definition: cast.h:30
ImageHelper * imageHelper
Definition: imagehelper.cpp:43
static SDL_Surface * loadPng(SDL_RWops *const rw)
#define MIMG_LoadPNG_RW(src)
Definition: debug.h:51
#define MSDL_FreeSurface(surface)
Definition: debug.h:53
#define BLOCK_START(name)
Definition: perfomance.h:78
int getType() const
Definition: dye.cpp:147
virtual SDL_Surface * create32BitSurface(int width, int height) const
#define BLOCK_END(name)
Definition: perfomance.h:79
static SDL_Surface * convertTo32Bit(SDL_Surface *const tmpImage)
const DyePalette * getAPalete() const
Definition: dye.h:72
static RenderType mUseOpenGL
Definition: imagehelper.h:117
Definition: dye.h:39
Logger * logger
Definition: logger.cpp:88
#define DYEPALETTEP(palette, color)
Definition: dyepalette.h:39
#define CAST_S32
Definition: cast.h:29
#define MIMG_LoadJPG_RW(src)
Definition: debug.h:52
void normalDye(uint32_t *pixels, const int bufSize) const
Definition: dye.cpp:156
#define PRAGMA48(str)
Definition: localconsts.h:190
const DyePalette * getSPalete() const
Definition: dye.h:66
virtual Image * loadSurface(SDL_Surface *const)
Definition: imagehelper.h:72
ImageHelper * surfaceImageHelper
Definition: imagehelper.cpp:44
static bool mEnableAlpha
Definition: imagehelper.h:116
#define MSDL_ConvertSurface(src, fmt, flags)
Definition: debug.h:56
Definition: image.h:61
Image * load(SDL_RWops *const rw)
Definition: imagehelper.cpp:49
void log(const char *const log_text,...)
Definition: logger.cpp:264
static void dumpSurfaceFormat(const SDL_Surface *const image)
RenderType
Definition: rendertype.h:24
#define MSDL_CreateRGBSurface(flags, w, h, d, r, g, b, a)
Definition: debug.h:54