So I am having a problem figuring out exactly what is going wrong with trying to read any 24bpp bitmap image and re-create it in the same folder. It works with one image, but not two others that I have tested it with. When reading from the bitmap, I use the information found in the header itself. It could be said I have three questions. 1) Am I reading from bitmap correctly? 2) Am I calculating/using/writing the padding correctly? 3) Am I outputting correctly?. Third is confirmed no with this image and its output.
Also the reason for allocating an 2d array for the Images is so that I can latter try to rotate bitmaps by 90 degrees.
Unfortunately I cannot post images, the image taken is from here, the rgb_24bpp.bmp http://pyglet.googlecode.com/svn/trunk/tests/image/
Here is the code used for reading from the image and to calculate the padding.
ifstream myBitmap("rgb_24bpp.bmp", ios::binary | ios::beg);
// Get the total file size in bytes, testing file access
begin = myBitmap.tellg();
myBitmap.seekg(0, ios::end);
end = myBitmap.tellg();
// Actually reading image file
myBitmap.seekg( 0, ios::beg);
myBitmap.read((char*)FileHeader, sizeof(BITMAPFILEHEADER));
myBitmap.read((char*)InfoHeader, sizeof(BITMAPINFOHEADER));
test = myBitmap.tellg();
RGBQUAD ** Image = new RGBQUAD*[InfoHeader->biWidth];
for (int i = 0; i < InfoHeader->biWidth; ++i) {
Image[i] = new RGBQUAD[InfoHeader->biHeight];
}
int pitch = InfoHeader->biWidth * 3;
if (pitch % 4 != 0)
{
pitch += 4 - (pitch % 4);
}
int padding = pitch - (InfoHeader->biWidth * 3);
cout << "padding: " << padding << endl;
myBitmap.seekg(FileHeader->bfOffBits, ios::beg);
for (int i = InfoHeader->biHeight; i > 0; --i) {
for (int j = 0; j < InfoHeader->biWidth; ++j) {
myBitmap.read((char*)&Image[j][i], sizeof(RGBQUAD));
}
if (padding != 0) myBitmap.read(PadBuffer, padding);
}
myBitmap.close();
begin/end/test are all of streampos and printed on console for debugging. And this is the code used to output/recreate the image.
ofstream BitmapOut("Output.bmp");
BitmapOut.write((char*)FileHeader, sizeof(BITMAPFILEHEADER));
BitmapOut.write((char*)InfoHeader, sizeof(BITMAPINFOHEADER));
for (int i = InfoHeader->biHeight; i > 0; --i) {
for (int j = 0; j < InfoHeader->biWidth; ++j) {
BitmapOut.write((char*)&Image[j][i], sizeof(RGBQUAD));
}
if (padding != 0) BitmapOut.write("\0\0\0\0\0\0\0", padding);
}
BitmapOut.close();
I have confirmed that both headers are indeed correct and can pull data from them properly in 3 different tests. Utilizing this guys code (sorry, this project is non-commercial and self-study only). reading a .bmp file in c++
With the exception of commenting out the reserved in the RGBQUAD and making effectively a RGBTRI instead.