Toon posts:

[c++] Wegschrijven structures

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleempje met het wegschrijfen van mijn structures naar een bestand

Als ik de volgende 2 structures wegschrijf heb ik meer data in mijn bestand dan dat ik wegschrijf 8)7, maar als ik gebruik maak van de structures in de windows.h dan werkt het wel goed |:( terwijl de structures hetzelfde zijn. Oh en ik maak gebruik van microsoft visual studio 2003.

C++:
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
typedef struct tagBITMAPFILEHEADER 
{
    unsigned short  bfType;
    unsigned long   bfSize;
    unsigned short  bfReserved1;
    unsigned short  bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER; 

typedef struct tagBITMAPINFOHEADER 
{   
    unsigned long   biSize;
    long        biWidth;
    long        biHeight;
    unsigned short  biPlanes;
    unsigned short       biBitCount;
    unsigned long        biCompression;
    unsigned long        biSizeImage;
    long        biXPelsPerMeter;
    long        biYPelsPerMeter;
    unsigned long        biClrUsed;
    unsigned long        biClrImportant;
} BITMAPINFOHEADER; 

BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;

bmpfile.write((char*)&bmfh, sizeof(bmfh));
bmpfile.write((char*)&bmih, sizeof(bmih)); 

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Ik snap geen bal van je vraag. Hoezo heb je meer data dan je wegschrijft? Dat kan helemaal niet :P

* curry684 hint subtiel naar P&W FAQ - De "quickstart" en de editknop ;)

[ Voor 47% gewijzigd door curry684 op 03-12-2004 14:39 ]

Professionele website nodig?


Verwijderd

Topicstarter
Toch is het zo als ik mijn output bmp met de hex editor bekijk heb ik 2 bytes teveel. vervang ik nu mijn bitmapio.h door de windows.h dan gaat het wel goed terwijl de structures hetzelfde zijn.

hieronder een snel voorbeeld van de totale code

C++:
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
bitmapio.h

typedef struct tagBITMAPFILEHEADER 
{
    unsigned short  bfType;
    unsigned long   bfSize;
    unsigned short  bfReserved1;
    unsigned short  bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER 
{   
    unsigned long   biSize;
    long        biWidth;
    long        biHeight;
    unsigned short  biPlanes;
    unsigned short       biBitCount;
    unsigned long        biCompression;
    unsigned long        biSizeImage;
    long        biXPelsPerMeter;
    long        biYPelsPerMeter;
    unsigned long        biClrUsed;
    unsigned long        biClrImportant;
} BITMAPINFOHEADER;


main.cpp

#include <iostream>
#include <fstream>
#include "BitmapIO.h" 


using namespace std;

int main()
{
    ofstream bmpfile("bitmap.bmp",ofstream::binary);
    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER bmih;
    int width = 4;
    int height = 4;
    unsigned char x[60] = {0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff};
    unsigned char *Buffer = x;
    long paddedsize = sizeof(x);
    
    // fill the fileheader with data
    bmfh.bfType = 0x4d42;       // 0x4d42 = 'BM'
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
    bmfh.bfOffBits = 0x36;          
    // fill the bmihheader
    
    bmih.biSize = sizeof(BITMAPINFOHEADER);
    bmih.biWidth = width;
    bmih.biHeight = height;
    bmih.biPlanes = 1;          // we only have one bitplane
    bmih.biBitCount = 24;       // RGB mode is 24 bits
    bmih.biCompression = 0; 
    bmih.biSizeImage = 0;       // can be 0 for 24 bit images
    bmih.biXPelsPerMeter = 0x0ec4;     // paint and PSP use this values
    bmih.biYPelsPerMeter = 0x0ec4;     
    bmih.biClrUsed = 0;          
    bmih.biClrImportant = 0;    // all colors are important

    bmpfile.write((char*)&bmfh, sizeof(bmfh));
    bmpfile.write((char*)&bmih, sizeof(bmih));
                bmpfile.write((char*)Buffer, paddedsize); 

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Kijk eens in de help bij 'structure packing size' ;)

Professionele website nodig?


Verwijderd

Topicstarter
Ik ben nog een beetje n00b met betrekking tot c++ ik zie dat het waarschijnlijk kan oplossen met pragma pack(n)

maar kan iemand mij uitleggen hoe dit precies werkt?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Als je kijkt naar de bitmapfileheader:
C++:
1
2
3
4
5
6
7
8
typedef struct tagBITMAPFILEHEADER 
{
    unsigned short  bfType;
    unsigned long   bfSize;
    unsigned short  bfReserved1;
    unsigned short  bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER; 

Deze is 2 longs van 4 bytes en 3 shorts van 2 bytes groot, dus theoretisch 14 bytes. Echter, hier komt de packing size kijken: "The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller. " De default packing size van 8 heb je hier geen last van op zich, behalve dat het inhoudt dat de 2e member bfSize een long groot is en dus oftewel op een veelvoud van 4 of van 8 komt te staan, whichever is smaller, dus 4. Omdat er enkel een short van 2 bytes voor staat worden daar dus 2 'padding bytes' toegevoegd.

Je lost dit dus als volgt op:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
#pragma pack(push, 1)

typedef struct tagBITMAPFILEHEADER 
{
    unsigned short  bfType;
    unsigned long   bfSize;
    unsigned short  bfReserved1;
    unsigned short  bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER; 

#pragma pack(pop)

Professionele website nodig?


Verwijderd

Topicstarter
Thx de bitmapheader wordt nu inderdaad herkent als een juiste bitmap _/-\o_
en het is me een beetje duidelijker hoe packing werkt B)

topic kan gesloten worden.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Waarom zou het op slot moeten, nu kunnen er tenminste nog mensen met andere tips en inzichten komen :)

We sluiten topics hier alleen als ze policies overtreden of anderszins zinloos zijn :)

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Misschien meteen erbij zeggen dat dit allemaal Visual Studio 32-bitsspecifiek is?

Of suggereer
C++:
1
2
3
4
5
6
7
8
9
10
11
12
struct BITMAPFILEHEADER  
{ 
    unsigned short  bfType; 
    unsigned short  bfSizeHigh; 
    unsigned short  bfSizeLow; 
    unsigned long   getSize() const { return bfSizeLow + (bfSizeHigh<<16UL); }
    unsigned short  bfReserved1; 
    unsigned short  bfReserved2; 
    unsigned short  bfOffBitsHigh;
    unsigned short  bfOffBitsLow;
    unsigned long   getOffBits() const { return bfSizeLow + (bfOffBitsLow<<16UL); }
} ;


PS. typedef struct x {...} is C, geen C++. windows.h is ook voor C, vandaar. In je eigen C++ code moet je dat niet doen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Overigens zijn de bitmap structures van windows.h er toch ook gewoon op gemaakt dat ze 1:1 vertalen naar een bmp file?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

.oisyn schreef op vrijdag 03 december 2004 @ 19:17:
Overigens zijn de bitmap structures van windows.h er toch ook gewoon op gemaakt dat ze 1:1 vertalen naar een bmp file?
Ja ik snap ook niet waarom ie herdefinieert eilijk :P

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
.oisyn schreef op vrijdag 03 december 2004 @ 19:17:
Overigens zijn de bitmap structures van windows.h er toch ook gewoon op gemaakt dat ze 1:1 vertalen naar een bmp file?
Alleen op een little endian machine (en dat is Windows natuurlijk) en met de Microsoft compiler dus. Maar ze zullen inderdaad niet voor niets gepacked zijn.

[ Voor 43% gewijzigd door Soultaker op 03-12-2004 19:38 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Gezien het feit dat het BMP-formaat van OS/2 gejat is zal het niet Windows-only zijn ;)

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Dat zei ik ook niet. Ik zeg alleen dat je zo'n packed struct niet op alle architecturen werkt (alleen toevallig wel op die waar DOS, Windows en OS/2 op draait). Behalve met endianess zit je ook met architecturen waar je geen unaligned data kan fetchen enzo (maar in theorie kan de compiler dat afhandelen, bedenk ik me nu, als je er vanuit gaat dat de structure zelf altijd aligned begint).

[ Voor 24% gewijzigd door Soultaker op 03-12-2004 19:45 ]

Pagina: 1