How to read 8bits RAW data from file - c++

I have 8 bit raw data representing a grayscale image (int value 0-255) in a file looking like this:
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 001c 354d 6576 8797
9fa4 a7a4 864b 252e 5973 7673 7b86 7e6d
6164 6c7a 8b98 a2ac b8bd ae96 857f 6d40
1d14 160b 0000 0000 0000 0000 0000 0000
and i need to read them and print their int value (0-255).
I try this, but all result looks like this: 0020 0a00 2000 2000 2000 2000 2000 2000
I dont know what is wrong, fopen as binary file is OK?
FILE * pFile;
pFile = fopen(inFileName.c_str(), "rb");
if (pFile==NULL){
cerr << "erro" << endl;
}
uint8_t bufferImmagine[height*width];
fread(bufferImmagine,1,height*width,pFile);
fclose (pFile);
for (int i = 0; i < height*width; ++i)
{
cout << bufferImmagine[i] << " ";
}

So bufferImmagine is an array of type uint8_t, and on many platforms uint8_t is an alias for unsigned char. When you stream unsigned char into std::cout, the stream treats it like a character, rather than a number.
If you want to print out each byte as a number 0-255, convert each byte to a wider integral type, like unsigned:
std::cout << static_cast<unsigned int>(bufferImmagine[i]) << " ";

I see a few potential problems with the code:
1) As mentioned in the comments, uint8_t bufferImmagine[height*width]; is problematic, in that C++ doesn't support variable-length arrays, so unless height and width can be made into compile-time constants, it would be better to use a std::vector instead (or if you are allergic to data structures you could allocate an array with the new operator, but then you risk leaking memory if you aren't very careful).
2) Depending on the values of width and height, the size of bufferImmagine could be quite large; possibly larger than the amount of stack space available. Another reason to use std::vector or allocate on the heap, instead.
3) You never check the return value of the fread() call to see if it read all of the data, or not. It might be reading fewer bytes than you asked it to read (most likely because the file you're reading isn't long enough), but without checking the value you won't know anything has gone wrong, so you'll be very confused if/when an error occurs.
4) As Jack C. mentioned in his answer, cout may print out uint8_t's as ASCII characters rather than integers, which isn't what you want here.
5) Not really a problem, but if you'd like the rows of your output to correspond to the rows-of-pixels in your file, then you'll want to apply carriage returns at the end of each 'row'. E.g.:
int i = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
const unsigned int iVal = bufferImmagine[i];
cout << iVal << " ";
i++;
}
cout << endl;
}

Related

C++ Math Weird After 65536

This is my first question asked so I am not sure exactly what to say. Basically, I wrote a program to find the diagonal of a rectangular prism with the inputs for length, width, and height being whole numbers ranging from 1 - 100,000. (The output of this function would only be stated in the console if it was a whole number.) Everything seems to work until it got to the number 65536, after which, the next output was 0.
I am still new to programming, and if I missed anything, feel free to ask, thank you all in advance!
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include<math.h>
#include <cmath>
int l = 1;
int w = 1;
int h = 1;
double temp1;
double temp2;
double Hypo1;
double temp3;
double Hypo2;
double temp4;
int main(){
while(h < 100000){
//Math to find diagonal of rectangular prism.
temp1 = l * l;
temp2 = w * w;
Hypo1 = temp1 + temp2;
temp3 = h * h;
temp4 = Hypo1 + temp3;
Hypo2 = sqrt(temp4);
//Output if answer is a whole number.
if(abs(floor(Hypo2)) == Hypo2){
std::cout << "<Length = "; std::cout << l;
std::cout << " | Width = "; std::cout << w;
std::cout << " | Height = "; std::cout << h;
std::cout << ">";
std::cout << " Total:"; std::cout << Hypo2 << std::endl;
}
//Add one to each input.
if(l == w && l == h){
l++;
}
else if(w < l && w == h){
w++;
}
else if(h < l && h < w){
h++;
}
}
}
Welcome to the wonders of Overflow.
So, here's what's happening:
You're using int, which stores values in a 4 byte (32 bit) variable. When you multiply two numbers stored in X bits you may need to store the result in 2*X bits.
In this case, 65536 is, in binary, 0000 0000 0000 0001 0000 0000 0000 0000 (in hex, 0x 0001 0000). When you multiply 65536 by itself, the result will be 1 0000 0000 0000 0000 0000 0000 0000 0000 (in hex, 0x 1 0000 0000). Now, the problem is that this value needs 33 bits to be correctly stored. As it only has 32, it stored the 32 least significant bits and discards the most significant bit. As such, the stored value will be 0. This is also what happens with greater values.
To correct this, replace int with long long or, even better, unsigned long long.
As a personal advice, get used to uint32_t and other standard types. They will come in handy. To use these, #include <cstdint>. In this case, you should use uint64_t to store unsigned integers in a 64-bit variable
You declared h as an int, so the result of h*h will also be an int. The conversion to double happens after the calculation is already done.
If you take a look at INT_MAX it's probably 2,147,483,647 on your platform.
So if you look at 65536 * 65536 it's 4,294,967,296, well outside of the value range.
If you convert one of the factors into a double value first, you might have some more luck temp3 = double(h) * h

Reading Binary Files Using Bitwise Shifters and Buffers in C++

I'm trying to read a binary file and simple convert the data to usable unsigned integers. The code below works for 2-byte reading, for certain file locations, and correctly prints the unsigned integer. When I use the 4-byte code though my value turns out to be a number much larger than it is supposed to be. I believe the issue lies within the read function, it seems as though I am getting the wrong character/decimal number (101 for example) which when bit shifted becomes a number much larger than it should be (~6662342).(when the program runs it throws an exception every now and then "stack around the variable buf runtime error #2" in visual studios). Any ideas? It may be my fundamental knowledge of how the data is stored in the char array that is affecting my data output.
working 2-byte code
unsigned char buf[2];
file.seekg(3513);
uint64_t value = readBufferLittleEndian(buf, &file);
printf("%i", value);
system("PAUSE");
return 0;
}
uint64_t readBufferLittleEndian(unsigned char buf[], std::ifstream *file)
{
file->read((char*)(&buf[0]), 2);
return (buf[1] << 8 | buf[0]);
}
broken 4-byte code
unsigned char buf[8 + 1]; //= { 0, 2 , 0 , 0 , 0 , 0 , 0, 0, 0 };
uint64_t buf1[9];
file.seekg(3213);
uint64_t value = readBufferLittleEndian(buf, &file, buf1);
std::cout << value;
system("PAUSE");
return 0;
}
uint64_t readBufferLittleEndian(unsigned char buf[], std::ifstream *file, uint64_t buf1[])
{
file->read((char*)(&buf[0]), 4);
for (int index = 0; index < 4; index++)
{
buf1[index] = buf[index];
}
buf1[0];
buf1[1];
buf1[2];
buf1[3];
//return (buf1[7] << 56 | buf1[6] << 48 | buf1[5] << 40 | buf1[4] << 32 | buf1[3] << 24 | buf1[2] << 16 | buf1[1] << 8 | buf1[0]);
return (buf1[3] << 24 | buf1[2] << 16 | buf1[1] << 8 | buf1[0]);
//return (buf1[1] << 8 | buf1[0]);
}
Please correct me if I got the endianess reversed.
code is C++ except for the printf line
you have to cast before shifting. You cannot shift a char left 56 bits.
ie do ((uint64_t)buf[n] << NN
Seekg(0) = byte 1, seekg(3212) = byte 3213. Not entirely sure why I was getting a zero in byte 3214 before, considering I now get 220 (indicating big-endianess). Getting 220 would have indicated that I was interpreting the functionality of seekg(). Oh well it is solved where it matters now anyway.

c++: How to flip the binary values of each bit in int

Suppose I have an integer int a
In c++, as this int uses 4 bytes(32 bits) of memory, all bits would be occupied by either 1's or 0's. So, I wish to flip the values of each bit. That is, wherever in each bit there is 1 convert it to 0 and 0 to 1.
Is there an easy way to go about this?
Edit: I also want to play with boolean algebra also. That is if I can execute basic boolean operations like addition, subtraction, etc.
You're looking for the binary not operator (~).
So
int a = 0x04;
int b = ~a;
the value of b is 1111 1111 1111 1011 while the value of a is 0000 0000 0000 0100.
The wikipedia and the GNU C have plenty of information of these binary operators.
Here is an example of bitwise NOT operator:
#include <iostream>
int main()
{
int a = 0;
int x = ~a;
unsigned int y = ~a;
std::cout << x << '\n';
std::cout << y << '\n';
}
Output:
-1
4294967295
For more information about binary operators and more try here

Integer into char array

I need to convert integer value into char array on bit layer. Let's say int has 4 bytes and I need to split it into 4 chunks of length 1 byte as char array.
Example:
int a = 22445;
// this is in binary 00000000 00000000 1010111 10101101
...
//and the result I expect
char b[4];
b[0] = 0; //first chunk
b[1] = 0; //second chunk
b[2] = 87; //third chunk - in binary 1010111
b[3] = 173; //fourth chunk - 10101101
I need this conversion make really fast, if possible without any loops (some tricks with bit operations perhaps). The goal is thousands of such conversions in one second.
I'm not sure if I recommend this, but you can #include <stddef.h> and <sys/types.h> and write:
*(u32_t *)b = htonl((u32_t)a);
(The htonl is to ensure that the integer is in big-endian order before you store it.)
int a = 22445;
char *b = (char *)&a;
char b2 = *(b+2); // = 87
char b3 = *(b+3); // = 173
Depending on how you want negative numbers represented, you can simply convert to unsigned and then use masks and shifts:
unsigned char b[4];
unsigned ua = a;
b[0] = (ua >> 24) & 0xff;
b[1] = (ua >> 16) & 0xff;
b[2] = (ua >> 8) & 0xff
b[3] = ua & 0xff;
(Due to the C rules for converting negative numbers to unsigned, this will produce the twos complement representation for negative numbers, which is almost certainly what you want).
To access the binary representation of any type, you can cast a pointer to a char-pointer:
T x; // anything at all!
// In C++
unsigned char const * const p = reinterpret_cast<unsigned char const *>(&x);
/* In C */
unsigned char const * const p = (unsigned char const *)(&x);
// Example usage:
for (std::size_t i = 0; i != sizeof(T); ++i)
std::printf("Byte %u is 0x%02X.\n", p[i]);
That is, you can treat p as the pointer to the first element of an array unsigned char[sizeof(T)]. (In your case, T = int.)
I used unsigned char here so that you don't get any sign extension problems when printing the binary value (e.g. through printf in my example). If you want to write the data to a file, you'd use char instead.
You have already accepted an answer, but I will still give mine, which might suit you better (or the same...). This is what I tested with:
int a[3] = {22445, 13, 1208132};
for (int i = 0; i < 3; i++)
{
unsigned char * c = (unsigned char *)&a[i];
cout << (unsigned int)c[0] << endl;
cout << (unsigned int)c[1] << endl;
cout << (unsigned int)c[2] << endl;
cout << (unsigned int)c[3] << endl;
cout << "---" << endl;
}
...and it works for me. Now I know you requested a char array, but this is equivalent. You also requested that c[0] == 0, c[1] == 0, c[2] == 87, c[3] == 173 for the first case, here the order is reversed.
Basically, you use the SAME value, you only access it differently.
Why haven't I used htonl(), you might ask?
Well since performance is an issue, I think you're better off not using it because it seems like a waste of (precious?) cycles to call a function which ensures that bytes will be in some order, when they could have been in that order already on some systems, and when you could have modified your code to use a different order if that was not the case.
So instead, you could have checked the order before, and then used different loops (more code, but improved performance) based on what the result of the test was.
Also, if you don't know if your system uses a 2 or 4 byte int, you could check that before, and again use different loops based on the result.
Point is: you will have more code, but you will not waste cycles in a critical area, which is inside the loop.
If you still have performance issues, you could unroll the loop (duplicate code inside the loop, and reduce loop counts) as this will also save you a couple of cycles.
Note that using c[0], c[1] etc.. is equivalent to *(c), *(c+1) as far as C++ is concerned.
typedef union{
byte intAsBytes[4];
int int32;
}U_INTtoBYTE;

64bit shift problem

Why this code does not write 0 as a last element but 18446744073709551615?
(compiled with g++)
#include <iostream>
using namespace std;
int main(){
unsigned long long x = (unsigned long long) (-1);
for(int i=0; i <= 64; i++)
cout << i << " " << (x >> i) << endl;
cout << (x >> 64) << endl;
return 0;
}
When you shift a value by more bits than word size, it usually gets shifted by mod word-size. Basically, shifting it by 64 means shifting by 0 bits which is equal to no shifting at all. You shouldn't rely on this though as it's not defined by the standard and it can be different on different architectures.
Shifting a number a number of bits that is equal to or larger than its width is undefined behavior. You can only safely shift a 64-bit integer between 0 and 63 positions.
This warning from the compiler should be a hint:
"warning: right shift count >= width of type"
This results in undefined behavior:
http://sourcefrog.net/weblog/software/languages/C/bitshift.html
well, you are shifting one too many times. you are shifting from 0 to 64 inclusive which is a total of 65 times. You generally want:
for(int i=0; i < 64; i++)
....
You overflow the shift. If you've noticed, GCC even warns you:
warning: right shift count >= width of type
How come? You include 64 as a valid shift, which is an undefined behavior.
counting from 0 to 64 there are 65 numbers (0 included). 0 being the first bit (much like arrays).
#include <iostream>
using namespace std;
int main(){
unsigned long long x = (unsigned long long) (-1);
for(int i=0; i < 64; i++)
cout << i << " " << (x >> i) << endl;
cout << (x >> 63) << endl;
return 0;
}
Will produce the output you'd expect.
You can use:
static inline pack_t lshift_fix64(pack_t shiftee, short_idx_t shifter){
return (shiftee << shifter) & (-(shifter < 64));
}
for such a trick,
(-(shifter < 64)) == 0xffff ffff ffff ffff
if shifter < 64 and
(-(shifter < 64)) == 0x0
otherwise.
I get:
test.c:8: warning: right shift count >= width of type
so perhaps it's undefined behavior?
The bit pattern of -1 looks like 0xFFFFFFFFFFFFFFFF in hex, for 64 bit types. Thus if you print it as an unsigned variable you will see the largest value an unsigned 64 bit variable can hold, i.e. 18446744073709551615.
When bit shifting we don't care what a value means in this case, i.e. it doesn't matter if the variable is signed or unsigned it is treated the same way (shifting all bits one step to the right in this case).
Another trap for the unwary: I know this is an old thread, but I came here looking for help. I got caught out on a 64 bit machine using 1&LT;&LT;k when I meant 1L&LT;&LT;k; no help from the compiler in this case :(