BMP Reader in C++

Computer Graphics & Vision Topics
Post Reply
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

BMP Reader in C++

Post by Neo » Tue Sep 22, 2009 11:54 pm

  1. The first thing you should always do when handling a program that uses Windows is to include the windows.h header.

    Code: Select all

    #include <windows.h>
  2. Header structure 1

    Code: Select all

    typedef struct tagBITMAPFILEHEADER { 
      WORD    bfType; 
      DWORD   bfSize; 
      WORD    bfReserved1; 
      WORD    bfReserved2; 
      DWORD   bfOffBits; 
    } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
    bfType
    Specifies the file type. It must be set to the signature word BM (0x4D42) to indicate bitmap.

    bfSize
    Specifies the size, in bytes, of the bitmap file.
    For a 24-bit file, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * Width * Height

    bfReserved1
    Reserved; set to zero

    bfReserved2
    Reserved; set to zero

    bfOffBits
    Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits.
    i.e.: sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
  3. Header structure 2

    Code: Select all

    typedef struct tagBITMAPINFOHEADER {
        DWORD  biSize;          // size of structure, in bytes
        DWORD  biWidth;         // bitmap width, in pixels
        DWORD  biHeight;        // bitmap height, in pixels
        WORD   biPlanes;        // see below
        WORD   biBitCount;      // see below
        DWORD  biCompression;   // see below
        DWORD  biSizeImage;     // see below
        DWORD  biXPelsPerMeter; // see below
        DWORD  biYPelsPerMeter; // see below
        DWORD  biClrUsed;       // see below
        DWORD  biClrImportant;  // see below
    } BITMAPINFOHEADER;
    biSize
    Specifies the size of the structure, in bytes.

    biWidth
    Specifies the width of the bitmap, in pixels.

    biHeight
    Specifies the height of the bitmap, in pixels.

    biPlanes
    Specifies the number of planes for the target device.
    This value must be set to 1.

    biBitCount
    Specifies the number of bits per pixel.

    biCompression
    Specifies the type of compression for a compressed bottom-up bitmap. Use BI_RGB for an uncompressed format.

    biSizeImage
    Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.

    biXPelsPerMeter
    Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap. Set this to 2400.

    biYPelsPerMeter
    Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap. Set this to 2400.

    biClrUsed
    Specifies the number of color indexes in the color table that are actually used by the bitmap. Set this to 0.

    biClrImportant
    Specifies the number of color indexes required for displaying the bitmap. If this value is zero, all colors are required.
  4. Image itself is an array of RGBTRIPLES. Sometimes padding is required, but we shouldn't encounter that problem with bitmaps that have a width as a multiple of 4.

    For a 128 * 128 pixel image, this would be declared as:

    Code: Select all

    RGBTRIPLE image[128*128];
  5. Simple example

    Code: Select all

    #include <windows.h>
    #include <iostream.h>
    
    HANDLE hfile;
    DWORD written;
    BITMAPFILEHEADER bfh;
    BITMAPINFOHEADER bih;
    RGBTRIPLE *image;
    
    void()
    {
     // Open the file
     hfile = CreateFile("source.bmp",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
     // Read the header
     ReadFile(hfile,&bfh,sizeof(bfh),&written,NULL);
     ReadFile(hfile,&bih,sizeof(bih),&written,NULL);
     // Read image
     imagesize = bih.biWidth*bih.biHeight; // Helps you allocate memory for the image
     image = new RGBTRIPLE[imagesize]; // Create a new image (I'm creating an array during runtime)
     ReadFile(hfile,image,imagesize*sizeof(RGBTRIPLE),&written,NULL); // Reads it off the disk
     // Close source file
     CloseHandle(hfile);
     // Now for some information
     cout<<"The image width is "<<bih.biWidth<<"\n"; // Will output the width of the bitmap
     cout<<"The image height is "<<bih.biHeight<<"\n"; // Will output the height of the bitmap
    }
  6. Since the BMP image is kept upside down in the file, we need to use following codes to read/write pixels.

    Code: Select all

    RGBTRIPLE get_pixel(int x,int y)
    {
     // Image define from earlier
     return image[(bih.biHeight-1-y)*bih.biWidth+x];
    }
    
    RGBTRIPLE set_pixel(int x,int y,RGBTRIPLE color)
    {
     // Image define from earlier
     image[(bih.biHeight-1-y)*bih.biWidth+x] = color;
    }
User avatar
edeferaxy
Posts: 1
Joined: Fri Jan 20, 2012 12:10 pm

Re: BMP Reader in C++

Post by edeferaxy » Fri Jan 20, 2012 4:35 pm

How do I get a zip file to be supported in a bmp (bitmap) file ? Trying to get some jazzy fonts, but when I attempt to open a zipfile (ttf.) it tells me the file isn't supported by a bitmap file. Is there a program I have to download for this ?
User avatar
Saman
Lieutenant Colonel
Lieutenant Colonel
Posts: 828
Joined: Fri Jul 31, 2009 10:32 pm
Location: Mount Lavinia

Re: BMP Reader in C++

Post by Saman » Fri Jan 20, 2012 10:34 pm

Read point 12 of ROBOT.LK - Terms of use. Please start a new topic with a descriptive subject to get an answer.
User avatar
SemiconductorCat
Major
Major
Posts: 455
Joined: Mon Aug 22, 2011 8:42 pm
Location: currently in hyperspace

Re: BMP Reader in C++

Post by SemiconductorCat » Sat Jan 21, 2012 10:41 pm

Nice piece of code.


anyway I have reviewed the code.One thing that I have noticed here.

This is another very difference between C and C++.

for a example.

Code: Select all

struct A{
    int a;
    int b;
};
//....
A a;
Is oky in C++ but not in C. In C you always have to ,

Code: Select all

typedef struct tag_A{
    int a;
    int b;
} A;

A a;

But still it's not a good practice.
The coding styles suggest you to use this style.

Code: Select all

struct A
{
    int a;
    int b;
};
typedef struct A A ;


I know neo and others are already know this,but I have mentioned this for completeness.
User avatar
Saman
Lieutenant Colonel
Lieutenant Colonel
Posts: 828
Joined: Fri Jul 31, 2009 10:32 pm
Location: Mount Lavinia

Re: BMP Reader in C++

Post by Saman » Sun Jan 22, 2012 7:32 am

It doesn't make sense as both structures are defined in Wingdi.h as BITMAPFILEHEADER structure and BITMAPINFOHEADER structure which includes when you use Windows.h.

Following is the common practice (just as by Microsoft).

Code: Select all

typedef struct tagA {
  WORD    bfType;
  DWORD   bfSize;
  WORD    bfReserved1;
  WORD    bfReserved2;
  DWORD   bfOffBits;
} A, *PA;
Instead of 'tagA', some programmers use 'A_'.

One thing that most people doesn't know is, in C++, class is an extension of the C language structure. Because the only difference between a structure and a class is that structure members have public access by default and class members have private access by default, you can use the keywords class or struct to define equivalent classes. See Classes Vs. structures (C++ only).
User avatar
SemiconductorCat
Major
Major
Posts: 455
Joined: Mon Aug 22, 2011 8:42 pm
Location: currently in hyperspace

Re: BMP Reader in C++

Post by SemiconductorCat » Mon Jan 23, 2012 4:39 pm

ya when you don't need to keep a reference or pointer to structure itself, there's not
use of the writng tag_A or tagA or A_ thing.But as a good practice microsoft API writers
have done it. I think it's a good practice.

it will be a issue when defining a structure like this, for a example:

Code: Select all

// part from my real project//
/* declares some internally used data-structures */
struct tab_linked_config_entry;
struct tab_linked_config_entry{
    config_parser_entry e;
    struct tab_linked_config_entry * next;
};

typedef struct tab_linked_config_entry linked_config_entry;

struct tag_linked_section_entry{
    linked_config_entry * ptr_entry_table;
    struct tag_linked_section_entry *next;
};
typedef struct tag_linked_section_entry linked_section_entry;
where in a case like that you can't write

Code: Select all

typedef struct
{
   linked_config_entry * ptr_entry_table;
   struct linked_section_entry * next;
} linked_section_entry;
because some compilers are not smart enough to see lookahead , and they do just left to right
parsing , in these cases when it generating the parser tree inside the structure definition and it's
elements it never heard anything about 'linked_section_entry'. I think professional compilers like
Microsoft VC++ , GNU G++ have fixed this issue. But the good practice is write it in the defensive
way.

May be in the next version of C++/C , C++0x these things may be fixed and solved.
Post Reply

Return to “Graphics & Vision”