HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Population of bitmap from file to memory

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filememorybitmappopulationfrom

Problem

I'm working on simple a 16/24/32-bit bitmap reader for fun, however, the method I am using to go about reading the DIB header seems odd. All this does is read a simple Windows Compatible Bitmap from a file and stores it in memory.

The idea here was that I wanted to auto-populate members of a struct with the corresponding values from the Bitmap File Header and DIB(Info) Header and then apply the image data to a buffer for later converting into an RGB and RGBA (32-bit only) array.

I do this by applying the struct members of the File and DIB header structs to a void* array and later looping over this with for(auto..). In this sense, it's pointless for the File Header because of it's fixed size, however for the DIB Header we do this since the DIB header varies between bitmap images depending on the different properties it has.

If you don't know about bitmaps, you can read up on them on the Wiki or Microsoft pages.

NOTE: Of course I could use a library, however that defeats the purpose of "fun" and/or "educational." This also isn't really for practical purposes, just for learning.

Bitmap Reader Header:

```
#ifndef LODEBMP
#define LODEBMP
#include

//
typedef bool BOOL;
typedef const char CBYTE;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef signed long LONG;

// Only recognizing two compression types:
enum Compression {
Bi_Rgb = 0, Bi_BitFields = 3
};

// Read errors for reading bitmaps from a file.
enum ReadErrors {
NoError = 0x0, BadFileType = 0x1 , ReadFailed = 0x2, BadBitMasks = 0x4 , WrongBitDepth = 0x8 ,
WrongCompression = 0x10 , BadBMPHeader = 0x20 , BadDIBHeader = 0x40 , BadImageData = 0x80 , NullImage = 0x100
};

// Bitmap header containing info on the physical file.
struct BITMAPFILEHEADER {
void* FileHeader[ 0xE ];
WORD FileType = 0;
DWORD FileSize = 0;
WORD ReserveX = 0;
WORD R

Solution

It looks like you're trying to use a data-driven method of reading in the file. That's not necessarily a bad idea, but it's a little odd because you have a bunch of structs that rely on the data being in a certain format that you already know ahead of time. It also means that you have a bunch of pieces of data that need to remain in synch, and those pieces of data are declared in 2 different files.

For example, in the header you declare BITMAPFILEHEADER to have an array of pointers to 14 elements. (Shouldn't it be 5 elements that take up 14 bytes?) In its constructor you hook the first 5 of those pointers up to the other members of the struct. You then declare an array of element sizes in the source file (BITMAPFILEDATA). Your loop for reading an filling in the array is now very general, but any time you want to update it (say to handle more formats, or newer versions of the format), you'll now need to make sure you have enough elements in the pointer array, the right elements as member variables, that you've hooked up all the pointers to all the member variables, and that the array of sizes has enough elements and in the correct order. This sounds like a nightmare to maintain.

Meanwhile, since that particular header is fixed, you could just read the 14 bytes directly from the file into a structure in memory in a single function call and be on your way.

Context

StackExchange Code Review Q#83160, answer score: 2

Revisions (0)

No revisions yet.