The Chief wrote:
Please send an example of such code.
<code snippet> bmpinfo = record (*BMP header*) b1, b2 : char; size : integer; reserved : integer; offset : integer; headersize : integer; width : integer; height : integer; planes : shortword; bpp : shortword; compression : integer; comprsize : integer; horresolution : integer; verresolution : integer; usedcolors : integer; importantcol : integer; end; ... var info : bmpinfo; source : file of bmpinfo; ... begin ... assign(source, dir+fname+ext); reset(source); read(source, info); close(source); </code snippet>
This code reads first two bytes ok (magic BM), then skips two byes (?) and from info.size all values are shifted two bytes. I have tried to use b1, b2 : byte or b1b2 : shortword or b1b2 : shortint - no way. Also I have changed source : file of byte and used blockread(source, info, 54) - no way, the same story. The only solution I found with GPC (this code works fine with FPC, VP) is to remove first two bytes out from the record, then open source as file of bytes and:
blockread(image, magic, 2); blockread(image, info, 52);
Peter.
__________________________________ Do you Yahoo!? Yahoo! Finance: Get your refund fast by filing online. http://taxes.yahoo.com/filing.html
Peter Norton wrote:
The Chief wrote:
Please send an example of such code.
<code snippet> bmpinfo = record (*BMP header*) b1, b2 : char; size : integer;
... snip ...
This code reads first two bytes ok (magic BM), then skips two byes (?) and from info.size all values are shifted two bytes.
Of course it does. char requires one byte, and no alignment. An integer requires 4 bytes, and must be aligned at a multiple of 4. Thus there are two packing bytes between b2 and size. You should define size as ARRAY[0..3] OF char; and create your own code to convert that into an integer. This also controls endianess in the file, which is independant of the executing system.
Looking at the remainder of the record, you would be better off creating the type
bmpint = ARRAY[0..3] OF char;
and replacing the integer types in bmpinfo by bmpint. Then you can create routines to extract (and maybe store) between bmpint and integer types.
You MIGHT get away with defining bmpinfo as a PACKED record, but that is not portable and could be broken at any time by a compiler revision.
On 7 Feb 2004 at 21:25, Peter Norton wrote:
The Chief wrote:
Please send an example of such code.
<code snippet> bmpinfo = record (*BMP header*)
[...] You will need to pack the record (bearing in mind CBF's warning about portability, etc.). Using "packed" may not always be portable. The following solution may or may not be portable (Frank can tell us):
type {$ifdef __GPC__}{$pack-struct, maximum-field-alignment 8} {$endif} bmpinfo = record (*BMP header*) b1, b2 : char; size : integer; reserved : integer; offset : integer; headersize : integer; width : integer; height : integer; planes : shortword; bpp : shortword; compression : integer; comprsize : integer; horresolution : integer; verresolution : integer; usedcolors : integer; importantcol : integer; end; {$ifdef __GPC__}{$no-pack-struct, maximum-field-alignment 0}{$endif}
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
On 7 Feb 2004 at 21:25, Peter Norton wrote:
The Chief wrote:
Please send an example of such code.
<code snippet> bmpinfo = record (*BMP header*)
[...] You will need to pack the record (bearing in mind CBF's warning about portability, etc.). Using "packed" may not always be portable. The following solution may or may not be portable (Frank can tell us):
type {$ifdef __GPC__}{$pack-struct, maximum-field-alignment 8} {$endif} bmpinfo = record (*BMP header*) b1, b2 : char; size : integer; reserved : integer; offset : integer; headersize : integer; width : integer; height : integer; planes : shortword; bpp : shortword; compression : integer; comprsize : integer; horresolution : integer; verresolution : integer; usedcolors : integer; importantcol : integer; end; {$ifdef __GPC__}{$no-pack-struct, maximum-field-alignment 0}{$endif}
To be portable, you cannot use types like `Integer' and `ShortWord' which can have different sizes. You can define your own types to be `Integer attribute (Size = 32)', `Cardinal attribute (Size = 16)' etc. Also you have to do explicit endianness conversions (see `ConvertFromLittleEndian' etc. in gpc.pas).
Frank
Frank Heckenbach wrote:
... snip ...
To be portable, you cannot use types like `Integer' and `ShortWord' which can have different sizes. You can define your own types to be `Integer attribute (Size = 32)', `Cardinal attribute (Size = 16)' etc. Also you have to do explicit endianness conversions (see `ConvertFromLittleEndian' etc. in gpc.pas).
Let's be clear that you mean "portable over gpc installations". This will not ensure generic portability over any ISO standard. In a way such may be useful, in that any transport to an ISO system should flag errors on those constructs and point out the area to be considered.
CBFalconer wrote:
Frank Heckenbach wrote:
... snip ...
To be portable, you cannot use types like `Integer' and `ShortWord' which can have different sizes. You can define your own types to be `Integer attribute (Size = 32)', `Cardinal attribute (Size = 16)' etc. Also you have to do explicit endianness conversions (see `ConvertFromLittleEndian' etc. in gpc.pas).
Let's be clear that you mean "portable over gpc installations". This will not ensure generic portability over any ISO standard.
Sure. Strictly ISO, anything involving external files is unportable -- not even the external representation of `Text' files is specified, also reading single characters from a `file of Char' and reassembling the integers is not guaranteed (by the standard) to work as expected (though it may have a higher chance of working with another ISO Pascal compiler).
In a way such may be useful, in that any transport to an ISO system should flag errors on those constructs and point out the area to be considered.
That's right. Whereas using ISO means and relying on semantics that are not guaranteed would fail silently ...
Frank