How to read in binary data and cast to unsigned char (C++)
Asked Answered
D

1

6

I have a raw image file that is saved in binary data (no encoding). I want to read in the file and cast the values to an unsigned char. But I'm not sure how to begin going about doing this. Each file contains 640x480 bytes. Each pixel is 8bits.

I've used the C++ help page here: http://www.cplusplus.com/doc/tutorial/files/, however when I am couting the data, it seems to be showing the same binary/non-human readable characters. Can someone please advise? Here is my code so far:

    #include <iostream>
    #include <fstream>
    using namespace std;

ifstream::pos_type size;
char * memblock;

int main () {
  ifstream file ("imageData.raw", ios::in|ios::binary|ios::ate);
  if (file.is_open())
  {
    size = file.tellg();
    memblock = new char [size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);

    cout << "the complete file content is in memory";

    for (int l=0; l<size; l++){
    cout << " memblock[] is = " << (unsigned char)memblock[l] << " index was l = " << l << endl;
    }

    file.close();


    delete[] memblock;
  }
  else cout << "Unable to open file";
  return 0;
}

Here is a sample capture of the output:

 memblock[] is = ▀ index was l = 2937
 memblock[] is = E index was l = 2938
 memblock[] is = τ index was l = 2939
 memblock[] is = C index was l = 2940
 memblock[] is = ┘ index was l = 2941
 memblock[] is = B index was l = 2942
 memblock[] is = ╬ index was l = 2943
 memblock[] is = D index was l = 2944
 memblock[] is = ┼ index was l = 2945
 memblock[] is = C index was l = 2946
 memblock[] is = ╝ index was l = 2947
 memblock[] is = B index was l = 2948
 memblock[] is = ┤ index was l = 2949
 memblock[] is = B index was l = 2950
 memblock[] is = ¿ index was l = 2951
 memblock[] is = > index was l = 2952
 memblock[] is = í index was l = 2953
 memblock[] is = ; index was l = 2954
 memblock[] is = £ index was l = 2955
 memblock[] is = 6 index was l = 2956
 memblock[] is = á index was l = 2957
 memblock[] is = 4 index was l = 2958
 memblock[] is = Ñ index was l = 2959
 memblock[] is = 7 index was l = 2960
 memblock[] is = ╡ index was l = 2961
Demimonde answered 26/6, 2012 at 19:38 Comment(0)
M
9
unsigned char* memblock; // change declaration of memblock

...

memblock = new unsigned char[size]; // change to unsigned char
file.seekg (0, ios::beg);
file.read ((char*)memblock, size); // cast to a char* to give to file.read

To print numeric values instead of characters, cast to an int before printing.

(int) memblock[l]
Molality answered 26/6, 2012 at 19:39 Comment(11)
Hmm, MathWizz, that gives me an int instead. I want to convert it to an unsigned char (0 to 255). Is there no way to do it? Do I need to convert it to an int only?Demimonde
What is the expected output? Are you only casting to print a numeric value?Molality
No, I want to deal with unsigned chars. I get raw images that are saved in binary. I just can't wrap my head around dealing with that non-readable format, so I want to work with unsigned chars just so that I can see what is happening. I was only casting for debugging for now. But I want the memblock to essentially convert all those values to unsigned chars instead ...Demimonde
So you want to convert memblock to an unsigned char*?Molality
The problem with that is file.read expects a char as input parameter1: istream& read ( char* s, streamsize n ); (cplusplus.com/reference/iostream/istream/read) , so I will run into compile errors ...Demimonde
Thanks MathWizz! Just one question, so if it reads it in as a char (as you'd specified). Does it merely truncate the other bits? How does it work?Demimonde
@Demimonde Any type that is not unsigned is singed. It has the same range of data, but half is negative, so a singed char has a range from -128 to 127. More here: en.wikipedia.org/wiki/Integer_(computer_science)Molality
Oh, I know the difference between unsigned and signed. What I meant to ask was when we are reading in the file: file.read ((char*)memblock, size); , we are reading it as a char. But the memblock structure is defined as type unsigned char. So I think every thing that was -128 becomes 0. And everything that was 127 becomes 255?Demimonde
Just one last question. What if I didn't end the program with delete[] memblock; What are the consequences?Demimonde
@Demimonde I'm not 100% sure about this, but I think all used memory is freed on exit. Source: cplusplus.com/forum/general/11808/#msg55971Molality
:) Next time you have questions like these, consider moving to a chat. This isn't really the place for it.Molality

© 2022 - 2024 — McMap. All rights reserved.