What does bmp mean? What is the BMP file extension? Which program to open the bmp extension

BMP(from English Bitmap Picture) is a raster image storage format developed by Microsoft.

A huge number of programs work with the BMP format, since its support is integrated into the Windows and OS/2 operating systems. BMP files can have extensions .bmp, .dib and .rle. Additionally, data in this format is included in binary RES resource files and PE files.

Microsoft has also developed ICO and CUR formats for its needs, which have a structure similar to BMP. In addition, structures from this format are used by some WinAPI functions of the GDI subsystem.

Color depths in this format can be 1, 2, 4, 8, 16, 24, 32, 48 bits per pixel, but 2 bits per pixel is not officially supported. In this case, for color depths less than 16 bits, a palette with full-color components with a depth of 24 bits is used.

In the BMP format, images can be stored as is or using some common compression algorithms. In particular, the BMP format supports RLE compression without loss of quality, and modern operating systems and software allow the use of JPEG and PNG (these formats are built into BMP as a container).

DIB and DDB

When using the DIB format Device Independent Bitmap, device-independent raster), the programmer can access all elements of the structures that describe the image using a regular pointer. But this data is not used to directly control the screen, since it is always stored in system memory and not in dedicated video memory. The pixel format in RAM may differ from the format that must be stored in video memory to display a dot of the same color. For example, the DIB format can use 24 bits to specify a pixel, and at this moment the graphics adapter can operate in HiColor mode with a color depth of 16 bits. In this case, the bright red dot will be specified in a hardware-independent format by three bytes 0x0000ff, and in video memory by the word 0xF800. When copying a picture to the screen, the system will spend additional time converting color codes from the 24-bit format to the video buffer format.

File structure overview

The BMP file consists of four parts:

  1. File header (BITMAPFILEHEADER)
  2. Image title (BITMAPINFOHEADER, may be missing). BITMAPV4HEADER (Win95, NT4.0) BITMAPV5HEADER (Win98/Me, 2000/XP)
  3. Palette (may be missing)
  4. The image itself

BITMAFILEHEADER

This structure contains information about the type, size, and representation of the data in the file. Size 14 bytes.

Typedef struct tagBITMAPFILEHEADER ( WORD bfType; // offset 0 bytes from the beginning of the file DWORD bfSize; // offset 2 bytes from the beginning of the file, length 4 bytes WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; // offset 10 bytes from the beginning of the file, length 4 bytes) BITMAPFILEHEADER, * PBITMAPFILEHEADER;

The WORD type must be 16 bits, the DWORD and LONG types must be 32 bits, the LONG type must be signed, and the byte order is assumed to be little endian.

  • bfType - file type, characters "BM" (in HEX: 0x42 0x4d).
  • bfSize - the size of the entire file in bytes.
  • bfReserved1 and bfReserved2 are reserved and must contain zeros.
  • bfOffBits - contains the offset in bytes from the beginning of the BITMAPFILEHEADER structure to the image bits themselves.

After the file header

BITMAPINFOHEADER

The simplest header option. Applications for Windows NT3.51 and earlier can only use this structure. Size 40 bytes.

Typedef struct tagBITMAPINFOHEADER( DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; B) ITMAPINFOHEADER, * PBITMAPINFOHEADER;

BiSize The size of this structure in bytes. The BMP format has been expanded over time, and the value of this field determines the version of the format. biWidth The width of the image in pixels. For Win98/Me and Win2000/XP: If the biCompression field contains BI_JPEG or BI_PNG, this is the width of the decompressed image. biHeight The height of the image in pixels. If it contains a positive value, the image is written in bottom-to-top order (zero pixel in the lower left corner). If the value is negative, the image is written from top to bottom (zero pixel in the upper left corner of the image). The biCompression field must contain the value BI_RGB or BI_BITFIELDS. Such an image cannot be compressed. biPlanes Number of color planes and in BMP format contains one. biBitCount Number of bits per pixel. Can take the following values:

  • 0 - makes sense for Win98/Me/2000/XP. The number of bits per pixel determines the JPEG or PNG format.
  • 1 - monochrome image. The bmiColors member of the BITMAPINFO structure contains two elements. Each bit of an image represents one pixel; if the bit is zero, the pixel has the color of the first element of the bmiColors table, otherwise - the color of the second.
  • 4 - sixteen-color image. Pixels are defined by 4-bit indices, each byte of the image contains information about two pixels - the most significant 4 bits for the first, the remaining ones for the second.
  • 8 - the palette contains up to 256 colors, each byte of the image stores an index in the palette for one pixel.
  • 16 - if the biCompression field contains the value BI_RGB, the file does not contain a palette. Every two bytes of the image store the intensity of the red, green and blue components of one pixel. In this case, the most significant bit is not used; 5 bits are allocated for each component: 0RRRRRGGGGGGBBBBB.
    If the biCompression field contains the value BI_BITFIELDS, the palette stores three four-byte values ​​that define a mask for each of the three color components. Each pixel in an image is represented by a two-byte value from which color components are extracted using masks. For WinNT/2000/XP, the bit sequences of each component must follow continuously, without overlapping or intersecting with the sequences of other components. For Win95/98/Me - only the following masks are supported: 5-5-5, where the mask of the blue component is 0x001F, green 0x03E0, red 0x7C00; and 5-6-5, where the mask of the blue component is 0x001F, green 0x07E0, red 0xF800.
  • 24 - the palette is not used, each three bytes of the image represents one pixel, one byte for the intensity of the blue, green and red channels, respectively.
  • 32 - If the biCompression field contains the value BI_RGB, the image does not contain a palette. Every four bytes of the image represent one pixel, one byte each for the intensity of the blue, green and red channels, respectively. The most significant byte of each quad is not usually used, but allows storing alpha channel data.
    If the biCompression field contains the value BI_BITFIELDS, three four-byte color masks are stored in the palette - for the red, green and blue components. Each pixel in an image is represented by four bytes. WinNT/2000: component masks must not overlap or intersect. Windows 95/98/Me: the system supports only one compression mode, completely similar to the mode without compression BI_RGB - the most significant byte of each four is used as an alpha channel, the next three are reserved for the blue, green and red channels, respectively: 0xAARRGGBB.
biCompression Compression type for compressed images:
Meaning Identifier Compression
0 BI_RGB uncompressed image
1 BI_RLE8 RLE compression for 8-bit images
2 BI_RLE4 RLE compression for 4-bit images
3 BI_BITFIELDS the image is not compressed, the palette contains three 4-byte masks for the red, green and blue color components. Used for 16 and 32 bit images
4 BI_JPEG Win98/Me/2000/XP: JPEG compression
5 BI_PNG Win98/Me/2000/XP: PNG compression
6 BI_ALPHABITFIELDS WinCE: the image is not compressed, the palette contains four 4-byte masks for the red, green, blue and transparent (alpha channel) color components. Used for 16 and 32 bit images
biSizeImage Image size in bytes. May contain zero for BI_RGB images. Win98/Me/2000/XP: If biCompression contains BI_JPEG or BI_PNG, biSizeImage specifies the size of the BI_JPEG or BI_PNG image buffer. biXPelsPerMeter Horizontal resolution in pixels per meter for the target device. An application can use this value to select from a group of image resources the most appropriate image for the current device. For DPI 96, which is accepted by Microsoft for monitors, it will be equal to 3780 (if calculated using the formula (96 / 25.4) * 1000). biYPelsPerMeter Vertical resolution in pixels per meter for the target device. biClrUsed The number of color indices used in the palette. If the value is zero, the image uses the maximum number of indexes available, according to the biBitCount value and the compression method specified in biCompression.
If contains a nonzero value and biBitCount is less than 16, biClrUsed specifies the number of colors that the device driver or application will access. If biBitCount is greater than or equal to 16, biClrUsed is the size of the palette used to optimize the performance of system palettes. If biBitCount is 16 or 32, the optimal palette follows immediately after three four-byte masks.
In a packed image, the pixel array immediately follows the BITMAPINFO structure, biClrUsed must contain zero or the actual palette size. biClrImportant The number of palette elements required to display the image. If it contains zero, all indexes are equally important.

The BITMAPINFO structure combines the BITMAPINFOHEADER and the palette, providing a complete description of the dimensions and colors of an image.

To find the palette in the BITMAPINFO structure, the application must use the information stored in biSize as follows:

PColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo-> bmiHeader.biSize ) ) ;

The raster is usually stored in a vertically mirrored form. But it is also possible to store the raster in a non-vertically mirrored form. A sign that the raster in BMP is not in vertical mirror form is specified by the biHeight parameter.

BITMAPV4HEADER

An expanded version of the structure described above. Win NT 3.51 and earlier must use the BITMAPINFOHEADER structure. Win98/Me/2000/XP can use the BITMAPV5HEADER structure instead of the BITMAPV4HEADER structure.

Typedef struct ( DWORD bV4Size; LONG bV4Width; LONG bV4Height; WORD bV4Planes; WORD bV4BitCount; DWORD bV4V4Compression; DWORD bV4SizeImage; LONG bV4XPelsPerMeter; LONG bV4YPelsPerMeter; DWORD bV4ClrUsed DW; ORD bV4ClrImportant; DWORD bV4GreenMask; ; CIEXYZTRIPLE bV4Endpoints; DWORD bV4GammaGreen; DWORD bV4GammaBlue;

The fields from the beginning of the structure up to and including bV4ClrImportant have the same purpose as the corresponding fields of the BITMAPINFOHEADER structure.

  • bV4RedMask - color mask of the red component of each pixel, used only if bV4Compression contains the BI_BITFIELDS value.
  • bV4GreenMask - color mask of the green component of each pixel, used only if bV4Compression contains the BI_BITFIELDS value.
  • bV4BlueMask - color mask of the blue component of each pixel, used only if bV4Compression contains the BI_BITFIELDS value.
  • bV4AlphaMask - mask defining the alpha channel component.
  • bV4CSType - defines the color space of the image.
  • bV4Endpoints is a CIEXYZTRIPLE structure specifying the x, y and z coordinates of three colors that correspond to the endpoints of the color space defined for the image. This field is ignored if bV4CSType does not contain a LCS_CALIBRATED_RGB value.
  • bV4GammaRed - tone curve of the red component. Ignored if bV4CSType does not contain a LCS_CALIBRATED_RGB value. Indicated in 16×16 format.
  • bV4GammaGreen - tone curve of the green component. Ignored if bV4CSType does not contain a LCS_CALIBRATED_RGB value.
  • bV4GammaBlue - blue component tone curve. Ignored if bV4CSType does not contain a LCS_CALIBRATED_RGB value.

BITMAPV5HEADER

Win95/NT 4.0: Applications can use BITMAPV4HEADER. Win NT 3.51 and earlier must use the BITMAPINFOHEADER structure.

Typedef struct ( DWORD bV5Size; LONG bV5Width; LONG bV5Height; WORD bV5Planes; WORD bV5BitCount; DWORD bV5Compression; DWORD bV5SizeImage; LONG bV5XPelsPerMeter; LONG bV5YPelsPerMeter; DWORD bV5ClrUsed; bV5ClrImportant; DWORD bV5GreenMask; DWORD bV5AlphaMask; ; CIEXYZTRIPLE bV5Endpoints; DWORD bV5GammaBlue; DWORD bV5ProfileSize; 5HEADER;

For fields from the beginning of the structure up to and including bV5GammaBlue, only differences from previous versions - BITMAPINFOHEADER and BITMAPV4HEADER will be described.

  • bV5CSType - defines the color space of the image, can take the following values:
LCS_CALIBRATED_RGB LCS_sRGB LCS_WINDOWS_COLOR_SPACE PROFILE_LINKED PROFILE_EMBEDDED
  • bV5Intent - can take the following values:
LCS_GM_ABS_COLORIMETRIC LCS_GM_BUSINESS LCS_GM_GRAPHICS LCS_GM_IMAGES
  • bV5ProfileData - offset in bytes from the beginning of the structure to the beginning of the profile data (profile file name, a string consisting exclusively of code table 1252 characters and ending with a zero byte). Ignored if bV5CSType contains a value other than PROFILE_LINKED and PROFILE_EMBEDDED.
  • bV5ProfileSize - profile data size in bytes.
  • bV5Reserved - reserved. Contains zero.

Palette

The palette can contain a sequence of four-byte fields according to the number of available colors (256 for an 8-bit image). The low three bytes of each field determine the intensity of the red, green and blue components of the color; the high byte is not used. Each pixel of the image is described in this case by one byte containing the number of the palette field in which the color of this pixel is stored.

If an image pixel is described by a 16-bit number, the palette can store three two-byte values, each of which defines a mask to extract the red, green, and blue color components from the 16-bit pixel.

A BMP file may not contain a palette if it stores an uncompressed full-color image.

Image data

A sequence of pixels recorded in one form or another. Pixels are stored row by row, from bottom to top. Each image line is padded with zeros to a length that is a multiple of four bytes.

In bmp files with a color depth of 24 bits, the color bytes of each pixel are stored in BGR (Blue, Green, Red) order.

In bmp files with a color depth of 32 bits, the color bytes of each pixel are stored in BGRA order (Blue, Green, Red, Alpha)

Image bit depth

Depending on the number of represented colors, each point is allocated from 1 to 48 bits:

  • 1 bit - monochrome image (two colors).
  • 2 bits - 4 possible colors (CGA operating modes) (2-bit mode is not officially standardized, but is used).
  • 4 bits - 16-color image (EGA operating modes).
  • 8 bits (1 byte) - 256 colors, the last of the modes to support indexed colors (see below).
  • 16 bits (2 bytes) - HiColor mode, For 5-6-5 = 65536 possible shades, for 5-5-5 = 32768 possible shades.
  • 24 bits (3 bytes) - TrueColor. Because 3 bytes do not map well to powers of two (especially when storing data in memory, where data alignment on a word boundary matters), a 32-bit image is often used instead. In TrueColor mode, each of the three channels (in RGB mode) is allocated 1 byte (256 possible values), the total number of colors is .
  • 32 bits (4 bytes) - this mode is almost similar to TrueColor, the fourth byte is usually not used, or it contains the alpha channel (transparency).
  • 48 bits (6 bytes) - a rarely used format with increased color accuracy (16 bits per channel), supported by a relatively small number of programs and equipment.

Indexed colors

When the number of bits is 1 (2 colors), 2 (4 colors), 4 (16 colors) or 8 (256 colors) per pixel, a special indexed color mode can be used. In this case, the number corresponding to each pixel does not indicate the color, but the number of the color in the palette. By using a palette, it is possible to adapt the image to the colors present in the image. In this case, the image is limited not by specified colors, but by the maximum number of colors used simultaneously.

Example program

The following program opens a 24-bit BMP file in an XWindow, the color depth should be 32 bits, it does not work at lower color renderings, as it complicates the example:

/* Compiled with the line: cc -o xtest xtest.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lm */#include #include #include #include #include #include #include #include #include #include #include #include "bitmap.h" /* Here are the BMP header definitions as described earlier in this article */ static XImage * CreateImageFromBuffer(Display*, unsigned char *, int, int) ; main(int argc, char * argv ) ( Display * dis; Window win; /* Our window */ XEvent event; /* Events */ GC gc; /* Graphics context */ XImage * image; int n, width, height, fd, size; unsigned char * data; BITMAPFILEHEADER bmp; BITMAPINFOHEADER inf; char * buf; if (argc< 2 ) { perror ("use: xtest file.bmp\n") ; exit(1); ) if ((fd = open(argv[ 1 ] , O_RDONLY) ) == - 1 ) ( printf ("Error open bitmap \n") ; exit(1); ) read(fd, & bmp, sizeof (BITMAPFILEHEADER) ) ; read(fd, & inf, sizeof (BITMAPINFOHEADER) ) ; width = inf.biWidth ; height = inf.biHeight ; if ((dis = XOpenDisplay(getenv ("DISPLAY" ) ) ) == NULL) ( printf ( "Can"t connect X server: %s\n ", strerror (errno) ) ; exit(1); ) win = XCreateSimpleWindow(dis, RootWindow(dis, DefaultScreen(dis) ) , 0 , 0 , width, height, 5 , BlackPixel(dis, DefaultScreen(dis) ) , WhitePixel(dis, DefaultScreen(dis) ) ) ; XSetStandardProperties(dis, win, argv[ 1 ], argv[ 0 ], None, argv, argc, NULL); gc = DefaultGC(dis, DefaultScreen(dis) ) ; /* Sometimes this space in the structure is not filled */ if (inf.biSizeImage == 0 ) ( /* Calculate the size */ size = width * 3 + width % 4 ; size = size * height; ) else ( size = inf.biSizeImage ; ) buf = malloc (size) ; if (buf == NULL) ( perror ("malloc" ) ; exit (1 ) ; ) printf ( "size = %d bytes allocated\n ", size) ; /* Let's move to the beginning of the image itself */ lseek(fd, bmp.bfOffBits , SEEK_SET) ; /* Read into the buffer */ n = read(fd, buf, size) ; printf( "size = %d bytes read\n ", n) ; image = CreateImageFromBuffer(dis, buf, width, height) ; /* Delete the buffer - we no longer need it */ free(buf); XMapWindow(dis, win) ; XSelectInput(dis, win, ExposureMask | KeyPressMask) ; while (1 ) ( XNextEvent(dis, & event) ; if (event.xany .window == win) ( switch (event.type ) ( case Expose: XPutImage(dis, win, gc, image, 0 , 0 , 0 , 0 , image-> width, image-> height) ; break ; case KeyPress: if (XLookupKeysym(& event.xkey , 0 ) == XK_q) ( XDestroyImage(image) ; XCloseDisplay(dis) ; close(fd) ; exit (EXIT_SUCCESS) ; break ; default : break ; /* Creates a Ximage from a BMP file, since the BMP image is stored upside down * and mirrored - this is corrected in the loop */ XImage * CreateImageFromBuffer(Display * dis, unsigned char * buf, int width, int height) ( int depth, screen; XImage * img = NULL; int i, j; int numBmpBytes; size_t numImgBytes; int32_t * imgBuf; int ind = 0 ; int line; int ih; /* Row and column numbers to reflect */ int new_ind; /* New index */ screen = DefaultScreen(dis) ; depth = DefaultDepth(dis, screen) ; temp = width * 3 ; line = temp + width % 4 ; /* String length taking into account alignment */ numImgBytes = (4 * (width * height) ) ; imgBuf = malloc(numImgBytes); /* Size allocated to BMP in the file, taking into account alignment */ numBmpBytes = line * height; for (i = 0 ; i< numBmpBytes; i++ ) { unsigned int r, g, b; /* Skip padding */ if (i >= temp && (i % line) >= temp) continue ; b = buf[ i] ; i++; g = buf[ i] ; i++; r = buf[ i] ; /* Calculate a new index for vertical reflection */ iw = ind % width; ih = ind / width; new_ind = iw + (height - ih - 1 ) * width; imgBuf[ new_ind] = (r | g<< 8 | b << 16 ) << 8 ; ind++; } img = XCreateImage(dis, CopyFromParent, depth, ZPixmap, 0 , (char * ) imgBuf, width, height, 32 , 0 ) ; XInitImage(img) ; /* Bit and byte order on PC should be like this */ img->byte_order = MSBFirst; img->bitmap_bit_order = MSBFirst; return img; )

The BMP file format (short for BitMaP) is the native raster graphics format for Windows because it most closely matches the native Windows format in which that system stores its raster arrays. The filename extension most often used in BMP format is BMP, although some files have the extension RLE, which stands for run length encoding. The RLE extension of a file name usually indicates that the file's raster information has been compressed using one of two RLE compression methods that are valid for BMP format files.

In BMP files, the color information of each pixel is encoded at 1, 4, 8, 16, or 24 bits (bits/pixel). The number of bits per pixel, also called color depth, determines the maximum number of colors in an image. An image with a depth of 1 bit/pixel can have only two colors, and with a depth of 24 bit/pixel - more than 16 million different colors.

The diagram below shows the structure of a typical BMP file containing a 256-color image (8 bits/pixel depth). The file is divided into four main sections: the raster graphics file header, the raster array information header, the color table, and the raster array data itself. The header of a raster graphics file contains information about the file, including the address at which the raster array data area begins. The raster array information header contains information about the image stored in the file, such as its height and width in pixels. The color table provides the RGB (red, green, blue) primary color values ​​for the colors used in the image. Programs that read and display BMP files, when using video adapters that do not allow displaying more than 256 colors, can programmatically set such RGB values ​​in the color palettes of the adapters for accurate color reproduction.

The format of the actual raster array data in a BMP file depends on the number of bits used to encode the color data for each pixel. With a 256-color image, each pixel in the part of the file that contains the actual raster array data is described by one byte (8 bits). This pixel description does not represent RGB color values, but serves as a pointer to enter the file's color table. Thus, if R/G/B=255/0/0 is stored as the first RGB color value in the color table of a BMP file, then the value of pixel 0 in the raster array will be assigned the color bright red. Pixel values ​​are stored in left-to-right order, starting (usually) at the bottom row of the image. Thus, in a 256-color BMP file, the first byte of raster array data is the index for the color of the pixel located in the lower left corner of the image; the second byte represents the index for the color of the pixel adjacent to the right, etc. If the number of bytes in each row is odd, then an extra byte is added to each row to align the raster array data on 16-bit boundaries.


Not all BMP files have a structure like the one shown in the diagram. For example, 16- and 24-bit/pixel BMP files do not have color tables; in these files, the pixel values ​​of the raster array directly characterize the RGB color values. The internal storage formats of individual sections of the file may also differ. For example, raster array information in some 16- and 256-color BMP files can be compressed using the RLE algorithm, which replaces sequences of identical image pixels with tokens that specify the number of pixels in the sequence and their color. On Windows, you can work with OS/2-style BMP files that use various raster array header and color table formats.

This article is about what the bmp graphic format looks like. Although this is one of the simpler formats, due to the fact that there are many variations of this format, not all points are obvious. So, stop pouring water, let's get started.

Format structures

The bmp format (from the words BitMaP - bit map, or, in Russian, bit array) is an uncompressed (mostly) image that is quite easy to read and display in Windows OS, which has special API functions that help.

First, let's give a graphical representation of the data in bmp (picture taken from MSDN).

At the beginning there is a file header (BITMAPFILEHEADER). It is described as follows:

bfType determines the file type. Here he should be BM. If you open any BMP file in a text editor (or better yet, in a hexadecimal editor), you will see that the first two characters are BM (from the word BitMap, as you probably already guessed).
bfSize is the size of the file itself in bytes. Strictly speaking, you should calculate it (which is recommended), but I set the file size incorrectly (though not on purpose :)) and there were no problems (ACDSee read without problems, my program worked), but I do not recommend you write it deliberately incorrectly , suddenly a conscientious program will appear that will compare this size with the real one and decide that it is not bmp, but something else. Ideally, all programs, in order to make sure that this is a real bmp and not a fake, should, firstly, check that bfType contains "BM" (without quotes), and, secondly, that bfSize is equal to the file size .
bfReserved1 and bfReserved2 are reserved and must be zero.
bfOffBits. This is one of the most important fields in this structure. It shows where the bitmap itself begins relative to the beginning of the file (or, as MSDN says, "from the beginning of the BITMAPFILEHEADER structure"), which describes the picture. That is, to be guaranteed to get to the beginning of the array you must write:

typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
) BITMAPINFOHEADER, * PBITMAPINFOHEADER;

biSize is the size of the structure itself. It needs to be initialized as follows: bih.biSize = sizeof(BITMAPINFOHEADER);
Here again we will assume that bih is declared as follows: BITMAPINFOHEADER bih;
biWidth and biHeight set the width and height of the image in pixels, respectively.
biPlanes specifies the number of planes. For now it is always set to 1.
biBitCount- Number of bits per pixel. We'll talk more about this below.
biCompression indicates the type of compression. Don’t be surprised or scared that bmp suddenly experiences compression. I personally have not seen more than one compressed bmp (but I'm not saying that they don't exist). If there is no compression, then this flag must be set to BI_RGB. In this article we are talking about the uncompressed format, so I won’t even list other flags. It seems that the same structure is used in JPEG and PNG files, because starting from Windows 98 there were options BI_JPEG, which shows that this picture is JPEG and BI_PNG, that it is PNG (I don’t know anything about the Jpeg format, I I just made these conclusions based on what is written in MSDN).
biSizeImage indicates the size of the image in bytes. If the image is uncompressed (that is, the previous field is set to BI_RGB), then a zero should be written here. biXPelsPerMeter And biYPelsPerMeter denote, respectively, the horizontal and vertical resolution (in pixels per meter) of the final device onto which the bitmap (raster) will be output. An application can use this value to select from a group of resources the most appropriate bitmap for the desired device. The fact is that the bmp format is essentially a hardware-independent raster, that is, when the appearance of what is obtained does not depend on what this raster is projected onto (so to speak). For example, a picture will look the same regardless of whether it is drawn on a monitor screen or printed on a printer. But the resolution of devices is different, and it is precisely in order to select the most suitable picture from the available ones that these parameters are used.
biClrUsed determines the number of colors used from the table. If this value is zero, then the raster uses the maximum number of colors allowed by the biBitCount value. This is only relevant for compressed images. If biClrUsed is non-zero and biBitCount is less than 16, then biClrUsed determines the current number of colors of the graphics engine or available device driver. If biBitCount is greater than or equal to 16, then biClrUsed determines the size of the color table used to optimize the current system palette.
biClrImportant- this is the number of important colors. Determines the number of colors that are needed to depict the drawing. If this value is 0 (as it usually is), then all colors are considered important.

Types of BMP format

All types of bmp format conditionally can be divided into two types: palette and non-palette. That is, whether the palette is used in a given format or not. Please note that the palette can even be in palette-free formats, but it is not used there. In palette-free bmps, the color is calculated directly from the bits that go in the file, starting from a certain place. And in palettes, each byte describes one or more pixels, and the byte (or bits) values ​​are the color index in the palette. To begin with, I will provide a table that compares the possible options. The type of picture (palette or palette-free) depends on how many bits are given per pixel, that is, on the biBitCount value of the BITMAPINFOHEADER structure.

biBitCountPalette or non-palette formatMaximum possible number of colorsNotes 1 Palette2 A two-color, mind you, not necessarily black and white, palette picture. If the raster bit (which is just below) is reset (equal to 0), then this means that the first color from the palette should be in this place, and if set (equal to 1), then the second. 4 Palette16 Each byte describes 2 pixels. Here is an example from MSDN. If the first byte in the image is 0x1F, then it corresponds to two pixels, the color of the first is the second color from the palette (because the countdown starts from zero), and the second pixel is the 16th color of the palette. 8 Palette256 One of the most common options. But at the same time, the simplest ones. The palette takes up one kilobyte (but it’s better not to count on it). One byte is one color. Moreover, its value is the color number in the palette. 16 No palette2^16 or 2^15This is the most confusing option. Let's start with the fact that it is palette-free, that is, every two bytes (one WORD word) in the raster uniquely define one pixel. But here’s what happens: there are 16 bits, and there are 3 color components (Red, Green, Blue). But 16 doesn’t want to be divided by 3. Therefore there are two options here. The first is to use 15 bits rather than 16, then there are 5 bits for each color component. This way we can use a maximum of 2^15 = 32768 colors and get the triple R-G-B = 5-5-5. But then a whole bit out of 16 is lost in vain. But it just so happens that our eyes, among all colors, perceive green better, so we decided to give this one bit to the green component, that is, then we get the triple R-G-B = 5-6-5, and now we can use 2^16 = 65536 colors. But the most unpleasant thing is that both options are used. MSDN suggests that in order to distinguish how many colors are used, fill the biClrUsed field from the BITMAPINFOHEADER structure with this value. To select each component you need to use the following masks. For 5-5-5 format: 0x001F for blue component, 0x03E0 for green and 0x7C00 for red. For the 5-6-5 format: 0x001F - blue, 0x07E0 - green and 0xF800 red components, respectively. 24 No palette2^24 And this is the simplest format. Here 3 bytes define 3 color components. That is, one component per byte. We simply read the RGBTRIPLE structure and use its rgbtBlue, rgbtGreen, rgbtRed fields. They go in that order. 32 No palette2^32 Here 4 bytes define 3 components. But, however, one byte is not used. It can be used, for example, for the alpha channel (transparency). In this case, it is convenient to read the raster using RGBQUAD structures, which are described as follows:

Data storage in bmp format

Well, now we come to the most interesting part. After the BITMAPFILEHEADER and BITMAPINFOHEADER structures comes the palette. Moreover, if the format is palette-free, then it may not be there, however, you shouldn’t count on it. The fact is that when I was just starting to understand the bmp format, I read in one book that, supposedly, if the format is palette-free, then it has no palette at all. There were even two pictures - format diagrams: one with a palette, the other without. And at that time I was writing a program that diligently operates with bmp files. And I had to convert incoming images from 256 colors to 24-bit (if any) into temporary files. And I simply did not create a palette in 24-bit (bfOffBits from the BITMAPFILEHEADER structure was equal to the sum of sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), and left the incoming 24-bit ones unchanged. With 256-color rasters everything worked as it should, until I didn’t come across a 24-bit image that had garbage displayed at the bottom instead of the required part. I didn’t immediately understand what was wrong until I compared the size of the original file with the theoretical one that should have been there if there had been no palette. The difference turned out to be exactly 1 KB (exactly). 1024 bytes). There was a palette. Therefore, never count on whether there is a palette and do not rely on its size (although all the pictures that I came across had a palette size of 256 colors, or 1Kb), always move through the file to the beginning of the raster, using bfOffBits. The palette is an array of RGBQUAD structures one after another. Even if not all colors are used in the palette (but only, for example, 16), then often 256 fields are allocated for the palette A 256 * 4 = 1024, where. 4 is the size of the RGBQUAD structure, that is, that same one kilobyte is obtained.

Immediately after the palette comes the raster itself. This is where things get more confusing. Firstly, the pixels are described here as written in the table above, depending on the format. And they can themselves contain the value of the color components (for palette-free ones), or they can be indexes of a palette array. The picture itself is recorded line by line. Secondly, the picture appears to be upside down. That is, the bottom line is written first, then the penultimate line, and so on until the very top. And thirdly, as written in, if the size of the raster line is not a multiple of 4, then it is padded with 1 to 3 empty (zero) bytes so that the length of the line is a multiple of the paragraph. This is the most unpleasant thing. The fact is that for each format you have to adjust this number of empty bytes (though I like to write part of the palette there, I just don’t want to create extra “zero” variables if these bytes are skipped anyway and no one needs them). I provide a table with formulas that show for which format how many bytes should be added to the end of the line. There, the Width variable, as you might guess, means the width of the image. All these formulas were established experimentally. I will give an example only for the most used formats. For the rest, you can write it yourself.

Example programs

You can download all the sources. I won’t write much here. I'll just give the functions with comments.

Hello 1. Creating a picture in bmp format.
Here a monochromatic picture is created. There are three examples of such functions: creating bmp 8, 16 and 24 bits. I will give only for 16-bit.

// Let's create a picture in bmp format 16 bits like 5-5-5, which will be simply monochromatic
void CreateBmp555(char * fname, WORD color)
{
HANDLE hFile;
DWORD RW;
int i, j;

// Declare the necessary structures
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
BYTE Palette[1024]; // Palette

// Let's have an image of 35 x 50 pixels
int Width = 35 ;
int Height = 50 ;

memset(Palette, 0, 1024); // In the palette we have zeros, fill them
memset (&bfh, 0 , sizeof (bfh) ) ;

Bfh.bfType = 0x4D42 ; // Let's denote that this is bmp "BM"
bfh.bfOffBits = sizeof (bfh) + sizeof (bih) + 1024 ; // The palette takes up 1Kb, but we won't use it
bfh.bfSize = bfh.bfOffBits +
sizeof(color) * Width * Height +
Height * ((sizeof (color) * Width) % 4 ) ; // Calculate the size of the final file
memset (&bih, 0 , sizeof (bih) ) ;
bih.biSize = sizeof(bih); // That's how it's supposed to be
bih.biBitCount = 16 ; // 16 bits per pixel
bih.biClrUsed = 32768 ; // We use 5-5-5
bih.biCompression = BI_RGB; // No compression
bih.biHeight = Height;
bih.biWidth = Width;
bih.biPlanes = 1 ; // Should be 1
// And the remaining fields remain 0

HFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return ;

// Write the headers
WriteFile (hFile, & bfh, sizeof (bfh) , & RW, NULL ) ;
WriteFile (hFile, & bih, sizeof (bih) , & RW, NULL ) ;

// Write the palette
WriteFile(hFile, Palette, 1024, &RW, NULL);
for (i = 0 ; i< Height; i++ )
{
for (j = 0 ; j< Width; j++ )
{
WriteFile (hFile, & color, sizeof (color) , & RW, NULL ) ;
}

// Align with the border
WriteFile (hFile, Palette, (sizeof (color) * Width) % 4 , & RW, NULL ) ;
}
CloseHandle(hFile) ;
}

color - picture color. The value of this variable must be filled in according to the first table. You can view the resulting picture in ACDSee, for example. I just tried to open it in Photoshop, but it turned out that it can’t read them in this format. But you can :).

Example 2. Converting a picture from 8-bit format (256 colors) to 24-bit.

BOOL Convert256To24 (char * fin, char * fout)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
int Width, Height;
RGBQUAD Palette[ 256 ] ;
BYTE * inBuf;
RGBTRIPLE * outBuf;
HANDLE hIn, hOut;
DWORD RW;
DWORD OffBits;
int i, j;

HIn = CreateFile (fin, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL) ;
if (hIn == INVALID_HANDLE_VALUE)
return FALSE;

HOut = CreateFile(fout, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hOut == INVALID_HANDLE_VALUE)
{
CloseHandle(hIn);
return FALSE;
}

// Read the data
ReadFile (hIn, & bfh, sizeof (bfh) , & RW, NULL ) ;
ReadFile (hIn, & bih, sizeof (bih) , & RW, NULL ) ;
ReadFile (hIn, Palette, 256 * sizeof (RGBQUAD) , & RW, NULL ) ;

// Set the pointer to the beginning of the raster
SetFilePointer (hIn, bfh.bfOffBits, NULL, FILE_BEGIN) ;
Width = bih.biWidth ;
Height = bih.biHeight ;
OffBits = bfh.bfOffBits ;

// Allocate memory
inBuf = new BYTE [ Width ] ;
outBuf = new RGBTRIPLE [ Width ] ;

// Fill in the headers
bfh.bfOffBits = sizeof (bfh) + sizeof (bih) ; // Let's not write a palette
bih.biBitCount = 24 ;
bfh.bfSize = bfh.bfOffBits + 4 * Width * Height + Height * (Width % 4 ) ; // File size

// And the rest remains unchanged
// Write the headers
WriteFile (hOut, & bfh, sizeof (bfh) , & RW, NULL ) ;
WriteFile (hOut, & bih, sizeof (bih) , & RW, NULL ) ;

// Let's start converting
for (i = 0 ; i< Height; i++ )
{
ReadFile(hIn, inBuf, Width, & RW, NULL);
for (j = 0 ; j< Width; j++ )
{
outBuf[ j].rgbtRed = Palette[ inBuf[ j] ] .rgbRed ;
outBuf[ j].rgbtGreen = Palette[ inBuf[ j] ] .rgbGreen ;
outBuf[ j].rgbtBlue = Palette[ inBuf[ j] ] .rgbBlue ;
}
WriteFile (hOut, outBuf, sizeof (RGBTRIPLE) * Width, & RW, NULL ) ;

// Write garbage for alignment
WriteFile (hOut, Palette, Width % 4 , & RW, NULL ) ;
SetFilePointer(hIn, (3 * Width) % 4, NULL, FILE_CURRENT) ;
}

delete inBuf;
delete outBuf;
CloseHandle(hIn);
CloseHandle(hOut);
return TRUE;
}

The names of the source and destination files must be passed to the function, respectively.

If you have installed on your computer antivirus program Can scan all files on your computer, as well as each file individually. You can scan any file by right-clicking on the file and selecting the appropriate option to scan the file for viruses.

For example, in this figure it is highlighted file my-file.bmp, then you need to right-click on this file and select the option in the file menu "scan with AVG". When you select this option, AVG Antivirus will open and scan the file for viruses.


Sometimes an error may occur as a result incorrect software installation, which may be due to a problem encountered during the installation process. This may interfere with your operating system link your BMP file to the correct application tool, influencing the so-called "file extension associations".

Sometimes simple reinstalling Adobe Illustrator CC can solve your problem by linking BMP correctly with Adobe Illustrator CC. In other cases, problems with file associations may result from bad software programming developer and you may need to contact the developer for further assistance.


Advice: Try updating Adobe Illustrator CC to the latest version to ensure you have the latest fixes and updates.


This may seem too obvious, but often The BMP file itself may be causing the problem. If you received a file via an email attachment or downloaded it from a website and the download process was interrupted (such as a power outage or other reason), the file may become damaged. If possible, try getting a new copy of the BMP file and try opening it again.


Carefully: A damaged file can cause collateral damage to previous or existing malware on your PC, so it is important to keep your computer up-to-date with an up-to-date antivirus.


If your file is BMP related to the hardware on your computer to open the file you may need update device drivers associated with this equipment.

This problem usually associated with media file types, which depend on successfully opening the hardware inside the computer, e.g. sound card or video card. For example, if you are trying to open an audio file but cannot open it, you may need to update sound card drivers.


Advice: If when you try to open a BMP file you receive .SYS file error message, the problem could probably be associated with corrupted or outdated device drivers that need to be updated. This process can be made easier by using driver update software such as DriverDoc.


If the steps do not solve the problem and you are still having problems opening BMP files, this could be due to lack of available system resources. Some versions of BMP files may require a significant amount of resources (e.g. memory/RAM, processing power) to properly open on your computer. This problem is quite common if you are using fairly old computer hardware and at the same time a much newer operating system.

This problem can occur when the computer is having difficulty keeping up with a task because the operating system (and other services running in the background) may consume too many resources to open a BMP file. Try closing all applications on your PC before opening Bitmap Image File. Freeing up all available resources on your computer will provide you with the best conditions for attempting to open your BMP file.


If you completed all the steps described above and your BMP file still won't open, you may need to run equipment update. In most cases, even when using older versions of hardware, the processing power can still be more than sufficient for most user applications (unless you're doing a lot of CPU-intensive work, such as 3D rendering, financial/scientific modeling, or intensive multimedia work) . Thus, it is likely that your computer does not have enough memory(commonly called "RAM" or random access memory) to perform the task of opening a file.




Top