Convert a 4-Bytes binary file 1024x1024 (.dat) to a matrix floating (.txt)

Hello Everyone!
I am in my master degree starting in image processing. I have a .dat 4-bytes 1024x1024 binary file, I need to read this aiming multiply it after for a image 1024x1024. I decided to convert the .dat file into a matrix 1024x1024 of floating points before the multiplication. I am getting some troubles. Someone could help me with this?
below my current code:

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

const int SRTM_SIZE = 1024;
float height[SRTM_SIZE][SRTM_SIZE] = { {0},{0} };

int main() {

ifstream file("uniformity_map_1024x1024.dat", ios::in | ios::binary);

if (!file) {
cout << "Error opening file!" << endl;
return -1;
}

unsigned char buffer[4];

for (int i = 0; i < SRTM_SIZE; ++i) {

for (int j = 0; j < SRTM_SIZE; ++j) {

if (!file.read(reinterpret_cast<char*>(buffer), sizeof(buffer))) {

cout << "Error reading file!" << endl;

return -1;
}

height[i][j] = (buffer[0] << 8) | buffer[1];

}
}

ofstream File;

File.open("C:/Users/Home/OneDrive/Desktop/READDAT/READDAT/READDAT/output.txt");

for (int x = 0; x < SRTM_SIZE; x++)
{

for (int y = 0; y < SRTM_SIZE; y++)
{/

File << height[x][y]<< " ";

}

File << endl;
}

File.close();
return 0;
}


I convert to txt, nevertheless the matrix is not a float. I do not known how implement a float value to fill the matrix height[i][j]=...
First please use code tags when posting code.

Second why are you trying to read the file as some kind of unsigned character instead of a float?

I really doubt that file.read(reinterpret_cast<char*>(buffer), sizeof(buffer)) is really doing anything close as to what you seem to expect. Perhaps if "buffer" were a single float you may get closer. But this is only a guess since I have no idea about how your input file was written, and how that file was formatted.
Last edited on
When posting code, remember to put it in "code tags" to preserve indentation, like this:

[code]
your code goes here
[/code]

As long as the 4-byte values in the binary file actually represent float data and they have the same endianess (byte order) as your system and they are stored in row-major order, then something like the following.
Note that you can read the bytes directly into a float variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <fstream>
using namespace std;

const int SRTM_SIZE = 1024;
const char* const InputFile = "uniformity_map_1024x1024.dat";
const char* const OutputFile
    = "C:/Users/Home/OneDrive/Desktop/READDAT/READDAT/READDAT/output.txt";

int main() {
    float height[SRTM_SIZE][SRTM_SIZE] = {{0}};

    ifstream in(InputFile, in.binary);
    if (!in) {
        cout << "Error opening input file\n";
        return 1;
    }

    for (int y = 0; y < SRTM_SIZE; ++y) {      // note that the row loop head come first
        for (int x = 0; x < SRTM_SIZE; ++x) {  // then columns
            if (!in.read(reinterpret_cast<char*>(&height[y][x]), sizeof f)) {
                cout << "Error reading file!\n";
                return 1;
            }
        }
    }

    ofstream out(OutputFile);
    if (!out) {
        cout << "Error opening output file\n";
        return 1;
    }
    for (int y = 0; y < SRTM_SIZE; y++)
    {
        for (int x = 0; x < SRTM_SIZE; x++)
            out << height[y][x]<< ' ';
        out << '\n';
    }
}

I don't see the point in writing it to a text file, though.
Last edited on
I really apologize for the mistakes in publishing the question. Thank you so much for the answers, they are helping a lot.

dutch thank you so much for the code. I've been made so changes due the errors in the compiler. I arrive at the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <fstream>
using namespace std;

const int SRTM_SIZE = 1024;
const char* const InputFile = "uniformity_map_1024x1024.dat";
const char* const OutputFile = "C:/Users/Home/OneDrive/Desktop/READDAT/READDAT/READDAT/output.txt";

int main() {
    float height[SRTM_SIZE][SRTM_SIZE] = { {0},{0} };

    ifstream in(InputFile, ios::binary);
    if (!in) {
        cout << "Error opening input file\n";
        return 1;
    }

    for (int y = 0; y < SRTM_SIZE; ++y) {      // note that rows come first
        for (int x = 0; x < SRTM_SIZE; ++x) {  // then columns
            if (!in.read(reinterpret_cast<char*>(&height[y][x]), sizeof (height[y][x]))) {
                cout << "Error reading file!\n";
                return 1;
            }
        }
    }

    ofstream out(OutputFile);
    if (!out) {
        cout << "Error opening output file\n";
        return 1;
    }
    for (int y = 0; y < SRTM_SIZE; y++)
    {
        for (int x = 0; x < SRTM_SIZE; x++)
            out << height[y][x] << ' ';
        out << '\n';
    }
}


Nevertheless, the IDE shows the warning C6262, which is about exceed the analyze:stacksize.
I see I forgot to change the f! I had used a separate f variable originally.
Instead of sizeof height[y][x] it may be better to say sizeof height[0][0].
Note that you don't actually need the parentheses if you are using a variable instead of a type.

To fix your current error, put this up above (outside) of main, like you had it before:

 
float height[SRTM_SIZE][SRTM_SIZE] = {{0}};

Note that you don't need to say = { {0},{0} }.
> float height[SRTM_SIZE][SRTM_SIZE] = { {0},{0} };
Yeah, 1024*1024*sizeof(float) is 4MB.
Probably your default stack size is 1MB.

Your short-term fix is.
 
static float height[SRTM_SIZE][SRTM_SIZE] = { {0},{0} };
I just came back to edit my answer to suggest what salem has just said.
I would go with that.
So leave it in main, but put the keyword static in front of it.
But it's still better to say = {{0}} since the second {0} does nothing.
I only have a thing to say:

Thank you so much Dutch, Salem C and jlb.

Perfect functional as I was looking for, and I learned I lot if any comment/answer.
I will let here the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Thank you so much.
#include <iostream>
#include <fstream>
using namespace std;

const int SRTM_SIZE = 1024;
const char* const InputFile = "uniformity_map_1024x1024.dat";
const char* const OutputFile = "C:/Users/Home/OneDrive/Desktop/READDAT/READDAT/READDAT/output.txt";
static float height[SRTM_SIZE][SRTM_SIZE] = { {0} };

int main() {
    
    ifstream in(InputFile, ios::binary); 
    if (!in) {
        cout << "Error opening input file\n";
        return 1;
    }

    for (int y = 0; y < SRTM_SIZE; ++y) {      // note that rows come first
        for (int x = 0; x < SRTM_SIZE; ++x) {  // then columns
            if (!in.read(reinterpret_cast<char*>(&height[y][x]), sizeof height[0][0])) {
                cout << "Error reading file!\n";
                return 1;
            }
        }
    }

    ofstream out(OutputFile);
    if (!out) {
        cout << "Error opening output file\n";
        return 1;
    }
    for (int y = 0; y < SRTM_SIZE; y++)
    {
        for (int x = 0; x < SRTM_SIZE; x++)
            out << height[y][x] << ",";
        out << '\n';
    }
}


Thank you.
You should move height back inside main. Either you use the word static and have it inside main, or you don't use the word static and leave it outside (although you can also use the word static outside main, but that just makes it inaccessible from another code file which is not needed in your case). Either way it is kept off of the stack. I suggest moving it back inside main with the static keyword.
You right. Done!
Topic archived. No new replies allowed.