World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
ImageLoader.cpp
См. документацию.
1 #include "Engine/Log.h"
2 
3 #include "Engine/ZlibWrapper.h"
4 
9 #include "Engine/Graphics/PCX.h"
11 
12 uint32_t *MakeImageSolid(unsigned int width, unsigned int height,
13  uint8_t *pixels, uint8_t *palette) {
14  uint32_t *res = new uint32_t[width * height];
15 
16  for (unsigned int y = 0; y < height; ++y) {
17  for (unsigned int x = 0; x < width; ++x) {
18  int index = pixels[y * width + x];
19  auto r = palette[(index * 3) + 0];
20  auto g = palette[(index * 3) + 1];
21  auto b = palette[(index * 3) + 2];
22  res[y * width + x] = Color32(r, g, b);
23  }
24  }
25 
26  return res;
27 }
28 
29 uint32_t *MakeImageAlpha(unsigned int width, unsigned int height,
30  uint8_t *pixels, uint8_t *palette) {
31  uint32_t *res = new uint32_t[width * height];
32 
33  for (unsigned int y = 0; y < height; ++y) {
34  for (unsigned int x = 0; x < width; ++x) {
35  int index = pixels[y * width + x];
36  auto r = palette[(index * 3) + 0];
37  auto g = palette[(index * 3) + 1];
38  auto b = palette[(index * 3) + 2];
39  if (index == 0) {
40  res[y * width + x] = 0x00000000;
41  } else {
42  res[y * width + x] = Color32(r, g, b);
43  }
44  }
45  }
46 
47  return res;
48 }
49 
50 uint32_t *MakeImageColorKey(unsigned int width, unsigned int height,
51  uint8_t *pixels, uint8_t *palette,
52  uint16_t color_key) {
53  uint32_t *res = new uint32_t[width * height];
54 
55  for (unsigned int y = 0; y < height; ++y) {
56  for (unsigned int x = 0; x < width; ++x) {
57  int index = pixels[y * width + x];
58  auto r = palette[(index * 3) + 0];
59  auto g = palette[(index * 3) + 1];
60  auto b = palette[(index * 3) + 2];
61  if (Color16(r, g, b) == color_key) {
62  res[y * width + x] = 0x00000000;
63  } else {
64  res[y * width + x] = Color32(r, g, b);
65  }
66  }
67  }
68 
69  return res;
70 }
71 
72 bool ColorKey_LOD_Loader::Load(unsigned int *out_width,
73  unsigned int *out_height, void **out_pixels,
74  IMAGE_FORMAT *out_format) {
75  *out_width = 0;
76  *out_height = 0;
77  *out_pixels = nullptr;
78  *out_format = IMAGE_INVALID_FORMAT;
79 
80  Texture_MM7 *tex = lod->GetTexture(
81  lod->LoadTexture(resource_name.c_str(), TEXTURE_24BIT_PALETTE));
82  if ((tex == nullptr) || (tex->pPalette24 == nullptr) ||
83  (tex->paletted_pixels == nullptr)) {
84  return false;
85  }
86 
87  if (tex->header.pBits & 512) {
88  *out_pixels = MakeImageAlpha(tex->header.uTextureWidth,
90  tex->paletted_pixels, tex->pPalette24);
91  } else {
92  *out_pixels = MakeImageColorKey(
94  tex->paletted_pixels, tex->pPalette24, colorkey);
95  }
96 
97  if (*out_pixels == nullptr) {
98  return false;
99  }
100 
101  *out_width = tex->header.uTextureWidth;
102  *out_height = tex->header.uTextureHeight;
103  *out_format = IMAGE_FORMAT_A8R8G8B8;
104 
105  return true;
106 }
107 
108 bool Image16bit_LOD_Loader::Load(unsigned int *out_width,
109  unsigned int *out_height, void **out_pixels,
110  IMAGE_FORMAT *out_format) {
111  *out_width = 0;
112  *out_height = 0;
113  *out_pixels = nullptr;
114  *out_format = IMAGE_INVALID_FORMAT;
115 
116  Texture_MM7 *tex = lod->GetTexture(
117  lod->LoadTexture(resource_name.c_str(), TEXTURE_24BIT_PALETTE));
118  if ((tex == nullptr) || (tex->pPalette24 == nullptr) ||
119  (tex->paletted_pixels == nullptr)) {
120  return false;
121  }
122 
123  if (tex->header.pBits & 512) {
124  *out_pixels = MakeImageAlpha(tex->header.uTextureWidth,
125  tex->header.uTextureHeight,
126  tex->paletted_pixels, tex->pPalette24);
127  } else {
128  *out_pixels = MakeImageSolid(tex->header.uTextureWidth,
129  tex->header.uTextureHeight,
130  tex->paletted_pixels, tex->pPalette24);
131  }
132 
133  if (*out_pixels == nullptr) {
134  return false;
135  }
136 
137  *out_width = tex->header.uTextureWidth;
138  *out_height = tex->header.uTextureHeight;
139  *out_format = IMAGE_FORMAT_A8R8G8B8;
140 
141  return true;
142 }
143 
144 bool Alpha_LOD_Loader::Load(unsigned int *out_width, unsigned int *out_height,
145  void **out_pixels, IMAGE_FORMAT *out_format) {
146  *out_width = 0;
147  *out_height = 0;
148  *out_pixels = nullptr;
149  *out_format = IMAGE_INVALID_FORMAT;
150 
151  Texture_MM7 *tex = lod->GetTexture(
152  lod->LoadTexture(resource_name.c_str(), TEXTURE_24BIT_PALETTE));
153  if ((tex == nullptr) || (tex->pPalette24 == nullptr) ||
154  (tex->paletted_pixels == nullptr)) {
155  return false;
156  }
157 
158  if ((tex->header.pBits == 0) || (tex->header.pBits & 512)) {
159  *out_pixels = MakeImageAlpha(tex->header.uTextureWidth,
160  tex->header.uTextureHeight,
161  tex->paletted_pixels, tex->pPalette24);
162  } else {
163  *out_pixels = MakeImageColorKey(
165  tex->paletted_pixels, tex->pPalette24, 0x7FF);
166  }
167 
168  if (*out_pixels == nullptr) {
169  return false;
170  }
171 
172  *out_width = tex->header.uTextureWidth;
173  *out_height = tex->header.uTextureHeight;
174  *out_format = IMAGE_FORMAT_A8R8G8B8;
175 
176  return true;
177 }
178 
179 bool PCX_Loader::DecodePCX(const void *pcx_data, uint16_t *pOutPixels,
180  unsigned int *width, unsigned int *height) {
181  return PCX::Decode(pcx_data, pOutPixels, width, height);
182 }
183 
184 bool PCX_File_Loader::Load(unsigned int *width, unsigned int *height,
185  void **pixels, IMAGE_FORMAT *format) {
186  *width = 0;
187  *height = 0;
188  *pixels = nullptr;
190 
191  FILE *file = fopen(this->resource_name.c_str(), "rb");
192  if (!file) {
193  log->Warning(L"Unable to load %s", this->resource_name.c_str());
194  return false;
195  }
196 
197  fseek(file, 0, SEEK_END);
198  size_t filesize = ftell(file);
199  fseek(file, 0, SEEK_SET);
200 
201  bool res = InternalLoad(file, filesize, width, height, pixels, format);
202 
203  fclose(file);
204 
205  return res;
206 }
207 
208 bool PCX_File_Loader::InternalLoad(void *file, size_t filesize,
209  unsigned int *width, unsigned int *height,
210  void **pixels, IMAGE_FORMAT *format) {
211  if (!PCX::IsValid(file)) {
212  return false;
213  }
214 
215  PCX::GetSize(file, width, height);
216  unsigned int num_pixels = *width * *height;
217  *pixels = new uint16_t[num_pixels + 2];
218 
219  if (pixels) {
220  if (!this->DecodePCX(file, (uint16_t*)*pixels, width,
221  height)) {
222  delete[] *(uint16_t**)pixels;
223  *pixels = nullptr;
224  } else {
226  }
227  }
228 
229  return *pixels != nullptr;
230 }
231 
232 bool PCX_LOD_File_Loader::Load(unsigned int *width, unsigned int *height,
233  void **pixels, IMAGE_FORMAT *format) {
234  *width = 0;
235  *height = 0;
236  *pixels = nullptr;
238 
239  size_t size;
240  void *data = lod->LoadRaw(resource_name, &size);
241  if (data == nullptr) {
242  log->Warning(L"Unable to load %s", this->resource_name.c_str());
243  return false;
244  }
245 
247 
248  free(data);
249 
250  return res;
251 }
252 
253 bool PCX_LOD_Loader::Load(unsigned int *width, unsigned int *height,
254  void **pixels, IMAGE_FORMAT *format) {
255  *width = 0;
256  *height = 0;
257  *pixels = nullptr;
259 
260  size_t data_size = 0;
261  void *pcx_data = lod->LoadCompressedTexture(resource_name, &data_size);
262  if (pcx_data == nullptr) {
263  log->Warning(L"Unable to load %s", resource_name.c_str());
264  return false;
265  }
266 
267  if (!PCX::IsValid(pcx_data)) {
268  free(pcx_data);
269  return false;
270  }
271 
272  PCX::GetSize(pcx_data, width, height);
273  unsigned int num_pixels = *width * *height;
274  *pixels = new uint16_t[num_pixels + 2];
275 
276  if (pixels) {
277  if (!this->DecodePCX(pcx_data, (uint16_t*)*pixels, width,
278  height)) {
279  delete[] *(uint16_t**)pixels;
280  *pixels = nullptr;
281  } else {
283  }
284  }
285 
286  free(pcx_data);
287 
288  return *pixels != nullptr;
289 }
290 
291 bool Bitmaps_LOD_Loader::Load(unsigned int *width, unsigned int *height,
292  void **out_pixels, IMAGE_FORMAT *format) {
293  *width = 0;
294  *height = 0;
295  *out_pixels = nullptr;
297 
298  auto tex = lod->GetTexture(lod->LoadTexture(this->resource_name.c_str()));
299 
300  int num_pixels = tex->header.uTextureWidth * tex->header.uTextureHeight;
301  auto pixels = new uint16_t[num_pixels];
302  if (pixels) {
303  *width = tex->header.uTextureWidth;
304  *height = tex->header.uTextureHeight;
306 
307  if (tex->header.pBits & 2) { // hardware bitmap
308  HWLTexture *hwl = render->LoadHwlBitmap(this->resource_name.c_str());
309  if (hwl) {
310  // linear scaling
311  for (int s = 0; s < tex->header.uTextureHeight; ++s) {
312  for (int t = 0; t < tex->header.uTextureWidth; ++t) {
313  unsigned int resampled_x = t * hwl->uWidth / tex->header.uTextureWidth,
314  resampled_y = s * hwl->uHeight / tex->header.uTextureHeight;
315  unsigned short sample = hwl->pPixels[resampled_y * hwl->uWidth + resampled_x];
316 
317  pixels[s * tex->header.uTextureWidth + t] = sample;
318  }
319  }
320 
321  delete[] hwl->pPixels;
322  delete hwl;
323  }
324 
325  *out_pixels = pixels;
326  return true;
327  }
328  }
329 
330  return false;
331 }
332 
333 bool Sprites_LOD_Loader::Load(unsigned int *width, unsigned int *height,
334  void **out_pixels, IMAGE_FORMAT *format) {
335  *width = 0;
336  *height = 0;
337  *out_pixels = nullptr;
339 
340  HWLTexture *hwl = render->LoadHwlSprite(this->resource_name.c_str());
341  if (hwl) {
342  int dst_width = hwl->uWidth;
343  int dst_height = hwl->uHeight;
344 
345  int num_pixels = dst_width * dst_height;
346  auto pixels = new uint16_t[num_pixels];
347  if (pixels) {
348  // linear scaling
349  for (int s = 0; s < dst_height; ++s) {
350  for (int t = 0; t < dst_width; ++t) {
351  unsigned int resampled_x = t * hwl->uWidth / dst_width,
352  resampled_y = s * hwl->uHeight / dst_height;
353 
354  unsigned short sample =
355  hwl->pPixels[resampled_y * hwl->uWidth + resampled_x];
356 
357  pixels[s * dst_width + t] = sample;
358  }
359  }
360 
361  delete[] hwl->pPixels;
362  delete hwl;
363 
364  *width = dst_width;
365  *height = dst_height;
367  }
368 
369  *out_pixels = pixels;
370  return true;
371  }
372 
373  return false;
374 }
uint16_t
unsigned __int16 uint16_t
Definition: SDL_config.h:37
s
GLdouble s
Definition: SDL_opengl.h:2063
Alpha_LOD_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:144
MakeImageSolid
uint32_t * MakeImageSolid(unsigned int width, unsigned int height, uint8_t *pixels, uint8_t *palette)
Definition: ImageLoader.cpp:12
Sprites_LOD_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:333
height
EGLSurface EGLint EGLint EGLint EGLint height
Definition: SDL_egl.h:1596
PCX::Decode
bool Decode(const void *pcx_data, uint16_t *pOutPixels, unsigned int *width, unsigned int *height)
Definition: PCX.cpp:41
Color32
uint32_t Color32(uint16_t color16)
Definition: Engine.cpp:135
PCX.h
ImageFormatConverter.h
ImageLoader.h
IMAGE_INVALID_FORMAT
@ IMAGE_INVALID_FORMAT
Definition: Image.h:12
TextureHeader::pBits
uint32_t pBits
Definition: Image.h:91
HWLTexture
Definition: HWLContainer.h:9
index
GLuint index
Definition: SDL_opengl_glext.h:663
Texture_MM7::paletted_pixels
uint8_t * paletted_pixels
Definition: Image.h:102
PCX_LOD_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **out_pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:253
PCX_Loader::DecodePCX
bool DecodePCX(const void *pcx_data, uint16_t *pOutPixels, unsigned int *width, unsigned int *height)
Definition: ImageLoader.cpp:179
TEXTURE_24BIT_PALETTE
@ TEXTURE_24BIT_PALETTE
Definition: LOD.h:17
IMAGE_FORMAT_A8R8G8B8
@ IMAGE_FORMAT_A8R8G8B8
Definition: Image.h:7
format
SDL_AudioFormat format
Definition: SDL_audio.h:194
Texture_MM7::header
TextureHeader header
Definition: Image.h:101
y
EGLSurface EGLint EGLint y
Definition: SDL_egl.h:1596
ColorKey_LOD_Loader::colorkey
uint16_t colorkey
Definition: ImageLoader.h:38
IRender.h
ZlibWrapper.h
x
EGLSurface EGLint x
Definition: SDL_egl.h:1596
Image16bit_LOD_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:108
IMAGE_FORMAT_R5G6B5
@ IMAGE_FORMAT_R5G6B5
Definition: Image.h:5
PCX_LOD_File_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:232
width
EGLSurface EGLint EGLint EGLint width
Definition: SDL_egl.h:1596
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
Bitmaps_LOD_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **out_pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:291
HWLTexture::uHeight
unsigned int uHeight
Definition: HWLContainer.h:18
MakeImageColorKey
uint32_t * MakeImageColorKey(unsigned int width, unsigned int height, uint8_t *pixels, uint8_t *palette, uint16_t color_key)
Definition: ImageLoader.cpp:50
HWLTexture::uWidth
unsigned int uWidth
Definition: HWLContainer.h:17
PCX::IsValid
bool IsValid(const void *pcx_data)
Definition: PCX.cpp:30
TextureHeader::uTextureWidth
uint16_t uTextureWidth
Definition: Image.h:82
ImageLoader::log
Log * log
Definition: ImageLoader.h:22
ImageLoader::resource_name
String resource_name
Definition: ImageLoader.h:21
HWLTexture::pPixels
uint16_t * pPixels
Definition: HWLContainer.h:21
Texture_MM7
Definition: Image.h:97
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
IMAGE_FORMAT
IMAGE_FORMAT
Definition: Image.h:4
PCX::GetSize
void GetSize(const void *pcx_data, unsigned int *width, unsigned int *height)
Definition: PCX.cpp:35
TextureHeader::uTextureHeight
uint16_t uTextureHeight
Definition: Image.h:83
uint8_t
unsigned __int8 uint8_t
Definition: SDL_config.h:35
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
PCX_File_Loader::InternalLoad
bool InternalLoad(void *file, size_t size, unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:208
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
IMAGE_FORMAT_A1R5G5B5
@ IMAGE_FORMAT_A1R5G5B5
Definition: Image.h:6
PCX_File_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:184
ColorKey_LOD_Loader::Load
virtual bool Load(unsigned int *width, unsigned int *height, void **pixels, IMAGE_FORMAT *format)
Definition: ImageLoader.cpp:72
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
Texture_MM7::pPalette24
uint8_t * pPalette24
Definition: Image.h:104
res
GLuint res
Definition: SDL_opengl_glext.h:7940
Color16
uint16_t Color16(uint32_t r, uint32_t g, uint32_t b)
Definition: Engine.cpp:148
HWLContainer.h
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1112
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
uint32_t
unsigned __int32 uint32_t
Definition: SDL_config.h:39
Log.h
Sprites.h
MakeImageAlpha
uint32_t * MakeImageAlpha(unsigned int width, unsigned int height, uint8_t *pixels, uint8_t *palette)
Definition: ImageLoader.cpp:29
lod
GLint lod
Definition: SDL_opengl_glext.h:3478
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52