Read BMP files & storing pixel values into array

Hi,

I'm a novice C programmer and I'm looking for help to read a bmp file into an array for manipulation like in matlab. I understand that in matlab, the bmp file can be immediately read and converted to a matrix using imread. How can I do this using C?

The bmp files are 24-bit truecolor RGB images of size 288x352.    
CalecAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CalecAuthor Commented:
I need sample C code for performing the task described above. Giving me a link is not helpful at all. The link is blocked, by the way, cos the site does not allow its pages to be linked. Once again, please help.
0
muskad202Commented:
then u can go to www.wotsit.org, click search, and then type in bmp to get info for the bmp format
i'm sorry..we don't write code for others..we don't have time for that, if u have some code of your own but are stuck at some point, paste it here, we'll try to help u fix it...but please don't ask us to write code for you...
in some cases it is okay. e.g, when the sample code is small, or the code which u're asking is something really generic or kinda popular in which case we might know of sample code on the net or might have written our own so that we can give it to you...but reading bmp files is a little advanced....at least i didn't find any sample code on google for doing it, and i don't have the time to write it..maybe someone else here can help u out...
anywayz..if u're a novice programmer in c, then what u are trying to do is kinda advanced, try learning basic stuff first like arrays and file handling, once u know that, check out the site above, read the bmp format, u'll find that its not that difficult ...all u need to know is file handling (specifically, reading specific bytes from a file), and using arrays ..
sorry if i sounded a little harsh :)
muskad202
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

msa2003Commented:
If you desired to use RGB image of pre-defined size, you will need in only one data structure defined below:

struct BITMAPFILEHEADER { // bmfh  
        WORD    bfType;
        DWORD   bfSize;
        WORD    bfReserved1;
        WORD    bfReserved2;
        DWORD   bfOffBits;
};

// The sample function getImage(char *name) will load image data to the imageData array

struct RGB {          // RGB color value
        BYTE    red;
        BYTE    green;
        BYTE    blue;
};

struct RGB imageData[288][352];

void getImage(char *name)
{
  FILE *fp;
  struct BITMAPFILEHEADER head;

  if ((fp=fpopen(name, "rb")) != NULL) {
    fread(&head, sizeof(head), 1, fp);
    fseek(fp, head.bfOffBits, 0);
    fread(&imageData, sizeof(imageData), 1, fp);
    fclose(fp);
  }
}

This code was not tested yet so it could contain an errors. For some important details read this: http://www.experts-exchange.com/Programming/Q_20516006.html
0
subhadeepinCommented:
This might help u.....
I can provide u with a working c++ code for that if you want. This code is a bit abstract so you need to move ahead carefully............

typedef struct BitmapFileHeader{
      unsigned short Type;
      unsigned int Size;
      unsigned short Reserved1;
      unsigned short Reserved2;
      unsigned int Offset;
}BitmapFileHeader;

typedef struct BitmapInfoHeader{
      unsigned int Size;
      unsigned int Width;
      unsigned int Height;
      unsigned short Planes;
      unsigned short BitCount;
      unsigned int Compression;
      unsigned int SizeImage;
      unsigned int XPelsPerMeter;
      unsigned int YPelsPerMeter;
      unsigned int ColorUsed;
      unsigned int ColorImportant;
}BitmapInfoHeader;

typedef struct RGBQuad{
      unsigned char Blue;
      unsigned char Green;
      unsigned char Red;
      unsigned char Reserved;
}RGBQuad;


int OpenImage(const char *FileName)
{
      int error_value;

      FileHandle = fopen(FileName,"r+b");

      if(FileHandle == NULL)
      {
            return(_FILE_OPEN_ERROR);
      }
      else
      {
            if((error_value=ReadBmpFileHeader())!=_NO_ERROR)
            {
                  if(FileHandle!=NULL)
                  {
                        fclose(FileHandle);
                        FileHandle = NULL;
                  }
                  return(error_value);
            }            
            if((error_value=ReadBmpInfoHeader())!=_NO_ERROR)
            {
                  if(FileHandle!=NULL)
                  {
                        fclose(FileHandle);
                        FileHandle = NULL;
                  }
                  return(error_value);
            }
            if((error_value=ReadRGBQuad())!=_NO_ERROR)
            {
                  if(FileHandle!=NULL)
                  {
                        fclose(FileHandle);
                        FileHandle = NULL;
                  }
                  return(error_value);
            }
      }
      return(_NO_ERROR);
}

void CloseImage()
{
      if(FileHandle!=NULL)
      {
            fclose(FileHandle);
            FileHandle = NULL;
      }
      if(rgbQuad!=NULL)
      {
            free(rgbQuad);
            rgbQuad = NULL;
      }
      if(rgbTriple!=NULL)
      {
            free(rgbTriple);
            rgbTriple = NULL;
      }

}

int GetImageBuffer(
            unsigned int SourceX,
            unsigned int SourceY,
            unsigned int SourceWidth,
            unsigned int SourceHeight,
            unsigned char *buffer)
{
      unsigned int i_width;
      if(SourceX+SourceWidth>bmpInfoHeader.Width)
      {
            i_width = SourceX+SourceWidth-bmpInfoHeader.Width;
            i_width = SourceWidth - i_width ;
      }
      else
            i_width = SourceWidth;

      unsigned int i_height;
      if(SourceY+SourceHeight>bmpInfoHeader.Height)
      {
            i_height = SourceY+SourceHeight-bmpInfoHeader.Height;
            i_height = SourceHeight - i_height;
      }
      else
            i_height = SourceHeight;


      unsigned int bytes_per_sample = GetSamplesPerPixel();
      for(unsigned int i=0;i<i_height;++i)
      {
            fseek(FileHandle,bmpFileHeader.Offset+(bmpInfoHeader.Height-i-1)*bytes_per_sample*bmpInfoHeader.Width - (SourceY*bytes_per_sample*bmpInfoHeader.Width) + (SourceX*bytes_per_sample),SEEK_SET);
            fread(&buffer[i*SourceWidth*bytes_per_sample],1,i_width*bytes_per_sample,FileHandle);
      }
      return(_NO_ERROR);
}

int GetImageBuffer(
            unsigned int SourceX,
            unsigned int SourceY,
            unsigned int SourceWidth,
            unsigned int SourceHeight,
            unsigned char *buffer,
            unsigned int LayerNumber)
{
      unsigned char *TempBuffer = (unsigned char *) malloc(SourceWidth*SourceHeight*(GetPixelSize()/8));
      if(TempBuffer==NULL)
            return(_MEMORY_ALLOCATION_ERROR);
      GetImageBuffer(SourceX,SourceY,SourceWidth,SourceHeight,TempBuffer);
      unsigned int k=LayerNumber;
      for(unsigned int i=0;i<SourceHeight;++i)
            for(unsigned int j=0;j<SourceWidth;++j)
            {
                  buffer[i*SourceWidth+j] = TempBuffer[k];
                  k = k + (GetPixelSize()/8);
            }
            
      free(TempBuffer);
      return (_NO_ERROR);


}



int ReadBmpImage::ReadBmpFileHeader()
{
      fread(&bmpFileHeader.Type,sizeof(unsigned short),1,FileHandle);
      fread(&bmpFileHeader.Size ,sizeof(unsigned int),1,FileHandle);
      fread(&bmpFileHeader.Reserved1 ,sizeof(unsigned short),1,FileHandle);
      fread(&bmpFileHeader.Reserved2 ,sizeof(unsigned short),1,FileHandle);
      fread(&bmpFileHeader.Offset ,sizeof(unsigned int),1,FileHandle);
      return(_NO_ERROR);
}

int ReadBmpImage::ReadBmpInfoHeader()
{
      fread(&bmpInfoHeader.Size ,sizeof(unsigned int),1,FileHandle);

      if(bmpInfoHeader.Size==40)
      {
            fread(&bmpInfoHeader.Width ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.Height ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.Planes ,sizeof(unsigned short),1,FileHandle);
            fread(&bmpInfoHeader.BitCount ,sizeof(unsigned short),1,FileHandle);
            if(bmpInfoHeader.BitCount<8)
                  return(_LOWER_NUMBER_OF_BITS);
            fread(&bmpInfoHeader.Compression ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.SizeImage ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.XPelsPerMeter ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.YPelsPerMeter ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.ColorUsed ,sizeof(unsigned int),1,FileHandle);
            fread(&bmpInfoHeader.ColorImportant ,sizeof(unsigned int),1,FileHandle);
      }
      else if(bmpInfoHeader.Size==12)
      {
            unsigned short Width,Height;
            fread(&Width ,sizeof(unsigned short),1,FileHandle);
            bmpInfoHeader.Width = Width;
            fread(&Height ,sizeof(unsigned short),1,FileHandle);
            bmpInfoHeader.Height = Height;
            fread(&bmpInfoHeader.Planes ,sizeof(unsigned short),1,FileHandle);
            fread(&bmpInfoHeader.BitCount ,sizeof(unsigned short),1,FileHandle);
            bmpInfoHeader.ColorUsed = 0;
            bmpInfoHeader.ColorImportant = 0;
      }
      else
            return(_INVALID_FILE_TYPE);
      
      return(_NO_ERROR);
}

int ReadBmpImage::ReadRGBQuad()
{      
      if(bmpInfoHeader.ColorUsed!=0)
      {
            rgbQuad = (RGBQuad *) malloc(bmpInfoHeader.ColorUsed*sizeof(RGBQuad));
            fread(rgbQuad,sizeof(RGBQuad),bmpInfoHeader.ColorUsed,FileHandle);
      }
      else
      {
            if(bmpInfoHeader.BitCount==8)
            {
                  if(bmpInfoHeader.Size==40)
                  {
                        rgbQuad = (RGBQuad *) malloc(256*sizeof(RGBQuad));
                        fread(rgbQuad,sizeof(RGBQuad),256,FileHandle);
                  }
                  else if(bmpInfoHeader.Size==12)
                  {
                        rgbTriple = (RGBTriple *) malloc(256*sizeof(RGBTriple));
                        fread(rgbTriple,sizeof(RGBTriple),256,FileHandle);
                  }
                  bmpInfoHeader.ColorUsed = 256;
            }
      }
      return(_NO_ERROR);
}

unsigned int ReadBmpImage::GetColorTable(RGBTriple *rgbTriple)
{
      if(bmpInfoHeader.Size==40)
      {
            for(unsigned int i=0;i<bmpInfoHeader.ColorUsed;++i)
            {
                  rgbTriple[i].Red = rgbQuad[i].Red;
                  rgbTriple[i].Green = rgbQuad[i].Green;
                  rgbTriple[i].Blue= rgbQuad[i].Blue;
            }
      }
      else if(bmpInfoHeader.Size == 12)
      {
            for(unsigned int i=0;i<bmpInfoHeader.ColorUsed;++i)
            {
                  rgbTriple[i].Red = this->rgbTriple[i].Blue;
                  rgbTriple[i].Green = this->rgbTriple[i].Green;
                  rgbTriple[i].Blue= this->rgbTriple[i].Red;
            }
      }

      return(bmpInfoHeader.ColorUsed);
}

unsigned int ReadBmpImage::GetColorEntries()
{
      if(bmpInfoHeader.BitCount==8&&bmpInfoHeader.ColorUsed==0)
            return(256);
      else
            return(bmpInfoHeader.ColorUsed);
}

0
CleanupPingCommented:
Calec:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
muskad202Commented:
i think the points should be split with "subhadeepin"
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.