0

I need to work with .bmp type of images. The format for it is:

struct bmp_fileheader
{
    unsigned char  fileMarker1; /* 'B' */
    unsigned char  fileMarker2; /* 'M' */
    unsigned int   bfSize; /* File's size */
    unsigned short unused1; /* Aplication specific */
    unsigned short unused2; /* Aplication specific */
    unsigned int   imageDataOffset; /* Offset to the start of image data */
};

struct bmp_infoheader
{
    unsigned int   biSize; /* Size of the info header - 40 bytes */
    signed int     width; /* Width of the image */
    signed int     height; /* Height of the image */
    unsigned short planes;
    unsigned short bitPix; /* Number of bits per pixel = 3 * 8 (for each channel R, G, B we need 8 bits */
    unsigned int   biCompression; /* Type of compression */
    unsigned int   biSizeImage; /* Size of the image data */
    int            biXPelsPerMeter;
    int            biYPelsPerMeter;
    unsigned int   biClrUsed;
    unsigned int   biClrImportant;
};

typedef struct pi {
  unsigned char r;
  unsigned char g;
  unsigned char b;
}Pixel;

struct bmp_image {
  struct bmp_fileheader file_header;
  struct bmp_infoheader info_header;
  Pixel ** pixel;
};

struct bmp_image image;

So, an image contains a header and a matrix(height * width) of pixels. I read the image from a file :

FILE *image_file = fopen("path.bmp", "rb");

After that, I read all the variables of the header and then the matrix of pixels. I need to make some changes on the image in order to create another image that is the black_and_white format from the initial image. The algorithm to do that is to change the (X, Y, Z) pixel with (B, B, B), where B = (X + Y + Z) / 3;. I create the black_and_white image just fine. The problem shows when I try to compare my black_and_white image with a black_and_white image made by a paint program.

cmp -lb airplane_black_white.bmp ref/airplane_black_white.bmp 
cmp: EOF on airplane_black_white.bmp
ad absurdum
  • 19,498
  • 5
  • 37
  • 60
  • First step is to create a program that reads the header information from both files, and prints out all of the header fields. Then see what's different. – user3386109 Dec 23 '16 at 10:23
  • i think after the pixels there is something else.. I don't know for sure... – Razvan Buzatu Dec 23 '16 at 10:28
  • this code skips a few important details of a .bmp image. 1) the width of a pixel can be anywhere from 1 byte (black and white image) to 4 bytes (where transparancy is the 4th byte) 2) each row must be a multiple of 4 bytes, so the width needs to be rounded up, something like `int numBytesPerRow = (((bitpix>>3)*width)+3) & 0xFFFFFFFC` – user3629249 Dec 25 '16 at 15:12
  • per: Format: BMP/DIB Platforms: Primarily DOS-Windows Owner: MicroSoft Notes: MicroSoft Windows format, rarely supported elsewhere. Supports 1,2,4,8, and 32 bit colour images. – user3629249 Dec 25 '16 at 15:29
  • per: The Pixel Data Pixel by pixel color information Row-by-row, bottom to top. Rows start on double word (4-byte) boundaries and are null padded if necessary. Each row is column-by-column, left to right. In 24-bit images, color order is Red, Green, Blue. In images less than 8-bits, the higher order bits are the left-most pixels. – user3629249 Dec 25 '16 at 15:32
  • this line in the data definitions: `Pixel ** pixel;` is not correct as the data is an `array` of arrays where each array is a 'scan line', not a `pointer to a pointer` The specific structure of the 'scan line' varies depending on the .bmp format I.E. height, width, bits per pixel – user3629249 Dec 25 '16 at 15:37
  • you might want to read: which discusses the format of a .BMP file in detail. – user3629249 Dec 25 '16 at 15:46

1 Answers1

1

Very often I see people thinking the pixels afer neatly laid-out one after another. That is not so. They are laid-out one after another on a scanline and then scanline after scanline and a scanline can contain a few unused bytes to allign it on a word boundary. But you say:

So, an image contains a header and a matrix(height * width) of pixels.

which is not so. You must process scanlines and a picture consists of scanlines that consist of pixels. That is generally more than your heigth * width, explaining why the compare prematurely sees EOF.

See What is wrong with this code for writing grey-scale bmp from an image RGB bmp pure C - Windows OS for how to process the bitmap image.

Community
  • 1
  • 1
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41