-
December 14th, 2010, 04:31 PM
#1
Questions about COSC1030 class code sample
Okay, so this project is done and over, so I'm not in a particular rush. I'm just trying to go through this code to figure out why some things are done in it. The code analyzes a BMP file and decodes a hidden message within it. I'll post the entire code and ask questions that have me stumped in between.
Code:
// BMPDecoder.cpp
// Retrieve coded message from BMP graphics file. The "hidden" message is contained in the least significant
// bits of the bitmap RGB data. If a data item is odd, that's a one-bit, if even, that's a zero-bit. Combine
// the bits from 8 contiguous data items together (big-endian order) to form a character.
// End of message is a '$'.
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
#include <fstream>
using std::fstream;
#include <ios>
using std::ios;
using std::ios_base;
#include <string>
using std::string;
#include <limits>
using std::numeric_limits;
enum BMPErrorCode { FILE_OPEN_FAILED, FILE_NOT_BMP };
void OpenInputFile( fstream& In )
{
string FileName;
cout << "Enter input file name: ";
cin >> FileName;
In.open( FileName.c_str(), ios::binary | ios::in);
if ( In.fail() )
throw( FILE_OPEN_FAILED );
}
void ConfirmBMP( fstream& In )
{
char tmp1, tmp2;
In.seekg(0);
tmp1=In.get();
tmp2=In.get();
if ( tmp1!='B' || tmp2!='M' || In.fail() )
throw( FILE_NOT_BMP );
unsigned int startBitmap;
In.seekg(10);
In.read(reinterpret_cast<char* >(&startBitmap),4);
In.seekg(startBitmap);
if ( In.fail() )
throw( FILE_NOT_BMP );
}
^-Here I have a question. I do not understand the purpose of the bolded lines. Why start with an unsigned int, only to reinterpret_cast it to a char pointer? Why read 4 bytes? What does seeking to this value accomplish?
Code:
char Decode(char* theBytes)
{
int tmp=0;
int thebit;
for(int i=0; i<8; i++) {
thebit = static_cast<unsigned char>(theBytes[i])%2;
tmp = (tmp*2)+(thebit);
}
return static_cast<char>(tmp);
}
^-Why static_cast theBytes[i] to an unsigned char?
Code:
void ReadDecodeDisplay( fstream& In )
{
char ByteList[8];
char TheChar;
bool done=false;
In.exceptions( ios_base::failbit );
while(!done) {
try {
In.read(ByteList, 8);
TheChar=Decode( ByteList );
if( TheChar=='$' )
done=true;
else
cout << TheChar;
}
catch(ios_base::failure) {
if( In.eof() )
done=true;
}
}
}
int main()
{
fstream InputFile;
try {
OpenInputFile( InputFile );
ConfirmBMP( InputFile );
ReadDecodeDisplay( InputFile );
InputFile.close();
}
catch(BMPErrorCode ErrorCode) {
switch(ErrorCode) {
case FILE_OPEN_FAILED:
cerr << "Error attempting to open input file" << endl;
break;
case FILE_NOT_BMP:
InputFile.close();
cerr << "Error in format of input file, not a BMP" << endl;
break;
default:
cerr << "Unknown error" << endl;
}
}
return 0;
}
-
December 14th, 2010, 04:54 PM
#2
Re: Questions about COSC1030 class code sample
1. The value to be read is a 32 bit integer stored at byte offset 10. To read the integer you would like to do as In.read( &startBitmap,4 ); but unfortunately read can only read bytes. The cast is used to overcome this by telling the compiler that you would like to treat the integer as just any consecutive 4 bytes. Fortunately the bytes are stored in the correct order so there's no need for a byte-swap.
2. theBytes is an array of char's. Most compilers default char to be signed char and as far as I know the modulo-operator is not defined for signed integers. A better way (in my opinion) would have been to declare theBytes unsigned char's instead.
Edit: Tried to find what's said about % and signed values in the standard but failed. However see this link http://en.wikipedia.org/wiki/Modulo_operation
Last edited by S_M_A; December 14th, 2010 at 05:02 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|