From f06347c8b7e2fcefb1abd524be5d5e78141ded00 Mon Sep 17 00:00:00 2001 From: cutealien Date: Thu, 5 Oct 2023 21:04:55 +0000 Subject: [PATCH] Load top-down bmp images correctly Previously we handled all sizes as unsigned, but Windows BMP files can have negative height to signal top-down images. No clue about left-right (would be trivial to swap as well, but found no info so far if that would be correct) Also casting away some new compile warning in gcc for COBJMeshFileLoader git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6558 dfc29bdd-3216-0410-991c-e03cc46cb475 --- source/Irrlicht/CImageLoaderBMP.cpp | 24 ++++++++++++++++++++---- source/Irrlicht/COBJMeshFileLoader.cpp | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/source/Irrlicht/CImageLoaderBMP.cpp b/source/Irrlicht/CImageLoaderBMP.cpp index 3c7b482e..8fdb309e 100644 --- a/source/Irrlicht/CImageLoaderBMP.cpp +++ b/source/Irrlicht/CImageLoaderBMP.cpp @@ -309,12 +309,25 @@ IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors); #endif - s32 pitch = 0; - //! return if the header is false - if (header.Id != 0x4d42) + bool topDown = false; + if (header.Id == 0x4d42) // BM = Windows header + { + // Sizes are signed integer with Windows header (unsigned with OS/2) + // Not sure if negative Width has any meaning, but negative height is for upside-down + header.Width = core::abs_((s32)header.Width); + if ( (s32)header.Height < 0 ) + { + topDown = true; + header.Height = core::abs_((s32)header.Height); + } + } + else + { + os::Printer::log("BMP files with OS/2 Headers not supported.", ELL_ERROR); return 0; + } if (header.Compression > 2) // we'll only handle RLE-Compression { @@ -354,7 +367,7 @@ IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const const s32 widthInBytes = core::ceil32(header.Width * (header.BPP / 8.0f)); const s32 lineSize = widthInBytes + ((4-(widthInBytes%4)))%4; - pitch = lineSize - widthInBytes; + const s32 pitch = lineSize - widthInBytes; u8* bmpData = new u8[header.BitmapDataSize]; file->read(bmpData, header.BitmapDataSize); @@ -435,6 +448,9 @@ cleanup: delete [] paletteData; delete [] bmpData; + if ( image && topDown ) + image->flip(true, false); + return image; } diff --git a/source/Irrlicht/COBJMeshFileLoader.cpp b/source/Irrlicht/COBJMeshFileLoader.cpp index f13a003f..b7de81bd 100644 --- a/source/Irrlicht/COBJMeshFileLoader.cpp +++ b/source/Irrlicht/COBJMeshFileLoader.cpp @@ -68,7 +68,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) if (!file) return 0; size_t filesize = file->getSize(); - if (filesize == 0 || filesize == -1L) + if (filesize == 0 || filesize == (size_t)-1L) return 0; const io::path fullName = file->getFileName();