Skip to content

Commit 286d44b

Browse files
author
rtri
committed
fix #5434
1 parent 4944ac0 commit 286d44b

File tree

1 file changed

+58
-47
lines changed

1 file changed

+58
-47
lines changed

rts/Rendering/Textures/Bitmap.cpp

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <utility>
55
#include <ostream>
66
#include <fstream>
7-
#include <memory>
87
#include <cstring>
98

109
#include <IL/il.h>
@@ -234,8 +233,8 @@ bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha)
234233
return false;
235234
}
236235

237-
unsigned char* buffer = new unsigned char[file.FileSize() + 2];
238-
file.Read(buffer, file.FileSize());
236+
std::vector<unsigned char> buffer(file.FileSize() + 2);
237+
file.Read(buffer.data(), file.FileSize());
239238

240239
std::lock_guard<spring::mutex> lck(devilMutex);
241240
ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
@@ -249,13 +248,12 @@ bool CBitmap::Load(std::string const& filename, unsigned char defaultAlpha)
249248
// do not signal floating point exceptions in devil library
250249
ScopedDisableFpuExceptions fe;
251250

252-
const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer, file.FileSize());
251+
const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer.data(), file.FileSize());
253252

254253
//FPU control word has to be restored as well
255254
streflop::streflop_init<streflop::Simple>();
256255

257256
ilDisable(IL_ORIGIN_SET);
258-
delete[] buffer;
259257

260258
if (success == false) {
261259
AllocDummy();
@@ -300,12 +298,11 @@ bool CBitmap::LoadGrayscale(const std::string& filename)
300298
channels = 1;
301299

302300
CFileHandler file(filename);
303-
if (!file.FileExists()) {
301+
if (!file.FileExists())
304302
return false;
305-
}
306303

307-
unsigned char* buffer = new unsigned char[file.FileSize() + 1];
308-
file.Read(buffer, file.FileSize());
304+
std::vector<unsigned char> buffer(file.FileSize() + 1);
305+
file.Read(buffer.data(), file.FileSize());
309306

310307
std::lock_guard<spring::mutex> lck(devilMutex);
311308
ilOriginFunc(IL_ORIGIN_UPPER_LEFT);
@@ -315,13 +312,11 @@ bool CBitmap::LoadGrayscale(const std::string& filename)
315312
ilGenImages(1, &ImageName);
316313
ilBindImage(ImageName);
317314

318-
const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer, file.FileSize());
315+
const bool success = !!ilLoadL(IL_TYPE_UNKNOWN, buffer.data(), file.FileSize());
319316
ilDisable(IL_ORIGIN_SET);
320-
delete[] buffer;
321317

322-
if (success == false) {
318+
if (!success)
323319
return false;
324-
}
325320

326321
ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
327322
xsize = ilGetInteger(IL_IMAGE_WIDTH);
@@ -350,7 +345,7 @@ bool CBitmap::Save(std::string const& filename, bool opaque, bool logged) const
350345
if (mem.empty() || channels != 4)
351346
return false;
352347

353-
std::unique_ptr<unsigned char[]> buf(new unsigned char[xsize * ysize * 4]);
348+
std::vector<unsigned char> buf(xsize * ysize * 4);
354349

355350
const int ymax = ysize - 1;
356351

@@ -383,32 +378,39 @@ bool CBitmap::Save(std::string const& filename, bool opaque, bool logged) const
383378
ilGenImages(1, &ImageName); assert(ilGetError() == IL_NO_ERROR);
384379
ilBindImage(ImageName); assert(ilGetError() == IL_NO_ERROR);
385380

386-
ilTexImage(xsize, ysize, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, buf.get()); assert(ilGetError() == IL_NO_ERROR);
381+
ilTexImage(xsize, ysize, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, buf.data()); assert(ilGetError() == IL_NO_ERROR);
382+
383+
384+
// const std::string& imageExt = FileSystem::GetExtension(filename);
385+
const std::string& fsFullPath = dataDirsAccess.LocateFile(filename, FileQueryFlags::WRITE);
386+
387+
// IL might be unicode-aware in which case it uses wchar_t{*}
388+
const std::vector<ILchar> ilFullPath(fsFullPath.begin(), fsFullPath.end());
387389

388-
const std::string& fullPath = dataDirsAccess.LocateFile(filename, FileQueryFlags::WRITE);
389-
const std::string& imageExt = FileSystem::GetExtension(filename);
390390

391-
bool success = ilSaveImage(fullPath.c_str());
391+
const bool success = ilSaveImage(ilFullPath.data());
392392

393+
#if 0
393394
if (!success) {
394395
if (logged)
395-
LOG("[CBitmap::%s] error 0x%x saving \"%s\" (ext. \"%s\") to \"%s\"", __func__, ilGetError(), filename.c_str(), imageExt.c_str(), fullPath.c_str());
396+
LOG("[CBitmap::%s] error 0x%x saving \"%s\" (ext. \"%s\"; sizeof(ILchar)=%lu) to \"%s\"", __func__, ilGetError(), filename.c_str(), imageExt.c_str(), sizeof(ILchar), fsFullPath.c_str());
396397

397398
// manual fallbacks
398399
switch (int(imageExt[0])) {
399-
case 'b': case 'B': { success = ilSave(IL_BMP, fullPath.c_str()); } break;
400-
case 'j': case 'J': { success = ilSave(IL_JPG, fullPath.c_str()); } break;
401-
case 'p': case 'P': { success = ilSave(IL_PNG, fullPath.c_str()); } break;
402-
case 't': case 'T': { success = ilSave(IL_TGA, fullPath.c_str()); } break;
403-
case 'd': case 'D': { success = ilSave(IL_DDS, fullPath.c_str()); } break;
400+
case 'b': case 'B': { success = ilSave(IL_BMP, fsFullPath.c_str()); } break;
401+
case 'j': case 'J': { success = ilSave(IL_JPG, fsFullPath.c_str()); } break;
402+
case 'p': case 'P': { success = ilSave(IL_PNG, fsFullPath.c_str()); } break;
403+
case 't': case 'T': { success = ilSave(IL_TGA, fsFullPath.c_str()); } break;
404+
case 'd': case 'D': { success = ilSave(IL_DDS, fsFullPath.c_str()); } break;
404405
}
405406
}
407+
#endif
406408

407409
if (logged) {
408410
if (success) {
409-
LOG("[CBitmap::%s] saved \"%s\" to \"%s\"", __func__, filename.c_str(), fullPath.c_str());
411+
LOG("[CBitmap::%s] saved \"%s\" to \"%s\"", __func__, filename.c_str(), fsFullPath.c_str());
410412
} else {
411-
LOG("[CBitmap::%s] error 0x%x (re-)saving \"%s\" to \"%s\"", __func__, ilGetError(), filename.c_str(), fullPath.c_str());
413+
LOG("[CBitmap::%s] error 0x%x (re-)saving \"%s\" to \"%s\"", __func__, ilGetError(), filename.c_str(), fsFullPath.c_str());
412414
}
413415
}
414416

@@ -427,14 +429,16 @@ bool CBitmap::SaveFloat(std::string const& filename) const
427429
// seems IL_ORIGIN_SET only works in ilLoad and not in ilTexImage nor in ilSaveImage
428430
// so we need to flip the image ourself
429431
const float* memf = reinterpret_cast<const float*>(&mem[0]);
430-
typedef unsigned short uint16;
431-
std::unique_ptr<uint16[]> buf(new uint16[xsize * ysize]);
432-
const int ymax = (ysize - 1);
432+
433+
std::vector<uint16_t> buf(xsize * ysize);
434+
435+
const int ymax = ysize - 1;
436+
433437
for (int y = 0; y < ysize; ++y) {
434438
for (int x = 0; x < xsize; ++x) {
435439
const int bi = x + (xsize * (ymax - y));
436-
const int mi = x + (xsize * (y));
437-
uint16 us = memf[mi] * 0xFFFF; // convert float 0..1 to ushort
440+
const int mi = x + (xsize * ( y));
441+
uint16_t us = memf[mi] * 0xFFFF; // convert float 0..1 to ushort
438442
buf[bi] = us;
439443
}
440444
}
@@ -449,10 +453,16 @@ bool CBitmap::SaveFloat(std::string const& filename) const
449453

450454
// note: DevIL only generates a 16bit grayscale PNG when format is IL_UNSIGNED_SHORT!
451455
// IL_FLOAT is converted to RGB with 8bit colordepth!
452-
ilTexImage(xsize, ysize, 1, 1, IL_LUMINANCE, IL_UNSIGNED_SHORT, buf.get());
456+
ilTexImage(xsize, ysize, 1, 1, IL_LUMINANCE, IL_UNSIGNED_SHORT, buf.data());
453457

454-
const std::string fullpath = dataDirsAccess.LocateFile(filename, FileQueryFlags::WRITE);
455-
const bool success = ilSaveImage(fullpath.c_str());
458+
459+
// const std::string& imageExt = FileSystem::GetExtension(filename);
460+
const std::string& fsFullPath = dataDirsAccess.LocateFile(filename, FileQueryFlags::WRITE);
461+
462+
const std::vector<ILchar> ilFullPath(fsFullPath.begin(), fsFullPath.end());
463+
464+
465+
const bool success = ilSaveImage(ilFullPath.data());
456466

457467
ilDeleteImages(1, &ImageName);
458468
return success;
@@ -785,16 +795,15 @@ SDL_Surface* CBitmap::CreateSDLSurface() const
785795
return surface;
786796
}
787797

788-
unsigned char* surfData = new unsigned char[xsize * ysize * channels];
789-
memcpy(surfData, &mem[0], xsize * ysize * channels);
798+
std::vector<unsigned char> surfData(xsize * ysize * channels);
799+
memcpy(surfData.data(), &mem[0], xsize * ysize * channels);
790800

791801

792802
// This will only work with 24bit RGB and 32bit RGBA pictures
793-
surface = SDL_CreateRGBSurfaceFrom(surfData, xsize, ysize, 8 * channels, xsize * channels, 0x000000FF, 0x0000FF00, 0x00FF0000, (channels == 4) ? 0xFF000000 : 0);
794-
if (surface == nullptr) {
803+
surface = SDL_CreateRGBSurfaceFrom(surfData.data(), xsize, ysize, 8 * channels, xsize * channels, 0x000000FF, 0x0000FF00, 0x00FF0000, (channels == 4) ? 0xFF000000 : 0);
804+
805+
if (surface == nullptr)
795806
LOG_L(L_WARNING, "CBitmap::CreateSDLSurface Failed!");
796-
delete[] surfData;
797-
}
798807

799808
return surface;
800809
}
@@ -942,16 +951,18 @@ void CBitmap::Tint(const float tint[3])
942951

943952
void CBitmap::ReverseYAxis()
944953
{
945-
if (compressed) return; // don't try to flip DDS
946-
unsigned char* tmpLine = new unsigned char[channels * xsize];
947-
for (int y=0; y < (ysize / 2); ++y) {
954+
if (compressed)
955+
return; // don't try to flip DDS
956+
957+
std::vector<unsigned char> tmpLine(channels * xsize);
958+
959+
for (int y = 0; y < (ysize / 2); ++y) {
948960
const int pixelLow = (((y ) * xsize) + 0) * channels;
949961
const int pixelHigh = (((ysize - 1 - y) * xsize) + 0) * channels;
950962

951963
// copy the whole line
952-
std::copy(mem.begin() + pixelHigh, mem.begin() + pixelHigh + channels * xsize, tmpLine);
953-
std::copy(mem.begin() + pixelLow, mem.begin() + pixelLow + channels * xsize, mem.begin() + pixelHigh);
954-
std::copy(tmpLine, tmpLine + channels * xsize, mem.begin() + pixelLow);
964+
std::copy(mem.begin() + pixelHigh, mem.begin() + pixelHigh + channels * xsize, tmpLine.data());
965+
std::copy(mem.begin() + pixelLow , mem.begin() + pixelLow + channels * xsize, mem.begin() + pixelHigh);
966+
std::copy(tmpLine.data(), tmpLine.data() + channels * xsize, mem.begin() + pixelLow);
955967
}
956-
delete[] tmpLine;
957968
}

0 commit comments

Comments
 (0)