Reading binary data issues

Hi y'all,

I'm trying to read a Bitmap file in the C++ way. This file has two headers (a file header and an image header). I succeed to read both of them. But now I'm trying to read data, the same way I red the headers, I fail. When I use the C way to read binary files everything is fine. Here is the codes:
im_bmp.cpp
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
#include <iostream>
#include <fstream>
#include "im_bmp.h"

using namespace std;

void read_bmp(const char* f)
{
    pict I; unsigned char pix[3]; px pxl; int i = 0;

    FILE* fl = fopen(f, "rb");
    fread(&I, sizeof(pict), 1, fl);
    printf("%d\n%d\n",I.im.bpp,I.fhd.f_off); // A test to show the bit per pixel and the offset(where image data begin)

    while(i<2)
    {
        fread(&pix,1,3,fl);
        printf("%d %d %d ",pix[2],pix[1],pix[0]); // A test to show the first two pixels
        i++;
    }

// The code below read binary files in the C++ way
/*
    ifstream ifs;
    ifs.open(f,ios::binary);
    ifs.read((char *)&I,sizeof(pict));
    cout << I.im.bpp << endl;           // It works here. It's headers
    ifs.read((char *)&pxl,sizeof(pxl));
    cout << pxl.r << endl;              // It fails here to read the first pixel
*/
    fclose(fl);
}


im_bmp.h
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#ifndef IM_BMP_H_INCLUDED
#define IM_BMP_H_INCLUDED

#include <iostream>
#include <fstream>
#pragma pack(1)

using namespace std;
/*
typedef int int32;
typedef short int16;

typedef struct px
{
    unsigned char r, g, b;
} px;

typedef struct pict
{
    int w, h;
    px dt;
} pict;

struct im_hd
{
    int32 hd_sz;
    int32 wdt;
    int32 hgt;
    int16 im_pl;
    int16 bpp;
    int32 cmp;
    int32 im_sz;
    int32 hr;
    int32 vr;
    int32 clr;
    int32 mclr;
};

struct fl_hd
{
    char hd[2];
    int32 sz;
    int32 rsv;
    int32 f_off;
    im_hd im;
};
*/

struct im_hd
{
    int hd_sz;
    int wdt;
    int hgt;
    short im_pl;
    short bpp;
    int cmp;
    int im_sz;
    int hr;
    int vr;
    int clr;
    int mclr;
};

struct fl_hd
{
    char hd[2];
    int sz;
    int rsv;
    int f_off;
    //im_hd im;
};

typedef struct px
{
    unsigned char r, g, b;
} px;

typedef struct pict
{
    fl_hd fhd;
    im_hd im;
    //int w, h;
    //px* dt;
} pict;

void read_bmp(const char* f);

#endif // IM_BMP_H_INCLUDED 


Please is anyone have any idea of what's wrong with the C++ way of reading that file?
Thanks in advance.
Last edited on
when you use #pragma pack in a header you should also use push and pop. See:

http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx


what's wrong with the first pixel?
When I try to display the first pixel, I ain't got nothing, blank!
If I try to display the second pixel, I get a blank for blue, a smiley for green and a blank for red.
it probably doesn't fail to read the data it fails to show them.

try this:

cout << (int) pxl.r << endl; // Note the cast

to show the values and not the characters (like the type implies)


on line 18 in im_bmp.cpp you treat char (%c) as int (%d). This accidentally works. See:

http://www.cplusplus.com/reference/cstdio/printf/

for the correct format


the stream classes are usually used for formatted input. For binary data you may stick to fopen/fread
Hi,

I found a good explanation on another website. For those who have the same problem, cout interprets my pixel data as a char instead of an int. So I had to cast my pixel data from char to int to display them correctly.

1
2
ifs.read((char *)&pxl,sizeof(pxl));
cout << static_cast<int>(pxl.r) << " " << static_cast<int>(pxl.g) << " " << static_cast<int>(pxl.b) << endl;


I can either use (int) or static_cast<int>

Thanks!
Topic archived. No new replies allowed.