From d0d5c5c40017db1857eb93e2b84b9ff933f8f63c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 15 May 2024 21:36:00 +0100 Subject: [PATCH] Codechange: Pass BmpInfo and BmpData as references. Avoids needing to check for nullptr. --- src/bmp.cpp | 142 ++++++++++++++++++++++------------------------ src/bmp.h | 4 +- src/heightmap.cpp | 34 +++++------ 3 files changed, 88 insertions(+), 92 deletions(-) diff --git a/src/bmp.cpp b/src/bmp.cpp index 0c310c7686..d68e5246fe 100644 --- a/src/bmp.cpp +++ b/src/bmp.cpp @@ -10,7 +10,6 @@ #include "stdafx.h" #include "bmp.h" #include "core/bitmath_func.hpp" -#include "core/mem_func.hpp" #include "safeguards.h" @@ -79,20 +78,20 @@ static inline void SetStreamOffset(BmpBuffer *buffer, int offset) * Reads a 1 bpp uncompressed bitmap * The bitmap is converted to a 8 bpp bitmap */ -static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint x, y, i; - uint8_t pad = GB(4 - info->width / 8, 0, 2); + uint8_t pad = GB(4 - info.width / 8, 0, 2); uint8_t *pixel_row; uint8_t b; - for (y = info->height; y > 0; y--) { + for (y = info.height; y > 0; y--) { x = 0; - pixel_row = &data->bitmap[(y - 1) * info->width]; - while (x < info->width) { + pixel_row = &data.bitmap[(y - 1) * info.width]; + while (x < info.width) { if (EndOfBuffer(buffer)) return false; // the file is shorter than expected b = ReadByte(buffer); for (i = 8; i > 0; i--) { - if (x < info->width) *pixel_row++ = GB(b, i - 1, 1); + if (x < info.width) *pixel_row++ = GB(b, i - 1, 1); x++; } } @@ -106,21 +105,21 @@ static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data) * Reads a 4 bpp uncompressed bitmap * The bitmap is converted to a 8 bpp bitmap */ -static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint x, y; - uint8_t pad = GB(4 - info->width / 2, 0, 2); + uint8_t pad = GB(4 - info.width / 2, 0, 2); uint8_t *pixel_row; uint8_t b; - for (y = info->height; y > 0; y--) { + for (y = info.height; y > 0; y--) { x = 0; - pixel_row = &data->bitmap[(y - 1) * info->width]; - while (x < info->width) { + pixel_row = &data.bitmap[(y - 1) * info.width]; + while (x < info.width) { if (EndOfBuffer(buffer)) return false; // the file is shorter than expected b = ReadByte(buffer); *pixel_row++ = GB(b, 4, 4); x++; - if (x < info->width) { + if (x < info.width) { *pixel_row++ = GB(b, 0, 4); x++; } @@ -135,12 +134,12 @@ static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo *info, BmpData *data) * Reads a 4-bit RLE compressed bitmap * The bitmap is converted to a 8 bpp bitmap */ -static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint x = 0; - uint y = info->height - 1; - uint8_t *pixel = &data->bitmap[y * info->width]; - while (y != 0 || x < info->width) { + uint y = info.height - 1; + uint8_t *pixel = &data.bitmap[y * info.width]; + while (y != 0 || x < info.width) { if (EndOfBuffer(buffer)) return false; // the file is shorter than expected uint8_t n = ReadByte(buffer); @@ -150,7 +149,7 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) case 0: // end of line x = 0; if (y == 0) return false; - pixel = &data->bitmap[--y * info->width]; + pixel = &data.bitmap[--y * info.width]; break; case 1: // end of bitmap @@ -162,23 +161,23 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) uint8_t dy = ReadByte(buffer); /* Check for over- and underflow. */ - if (x + dx >= info->width || x + dx < x || dy > y) return false; + if (x + dx >= info.width || x + dx < x || dy > y) return false; x += dx; y -= dy; - pixel = &data->bitmap[y * info->width + x]; + pixel = &data.bitmap[y * info.width + x]; break; } default: { // uncompressed uint i = 0; while (i++ < c) { - if (EndOfBuffer(buffer) || x >= info->width) return false; + if (EndOfBuffer(buffer) || x >= info.width) return false; uint8_t b = ReadByte(buffer); *pixel++ = GB(b, 4, 4); x++; if (i++ < c) { - if (x >= info->width) return false; + if (x >= info.width) return false; *pixel++ = GB(b, 0, 4); x++; } @@ -193,10 +192,10 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) * pixels to be written is higher than the remaining line width. * Ignore the superfluous pixels instead of reporting an error. */ uint i = 0; - while (x < info->width && i++ < n) { + while (x < info.width && i++ < n) { *pixel++ = GB(c, 4, 4); x++; - if (x < info->width && i++ < n) { + if (x < info.width && i++ < n) { *pixel++ = GB(c, 0, 4); x++; } @@ -209,16 +208,16 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) /** * Reads a 8 bpp bitmap */ -static inline bool BmpRead8(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +static inline bool BmpRead8(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint i; uint y; - uint8_t pad = GB(4 - info->width, 0, 2); + uint8_t pad = GB(4 - info.width, 0, 2); uint8_t *pixel; - for (y = info->height; y > 0; y--) { + for (y = info.height; y > 0; y--) { if (EndOfBuffer(buffer)) return false; // the file is shorter than expected - pixel = &data->bitmap[(y - 1) * info->width]; - for (i = 0; i < info->width; i++) *pixel++ = ReadByte(buffer); + pixel = &data.bitmap[(y - 1) * info.width]; + for (i = 0; i < info.width; i++) *pixel++ = ReadByte(buffer); /* Padding for 32 bit align */ SkipBytes(buffer, pad); } @@ -228,12 +227,12 @@ static inline bool BmpRead8(BmpBuffer *buffer, BmpInfo *info, BmpData *data) /** * Reads a 8-bit RLE compressed bpp bitmap */ -static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint x = 0; - uint y = info->height - 1; - uint8_t *pixel = &data->bitmap[y * info->width]; - while (y != 0 || x < info->width) { + uint y = info.height - 1; + uint8_t *pixel = &data.bitmap[y * info.width]; + while (y != 0 || x < info.width) { if (EndOfBuffer(buffer)) return false; // the file is shorter than expected uint8_t n = ReadByte(buffer); @@ -243,7 +242,7 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) case 0: // end of line x = 0; if (y == 0) return false; - pixel = &data->bitmap[--y * info->width]; + pixel = &data.bitmap[--y * info.width]; break; case 1: // end of bitmap @@ -255,17 +254,17 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) uint8_t dy = ReadByte(buffer); /* Check for over- and underflow. */ - if (x + dx >= info->width || x + dx < x || dy > y) return false; + if (x + dx >= info.width || x + dx < x || dy > y) return false; x += dx; y -= dy; - pixel = &data->bitmap[y * info->width + x]; + pixel = &data.bitmap[y * info.width + x]; break; } default: { // uncompressed for (uint i = 0; i < c; i++) { - if (EndOfBuffer(buffer) || x >= info->width) return false; + if (EndOfBuffer(buffer) || x >= info.width) return false; *pixel++ = ReadByte(buffer); x++; } @@ -278,7 +277,7 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) /* Apparently it is common to encounter BMPs where the count of * pixels to be written is higher than the remaining line width. * Ignore the superfluous pixels instead of reporting an error. */ - for (uint i = 0; x < info->width && i < n; i++) { + for (uint i = 0; x < info.width && i < n; i++) { *pixel++ = c; x++; } @@ -290,14 +289,14 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data) /** * Reads a 24 bpp uncompressed bitmap */ -static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint x, y; - uint8_t pad = GB(4 - info->width * 3, 0, 2); + uint8_t pad = GB(4 - info.width * 3, 0, 2); uint8_t *pixel_row; - for (y = info->height; y > 0; y--) { - pixel_row = &data->bitmap[(y - 1) * info->width * 3]; - for (x = 0; x < info->width; x++) { + for (y = info.height; y > 0; y--) { + pixel_row = &data.bitmap[(y - 1) * info.width * 3]; + for (x = 0; x < info.width; x++) { if (EndOfBuffer(buffer)) return false; // the file is shorter than expected *(pixel_row + 2) = ReadByte(buffer); // green *(pixel_row + 1) = ReadByte(buffer); // blue @@ -313,92 +312,89 @@ static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data) /* * Reads bitmap headers, and palette (if any) */ -bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +bool BmpReadHeader(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { uint32_t header_size; - assert(info != nullptr); - MemSetT(info, 0); + info = {}; /* Reading BMP header */ if (ReadWord(buffer) != 0x4D42) return false; // signature should be 'BM' SkipBytes(buffer, 8); // skip file size and reserved - info->offset = ReadDword(buffer); + info.offset = ReadDword(buffer); /* Reading info header */ header_size = ReadDword(buffer); if (header_size < 12) return false; // info header should be at least 12 bytes long - info->os2_bmp = (header_size == 12); // OS/2 1.x or windows 2.x info header is 12 bytes long + info.os2_bmp = (header_size == 12); // OS/2 1.x or windows 2.x info header is 12 bytes long - if (info->os2_bmp) { - info->width = ReadWord(buffer); - info->height = ReadWord(buffer); + if (info.os2_bmp) { + info.width = ReadWord(buffer); + info.height = ReadWord(buffer); header_size -= 8; } else { - info->width = ReadDword(buffer); - info->height = ReadDword(buffer); + info.width = ReadDword(buffer); + info.height = ReadDword(buffer); header_size -= 12; } if (ReadWord(buffer) != 1) return false; // BMP can have only 1 plane - info->bpp = ReadWord(buffer); - if (info->bpp != 1 && info->bpp != 4 && info->bpp != 8 && info->bpp != 24) { + info.bpp = ReadWord(buffer); + if (info.bpp != 1 && info.bpp != 4 && info.bpp != 8 && info.bpp != 24) { /* Only 1 bpp, 4 bpp, 8bpp and 24 bpp bitmaps are supported */ return false; } /* Reads compression method if available in info header*/ if ((header_size -= 4) >= 4) { - info->compression = ReadDword(buffer); + info.compression = ReadDword(buffer); header_size -= 4; } /* Only 4-bit and 8-bit rle compression is supported */ - if (info->compression > 2 || (info->compression > 0 && !(info->bpp == 4 || info->bpp == 8))) return false; + if (info.compression > 2 || (info.compression > 0 && !(info.bpp == 4 || info.bpp == 8))) return false; - if (info->bpp <= 8) { + if (info.bpp <= 8) { /* Reads number of colours if available in info header */ if (header_size >= 16) { SkipBytes(buffer, 12); // skip image size and resolution - info->palette_size = ReadDword(buffer); // number of colours in palette + info.palette_size = ReadDword(buffer); // number of colours in palette SkipBytes(buffer, header_size - 16); // skip the end of info header } - uint maximum_palette_size = 1U << info->bpp; - if (info->palette_size == 0) info->palette_size = maximum_palette_size; + uint maximum_palette_size = 1U << info.bpp; + if (info.palette_size == 0) info.palette_size = maximum_palette_size; /* More palette colours than palette indices is not supported. */ - if (info->palette_size > maximum_palette_size) return false; + if (info.palette_size > maximum_palette_size) return false; - data->palette.resize(info->palette_size); + data.palette.resize(info.palette_size); - for (auto &colour : data->palette) { + for (auto &colour : data.palette) { colour.b = ReadByte(buffer); colour.g = ReadByte(buffer); colour.r = ReadByte(buffer); - if (!info->os2_bmp) SkipBytes(buffer, 1); // unused + if (!info.os2_bmp) SkipBytes(buffer, 1); // unused } } - return buffer->real_pos <= info->offset; + return buffer->real_pos <= info.offset; } /* * Reads the bitmap * 1 bpp and 4 bpp bitmaps are converted to 8 bpp bitmaps */ -bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data) +bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo &info, BmpData &data) { - assert(info != nullptr && data != nullptr); - - data->bitmap.resize(static_cast(info->width) * info->height * ((info->bpp == 24) ? 3 : 1)); + data.bitmap.resize(static_cast(info.width) * info.height * ((info.bpp == 24) ? 3 : 1)); /* Load image */ - SetStreamOffset(buffer, info->offset); - switch (info->compression) { + SetStreamOffset(buffer, info.offset); + switch (info.compression) { case 0: // no compression - switch (info->bpp) { + switch (info.bpp) { case 1: return BmpRead1(buffer, info, data); case 4: return BmpRead4(buffer, info, data); case 8: return BmpRead8(buffer, info, data); diff --git a/src/bmp.h b/src/bmp.h index fa3dd4df8f..de094a2b53 100644 --- a/src/bmp.h +++ b/src/bmp.h @@ -38,7 +38,7 @@ struct BmpBuffer { }; void BmpInitializeBuffer(BmpBuffer *buffer, FILE *file); -bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data); -bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data); +bool BmpReadHeader(BmpBuffer *buffer, BmpInfo &info, BmpData &data); +bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo &info, BmpData &data); #endif /* BMP_H */ diff --git a/src/heightmap.cpp b/src/heightmap.cpp index ad68341687..f39f04cc3c 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -206,19 +206,19 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, uint8_t **m /** * The BMP Heightmap loader. */ -static void ReadHeightmapBMPImageData(uint8_t *map, BmpInfo *info, BmpData *data) +static void ReadHeightmapBMPImageData(uint8_t *map, const BmpInfo &info, const BmpData &data) { uint x, y; uint8_t gray_palette[256]; - if (!data->palette.empty()) { + if (!data.palette.empty()) { uint i; bool all_gray = true; - if (info->palette_size != 2) { - for (i = 0; i < info->palette_size && (info->palette_size != 16 || all_gray); i++) { - all_gray &= data->palette[i].r == data->palette[i].g && data->palette[i].r == data->palette[i].b; - gray_palette[i] = RGBToGrayscale(data->palette[i].r, data->palette[i].g, data->palette[i].b); + if (info.palette_size != 2) { + for (i = 0; i < info.palette_size && (info.palette_size != 16 || all_gray); i++) { + all_gray &= data.palette[i].r == data.palette[i].g && data.palette[i].r == data.palette[i].b; + gray_palette[i] = RGBToGrayscale(data.palette[i].r, data.palette[i].g, data.palette[i].b); } /** @@ -227,9 +227,9 @@ static void ReadHeightmapBMPImageData(uint8_t *map, BmpInfo *info, BmpData *data * the first entry is the sea (level 0), the second one * level 1, etc. */ - if (info->palette_size == 16 && !all_gray) { - for (i = 0; i < info->palette_size; i++) { - gray_palette[i] = 256 * i / info->palette_size; + if (info.palette_size == 16 && !all_gray) { + for (i = 0; i < info.palette_size; i++) { + gray_palette[i] = 256 * i / info.palette_size; } } } else { @@ -243,12 +243,12 @@ static void ReadHeightmapBMPImageData(uint8_t *map, BmpInfo *info, BmpData *data } /* Read the raw image data and convert in 8-bit grayscale */ - for (y = 0; y < info->height; y++) { - uint8_t *pixel = &map[y * info->width]; - uint8_t *bitmap = &data->bitmap[y * info->width * (info->bpp == 24 ? 3 : 1)]; + for (y = 0; y < info.height; y++) { + uint8_t *pixel = &map[y * info.width]; + const uint8_t *bitmap = &data.bitmap[y * info.width * (info.bpp == 24 ? 3 : 1)]; - for (x = 0; x < info->width; x++) { - if (info->bpp != 24) { + for (x = 0; x < info.width; x++) { + if (info.bpp != 24) { *pixel++ = gray_palette[*bitmap++]; } else { *pixel++ = RGBToGrayscale(*bitmap, *(bitmap + 1), *(bitmap + 2)); @@ -278,7 +278,7 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, uint8_t **m BmpInitializeBuffer(&buffer, f); - if (!BmpReadHeader(&buffer, &info, &data)) { + if (!BmpReadHeader(&buffer, info, data)) { ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR); fclose(f); return false; @@ -291,14 +291,14 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, uint8_t **m } if (map != nullptr) { - if (!BmpReadBitmap(&buffer, &info, &data)) { + if (!BmpReadBitmap(&buffer, info, data)) { ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR); fclose(f); return false; } *map = MallocT(static_cast(info.width) * info.height); - ReadHeightmapBMPImageData(*map, &info, &data); + ReadHeightmapBMPImageData(*map, info, data); } *x = info.width;