loshca loshca - 2 months ago 30
C++ Question

Reading BMP file C++ (trouble with reading BMP header)

I am trying to write BMP image class with reading method. I saw msdn specification of BMP files, so I try to read the headers and after, using the biHeight and biWidth information, read RGB info of every pixel.
So, it don't read header information, the value of every header parameter is -1.

Here's code:

#ifndef BMP_IMAGE_H
#define BMP_IMAGE_H

#include <fstream>

using namespace std;


typedef struct
{
unsigned int bfType;
unsigned long bfSize;
unsigned int bfReserved1;
unsigned int bfReserved2;
unsigned long bfOffBits;
} BitMapFileHeader;

typedef struct
{
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BitMapInfoHeader;

typedef struct
{
int rgbBlue;
int rgbGreen;
int rgbRed;
int rgbReserved;
} RGBColor;


class BMPImage
{
private:
unsigned short read_u16();
unsigned int read_u32();
int read_s32();
public:
ifstream pFile;
int imageWidth;
int imageHeight;
RGBColor **rgb;
BMPImage(char* fileName);
void pixelsInfo();
};

#endif // BMP_IMAGE_H

#include "bmp_image.h"
#include <iostream>
using namespace std;
BMPImage::BMPImage(char* fileName)
{
ifstream pFile(fileName, ios::in | ios::binary);


// read the header of file
BitMapFileHeader header __attribute__((unused));

header.bfType = read_u16();
header.bfSize = read_u32();
header.bfReserved1 = read_u16();
header.bfReserved2 = read_u16();
header.bfOffBits = read_u32();

// read the header of image
BitMapInfoHeader bmiHeader;

bmiHeader.biSize = read_u32();
bmiHeader.biWidth = read_s32();
bmiHeader.biHeight = read_s32();
bmiHeader.biPlanes = read_u16();
bmiHeader.biBitCount = read_u16();
bmiHeader.biCompression = read_u32();
bmiHeader.biSizeImage = read_u32();
bmiHeader.biXPelsPerMeter = read_s32();
bmiHeader.biYPelsPerMeter = read_s32();
bmiHeader.biClrUsed = read_u32();
bmiHeader.biClrImportant = read_u32();

cout << (int)bmiHeader.biHeight <<"\n";
RGBColor **rgb = new RGBColor*[bmiHeader.biHeight];
for (int i = 0; i < bmiHeader.biWidth; i++)
rgb[i] = new RGBColor[bmiHeader.biHeight];

for (int i = 0; i < bmiHeader.biWidth; i++) {
for (int j = 0; j < bmiHeader.biHeight; j++) {
rgb[i][j].rgbBlue = pFile.get();
rgb[i][j].rgbGreen = pFile.get();
rgb[i][j].rgbRed = pFile.get();


}


char temp;
pFile.get(temp);
}

imageWidth = bmiHeader.biWidth;
imageHeight = bmiHeader.biHeight;

pFile.close();
}

unsigned short BMPImage::read_u16(){
unsigned char b0, b1;
b0 = pFile.get();
b1 = pFile.get();

return ((b1 << 8) | b0);
}

unsigned int BMPImage::read_u32(){
unsigned char b0, b1, b2, b3;
b0 = pFile.get();
b1 = pFile.get();
b2 = pFile.get();
b3 = pFile.get();

return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}

int BMPImage::read_s32(){
unsigned char b0, b1, b2, b3;
b0 = pFile.get();
b1 = pFile.get();
b2 = pFile.get();
b3 = pFile.get();
return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);

}

void BMPImage::pixelsInfo(){
for (int i = 0; i < imageWidth; i++) {
for (int j = 0; j < imageHeight; j++) {
std::cout << rgb[i][j].rgbRed <<" " << rgb[i][j].rgbGreen << " " << rgb[i][j].rgbBlue << std::endl;
}
std::cout << std::endl;
}
}


P.S. Thank you everybody for help

Answer

The member

ifstream pFile;

of class BMPImage is not being initialized, so when you use it in member functions it isn't valid. Instead you are locally defining a different pFile instance in the constructor. These should probably be the same instance.

Comments