![]() |
|
#1
|
||||
|
||||
reading bmp'sI've written the following code for reading/writing/displaying bmp images. Everything but reading 4 bit encoded mode works. I have been trying to figure out why for two days. I think it's an endianness problem, but I can't figure out what to do about it.
Here's the code: CPP / C++ / C Code:
|
|
#2
|
|||
|
|||
Re: reading bmp'sQuote:
1. What compiler/operating system? Did you receive any compiler warning error messages? 2. What do you mean when you say, "Everything but reading 4 bit encoded mode works"? How many modes did you test? How many modes worked? How did you know that they worked. (In other words, how did you test them?) How many modes didn't work? How do you know it didn't work? (In other words, how did you test it?) 3. What makes you say, "I think it's an endianness problem"? Which of the routines are used in both the mode that doesn't work and the modes that work? Are any of the routines only used in the mode that doesn't work? Are any of the routines used differently for the different modes? How did the modes that worked get the endianness right? Have you identified exactly where in each mode that endianness affects the code? 4. How the heck can anyone help you if you don't give us the program you used for testing and a file that exhibits the problem? For example: the code for flipNibbles(unsigned short x) is certainly wrong, but I don't see where it is used in any of the member functions. Did you write all of the code that you posted? Did you test the member functions of your class? How? Regards, Dave Last edited by davekw7x : 30-Nov-2005 at 08:33.
|
|
#3
|
||||
|
||||
Re: reading bmp'sQuote:
Borland C++Builder/Windows XP No compiler errors/warnings. Quote:
I've tested every mode by making images in photoshop, saving them in the various bmp formats, and reading them. To check if they have been read correctly I use the draw function to display them on the screen. I know that 4 bit encoded mode does not work because there is a run time error while the image is being read. I believe the problem is that the currentX variable exceeds the x resolution of the image. Quote:
I'm only guessing that it's an endianess problem because that's the only thing I can think of. The read_int and read_short functions are used in all modes. They are the only subroutines called when reading 4 bit encoded mode. I dealt with endianess by reading r, g, and b in the correct order in the other modes > 4. In 4 bit mode, I need to switch the high and low order nibbles in each byte. Quote:
I don't have the code on me at the moment. I'll post it later today. |
|
#4
|
|||||
|
|||||
Re: reading bmp'sQuote:
Quote:
Quote:
What does endianness have to do with your observation that you believe the problem is that a variable exceeds the x resolution of the image? Why don't you go into the code where it is reading a 4-bit bitmap and put cout<< statements to show what the current value of array index is and also show the array size (the maximum index value allowed for that array)? This does several things: 1. It makes you look at the part of the code where your observation leads you to believe the problem may lie. Sometimes just looking closely can let you see something that was overlooked in the 590 lines of code of the class definitions. 2. It prints out values that may show you what's wrong. 3. If it bombs sometime in the middle of the loop, you confirm that that is where the problem is. (And you can see the values that may be causing the problem.) 4. If it gets through that part of the code without bombing, you know the problem may be somewhere else. (So you go to the next step in the algorithm and put some cout<< stuff there to see what the program is working on.) Quote:
In the first place, endianness usually refers to byte positions within 16-bit or 32-bit (or 64-bit) data items, not nibbles within a byte. However... If you didn't perform the nibble-swap properly, I could see how it would mess up the picture, but I don't see exactly how it would cause a run time error. However, it may be something to test, if your other efforts don't lead to a complete fix. Quote:
Before you do that, why don't you try to isolate the runtime error? Maybe some of my suggestions can help you get started. (The point is to get you to a place where you can debug your code yourself.) A very powerful debugging methodology is: Make the program tell you what is happening. This is faster, I claim, than posting a request for help and waiting for a helpful response. And it helps you learn about debugging. Since I spend something less than 15 percent of my time writing code and the rest of the time debugging, I think debugging skills are worth developing. Regards, Dave "We can face our problem. We can arrange such facts as we have with order and method." Hercule Poirot --- in Murder on the Orient Express |
|
#5
|
||||
|
||||
Re: reading bmp'sI don't think I was clear on one thing. I know that I am getting out of bounds exceptions, because I've printed out the values of currentX and currentY. I think that may be happening because something is being read in incorrectly, possibly because of endianess.
Quote:
I'm aware of that much, and I can't figure out why, then, I have to flip nibbles in the four bit enencoded case. I agree with everything you've said about debugging. That's exactly how I normally proceed with a debugging a program, and it usually works for me, but I have been doing that for two days now with now luck. I've even tried comparing my code to code written by others, and as far as I can tell it does exactly the same thing. This is driving me crazy. The algorithm itself my be the problem. Thanks for the help. |
|
#6
|
||||
|
||||
Re: reading bmp'sHere's the code I use to test it:
CPP / C++ / C Code:
4bit-cmp.bmp is a compressed 4bit bitmap. |
|
#7
|
|||
|
|||
Re: reading bmp'sQuote:
So: how can the values go out of bounds? Now I understand now how you could think it's related to endianness. And I see how it could create a problem. (Your problem, that is.) Well, when you read in values for the sizes that are used as limits on the loops that are giving you grief: print out the sizes. Regards, Dave |
|
#8
|
||||
|
||||
Re: reading bmp'sI found one problem; I was reading 2 bytes in several places where I should have been reading only 1. Unfortunatly that didn't fix it.
I'm still getting the out of bounds exception. The interesting is that when it happens, it only exceeds the bounds by ; I replaced this: CPP / C++ / C Code:
with this: CPP / C++ / C Code:
Thus if currentX gets to large, it simply ignores it and keeps on going. Every single time the first "if" branch of the if-else statement is taken, it is because xCurrent == xRes. I'm really not sure what to make of that. This keeps it from crashing. Interestingly the image comes out ~ 99% correct when it displays. |
|
#9
|
|||
|
|||
Re: reading bmp'sQuote:
Thanks for the update. Well, it is possible that there are more than one bugs that cause bad behavior. Fix each one that you find and do some more testing. (You can't prove that this correct by testing, of course, but you can uncover some bugs.) Quote:
OK. That's pretty good detective work to get this far. pixel_data is a vector of vectors. It is perfectly legal to use the array index notation to access the elements, but you do know that no bounds checking is performed, right? If your program has a bug that causes it to try to access something beyond the end of the array, your fix eliminates one of effect of the bug (for your test case: doesn't crash), but doesn't fix the bug. I suggest you try to find why the program doesn't know the size of whatever it is accessing. Quote:
This is a deterministic algorithm. I assume that you aren't satisfied with ~99% correct on your test case. How do you know how many bad things can happen with other images? Regards, Dave |
|
#10
|
||||
|
||||
Re: reading bmp'sI got it! Each block of encoded data has to start on an even-numbered byte. Here's the code incase anyone else has use for it. The header file (image.h): CPP / C++ / C Code:
and the cpp file (image.cpp): CPP / C++ / C Code:
|