Display 8-bit, 256-color BMP bitmap in DOS

Source: Internet
Author: User
Tags bmp image ultraedit

 

# Include <stdio. h>

# Include <stdlib. h> // exit ()

# Include <dos. h> // in86 ()

# Include <bios. h> // close ()

# Include <fcntl. h> // open ()

# Include <io. h> // lseek (), read ()

 

# Include <conio. h> // outp (), getch ()

 

# Define VGA256 0x13 // 320*200 256 color display mode

# Define TEXT_MODE 0x03 // 80x25 16-color text mode

 

# Define SCREEN_HEIGHT 200 // Image Height, in pixels

# Define SCREEN_WIDTH 320 // image width, in pixels

 

# Define PALETTE_MASK 0x3c6 // mask register port in the palette. Put 0xff to access your desired register through the color palette index registers 0x3c7 and 0x3c8

# Define PALETTE_REGISTER_RD 0x3c7 // read color register Port

# Define PALETTE_REGISTER_WR 0x3c8 // write color register Port

# Define PALETTE_DATA 0x3c9 // palette data register Port

 

Unsigned char far * video_buffer = (char far *) 0xA0000000L;

 

Typedef struct BMP _file

{

Unsigned int bfType; // The constant value here is 0x4D42, with the ASCII character 'bm'

Unsigned long bfSize; // file size, in bytes

Unsigned int Reserved1; // standby, must be 0

Unsigned int reserved2; // standby, must be 0

Unsigned long bfOffset; // The position offset of the data area in the file, in bytes

} Bitmapfile; // File Header structure, 14 bytes

 

Typedef struct BMP _info

{

Unsigned long biSize; // the size of the bitmap information header, the number of bytes occupied by this structure

Unsigned long biWidth; // image width, in pixels

Unsigned long biHeight; // Image Height, in pixels

Unsigned int biPlanes; // bit plane tree. The level of the target device, which must be 1

Unsigned int biBitCount; // The number of digits in pixels, indicating the number of digits in the color of the BMP image. It must be 1 (two-color), 4 (16 colors), 8 (256 colors ), 24 Bitmap (true color), 32 bitmap

Unsigned long biCompression; // Image Compression attribute, which must be: 0 (not compressed), 1 (BI_RLE8 compression type), or 2 (BI_RLE4 compression type)

Unsigned long biSizeImage; // indicates the size of the image data area. If biBompression is equal to 0, the value here can be omitted.

Unsigned long biXpolsPerMeter; // horizontal resolution, number of workers per meter, can be omitted

Unsigned long biYpelsPerMeter; // vertical resolution, number of bytes per meter, can be omitted

Unsigned long biClrUsed; // indicates the number of color index tables used. Generally, the biBitCount attribute is used only when it is less than 16. If it is equal to 0, there are 2 ^ itcount color index tables.

Unsigned long biClrImportant; // indicates the number of important colors. If it is equal to 0, it indicates that all colors are important.

} Bitmapinfo; // Bitmap header, 40 bytes

 

 

Typedef struct rgb_bmp _typ

{

Unsigned char blue; // The blue brightness (value range: 0-255)

Unsigned char green; // The brightness of the green color (value range: 0-255)

Unsigned char red; // brightness of the red color (value range: 0-255)

Unsigned char reserved; // reserved, must be 0

} RGB_BMP, * RGB_BMP _ptr; // color struct of a single pixel, 4 bytes

 

Typedef struct BMP _picture_typ

{

Bitmapfile file; // Bitmap file Header

Bitmapinfo info; // bitmap information Header

RGB_BMP palette [256]; // bitmap color table

} BMP _picture, * BMP _picture_ptr; // bitmap non-Data Partition Structure

 

Void set_bmp _palette_register (int index, rgb_bmp _ptr color) // sets the color palette register ......

{

Outp (PALETTE_MASK, 0xff );

Outp (PALETTE_REGISTER_WR, index );

Outp (PALETTE_DATA, color-> red> 2 );

Outp (PALETTE_DATA, color-> green> 2 );

Outp (PALETTE_DATA, color-> blue> 2 );

}

 

Void Check_Bmp (BMP _picture_ptr BMP _ptr) // checks whether the BMP file is used.

{

If (BMP _ptr-> file. bfType! = 0x4d42)

{

Printf ("Not a BMP file! \ N ");

Exit (1 );

}

If (BMP _ptr-> info. biCompression! = 0)

{

Printf ("Can not display a compressed BMP file! \ N ");

Exit (1 );

}

If (BMP _ptr-> info. biBitCount! = 8)

{

Printf ("Not a index 16 color BMP file! \ N ");

Exit (1 );

}

}

 

 

Void bmp _load_screen (char * BMP) // load the bmp file and display it ......

{

Int I, j, fp, n_bytes;

BMP _picture BMP 256;

Unsigned char line_buf [SCREEN_WIDTH];

Unsigned char far * line_ptr;

If (fp = open (bmp, O_RDONLY) = 1)

{

Printf ("Can not open file: % s", bmp );

Exit (1 );

}

 

Read (fp, & BMP 256.file, sizeof (bitmapfile ));

Read (fp, & BMP 256.info, sizeof (bitmapinfo ));

 

Check_Bmp (BMP _picture_ptr) & BMP 256 );

/* Lseek (fp, 54,0 );*/

For (I = 0; I <256; I ++) // read the data in the file color table.

{

Read (fp, & BMP 256.palette [I]. blue, 1 );

Read (fp, & BMP 256.palette [I]. green, 1 );

Read (fp, & BMP 256.palette [I]. red, 1 );

Read (fp, & BMP 256.palette [I]. reserved, 1 );

}

For (I = 0; I <256; I ++)

Set_bmp _palette_register (I, (rgb_bmp _ptr) & BMP 256.palette [I]); // set the palette register ......

 

For (I = SCREEN_HEIGHT-1; I> = 0; I --) // display bitmap

{

Lseek (fp,-(long) (SCREEN_HEIGHT-i) * SCREEN_WIDTH, SEEK_END); // locate the read data area

N_bytes = read (fp, line_buf, SCREEN_WIDTH); // read data in the data Zone

Line_ptr = video_buffer + (SCREEN_HEIGHT-i-1) * SCREEN_WIDTH;

For (j = 0; j <n_bytes; j ++) // place data in the video graphic Area

Line_ptr [j] = line_buf [j];

}

Close (fp );

}

 

Void Set_Video_Mode (int mode) // sets the display mode ......

{

Union REGS inregs, outregs;

Inregs. h. ah = 0;

Inregs. h. al = (unsigned char) mode;

Int86 (0x10, & inregs, & outregs );

}

 

Void main ()

{

Set_Video_Mode (VGA256); // set the display mode to 320*200 256 colors.

BMP _load_screen ("256.bmp"); // load to display the bitmap and

Getch ();

Set_Video_Mode (TEXT_MODE); // you can specify the return mode.

}

 

 

 

Detailed description of BMP format

 

Format of the bitmap file header:

Typedef struct {

Int bfType; // bfType (2 bytes), which is always equal to & H4D42, ASCII character 'bm'

Long bfSize; // file size, in 4 bytes

Int bfReserve1; // standby

Int bfReserve2; // standby

Long bfoffBits; // The position offset of the data area in the file

} BITMAPFILEHEADER; // File Header structure, 14 bytes

 

Typedef struct {

Long bitSize; // the size of the Bitmap header.

Long biWidth; // image width, in pixels

Long biHeight; // Image Height, in pixels

Int biPlanes; // Bit Plane Tree = 1

Int biBitCount; // the number of bits in pixels, indicating the number of bits in the color of the bmp image.

Long biCompression; // compression attribute of the image. The bmp image is not compressed and is equal to 0.

Long biSizeImage; // indicates the size of the bmp image data zone. If biCompression is equal to 0, the value here can be omitted.

Long biXPlosPerMeter; // horizontal resolution, which can be omitted

Long biYPlosPerMeter; // vertical resolution, which can be omitted

Long biClrUsed; // indicates the number of color index tables used. Generally, the biBitCount attribute is used only when it is less than 16. If it is equal to 0, there are 2 ^ itcount color index tables.

Long biClrImportant; // indicates the number of important colors. If it is equal to 0, it indicates that all colors are important.

} BITMAPINFOHEADER; // Bitmap header, 40 bytes

 

 

 

Detailed description of BMP files

1. BITMAPFILEHEADER struct

 

A bmp file starts with a BITMAPFILEHEADER struct.

 

The 1st attributes are bfType (2 bytes), which is always equal to & H4D42. Because the data in the memory is arranged on the left and right, the data in the memory is displayed as (42 4D) from the left to the right ), therefore, in UltraEdit, the first two bytes are displayed as (42 4D), which is the feature of future data and will not be repeated.

 

The 2nd attribute is bfSize (4 bytes), which indicates the size of the entire bmp file, which is equal to & H000004F8 = 1272 bytes.

 

The 3rd and 4th attributes are bfReserved1 and bfReserved2 (two bytes each). Here there are two reserved attributes, all of which are 0. Here they are equal to & H0000 and & H0000.

 

The first attribute is bfOffBits (4 bytes), which indicates the position offset of the DIB data zone in the bmp file. Here it is equal to & hsf-0076 = 5th, indicates that the data zone starts from 118 bytes after the start of the file.

 

The BITMAPFILEHEADER struct is over here. We will find that BITMAPFILEHEADER only occupies the 14-byte length starting from the bmp file. However, we need to note that a BITMAPFILEHEADER struct variable is defined in vb, the length of the attribute occupies 16 bytes, because the 1st attributes should have been allocated only 2 bytes, but actually 4 bytes are allocated and 2 more bytes are allowed, therefore, if you want to save a bmp image, pay attention to this when writing the BITMAPFILEHEADER struct.

 

 

 

2. BITMAPINFO struct.

 

Next is the BITMAPINFO struct.

 

The BITMAPINFO segment consists of the BITMAPINFOHEADER struct and RGBQUAD struct.

The RGBQUAD struct indicates the color information of the image, which can be omitted in some cases. Generally, the 24-bit and 32-bit images do not contain the RGBQUAD struct, because the RGB values shown in the DIB data area are directly displayed, generally, four and eight images have the RGBQUAD structure. (The number of digits indicates the color information. For example, a four-digit image uses four bits to indicate the color information .) Whether the RGBQUAD struct exists in a bmp file can be determined based on bfOffBits, the first 5th attribute of the BITMAPFILEHEADER struct, because the length of the BITMAPINFOHEADER struct is 40 bit, if the BITMAPINFOHEADER struct is not offset to the DIB data zone after it ends, the following data is the RGBQUAD struct. Here C: \ WINDOWS \ Blue sans 16.bmp is a 4bit image, so it carries the RGBQUAD struct.

 

 

 

3. BITMAPINFOHEADER.

 

Next, go to the BITMAPINFOHEADER section.

 

The first attribute is biSize (4 bytes), which indicates the length of the BITMAPINFOHEADER struct. The most common length is 40 bytes. In UltraEdit, we can see that the next four bytes are equal to & hsf-0028 = 40 bytes.

 

The 2nd attribute is biWidth (4 bytes), indicating the width of the bmp image, which is equal to & H00000030 = 48 pixels.

 

The 3rd attribute is biHeight (4 bytes), indicating the height of the bmp image. Here it is equal to & hsf-0030 = 48 pixels.

 

The 4th attributes are biPlanes (2 bytes), indicating that the plane of the bmp image belongs. Obviously, the display has only one plane, so it is always equal to 1. Here it is equal to & H0001.

 

The 5th attribute is biBitCount (2 bytes), indicating the number of bits in the color of the bmp image, that is, 24 bitmap, 32 bitmap, and so on.

This parameter is equal to & H0004, indicating that the image is a 4-Bit Bitmap.

 

The first attribute is biCompression (4 bytes), which indicates the compression attribute of the image. The bmp image is not compressed and is equal to 0. Therefore, it is & H00000000.

 

The 7th attributes are biSizeImage (4 bytes), which indicates the size of the bmp image data zone. When a person familiar with biCompression is equal to 0, the value here can be omitted, so it is equal to & H00000000.

 

The 8th attribute is biXPelsPerMeter (4 bytes), which indicates the number of pixels per meter on the X axis of the image. This attribute is equal to & H00000EC3 = 3779 pixels/meter.

 

The 9th attribute is biYPelsPerMeter (4 bytes), which indicates the number of pixels per meter on the Y axis of the image. This attribute is equal to & H00000EC3 = 3779 pixels/meter.

 

The 10th attributes are biClrUsed (4 bytes), which indicates the number of color index tables used. Generally, the biBitCount attribute is used only when it is smaller than 16, if it is equal to 0, there are 2 ^ itcount color index tables, so here it is still equal to & H00000000.

 

The 11th attributes are biClrImportant (4 bytes), which indicates the number of important colors. If it is equal to 0, it indicates that all colors are important, so here it is equal to & H00000000.

 

The BITMAPINFOHEADER struct ends.

 

 

 

4. RGBQUAD struct

 

Since this image has not yet reached the offset of the DIB data zone, the following part is the RGBQUAD struct.

 

The RGBQUAD struct is composed of 4 bytes of data. Therefore, an RGBQUAD struct occupies only 4 bytes of space, represented in sequence from left to right (blue, green, red, not used ). For example, I have counted a total of 16 RGBQUAD components. Since the image is a 4-bitmap, 2 ^ 4 is exactly equal to 16, therefore, all 16 colors are enumerated. These colors are a color index table. Color index table number starts from 0, a total of 16 colors, so the number is 0-15. From UltraEdit, we can see that in order, the 16

 

The RGBQUAD struct is:

 

No.: (blue, green, red, empty)

0)

1)

2)

3)

4th)

No. 5)

6: (80, 80)

7: (80, 80, 80, 00)

(C0, C0, C0, 00)

9: (, FF, 00)

10: (00, FF)

11: (00, FF, FF, 00)

12: (FF, 00)

13: (FF, 00, FF, 00)

14: (FF, FF)

15th: (FF, 00)

 

For more intuitive representation of these colors, see the following picture.

 

Here, the offset of the DIB data zone is met, so the following bytes are the image content. Note that all the DIB data scan rows are upside down and upside down. That is to say, an image first draws the bottom pixel and then the top pixel, therefore, the pixels represented by DIB data are represented from the lower left corner of the image to the upper right corner of the image.

 

Because the image here is a 4-bit image, that is, 4-bit indicates a pixel, and one byte has 8 bits, a word can be saved to 2 pixels.

 

From UltraEdit, we can see that the first byte in the dib data zone is & H44, And the hexadecimal number is exactly written in every 4 groups, the image is exactly the same as the 4-bit image. Therefore, & H44 indicates two pixels. 4 indicates the first pixel in the high position, and 4 indicates the second pixel in the low position. Here, 4 does not represent the RGB color, but the color index number is 4. Because the quotation marks start from 0, 4 indicates the 5th colors in the index table, from the figure, we can see that the index number 4 is blue. This is the first byte, indicating 2 pixels in the lower left corner of the image. If PhotoShop opens the image, the color RGB values obtained from two pixels in the lower left corner are exactly the same as the RGB values of the 5th colors in the index table. The DIB data is similar.

 

At this point, a bmp image is completely parsed. Based on this information, you can draw a bmp image.

 

========================================================== ====

 

If you still don't understand, there are:

 

1. BMP file Composition

A bmp file consists of four parts: File Header, bitmap information header, color information, and graphic data.

 

2. BMP File Header

The data structure of the BMP file header contains information such as the type, size, and start position of the BMP file.

 

Its structure is defined as follows:

 

Typedef struct tagBITMAPFILEHEADER

{

WORDbfType; // The type of the bitmap file, which must be BM.

DWORD bfSize; // the size of the bitmap file, in bytes.

WORDbfReserved1; // reserved word for bitmap files, which must be 0

WORDbfReserved2; // reserved word for bitmap files, which must be 0

DWORD bfOffBits; // the starting position of the bitmap data, expressed in bytes as the offset relative to the bitmap file header.

} BITMAPFILEHEADER;

 

3. Bitmap header

The BMP Bitmap header is used to describe the size and other information of the bitmap.

 

Typedef struct tagBITMAPINFOHEADER {

DWORD biSize; // number of bytes occupied by the structure

LONGbiWidth; // The width of the bitmap, in pixels.

LONGbiHeight; // The height of the bitmap, in pixels

WORD biPlanes; // The level of the target device, which must be 1

WORD biBitCount // The number of digits required for each pixel. It must be one of 1 (two-color), 4 (16 colors), 8 (256 colors), or 24 (true color ).

DWORD biCompression; // bitmap compression type, which must be 0 (not compressed), 1 (BI_RLE8 compression type), or 2 (BI_RLE4 compression type)

DWORD biSizeImage; // bitmap size, in bytes

LONGbiXPelsPerMeter; // horizontal bitmap resolution, number of workers per meter

LONGbiYPelsPerMeter; // bitmap vertical resolution, number of workers per meter

DWORD biClrUsed; // number of colors in the color table used by the bitmap

DWORD biClrImportant; // number of important colors in the bitmap display process

} BITMAPINFOHEADER;

 

4. Color Table

A color table is used to describe the color in a bitmap. It has several table items. Each table item is an RGBQUAD-type structure and defines a color. The RGBQUAD structure is defined as follows:

 

Typedef struct tagRGBQUAD {

BYTErgbBlue; // blue brightness (value range: 0-255)

BYTErgbGreen; // The brightness of the green color (value range: 0-255)

BYTErgbRed; // The Red brightness (value range: 0-255)

BYTErgbReserved; // reserved, must be 0

} RGBQUAD;

 

The number of RGBQUAD structure data in the color table is determined by biBitCount:

When biBitCount is 1, 4, and 8, there are 2, 16, and 256 table items respectively;

When biBitCount = 24, there is no color table item.

The bitmap information header and the color table form the bitmap information,

The BITMAPINFO structure is defined as follows:

 

Typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader; // Bitmap header

RGBQUAD bmiColors [1]; // color table

} BITMAPINFO;

 

5. bitmap data

The bitmap data records each pixel value of the bitmap. The record sequence is from left to right in the scan row, and the rows are from bottom to top. The number of bytes occupied by a pixel value of a bitmap:

 

When biBitCount = 1, 8 pixels constitute 1 byte;

When biBitCount = 4, 2 pixels constitute 1 byte;

When biBitCount = 8, 1 pixel occupies 1 byte;

When biBitCount = 24, one pixel occupies three bytes;

Windows requires that the number of bytes occupied by a scan row must be a multiple of 4 (in the unit of long), and the number of insufficient bytes must be filled with 0,

Calculation of the number of bytes occupied by a scanned row:

DataSizePerLine = (biWidth * biBitCount + 31)/8; // number of bytes occupied by a scanned row

DataSizePerLine = DataSizePerLine/4*4; // The number of bytes must be a multiple of 4

Bitmap data size (without compression ):

DataSize = DataSizePerLine * biHeight;

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.