Thread: Broken .bmp output. Help!

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    14

    Broken .bmp output. Help!

    I am trying to write a program that outputs a bmp file. The code compiles, and runs, but the .bmp won't open! Where am I going wrong?

    Here is my code for generating the bitmap...

    Code:
    void generateImage(int **grid, int gridsize){
    	int bytesPerLine,i,j;
    	bmpHeader header;
    	FILE* image;
    	int count=0;
    	int test;
    	
    	memset ((char *)&header,0,sizeof(bmpHeader));
    	memcpy (header.bm,"BM",2);
    	header.headerSize = 54L;
    	header.infoSize = 0x28L;
    	header.width = gridsize;
    	header.height = gridsize;
    	header.planes = 1;
    	header.bits = 24;
    	header.compression = 0L;
    	
    	bytesPerLine = header.width * 3;
    	if (bytesPerLine & 0x0003){
    		bytesPerLine |= 0x0003;
    		++bytesPerLine;
    	}
    	
    	header.filesize = header.headerSize + (long)bytesPerLine * header.height;
    	
    	image = fopen("generatedPattern.bmp","w");
    	fwrite(&header,1,sizeof(header),image);
    	
    	char* arrayLine;
    	arrayLine = (char*)malloc(bytesPerLine);
    	
    	for (j=gridsize;j>0;j--) {
    		memset((char*)arrayLine,0,bytesPerLine);
    		for (i=0;i<(3*gridsize);i=i+3) {
    			if (grid[j-1][i/3] !=0) {
    				arrayLine[i]   = 255;
    				arrayLine[i+1] = 255;
    				arrayLine[i+2] = 255;
    			}
    			else {
    				arrayLine[i]   = 0;
    				arrayLine[i+1] = 0;
    				arrayLine[i+2] = 0;
    			}
    
    		}
    		test=fwrite(arrayLine,1,bytesPerLine,image);
    		if (!test) printf("Write failed");
    	}
    	fclose(image);
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    "It won't open" means what? It's corrupt? It doesn't look like it should when you open it up in paint? No .bmp file appears? What?

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    You should pass "wb" to fopen instead of "w".
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    Dec 2010
    Posts
    14
    Changed it to wb, I still get the same result; the file refuses to open, I get the error message:

    "The file generatedPattern.bmp could not be opened, It may be damaged or use a file format that Preview doesn’t recognize."

  5. #5
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Yes, i didn't notice it earlier: You forgot to add the BITMAPFILEHEADER at the very beginning of your bitmap. Windows Bitmap uses a specific binary format. Look up BITMAPFILEHEADER and BITMAPINFOHEADER on google.
    Devoted my life to programming...

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    14
    I probably should have put in my structures...
    Code:
    typedef struct {
    	char  bm[2];
    	long  filesize;
    	int   reserved[2];
    	long  headerSize;
    	long  infoSize;
    	long  width;
    	long  height;
    	short planes;
    	short bits;
    	long  compression;
    	long  imageSize;
    	long  xPixMeter;
    	long  yPixMeter;
    	long  numColours;
    	long  importantColours;
    } bmpHeader;
    Although I may just be being stupid, do I not already have both of those things in one structure? Or do I need to have split them up?

  7. #7
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Remember that int may not be the size you want it to!
    reserved should be of short type.

    BYTE is unsigned char
    WORD is unsigned short
    DWORD is unsigned long
    Devoted my life to programming...

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't think you've got the same number of fields as I'm seeing in the MSDN docs, though.

  9. #9
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    O_o ... I'm looking at MSDN right now!

    ( The device independant format, which is the one everyone use )
    Devoted my life to programming...

  10. #10
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Have you tried to check the size of your header struct? I noticed that you write it in one go, if there is padding in there it won't work.

    I used this header struct a while back when I was messing around with bmp images.

    Code:
    struct bmp_header{
    	UInt16	magic_number;
    	UInt32	file_size;
    	UInt16	reserved;
    	UInt16	reserved2;
    	UInt32	img_data_offset;
    	UInt32	header_chunk_size;
    	UInt32	img_width;
    	UInt32	img_heigt;
    	UInt16	color_planes;
    	UInt16	bits_per_pixel;
    	UInt32	compression;
    	UInt32	img_data_size;
    	UInt32	horisontal_resolution;
    	UInt32	vertical_resolution;
    	UInt32	colors_in_pallette;
    	UInt32	important_colors;
    } __attribute__((packed));
    The attribute will only work with GCC afaik, it's there to prevent the padding.
    Last edited by Subsonics; 12-20-2010 at 10:32 AM.

  11. #11
    Registered User
    Join Date
    Dec 2010
    Posts
    14
    Hmm, that doesn't seem to have made any difference either. The output in textedit looks the same as well. This is all very confusing...
    (I meant changing it to short, will have a look at the other suggestions, thanks)

  12. #12
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    If using gcc you should put pragma comments before and after your struct in order to be packed correctly:
    Code:
    #pragma pack(push, 1)
    
    struct bitmapHeader { ... };
    
    #pragma pack(pop)
    Devoted my life to programming...

  13. #13
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Hm, I have managed to get it to work with only the attribute. Just compile with -Wpacked and it will warn if it's ignoring you.

  14. #14
    Registered User
    Join Date
    Dec 2010
    Posts
    14
    I've tried this:
    Code:
    #pragma pack(push, 1)
    typedef struct{
    	unsigned char  bm[2];
    	unsigned long  filesize;
    	unsigned short reserved1;
    	unsigned short reserved2;
    	unsigned long  headerSize;
    	unsigned long  infoSize;
    	unsigned long  width;
    	unsigned long  height;
    	unsigned short planes;
    	unsigned short bits;
    	unsigned long  compression;
    	unsigned long  imageSize;
    	unsigned long  xPixMeter;
    	unsigned long  yPixMeter;
    	unsigned long  numColours;
    	unsigned long  importantColours;
    } bmpHeader;
    #pragma pack(pop)
    But it doesn't seem to make any difference.
    Am I using #pragma right? I've never heard of it before.

  15. #15
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Try printing a sizeof() on your struct to confirm if it's working or not. What's the size of long on your system?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. code output...
    By roaan in forum C Programming
    Replies: 6
    Last Post: 07-03-2009, 02:22 AM
  2. Help for my output array
    By qwertysingh in forum C Programming
    Replies: 1
    Last Post: 02-17-2009, 03:08 PM
  3. Replies: 4
    Last Post: 11-30-2005, 04:44 PM
  4. Formatting output into even columns?
    By Uncle Rico in forum C Programming
    Replies: 2
    Last Post: 08-16-2005, 05:10 PM
  5. Output problems with structures
    By Gkitty in forum C Programming
    Replies: 1
    Last Post: 12-16-2002, 05:27 AM