   Making a BMP in c++
  edit:OK, I fixed the problem. The following code works if 4 is already a factor of the width in bytes, I havn't worked in padding size detection yet. (it just opts for 0 padding and will not work)#include <stdint.h>#include <iostream>//#include <windows.h>struct fileHeaderMagic{  unsigned char magic[2];}; struct fileHeader{  uint32_t filesz;  uint16_t creator1;  uint16_t creator2;  uint32_t bmp_offset;};typedef struct{  uint32_t header_sz;  uint32_t width;  uint32_t height;  uint16_t nplanes;  uint16_t bitspp;  uint32_t compress_type;  uint32_t bmp_bytesz;  uint32_t hres;  uint32_t vres;  uint32_t ncolors;  uint32_t nimpcolors;} bmpHeader;struct colour{  unsigned char b,  g,  r;};using namespace std;//application entry pointint main(){    //bits per pixel  uint16_t bpp = 24;  //file dimensions  uint32_t width = 64,height = 64,  //calculate some required information  pixels = width*height,dataSize;    //make the "magic", file header and bitmap header  fileHeaderMagic file_headerMagic;  fileHeader file_header;  bmpHeader file_bmpHeader;    //make a colour in rbg 24 bit format  colour bmpCol;  bmpCol.r = 0xff;  bmpCol.g = 0;  bmpCol.b = 0;    int16_t padding;  //calculate the size in bytes of the pixels in each row  int16_t pixelRowBytes = width*bpp/8;  cout << "pixelRowBytes: " << pixelRowBytes << endl;  //calculate the padding at the end of a row  if(pixelRowBytes%4 == 0){ //if no padding is required    cout << "no padding required" << endl;    padding = 0;  } else {    cout << "needs padding" << endl;    padding = 0; //bleh  }  //calculate the width of a row in bytes  uint16_t rowBytes = pixelRowBytes + padding;  cout << "rowBytes: "  << rowBytes << endl;    //which part of the colour is being written (bgr)  uint16_t colourPart = 0;  //calculate the data size  dataSize = height*rowBytes;  cout << "dataSize: " << dataSize << endl;  //make the bitmap data array  unsigned char bmpData[dataSize];  //fill the data  for(uint16_t row = height;row > 0;row --){ //loop rows, bottom to top order    for(uint16_t col = 0;col < pixelRowBytes;col ++){ //each column with pixels switch(colourPart){   case 0:bmpData[row*pixelRowBytes-pixelRowBytes+col] = bmpCol.b; //fill the blue bytecolourPart = 1;break;   case 1:bmpData[row*pixelRowBytes-pixelRowBytes+col] = bmpCol.g; //fill the green bytecolourPart = 2;break;   case 2:bmpData[row*pixelRowBytes-pixelRowBytes+col] = bmpCol.r; //fill the red bytecolourPart = 0;break; }    }  }    //populate the "magic"  file_headerMagic.magic[0] = 0x42; //B  file_headerMagic.magic[1] = 0x4D; //M    //populate the file header  file_header.filesz = sizeof(fileHeaderMagic)+sizeof(fileHeader)+  sizeof(bmpHeader)+dataSize;  file_header.creator1 = 0;  file_header.creator2 = 0;  file_header.bmp_offset = sizeof(fileHeaderMagic)+  sizeof(fileHeader)+sizeof(bmpHeader);    //populate the bitmap header  file_bmpHeader.header_sz = sizeof(bmpHeader);  file_bmpHeader.width = width;  file_bmpHeader.height = height;  file_bmpHeader.nplanes = 1;  file_bmpHeader.bitspp = bpp;  file_bmpHeader.compress_type = 0; //uncompressed  file_bmpHeader.bmp_bytesz = dataSize; //size in bytes of the data  file_bmpHeader.hres = 2835; //pixels per meter, wut  file_bmpHeader.vres = 2835;  file_bmpHeader.ncolors = 0; //no colours in palette  file_bmpHeader.nimpcolors = 0;    //handle for the image file  FILE * image;  //path for the image file  image = fopen("image.bmp","w");    //write the "magic"  fwrite(&file_headerMagic,1,sizeof(fileHeaderMagic),image);  //write the file header  fwrite(&file_header,1,sizeof(fileHeader),image);  //write the bitmap header  fwrite(&file_bmpHeader,1,sizeof(bmpHeader),image);  //write the bitmap data  fwrite(bmpData,1,dataSize,image);  //done with the image  fclose(image);    //wait for keypress  system("pause");  //exit application  return 0;}---------------This should be really straight forward, but I am having problems just generating a bitmap in c++.First, heres the code:Removed by OPThat is the latest iteration of my tests, I have been trying to get it to work for ages without success. I just want to make a bitmap of one solid colour, but it seems I can only make a grey filled one; by filling every byte in testData with the same number.I have tested a lot of different ways, I am starting to think that wikipedia is just wrong.According to that, for the format I am using, pixels have to be in sets of 2.Each set of 2 pixels is 64 bits worth of data. I have arranged mine (with my current code) into 2 32 bit unsigned ints.The idea is, the first int (according to wikipedia) must contain the following bit pattern: bbbbbbbbggggggggrrrrrrrrbbbbbbbbThat being 8 bits for each of the first pixel's bgr components and the last 8 bits for the second pixel's blue component. The second uint32_t consists of: ggggggggrrrrrrrr0000000000000000That being 8 bits for the second pixel's green and red components, then 16 spare bits that can be anything at all.As far as I can tell, I haven't been doing anything wrong (my current code might be wrong, but I have been trying for hours with various attempts: none of which seem to make sense)Can anybody shed any light on the issue? Is wikipedia wrong or am I missing something?[Edited by - Bozebo on July 8, 2010 4:25:09 PM]
  I Think i see what your doing, its interesting...but making life hard.Your are doing something very complex that only needs to be approached if you are using 16 bit depth bitmaps.For 24 byte bitmapsJust use an array of unsigned chars to represent the data. One char=one channel (R/G or B).You will need to take into account padding to 4 byte alignment. So just calculate how many extra bytes you need to round up to 4 and make that the number of bytes per line.When filling the bitmap remember each line starts at a multiple of the BytesPerRow you just calculated.Your total bitmap data size will be BytesPerRow*Height. And BytesPerRow will be (Width*3)+PaddingHTH[Edited by - empirical2 on July 8, 2010 2:46:15 PM];  Uhh no, just use 3 bytes for each 24-bit pixel.  bit maps also go bottom to top.  here's some code of mine where i take a captured video image (YUV) and store it in a 720x480 24-bit Bitmap.pucBMPptr = pucBitMap;   /* put bitmap header at front */    memcpy(pucBitMap, ku32BMPheader, sizeof(ku32BMPheader));   /* move Bitmap pointer to the end of the BMP data*/    pucBMPptr += (BITMAP_SIZE - 1);   /* convert the YUV image to a RGB image in reverse order */    for(i = 0; i < GraphicsMap.uwHeight; i++)    {   //for (j = 0; j < GraphicsMap.uwWidth/2; j++)   for (j = GraphicsMap.uwWidth/2-1; j >= 0; j--)   {  /* convert YUV to RGB */  //u32YUV = *pu32Image++;    /* go from right to left up lines */  u32YUV = pu32Image[i*(GraphicsMap.uwWidth/2) + j];  u32RGB = YUVtoRGB(u32YUV&0xFF, (u32YUV>>8)&0xFF, (u32YUV>>24)&0xFF);    /* copy the 1st Y with two UV */  /* B, then G, then R (reverse since it's backwards) */  *pucBMPptr-- = (u32RGB >> 16) & 0xFF;  *pucBMPptr-- = (u32RGB >> 8)  & 0xFF;  *pucBMPptr-- =  u32RGB   & 0xFF;    /* copy the 2nd Y with two UV */  u32RGB = YUVtoRGB((u32YUV>>16)&0xFF, (u32YUV>>8)&0xFF, (u32YUV>>24)&0xFF);    *pucBMPptr-- = (u32RGB >> 16) & 0xFF;  *pucBMPptr-- = (u32RGB >> 8)  & 0xFF;  *pucBMPptr-- =  u32RGB   & 0xFF;   }    }Where ku32BMPheader is:/* BMP header for a 720x480 24-bit image */const U32 ku32BMPheader[] = {0xd2364d42, 0x0000000f, 0x00360000, 0x00280000, 0x02d00000, 0x01e00000, 0x00010000, 0x00000018, 0xd2000000, 0x0ec4000f, 0x0ec40000, 0x00000000,  0x00000000, 0x00000000};;  Oops, I completely misinterpreted something important.I thought that every 2 pixels (48 bits) had a gap of 8 bits afterwards...I looked at the table of example bitmap and that is just what it seemed like. Must not have been paying attention when I read: "each row of pixels is extended to a 32-bit (4-byte) boundary"of course the row in the example was 2 pixels wide &_&edit:OK, I have it working now.Edited code in original post, incase someone happens to need some bmp saving source code.[Edited by - Bozebo on July 8, 2010 4:29:05 PM];  Just so you know, that code could be simplified a tad. Something like this? for(uint16_t row = height;row > 0;row --){ //loop rows, bottom to top orderunsigned char * pData=bmpData+(row*pixelRowBytes-pixelRowBytes);    for(uint16_t col = 0;col < pixelRowBytes/3;col ++){ //each column with pixelspData[0]= bmpCol.b;pData[1]= bmpCol.g;pData[2]= bmpCol.r;pData+=3;}}(Further room for optimization as well)   ;Quote:Original post by empirical2 Just so you know, that code could be simplified a tad. Something like this?Oops, yeah that would have been the obvious solution I don't know why I overcomplicated it so much.