summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/msdib.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2023-04-13 05:49:05 +1000
committer Vas Crabb <vas@vastheman.com>2023-04-13 05:49:05 +1000
commitb6b6c9b15c34471fd3938bdb9715754f09f10e00 (patch)
treeb77d63379d6fb1305ca64342f7e5ca7f9aff3d3c /src/lib/util/msdib.cpp
parent81dd75f7d7db2967d00075bd443c85e8b042251d (diff)
Allow loading PNG/JPEG/MS DIB bitmaps from Lua, and cleanup.
Use VirtualAlloc rather than VirtualProtect on Windows to change page protection, as the latter can cause severe performance issues with some antivirus software. Added noexcept to lots of hash- and bitmap-related things, and added a little more error checking. Yes, I realise it will abort if an allocation fails while printing a log message, but if you get to that point, you're probably screwed already.
Diffstat (limited to 'src/lib/util/msdib.cpp')
-rw-r--r--src/lib/util/msdib.cpp22
1 files changed, 13 insertions, 9 deletions
diff --git a/src/lib/util/msdib.cpp b/src/lib/util/msdib.cpp
index 6ce0e0fd990..7b537fdae61 100644
--- a/src/lib/util/msdib.cpp
+++ b/src/lib/util/msdib.cpp
@@ -93,7 +93,7 @@ union bitmap_headers
};
-bool dib_parse_mask(std::uint32_t mask, unsigned &shift, unsigned &bits)
+bool dib_parse_mask(std::uint32_t mask, unsigned &shift, unsigned &bits) noexcept
{
shift = count_leading_zeros_32(mask);
mask <<= shift;
@@ -104,7 +104,7 @@ bool dib_parse_mask(std::uint32_t mask, unsigned &shift, unsigned &bits)
}
-void dib_truncate_channel(unsigned &shift, unsigned &bits)
+void dib_truncate_channel(unsigned &shift, unsigned &bits) noexcept
{
if (8U < bits)
{
@@ -115,7 +115,7 @@ void dib_truncate_channel(unsigned &shift, unsigned &bits)
}
-std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits)
+std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits) noexcept
{
assert(8U >= bits);
for (val <<= (8U - bits); bits && (8U > bits); bits <<= 1)
@@ -124,7 +124,7 @@ std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits)
}
-msdib_error dib_read_file_header(read_stream &fp, std::uint32_t &filelen)
+msdib_error dib_read_file_header(read_stream &fp, std::uint32_t &filelen) noexcept
{
std::size_t actual;
@@ -172,7 +172,7 @@ msdib_error dib_read_bitmap_header(
std::size_t &palette_entries,
std::size_t &palette_size,
std::size_t &row_bytes,
- std::uint32_t length)
+ std::uint32_t length) noexcept
{
std::size_t actual;
@@ -397,7 +397,7 @@ msdib_error dib_read_bitmap_header(
-msdib_error msdib_verify_header(random_read &fp)
+msdib_error msdib_verify_header(random_read &fp) noexcept
{
msdib_error err;
@@ -438,7 +438,7 @@ msdib_error msdib_verify_header(random_read &fp)
}
-msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap)
+msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap) noexcept
{
std::uint32_t file_length;
msdib_error const headerr(dib_read_file_header(fp, file_length));
@@ -449,7 +449,7 @@ msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap)
}
-msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight)
+msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight) noexcept
{
// read the bitmap header
std::size_t actual;
@@ -570,11 +570,15 @@ msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::
dib_truncate_channel(alpha_shift, alpha_bits);
}
- // allocate the bitmap and process row data
+ // allocate a row buffer as well as the destination bitmap
std::unique_ptr<std::uint8_t []> row_data(new (std::nothrow) std::uint8_t [row_bytes]);
if (!row_data)
return msdib_error::OUT_OF_MEMORY;
bitmap.allocate(header.info.width, header.info.height);
+ if (!bitmap.valid())
+ return msdib_error::OUT_OF_MEMORY;
+
+ // process row data
int const y_inc(top_down ? 1 : -1);
for (std::int32_t i = 0, y = top_down ? 0 : (header.info.height - 1); header.info.height > i; ++i, y += y_inc)
{