mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Pass BmpInfo and BmpData as references.
Avoids needing to check for nullptr.pull/12897/head
parent
f829b1d74a
commit
d0d5c5c400
142
src/bmp.cpp
142
src/bmp.cpp
|
@ -10,7 +10,6 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "bmp.h"
|
#include "bmp.h"
|
||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
#include "core/mem_func.hpp"
|
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
@ -79,20 +78,20 @@ static inline void SetStreamOffset(BmpBuffer *buffer, int offset)
|
||||||
* Reads a 1 bpp uncompressed bitmap
|
* Reads a 1 bpp uncompressed bitmap
|
||||||
* The bitmap is converted to a 8 bpp 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;
|
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 *pixel_row;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info.height; y > 0; y--) {
|
||||||
x = 0;
|
x = 0;
|
||||||
pixel_row = &data->bitmap[(y - 1) * info->width];
|
pixel_row = &data.bitmap[(y - 1) * info.width];
|
||||||
while (x < info->width) {
|
while (x < info.width) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
b = ReadByte(buffer);
|
b = ReadByte(buffer);
|
||||||
for (i = 8; i > 0; i--) {
|
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++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,21 +105,21 @@ static inline bool BmpRead1(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
* Reads a 4 bpp uncompressed bitmap
|
* Reads a 4 bpp uncompressed bitmap
|
||||||
* The bitmap is converted to a 8 bpp 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;
|
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 *pixel_row;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info.height; y > 0; y--) {
|
||||||
x = 0;
|
x = 0;
|
||||||
pixel_row = &data->bitmap[(y - 1) * info->width];
|
pixel_row = &data.bitmap[(y - 1) * info.width];
|
||||||
while (x < info->width) {
|
while (x < info.width) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
b = ReadByte(buffer);
|
b = ReadByte(buffer);
|
||||||
*pixel_row++ = GB(b, 4, 4);
|
*pixel_row++ = GB(b, 4, 4);
|
||||||
x++;
|
x++;
|
||||||
if (x < info->width) {
|
if (x < info.width) {
|
||||||
*pixel_row++ = GB(b, 0, 4);
|
*pixel_row++ = GB(b, 0, 4);
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
@ -135,12 +134,12 @@ static inline bool BmpRead4(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
* Reads a 4-bit RLE compressed bitmap
|
* Reads a 4-bit RLE compressed bitmap
|
||||||
* The bitmap is converted to a 8 bpp 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 x = 0;
|
||||||
uint y = info->height - 1;
|
uint y = info.height - 1;
|
||||||
uint8_t *pixel = &data->bitmap[y * info->width];
|
uint8_t *pixel = &data.bitmap[y * info.width];
|
||||||
while (y != 0 || x < info->width) {
|
while (y != 0 || x < info.width) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
|
|
||||||
uint8_t n = ReadByte(buffer);
|
uint8_t n = ReadByte(buffer);
|
||||||
|
@ -150,7 +149,7 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
case 0: // end of line
|
case 0: // end of line
|
||||||
x = 0;
|
x = 0;
|
||||||
if (y == 0) return false;
|
if (y == 0) return false;
|
||||||
pixel = &data->bitmap[--y * info->width];
|
pixel = &data.bitmap[--y * info.width];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // end of bitmap
|
case 1: // end of bitmap
|
||||||
|
@ -162,23 +161,23 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
uint8_t dy = ReadByte(buffer);
|
uint8_t dy = ReadByte(buffer);
|
||||||
|
|
||||||
/* Check for over- and underflow. */
|
/* 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;
|
x += dx;
|
||||||
y -= dy;
|
y -= dy;
|
||||||
pixel = &data->bitmap[y * info->width + x];
|
pixel = &data.bitmap[y * info.width + x];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: { // uncompressed
|
default: { // uncompressed
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
while (i++ < c) {
|
while (i++ < c) {
|
||||||
if (EndOfBuffer(buffer) || x >= info->width) return false;
|
if (EndOfBuffer(buffer) || x >= info.width) return false;
|
||||||
uint8_t b = ReadByte(buffer);
|
uint8_t b = ReadByte(buffer);
|
||||||
*pixel++ = GB(b, 4, 4);
|
*pixel++ = GB(b, 4, 4);
|
||||||
x++;
|
x++;
|
||||||
if (i++ < c) {
|
if (i++ < c) {
|
||||||
if (x >= info->width) return false;
|
if (x >= info.width) return false;
|
||||||
*pixel++ = GB(b, 0, 4);
|
*pixel++ = GB(b, 0, 4);
|
||||||
x++;
|
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.
|
* pixels to be written is higher than the remaining line width.
|
||||||
* Ignore the superfluous pixels instead of reporting an error. */
|
* Ignore the superfluous pixels instead of reporting an error. */
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
while (x < info->width && i++ < n) {
|
while (x < info.width && i++ < n) {
|
||||||
*pixel++ = GB(c, 4, 4);
|
*pixel++ = GB(c, 4, 4);
|
||||||
x++;
|
x++;
|
||||||
if (x < info->width && i++ < n) {
|
if (x < info.width && i++ < n) {
|
||||||
*pixel++ = GB(c, 0, 4);
|
*pixel++ = GB(c, 0, 4);
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
@ -209,16 +208,16 @@ static inline bool BmpRead4Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
/**
|
/**
|
||||||
* Reads a 8 bpp bitmap
|
* 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 i;
|
||||||
uint y;
|
uint y;
|
||||||
uint8_t pad = GB(4 - info->width, 0, 2);
|
uint8_t pad = GB(4 - info.width, 0, 2);
|
||||||
uint8_t *pixel;
|
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
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
pixel = &data->bitmap[(y - 1) * info->width];
|
pixel = &data.bitmap[(y - 1) * info.width];
|
||||||
for (i = 0; i < info->width; i++) *pixel++ = ReadByte(buffer);
|
for (i = 0; i < info.width; i++) *pixel++ = ReadByte(buffer);
|
||||||
/* Padding for 32 bit align */
|
/* Padding for 32 bit align */
|
||||||
SkipBytes(buffer, pad);
|
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
|
* 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 x = 0;
|
||||||
uint y = info->height - 1;
|
uint y = info.height - 1;
|
||||||
uint8_t *pixel = &data->bitmap[y * info->width];
|
uint8_t *pixel = &data.bitmap[y * info.width];
|
||||||
while (y != 0 || x < info->width) {
|
while (y != 0 || x < info.width) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
|
|
||||||
uint8_t n = ReadByte(buffer);
|
uint8_t n = ReadByte(buffer);
|
||||||
|
@ -243,7 +242,7 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
case 0: // end of line
|
case 0: // end of line
|
||||||
x = 0;
|
x = 0;
|
||||||
if (y == 0) return false;
|
if (y == 0) return false;
|
||||||
pixel = &data->bitmap[--y * info->width];
|
pixel = &data.bitmap[--y * info.width];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // end of bitmap
|
case 1: // end of bitmap
|
||||||
|
@ -255,17 +254,17 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
uint8_t dy = ReadByte(buffer);
|
uint8_t dy = ReadByte(buffer);
|
||||||
|
|
||||||
/* Check for over- and underflow. */
|
/* 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;
|
x += dx;
|
||||||
y -= dy;
|
y -= dy;
|
||||||
pixel = &data->bitmap[y * info->width + x];
|
pixel = &data.bitmap[y * info.width + x];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: { // uncompressed
|
default: { // uncompressed
|
||||||
for (uint i = 0; i < c; i++) {
|
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);
|
*pixel++ = ReadByte(buffer);
|
||||||
x++;
|
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
|
/* Apparently it is common to encounter BMPs where the count of
|
||||||
* pixels to be written is higher than the remaining line width.
|
* pixels to be written is higher than the remaining line width.
|
||||||
* Ignore the superfluous pixels instead of reporting an error. */
|
* 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;
|
*pixel++ = c;
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
@ -290,14 +289,14 @@ static inline bool BmpRead8Rle(BmpBuffer *buffer, BmpInfo *info, BmpData *data)
|
||||||
/**
|
/**
|
||||||
* Reads a 24 bpp uncompressed bitmap
|
* 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;
|
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;
|
uint8_t *pixel_row;
|
||||||
for (y = info->height; y > 0; y--) {
|
for (y = info.height; y > 0; y--) {
|
||||||
pixel_row = &data->bitmap[(y - 1) * info->width * 3];
|
pixel_row = &data.bitmap[(y - 1) * info.width * 3];
|
||||||
for (x = 0; x < info->width; x++) {
|
for (x = 0; x < info.width; x++) {
|
||||||
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
if (EndOfBuffer(buffer)) return false; // the file is shorter than expected
|
||||||
*(pixel_row + 2) = ReadByte(buffer); // green
|
*(pixel_row + 2) = ReadByte(buffer); // green
|
||||||
*(pixel_row + 1) = ReadByte(buffer); // blue
|
*(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)
|
* 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;
|
uint32_t header_size;
|
||||||
assert(info != nullptr);
|
info = {};
|
||||||
MemSetT(info, 0);
|
|
||||||
|
|
||||||
/* Reading BMP header */
|
/* Reading BMP header */
|
||||||
if (ReadWord(buffer) != 0x4D42) return false; // signature should be 'BM'
|
if (ReadWord(buffer) != 0x4D42) return false; // signature should be 'BM'
|
||||||
SkipBytes(buffer, 8); // skip file size and reserved
|
SkipBytes(buffer, 8); // skip file size and reserved
|
||||||
info->offset = ReadDword(buffer);
|
info.offset = ReadDword(buffer);
|
||||||
|
|
||||||
/* Reading info header */
|
/* Reading info header */
|
||||||
header_size = ReadDword(buffer);
|
header_size = ReadDword(buffer);
|
||||||
if (header_size < 12) return false; // info header should be at least 12 bytes long
|
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) {
|
if (info.os2_bmp) {
|
||||||
info->width = ReadWord(buffer);
|
info.width = ReadWord(buffer);
|
||||||
info->height = ReadWord(buffer);
|
info.height = ReadWord(buffer);
|
||||||
header_size -= 8;
|
header_size -= 8;
|
||||||
} else {
|
} else {
|
||||||
info->width = ReadDword(buffer);
|
info.width = ReadDword(buffer);
|
||||||
info->height = ReadDword(buffer);
|
info.height = ReadDword(buffer);
|
||||||
header_size -= 12;
|
header_size -= 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadWord(buffer) != 1) return false; // BMP can have only 1 plane
|
if (ReadWord(buffer) != 1) return false; // BMP can have only 1 plane
|
||||||
|
|
||||||
info->bpp = ReadWord(buffer);
|
info.bpp = ReadWord(buffer);
|
||||||
if (info->bpp != 1 && info->bpp != 4 && info->bpp != 8 && info->bpp != 24) {
|
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 */
|
/* Only 1 bpp, 4 bpp, 8bpp and 24 bpp bitmaps are supported */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reads compression method if available in info header*/
|
/* Reads compression method if available in info header*/
|
||||||
if ((header_size -= 4) >= 4) {
|
if ((header_size -= 4) >= 4) {
|
||||||
info->compression = ReadDword(buffer);
|
info.compression = ReadDword(buffer);
|
||||||
header_size -= 4;
|
header_size -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only 4-bit and 8-bit rle compression is supported */
|
/* 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 */
|
/* Reads number of colours if available in info header */
|
||||||
if (header_size >= 16) {
|
if (header_size >= 16) {
|
||||||
SkipBytes(buffer, 12); // skip image size and resolution
|
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
|
SkipBytes(buffer, header_size - 16); // skip the end of info header
|
||||||
}
|
}
|
||||||
|
|
||||||
uint maximum_palette_size = 1U << info->bpp;
|
uint maximum_palette_size = 1U << info.bpp;
|
||||||
if (info->palette_size == 0) info->palette_size = maximum_palette_size;
|
if (info.palette_size == 0) info.palette_size = maximum_palette_size;
|
||||||
|
|
||||||
/* More palette colours than palette indices is not supported. */
|
/* 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.b = ReadByte(buffer);
|
||||||
colour.g = ReadByte(buffer);
|
colour.g = ReadByte(buffer);
|
||||||
colour.r = 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
|
* Reads the bitmap
|
||||||
* 1 bpp and 4 bpp bitmaps are converted to 8 bpp bitmaps
|
* 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<size_t>(info.width) * info.height * ((info.bpp == 24) ? 3 : 1));
|
||||||
|
|
||||||
data->bitmap.resize(static_cast<size_t>(info->width) * info->height * ((info->bpp == 24) ? 3 : 1));
|
|
||||||
|
|
||||||
/* Load image */
|
/* Load image */
|
||||||
SetStreamOffset(buffer, info->offset);
|
SetStreamOffset(buffer, info.offset);
|
||||||
switch (info->compression) {
|
switch (info.compression) {
|
||||||
case 0: // no compression
|
case 0: // no compression
|
||||||
switch (info->bpp) {
|
switch (info.bpp) {
|
||||||
case 1: return BmpRead1(buffer, info, data);
|
case 1: return BmpRead1(buffer, info, data);
|
||||||
case 4: return BmpRead4(buffer, info, data);
|
case 4: return BmpRead4(buffer, info, data);
|
||||||
case 8: return BmpRead8(buffer, info, data);
|
case 8: return BmpRead8(buffer, info, data);
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct BmpBuffer {
|
||||||
};
|
};
|
||||||
|
|
||||||
void BmpInitializeBuffer(BmpBuffer *buffer, FILE *file);
|
void BmpInitializeBuffer(BmpBuffer *buffer, FILE *file);
|
||||||
bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data);
|
bool BmpReadHeader(BmpBuffer *buffer, BmpInfo &info, BmpData &data);
|
||||||
bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data);
|
bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo &info, BmpData &data);
|
||||||
|
|
||||||
#endif /* BMP_H */
|
#endif /* BMP_H */
|
||||||
|
|
|
@ -206,19 +206,19 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, uint8_t **m
|
||||||
/**
|
/**
|
||||||
* The BMP Heightmap loader.
|
* 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;
|
uint x, y;
|
||||||
uint8_t gray_palette[256];
|
uint8_t gray_palette[256];
|
||||||
|
|
||||||
if (!data->palette.empty()) {
|
if (!data.palette.empty()) {
|
||||||
uint i;
|
uint i;
|
||||||
bool all_gray = true;
|
bool all_gray = true;
|
||||||
|
|
||||||
if (info->palette_size != 2) {
|
if (info.palette_size != 2) {
|
||||||
for (i = 0; i < info->palette_size && (info->palette_size != 16 || all_gray); i++) {
|
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;
|
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);
|
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
|
* the first entry is the sea (level 0), the second one
|
||||||
* level 1, etc.
|
* level 1, etc.
|
||||||
*/
|
*/
|
||||||
if (info->palette_size == 16 && !all_gray) {
|
if (info.palette_size == 16 && !all_gray) {
|
||||||
for (i = 0; i < info->palette_size; i++) {
|
for (i = 0; i < info.palette_size; i++) {
|
||||||
gray_palette[i] = 256 * i / info->palette_size;
|
gray_palette[i] = 256 * i / info.palette_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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 */
|
/* Read the raw image data and convert in 8-bit grayscale */
|
||||||
for (y = 0; y < info->height; y++) {
|
for (y = 0; y < info.height; y++) {
|
||||||
uint8_t *pixel = &map[y * info->width];
|
uint8_t *pixel = &map[y * info.width];
|
||||||
uint8_t *bitmap = &data->bitmap[y * info->width * (info->bpp == 24 ? 3 : 1)];
|
const uint8_t *bitmap = &data.bitmap[y * info.width * (info.bpp == 24 ? 3 : 1)];
|
||||||
|
|
||||||
for (x = 0; x < info->width; x++) {
|
for (x = 0; x < info.width; x++) {
|
||||||
if (info->bpp != 24) {
|
if (info.bpp != 24) {
|
||||||
*pixel++ = gray_palette[*bitmap++];
|
*pixel++ = gray_palette[*bitmap++];
|
||||||
} else {
|
} else {
|
||||||
*pixel++ = RGBToGrayscale(*bitmap, *(bitmap + 1), *(bitmap + 2));
|
*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);
|
BmpInitializeBuffer(&buffer, f);
|
||||||
|
|
||||||
if (!BmpReadHeader(&buffer, &info, &data)) {
|
if (!BmpReadHeader(&buffer, info, data)) {
|
||||||
ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR);
|
ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
|
@ -291,14 +291,14 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, uint8_t **m
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map != nullptr) {
|
if (map != nullptr) {
|
||||||
if (!BmpReadBitmap(&buffer, &info, &data)) {
|
if (!BmpReadBitmap(&buffer, info, data)) {
|
||||||
ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR);
|
ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*map = MallocT<uint8_t>(static_cast<size_t>(info.width) * info.height);
|
*map = MallocT<uint8_t>(static_cast<size_t>(info.width) * info.height);
|
||||||
ReadHeightmapBMPImageData(*map, &info, &data);
|
ReadHeightmapBMPImageData(*map, info, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
*x = info.width;
|
*x = info.width;
|
||||||
|
|
Loading…
Reference in New Issue