简体   繁体   中英

Reading a raw image file with C++

I have two identical C++ codes which each read in identical .raw image files as such:

this->file_variable = fopen(filename, "r")

They process the information within them as such:

status = fread ((void *)this->img1,
  sizeof(float),
  (this->width * this->height),
  this->file_variable)
)

The only difference between the two codes is that they were compiled on different boxes, but I'm getting completely different results from the img1 array. I have absolutely no idea how to even start debugging this. Could anyone please point me in the right direction?

Edit: I'm slowly gaining more information on the files. They are (width x height) 1800 x 1728 pixels, 1 channel, 8 bits depth.

It sounds like the file was written in binary format, so you need to open it likewise:

this->file_variable = fopen(filename, "rb")

Without the "b", it's being read as ASCII.

Now I see your problem. Your data is stored in big endian and you're reading it on a little endian system. You need to simply convert each float by reversing the byte order. Use a function like this (taken from a similar answer elsewhere):

float ReverseFloat( const float inFloat )
{
float retVal;
char *floatToConvert = ( char* ) & inFloat;
char *returnFloat = ( char* ) & retVal;

// swap the bytes into a temporary buffer
returnFloat[0] = floatToConvert[3];
returnFloat[1] = floatToConvert[2];
returnFloat[2] = floatToConvert[1];
returnFloat[3] = floatToConvert[0];

return retVal;
}

There is no guarantee that the binary (!) format of values are the same on different machines. Where do the other this-> values come from?

Here Is A Great Function To Flip The Byte Order Of Any Variable, Which Can Be Easily Used To Change The Endianness.

void byteFlip(void* original, size_t numberOfBytes)
{
    char* reversed = (char*) malloc(numberOfBytes);
    for (int i = 0; i < numberOfBytes; i++)
    {
        reversed[i] = ((char*)original)[numberOfBytes - i - 1];
    }
    memcpy(original, reversed, numberOfBytes);
    free(reversed);
}

This Will Flip The Byte Order Of The Variable Used In The 'original' parameter. Example:

short a = 512;
//AAAAAAAA BBBBBBBB - 00000010 00000000
cout << a << endl; //outputs 512
byteFlip(&a, sizeof(short)); //flip byte order of 'a'
//BBBBBBBB AAAAAAAA - 00000000 00000010
cout << a << endl; //outputs 2

Explanation: this function takes a pointer to any type of variable, and the size in bytes of that variable. Since we are reversing the byte order, and 1 character = 1 byte, we can therefore treat this the same way as we would reverse a string. We create a new string the same size as our variable to hold the reversed data. Now we use a for loop to copy each byte as a char in reversed order into the reversed character array variable. Once the loop has completed we can copy the memory of our reversed string into the original pointer. Finally we free the memory of the reversed string variable since it has been copied into the original pointer, and therefore no longer needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM