visitor (0 QPoints)
  • FR
  • EN
  • NL
  • DE
  • ES
315 experts, 1193 registered users, 1659 questions already answered
European Experts Exchange, the very best site for high-quality IT solutions

New Improved Search!

 


05/10/2011 1h30 : Steve Jobs is dead, the father of Apple ][ is gone, we are all orphaned.

Languages :: Pascal :: Now about BMP


By: soendoro U.S.A.  Date: 16/06/2003 00:00:00  English  Points: 100 Status: Answered
Quality : Excellent
Me again :p
I have got source code like this from RAID :

Uses
Crt, graph, initgrp;

Type
ColorType = Record
Blue: Byte;
Green: Byte;
Red: Byte;
Reserved: Byte;
End;


Procedure LoadBMP(FileName: String);
Var
Color: Byte;
LoopVar: Word;
ReadVar: Byte;
BitsPerPlane: Word;
BitsPerPixel: Word;
LoopX: Word;
LoopY: Word;
BMPSizeX: Longint;
BMPSizeY: Longint;
BitCompression: Longint;
ColorsUsed: Longint;
ColorsImportant: Longint;
ImageSize: Longint;
ResX: Longint;
ResY: Longint;
Colors: array[0 .. 255] of ColorType;
FileVar: File;
Begin
assign(FileVar, FileName); reset(FileVar, 1); { Open BMP }

{ Now, lets load the header(1st Part) }
{ The first 18 bytes in the file }
{ have nothing to do with the graphic }
for LoopVar := 1 to 18 do blockread(FileVar, ReadVar, 1);

{ Read The next 4 Bytes(Longint) which is the width of the BMP }
blockread(FileVar, BMPSizeX, 4);

{ Read The next 4 Bytes(Longint) which is the length of the BMP }
blockread(FileVar, BMPSizeY, 4);

{ Read The next 2 Bytes(Word) for the number of Bits per plane }
blockread(FileVar, BitsPerPlane, 2);

{ Read The next 2 Bytes(Word) for the number of Bits per pixel }
{ Bits per pixel example }
{ Lets say the value is 8, that means 8 Bits per pixel, in other }
{ words that means 256 Colors }
{ 8-Bits is a Byte(256 Values) }
{ 16-Bits is a Word(65536 Values) }
{ 24-Bits is a Lonting(-2 Million to 2 Million, Roughly) }
blockread(FileVar, BitsPerPixel, 2);

{ Next, we read the bit compression Value, which is 4 Bytes(Longint) }
{ Don't worry about this, because most BMPS don't have bit compression }
blockread(FileVar, BitCompression, 4);

{ The next 4 Bytes(Longint) is the size of the BMP Graphic }
{ Size of Graphic should be BMPSizeX * BMPSizeY }
blockread(FileVar, ImageSize, 4);

{ The next 4 Bytes(Longint) is the resolution width }
{ Don't worry about this, because it has to do with windows }
{ I presume. }
blockread(FileVar, ResX, 4);

{ And the next 4 Bytes(Longint) is the resolution length }
{ also don't worry about it }
blockread(FileVar, ResY, 4);

{ The next 4 Bytes(Longint) is how many colors there are used }
{ in the BMP. }
blockread(FileVar, ColorsUsed, 4);

{ And the Next 4 Bytes(Longint) is how many colors are important }
{ This is the value that you are looking for of how many colors }
{ There are in the BMP }
blockread(FileVar, ColorsImportant, 4);

{ -Phew- done loading the Header. Now lets go on to loading the colors }
{ which is the 2nd Part }
{ The colors are saved like this: }
{ Color 0: }
{ Blue(Byte) }
{ Green(Byte) }
{ Red(Byte) }
{ Reserved(Byte) }
{ Color 1: }
{ Blue(Byte) }
{ Green(Byte) }
{ Red(Byte) }
{ Reserved(Byte) }
{ Color 2: }
{ Blue(Byte) }
{ Green(Byte) }
{ Red(Byte) }
{ Reserved(Byte) }
{ etc. }

{ Load Colors into Variable }
if ColorsImportant = 0 then ColorsImportant := 256;
for LoopVar := 0 to ColorsImportant - 1 do begin
blockread(FileVar, Colors[LoopVar], SizeOf(ColorType));
end;

{ To Palette the Colors Quickly, do this }
port[$3c8] := 0; { Start at color 0 }
for LoopVar := 0 to ColorsImportant - 1 do begin
port[$3c9] := Colors[LoopVar].Red div 4;
port[$3c9] := Colors[LoopVar].Green div 4;
port[$3c9] := Colors[LoopVar].Blue div 4;
end;
{ or you could set the palette using SetRGBPalette }
{ eep! }

{ Then, (Finally) we load the 3rd part, which is the graphic }
{ The graphic is saved funny, I don't know why the people who }
{ designed the BMP saved from left-right, down-up. Instead of }
{ left-right, up-down. I guess they wanted to be different }
{ Ok, lets draw it }
for LoopY := BMPSizeY downto 1 do begin
for LoopX := 1 to BMPSizeX do begin
blockread(FileVar, Color, 1);
putpixel(LoopX - 1, LoopY - 1, Color);
end;
end;

close(FileVar); { Close BMP }

{ If you have any questions, contact RAID }
End;

Var
driver,mode : integer;
Begin
{Example}
driver:=detect;
SiapkanGrafik(driver,mode);
LoadBMP('d:\tesis\artikel\bmp\program\bmp256.bmp');
readln;
closegraph;
End.


I have some questions about source code above,
1. { The first 18 bytes in the file }
{ have nothing to do with the graphic }
for LoopVar := 1 to 18 do blockread(FileVar, ReadVar, 1);
What does "have nothing to do with the graphic" mean?

2. { The next 4 Bytes(Longint) is how many colors there are used }
{ in the BMP. }
blockread(FileVar, ColorsUsed, 4);
If i use image with one color (example : red), why is the number of colorsused=0?

3. { And the Next 4 Bytes(Longint) is how many colors are important }
{ This is the value that you are looking for of how many colors }
{ There are in the BMP }
blockread(FileVar, ColorsImportant, 4);
If i use image with one color (example : red), why is the number of colorsImportant=0 too?

4. if ColorsImportant = 0 then ColorsImportant := 256;
What does it mean?

5.{ To Palette the Colors Quickly, do this }
port[$3c8] := 0; { Start at color 0 }
for LoopVar := 0 to ColorsImportant - 1 do begin
port[$3c9] := Colors[LoopVar].Red div 4;
port[$3c9] := Colors[LoopVar].Green div 4;
port[$3c9] := Colors[LoopVar].Blue div 4;
end;
What are the functions of palette ?
What are the functions of source code above?

6. I have tried that source code for BMP 256, and it worked. but when I tried it for BMP 24 bit and BMP 16 bit, it did not work.
How could it be? And what should be changed so that it works? If you have source code that works for BMP 24 bit and BMP 16 bit, please give me that source code.

I will give you 100 points for all questions and the source code I ask!

Thanks,
Soen.

By: VGR Date: 16/06/2003 01:16:00 English  Type : Answer
1) some kind of header or padding I suppose
2) I suspect ColorsUsed=0 means in fact one colour
3) idem
4) it means apparently that he wants the BMP in 256 colours anyway [or it explains (2) and (3) : 0 means 256]
5) apparently, sending on port $03C8 the number of colours, then sequentially each colour component (RGB) to port $03C9 : never saw this, but I suspect it's direct video memory access of some kind
Palette is explicit : imagine a palette of 10 colours chosen between 256 available (by example)... You store only 10 colour codes and not the 256 ones. Now imagine the power of palettes with 16 M colours available and only 2 used ;-)

6) yes, clearly. The code is done for BMP256
I has to be adapted
By: digitaltree Date: 16/06/2003 02:37:00 English  Type : Assist
The actual format for BitMap files varies. The 24 and 16 bit versions start off with a TBitmapFileHeader followed by palette information and then the actual bitmap.

TBitmapFileHeader = record
bfType : Word;
bfSize : Longint;
bfReserved1 : Word;
bfReserved2 : Word;
bfOffBits : Longint;
end;

bfType = "BM"
bfSize = size of the file in 4-byte words
bfOffbits = how many bytes from file start is the actual bitmap.

Then follows the TBitmapInfo record

record
bmiHeader : TBitmapInfoHeader;
bmiColors : array[0..x] of TRGBQuad;
end;

The bmiColors is the palette array whose length depends on the number of colors
bmiHeader is :

record
biSize : Longint;
biWidth : Longint;
biHeight : Longint;
biPlanes : Word;
biBitcount : Word;
biCompression : Longint;
biSizeImage : Longint;
biXPelsPerMeter : Longint;
biYPelsPerMeter : Longint;
biClrUsed : Longint;
biClrImportant : Longint;
end;

<A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp</a>

<A HREF="http://prem-01.portlandpremium.co.uk/p1-28/swagcode/GRAPHICS/0171.PAS.html">http://prem-01.portlandpremium.co.uk/p1-28/swagcode/GRAPHICS/0171.PAS.html</a>
By: sumotimor Date: 16/06/2003 09:12:00 English  Type : Assist
Well here's a more explanatory doc about .bmp

The .bmp file format (sometimes also saved as .dib) is the standard for a Windows 3.0 or later DIB(device independent bitmap) file. It may use compression (though I never came across a compressed .bmp-file) and is (by itself) not capable of storing animation. However, you can animate a bitmap using different methods but you have to write the code which performs the animation. There are different ways to compress a .bmp-file, but I won't explain them here because they are so rarely used. The image data itself can either contain pointers to entries in a color table or literal RGB values (this is explained later).

Basic structure:

A .bmp file contains of the following data structures:
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD aColors[];
BYTE aBitmapBits[];

bmfh contains some information about the bitmap file (about the file, not about the bitmap itself). bmih contains information about the bitmap such as size, colors,... The aColors array contains a color table. The rest is the image data, which format is specified by the bmih structure.



Exact structure:

The following tables give exact information about the data structures and also contain the settings for a bitmap with the following dimensions: size 100x100, 256 colors, no compression. The start-value is the position of the byte in the file at which the explained data element of the structure starts, the size-value contains the nuber of bytes used by this data element, the name-value is the name assigned to this data element by the Microsoft API documentation. Stdvalue stands for standard value. There actually is no such a thing as a standard value but this is the value Paint assigns to the data element if using the bitmap dimensions specified above (100x100x256). The meaning-column gives a short explanation of the purpose of this data element.

The BITMAPFILEHEADER:

start size name stdvalue purpose
1 2 bfType 19778 must always be set to 'BM' to declare that this is a .bmp-file.
3 4 bfSize ?? specifies the size of the file in bytes.
7 2 bfReserved1 0 must always be set to zero.
9 2 bfReserved2 0 must always be set to zero.
11 4 bfOffBits 1078 specifies the offset from the beginning of the file to the bitmap data.


The BITMAPINFOHEADER:

start size name stdvalue purpose
15 4 biSize 40 specifies the size of the BITMAPINFOHEADER structure, in bytes.
19 4 biWidth 100 specifies the width of the image, in pixels.
23 4 biHeight 100 specifies the height of the image, in pixels.
27 2 biPlanes 1 specifies the number of planes of the target device, must be set to zero.
29 2 biBitCount 8 specifies the number of bits per pixel.
31 4 biCompression 0 Specifies the type of compression, usually set to zero (no compression).
35 4 biSizeImage 0 specifies the size of the image data, in bytes. If there is no compression,
it is valid to set this member to zero.
39 4 biXPelsPMtr 0 specifies the the horizontal pixels per meter on the designated targer device,
usually set to zero.
43 4 biYPelsPMtr 0 specifies the the vertical pixels per meter on the designated targer device,
usually set to zero.
47 4 biClrUsed 0 specifies the number of colors used in the bitmap, if set to zero the number of
colors is calculated using the biBitCount member.
51 4 biClrImportant 0 specifies the number of color that are 'important' for the bitmap, if set to zero,
all colors are important.

Note that biBitCount actually specifies the color resolution of the bitmap. The possible values are: 1 (black/white); 4 (16 colors); 8 (256 colors); 24 (16.7 million colors). The biBitCount data element also decides if there is a color table in the file and how it looks like. In 1-bit mode the color table has to contain 2 entries (usually white and black). If a bit in the image data is clear, it points to the first palette entry. If the bit is set, it points to the second. In 4-bit mode the color table must contain 16 colors. Every byte in the image data represents two pixels. The byte is split into the higher 4 bits and the lower 4 bits and each value of them points to a palette entry. There are also standard colors for 16 colors mode (16 out of Windows 20 reserved colors (without the entries 8, 9, 246, 247)). Note that you do not need to use this standard colors if the bitmap is to be displayed on a screen which support 256 colors or more, however (nearly) every 4-bit image uses this standard colors. In 8-bit mode every byte represents a pixel. The value points to an entry in the color table which contains 256 entries (for details see Palettes in Windows. In 24-bit mode three bytes represent one pixel. The first byte represents the red part, the second the green and the third the blue part. There is no need for a palette because every pixel contains a literal RGB-value, so the palette is omitted.

The RGBQUAD array:

The following table shows a single RGBQUAD structure:
start size name stdvalue purpose
1 1 rgbBlue - specifies the blue part of the color.
2 1 rgbGreen - specifies the green part of the color.
3 1 rgbRed - specifies the red part of the color.
4 1 rgbReserved - must always be set to zero.

Note that the term palette does not refer to a RGBQUAD array, which is called color table instead. Also note that, in a color table (RGBQUAD), the specification for a color starts with the blue byte. In a palette a color always starts with the red byte. There is no simple way to map the whole color table into a LOGPALETTE structure, which you will need to display the bitmap. You will have to write a function that copies byte after byte.


The pixel data

It depens on the BITMAPINFOHEADER structure how the pixel data is to be interpreted (see above).
It is important to know that the rows of a DIB are stored upside down. That means that the uppest row which appears on the screen actually is the lowest row stored in the bitmap, a short example:
Another important thing is that the number of bytes in one row must always be adjusted to fit into the border of a multiple of four. You simply append zero bytes until the number of bytes in a row reaches a multiple of four, an example:

6 bytes that represent a row in the bitmap: A0 37 F2 8B 31 C4
must be saved as: A0 37 F2 8B 31 C4 00 00

to reach the multiple of four which is the next higher after six (eight). If you keep these few rules in mind while working with .bmp files it should be easy for you, to master it.

By: CabuzelTh Date: 21/06/2003 18:37:00 English  Type : Assist
5.{ To Palette the Colors Quickly, do this }
port[$3c8] := 0; { Start at color 0 }
for LoopVar := 0 to ColorsImportant - 1 do begin
port[$3c9] := Colors[LoopVar].Red div 4;
port[$3c9] := Colors[LoopVar].Green div 4;
port[$3c9] := Colors[LoopVar].Blue div 4;
end;
What are the functions of palette ?
What are the functions of source code above?

This part of the code if from the good old DOS day where you need to send to the DAC (Digital Analog Converter) of the video card the 256 colors palette of the VGA mode, but this mode don't have true color but just 262144 colors hence the 'div 4'. Now if you work in true color (16M), you need to store the palette in a array like MyPalette [LoopVar] := Colors[LoopVar].Red + Colors[LoopVar].Green * 256 + Colors[LoopVar].Blue * 256 * 256 And when you need to do a putPixel do it like putpixel(LoopX - 1, LoopY - 1, MyPalette [Color]); if you graphic library support true color.

Do register to be able to answer

EContact
browser fav
page generated in 100.891830 milliseconds

Why Google AdSense ads ?

compteur
 Ranking-Hits PageRank for this page