Hi, I'm reading a bitmap manually to try and make a program that does steganography, but I can't read the file correctly. The headers I read come out completely messed up, and they fail the check to see if I'm reading a bitmap file or not (if (FileHeader.bfType != (int)"BM")). Please help.

#include <iostream>
#include <stdio.h>
using namespace std;


class BMP
{
   public:
          
	  typedef struct 
	  {
	  WORD bfType;
	  DWORD bfSize;
	  DWORD bfReserved;
	  DWORD bfOffBits;
	  } BMP_FILE_HEADER;

	  typedef struct 
	  {
	  DWORD biSize;
	  LONG biWidth;
	  LONG biHeight;
	  WORD biPlanes;
	  WORD biBitCount;
	  DWORD biCompression;
	  DWORD biSizeImage;
	  LONG biXPelsPerMeter;
	  LONG biYPelsPerMeter;
	  DWORD biClrUsed;
	  DWORD biClrImportant;
	  } BMP_INFO_HEADER;
	  
 	  BMP_FILE_HEADER FileHeader;
	  BMP_INFO_HEADER InfoHeader;
	  unsigned char *Data;
	  
	  // Methods
      bool LoadBitmapFile(const char *Filename);
};

bool BMP::LoadBitmapFile(const char *Filename)
{
   BMP Bitmap;
   unsigned char *bitmap_Image;
 
   FILE *File = NULL;
   unsigned int ImageIdx = 0;

   File = fopen(Filename,"rb");
   
   if (!File)
      return false;
   
   // Read the file header
   fread(&Bitmap.FileHeader, sizeof(BMP_FILE_HEADER), 1, File);
   
   // Check if its a bitmap or not
   if (FileHeader.bfType != (int)"BM")
      return false;
   
   // Read the info header
   fread(&Bitmap.InfoHeader, sizeof(BMP_INFO_HEADER), 1, File);
   
   // Store the data
   memcpy((char*)&this->FileHeader, (char*)&Bitmap.FileHeader, sizeof(BMP_FILE_HEADER));
   memcpy((char*)&this->InfoHeader, (char*)&Bitmap.InfoHeader, sizeof(BMP_INFO_HEADER));

   // Move to the bitmap data
   fseek(File, Bitmap.FileHeader.bfOffBits, SEEK_SET);
   
   // Allocate memory
   if (Bitmap.InfoHeader.biSizeImage != 0)
      bitmap_Image = (unsigned char*)calloc(Bitmap.InfoHeader.biSizeImage, sizeof(unsigned char));
   
   if (!bitmap_Image)
   {
   free(bitmap_Image);
   fclose(File);
   return false;
   }
   
   // Get RGB instead of BGR
   for (ImageIdx=0; ImageIdx < Bitmap.InfoHeader.biSizeImage; ImageIdx+=3)
   {
      bitmap_Image[ImageIdx] = bitmap_Image[+2];
      bitmap_Image[ImageIdx+2] = bitmap_Image[ImageIdx];
   }
   
   // Store the bitmap data
   memcpy((unsigned char*)&this->Data, (unsigned char*)&bitmap_Image, Bitmap.InfoHeader.biSizeImage);
   
   // Clean up and return
   fclose(File);
   return true;
};

int main(int argc, char **argv)
{
   BMP bmp;
   
   if (bmp.LoadBitmapFile("untitled.bmp"))
   {
      printf("UNTITLED.BMP\n\n");
      cout << bmp.InfoHeader.biWidth << " by " << bmp.InfoHeader.biHeight;
   }
   else
      cout << "ERROR!";
   
   cin.ignore();
   
}

Weird, I just used Windows' BITMAPFILEHEADER and BITMAPINFOHEADER structures and it worked fine. Thx anyway.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.