Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion librtt/Display/Rtt_TextureFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,12 @@ TextureFactory::FindOrCreate(
if ( result.IsNull() )
{
PlatformBitmap *bitmap = CreateBitmap( filePath.GetString(), flags, isMask );
result = CreateAndAdd( key, bitmap, true, isRetina );

// Guards the NULL bitmap Linux returns on a failed load; no-op on emscripten (returns an empty bitmap).
if ( bitmap )
{
result = CreateAndAdd( key, bitmap, true, isRetina );
}
}

return result;
Expand Down
32 changes: 27 additions & 5 deletions platform/emscripten/Rtt_EmscriptenBitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "Core/Rtt_Types.h"
#include "Rtt_BitmapUtils.h"
#include <SDL2/SDL.h>
#include <cctype>
#include <cstring>

#if defined(EMSCRIPTEN)
#include "emscripten/emscripten.h" // for native alert and etc
Expand Down Expand Up @@ -171,14 +173,24 @@ namespace Rtt
{
Rtt_ASSERT(fData == NULL);

// get file ext
int n = strlen(path);
if (n < 5)
if (path == NULL)
{
return false;
}

std::string ext = path + n - 4;
// Extract extension after the last dot. Case-insensitive to accept .JPG, .PNG, etc.
const char *dot = strrchr(path, '.');
if (dot == NULL || dot[1] == '\0')
{
return false;
}

std::string ext(dot);
for (size_t i = 0; i < ext.size(); i++)
{
ext[i] = (char)tolower((unsigned char)ext[i]);
}

if (ext == ".bmp")
{
fData = bitmapUtil::loadBMP(path, fWidth, fHeight, fFormat);
Expand All @@ -198,11 +210,16 @@ namespace Rtt
{
fFormat = kRGBA;
}
else
{
fWidth = 0;
fHeight = 0;
}
fclose(f);
}
}
else
if (ext == ".jpg")
if (ext == ".jpg" || ext == ".jpeg")
{
FILE* f = fopen(path, "rb");
if (f)
Expand Down Expand Up @@ -230,6 +247,11 @@ namespace Rtt
}
free(img);
}
else
{
fWidth = 0;
fHeight = 0;
}
fclose(f);
return fData != NULL;
}
Expand Down
7 changes: 0 additions & 7 deletions platform/emscripten/Rtt_EmscriptenPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,6 @@ namespace Rtt
}
}

if (result && result->GetFormat() == PlatformBitmap::kUndefined)
{
// failed to load bitmap
Rtt_DELETE(result);
result = NULL;
}

return result;
}

Expand Down
10 changes: 9 additions & 1 deletion platform/shared/Rtt_BitmapUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ namespace bitmapUtil
};
typedef struct JpegErrorMgr* jpegErrorMgr;

// Replace libpng's default error handler, which crashes on emscripten, with a clean longjmp.
void pngErrorHandler(png_structp png_ptr, png_const_charp)
{
longjmp(png_jmpbuf(png_ptr), 1);
}

void jpgErrorHandler(j_common_ptr cinfo)
{
char jpegLastErrorMsg[JMSG_LENGTH_MAX];
Expand Down Expand Up @@ -246,7 +252,7 @@ namespace bitmapUtil

uint8_t* loadPNG(FILE* fp, int& w, int& h)
{
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, pngErrorHandler, NULL);
if (png == NULL)
{
return NULL;
Expand All @@ -255,11 +261,13 @@ namespace bitmapUtil
png_infop info = png_create_info_struct(png);
if (info == NULL)
{
png_destroy_read_struct(&png, NULL, NULL);
return NULL;
}

if (setjmp(png_jmpbuf(png)))
{
png_destroy_read_struct(&png, &info, NULL);
return NULL;
}

Expand Down