Jump to content
  • Advertisement
Sign in to follow this  
jeffkiwi

The latest BMP I made crashes the program, other BMPs work fine

This topic is 840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is it better to use a PNG? I cut'n'pasted to make a program that basically does nothing besides load an image, and simply loading the new BMP causes the crash. I confirmed that, with a simple error check which makes a dialogue box.

Share this post


Link to post
Share on other sites
Advertisement

Doing a quick test is indeed a good way to verify your findings.

 

 

The point with loading any data from anywhere is that you cannot trust it (and that generally includes files you make yourself, it's amazing how often you make a mistake somewhere and produce just garbage data files). This holds for any type of file, including BMP, PNG, or whatever you have.

 

I don't know how you load the BMP, but if the program crashes on loading an image file, the BMP loader is just broken. Loaders should not crash under any circumstance, even if you feed it garbage data (almost correct data is even sneakier, as it's harder to detect being wrong).

Instead of crashing, it should say "I don't understand this file, sorry!", and return that error, an empty image, or a default image, whatever is appropriate.

 

I'll assume you wrote your own BMP loader here (if you used a library, that library is broken).

 

 

You avoid crashes by checking each and every byte that you get in every possible way you can think of.

The rule is that you may not use any data that you didn't check inside out first. If any check fails, refuse it.

 

If the BMP format definition says some byte should be the value 5, check it. If it's not 5, refuse the data.

If data value must be one of three possible types, check that. Assume some $random data file will use a 4th or 5th value there or a negative value if it can be done.

If you have a size, check it. Assume someone will make a picture of width -1, width 0, or width 12345678. Similarly for the height.

If you get data bytes for the pixels, check how many bytes you expect (from the sizes), and how many you really have. If it's not the same, refuse to accept it.

Also check area, is it ok to get an image of 12345678 * 87654321 pixels ?

If there are x/y positions or jumps of coordinates in the data file, people will provide you data files that jumps outside the image bounds.

At the end of the data, check that the file also ends. If not, something is not right, refuse the data.

Edited by Alberth

Share this post


Link to post
Share on other sites

First, the new bitmap have RLE compression?

Can you post the code that loads the BMP?

 

Chaning the format to PNG will not help you if the loader can not read the data.

 

HTH

Share this post


Link to post
Share on other sites

I'll assume you wrote your own BMP loader here (if you used a library, that library is broken).


I didn't write my own loader, I'm not that smart  :wink:  It's just libsdl-2 and I mean the standard library's image loader not libsdl-image.
 

If the BMP format definition says some byte should be the value 5, check it. If it's not 5, refuse the data.
If data value must be one of three possible types, check that. Assume some $random data file will use a 4th or 5th value there or a negative value if it can be done.
If you have a size, check it. Assume someone will make a picture of width -1, width 0, or width 12345678. Similarly for the height.
If you get data bytes for the pixels, check how many bytes you expect (from the sizes), and how many you really have. If it's not the same, refuse to accept it.
Also check area, is it ok to get an image of 12345678 * 87654321 pixels ?
If there are x/y positions or jumps of coordinates in the data file, people will provide you data files that jumps outside the image bounds.
At the end of the data, check that the file also ends. If not, something is not right, refuse the data.


I've found a technical guide to the BMP format. How to open the file as data though? Sure, cstdlib or iostream, but is there a way to open in notepad or similar? I thought notepad just showed gibberish when opening a bitmap.
 

First, the new bitmap have RLE compression?
Can you post the code that loads the BMP?


I'll check for RLE compression when I get back home (I'm using library internet right now). I think the problem is one of those flags/options when saving the file.
 

First of all, learn to use your debugger.  It's often trivial to identify causes of crashes by running a debug build under a good debugger; it will halt on the line of code that crashed and you can then inspect the contents of variables and follow the execution of code to help determine what went wrong.
 
Secondly, learn the file format you're using.  Did you know that the BMP format requires each row to be padded to a multiple of 4 bytes?  If you didn't know that, there's a good probability that this is the cause of your crash.


Thanks for the suggestion. I just found a guide on the codeblocks wiki.
 

Thirdly, learn how to ask for help properly.  Don't just say "it crashed"; give as much information as possible to help others help you.  Even worse is saying "it gave an error message" without saying what the error message was.


It's the standard libsdl load image feature that crashes the program, and the error message is one I made myself by checking if image == null. Next time I'll go "watch imgname" in the debugger and set a breakpoint.

 

Update? - no fix yet. I'm going to copy my image and save it as a fresh file. If the file was corrupted then making a new file with the same image might work.

Edited by jeffkiwi

Share this post


Link to post
Share on other sites
I didn't write my own loader, I'm not that smart  :wink:  It's just libsdl-2 and I mean the standard library's image loader not libsdl-image.

Ha, in that case, your library is broken :p

 

Not sure how much use that is. If the image is nothing special, you could report the problem upstream, providing the image as proof.

Otherwise, maybe you should use a different image loader, one that doesn't break.

 

BMP is a pretty simple file format, you may want to try writing your own loader for fun and learning.

 

 

I've found a technical guide to the BMP format. How to open the file as data though? Sure, cstdlib or iostream, but is there a way to open in notepad or similar? I thought notepad just showed gibberish when opening a bitmap.

It's binary data (which just means "it also has non-text bytes"), so yeah, notepad can't make sense of it. You're supposed to open it in an image editor :)

Some text editor may have a "binary mode" though, similar to the hexdump idea I explain below.

 

To see what's inside a binary file, you can make a hexdump of the file, which basically means each byte in the file is printed in hexadecimal notation. A hex-dump is plain text, which you can load in any text editor. While you can read the file contents then, it's a lot of manually counting bytes and offsets, and reading the file format definition, to make sense of the data.

 

For example, like

00000000: 42 4d 9e 02 00 00 00 00 00 00 36 00 00 00 28 00  BM........6...(.
00000010: 00 00 0e 00 00 00 0e 00 00 00 01 00 18 00 00 00  ................
00000020: 00 00 68 02 00 00 c4 0e 00 00 c4 0e 00 00 00 00  ..h.............
00000030: 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff  ................
00000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000060: 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000080: ff ff ff ff ff ff ff ff ff ff ff ff 00 00 ff ff  ................
00000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000b0: ff ff ff ff ff ff ff ff 00 00 ff ff ff ff ff ff  ................
000000c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000e0: ff ff ff ff 00 00 ff ff ff 22 22 22 ff ff ff ff  ........."""....
000000f0: ff ff b2 b2 b2 3b 3b 3b 29 29 29 55 55 55 db db  .....;;;)))UUU..
00000100: db 92 92 92 2b 2b 2b ff ff ff 22 22 22 ff ff ff  ....+++..."""...
00000110: 00 00 ff ff ff 22 22 22 ff ff ff ff ff ff 32 32  ....."""......22
00000120: 32 cd cd cd f9 f9 f9 d9 d9 d9 83 83 83 37 37 37  2............777
00000130: e1 e1 e1 ff ff ff 22 22 22 ff ff ff 00 00 ff ff  ......""".......

The first long number "00000000:" is the offset in the file (offset 0 is something you'd expect at the start of a file), then come 16 bytes (bytes 0 to 15 in the file), each in hexadecimal notation, then the same 16 bytes, but as ASCII text characters, if they are printable, or a dot otherwise. Second line does the same for bytes 16 to 31, and so on. I chopped the file at offset 0x140.

 

The first character of the file is thus 0x42 (66), which is the 'B' letter, then 0x4d, the 'M' letter, and so on.

 

 

In C, you open it just like other files, but in binary mode   FILE *fp = fopen(filename, "rb");

Binary mode prevents special interpretation of newline characters, otherwise it's just the same. Obviously, in binary mode, you'll get characters 0 to 255, instead of the usual 9/10/13 and 32 to 126, in text files.

Share this post


Link to post
Share on other sites
It sounds like the crash is due to dereferencing a null pointer (since you could create an error message checking image == null). This is not the same as the image loader crashing your application.
The loader is probably failing to load the image, returning a null pointer, and your application doesn't handle this case properly.
 
One of the most common reason for failing to load an image is typing in an incorrect filepath/filename, so you should triple check that it's correct. Even if you're sure it's correct, check again.
 
Other than that, step through in a debugger and see where things go wrong.
 
 
EDIT:
Some additional advice;
Refer to the documentation to see what a function should return, and what is returned in the case of an error.
With that in mind, do error checking whenever possible. (For SDL this is usually checking for a null pointer and then calling some xxx_GetError function).
If you have problems with your code, post your code. Don't make us guess what might be the problem.
Learn how to use a debugger. This is a skill you will need as you progress. The sooner you learn, the better.
Edited by Lactose!

Share this post


Link to post
Share on other sites

To see what's inside a binary file, you can make a hexdump of the file, which basically means each byte in the file is printed in hexadecimal notation. A hex-dump is plain text, which you can load in any text editor. While you can read the file contents then, it's a lot of manually counting bytes and offsets, and reading the file format definition, to make sense of the data.
 
For example, like

00000000: 42 4d 9e 02 00 00 00 00 00 00 36 00 00 00 28 00  BM........6...(.
00000010: 00 00 0e 00 00 00 0e 00 00 00 01 00 18 00 00 00  ................
00000020: 00 00 68 02 00 00 c4 0e 00 00 c4 0e 00 00 00 00  ..h.............
00000030: 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff  ................
00000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000060: 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000080: ff ff ff ff ff ff ff ff ff ff ff ff 00 00 ff ff  ................
00000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000b0: ff ff ff ff ff ff ff ff 00 00 ff ff ff ff ff ff  ................
000000c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
000000e0: ff ff ff ff 00 00 ff ff ff 22 22 22 ff ff ff ff  ........."""....
000000f0: ff ff b2 b2 b2 3b 3b 3b 29 29 29 55 55 55 db db  .....;;;)))UUU..
00000100: db 92 92 92 2b 2b 2b ff ff ff 22 22 22 ff ff ff  ....+++..."""...
00000110: 00 00 ff ff ff 22 22 22 ff ff ff ff ff ff 32 32  ....."""......22
00000120: 32 cd cd cd f9 f9 f9 d9 d9 d9 83 83 83 37 37 37  2............777
00000130: e1 e1 e1 ff ff ff 22 22 22 ff ff ff 00 00 ff ff  ......""".......
The first long number "00000000:" is the offset in the file (offset 0 is something you'd expect at the start of a file), then come 16 bytes (bytes 0 to 15 in the file), each in hexadecimal notation, then the same 16 bytes, but as ASCII text characters, if they are printable, or a dot otherwise. Second line does the same for bytes 16 to 31, and so on. I chopped the file at offset 0x140.
 
The first character of the file is thus 0x42 (66), which is the 'B' letter, then 0x4d, the 'M' letter, and so on.

 

One could just use an actual hex editor - there are plenty of good ones out there (even good free ones).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!