2 This library provides BMP image decoding capability.
4 Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <IndustryStandard/Bmp.h>
17 #include <Protocol/GraphicsOutput.h>
18 #include <Library/BaseLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/ImageDecoderLib.h>
24 Convert a *.BMP graphics image to a callee allocated GOP blt buffer.
26 @param ImageFormat Format of the image file.
27 @param BmpImage Pointer to BMP file
28 @param BmpImageSize Number of bytes in BmpImage
29 @param GopBlt Buffer containing GOP version of BmpImage.
30 @param GopBltSize Size of GopBlt in bytes.
31 @param PixelHeight Height of GopBlt/BmpImage in pixels
32 @param PixelWidth Width of GopBlt/BmpImage in pixels
34 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
35 @retval EFI_INVALID_PARAMETER GopBlt or GopBltSize is NULL.
36 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
37 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
42 BmpImageDecoderLibConvertBmpToGopBlt (
43 IN IMAGE_FORMAT ImageFormat
,
45 IN UINTN BmpImageSize
,
46 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
**GopBlt
,
47 OUT UINTN
*GopBltSize
,
48 OUT UINTN
*PixelWidth
,
49 OUT UINTN
*PixelHeight
54 BMP_IMAGE_HEADER
*BmpHeader
;
55 BMP_COLOR_MAP
*BmpColorMap
;
56 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
57 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Blt
;
63 UINT32 DataSizePerLine
;
66 ASSERT ((GopBlt
!= NULL
) && (GopBltSize
!= NULL
));
68 if (ImageFormat
!= ImageFormatBmp
) {
69 return EFI_UNSUPPORTED
;
72 if (sizeof (BMP_IMAGE_HEADER
) > BmpImageSize
) {
73 return EFI_UNSUPPORTED
;
76 BmpHeader
= (BMP_IMAGE_HEADER
*) BmpImage
;
78 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M') {
79 return EFI_UNSUPPORTED
;
83 // Doesn't support compress.
85 if (BmpHeader
->CompressionType
!= 0) {
86 return EFI_UNSUPPORTED
;
90 // Only support BITMAPINFOHEADER format.
91 // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
93 if (BmpHeader
->HeaderSize
!= sizeof (BMP_IMAGE_HEADER
) - OFFSET_OF(BMP_IMAGE_HEADER
, HeaderSize
)) {
94 return EFI_UNSUPPORTED
;
98 // The data size in each line must be 4 byte alignment.
100 DataSizePerLine
= ((BmpHeader
->PixelWidth
* BmpHeader
->BitPerPixel
+ 31) >> 3) & (~0x3);
101 BltBufferSize
= MultU64x32 (DataSizePerLine
, BmpHeader
->PixelHeight
);
102 if (BltBufferSize
> (UINT32
) ~0) {
103 return EFI_INVALID_PARAMETER
;
106 if ((BmpHeader
->Size
!= BmpImageSize
) ||
107 (BmpHeader
->Size
< BmpHeader
->ImageOffset
) ||
108 (BmpHeader
->Size
- BmpHeader
->ImageOffset
!= BmpHeader
->PixelHeight
* DataSizePerLine
)) {
109 return EFI_INVALID_PARAMETER
;
113 // Calculate Color Map offset in the image.
116 BmpColorMap
= (BMP_COLOR_MAP
*) (Image
+ sizeof (BMP_IMAGE_HEADER
));
117 if (BmpHeader
->ImageOffset
< sizeof (BMP_IMAGE_HEADER
)) {
118 return EFI_INVALID_PARAMETER
;
121 if (BmpHeader
->ImageOffset
> sizeof (BMP_IMAGE_HEADER
)) {
122 switch (BmpHeader
->BitPerPixel
) {
137 // BMP file may has padding data between the bmp header section and the bmp data section.
139 if (BmpHeader
->ImageOffset
- sizeof (BMP_IMAGE_HEADER
) < sizeof (BMP_COLOR_MAP
) * ColorMapNum
) {
140 return EFI_INVALID_PARAMETER
;
145 // Calculate graphics image data address in the image
147 Image
= ((UINT8
*) BmpImage
) + BmpHeader
->ImageOffset
;
151 // Calculate the BltBuffer needed size.
153 BltBufferSize
= MultU64x32 ((UINT64
) BmpHeader
->PixelWidth
, BmpHeader
->PixelHeight
);
155 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
157 if (BltBufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
158 return EFI_UNSUPPORTED
;
160 BltBufferSize
= MultU64x32 (BltBufferSize
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
162 *GopBltSize
= (UINTN
) BltBufferSize
;
163 *GopBlt
= AllocatePool (*GopBltSize
);
164 if (*GopBlt
== NULL
) {
165 return EFI_OUT_OF_RESOURCES
;
168 *PixelWidth
= BmpHeader
->PixelWidth
;
169 *PixelHeight
= BmpHeader
->PixelHeight
;
172 // Convert image from BMP to Blt buffer format
175 for (Height
= 0; Height
< BmpHeader
->PixelHeight
; Height
++) {
176 Blt
= &BltBuffer
[(BmpHeader
->PixelHeight
- Height
- 1) * BmpHeader
->PixelWidth
];
177 for (Width
= 0; Width
< BmpHeader
->PixelWidth
; Width
++, Image
++, Blt
++) {
178 switch (BmpHeader
->BitPerPixel
) {
181 // Convert 1-bit (2 colors) BMP to 24-bit color
183 for (Index
= 0; Index
< 8 && Width
< BmpHeader
->PixelWidth
; Index
++) {
184 Blt
->Red
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Red
;
185 Blt
->Green
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Green
;
186 Blt
->Blue
= BmpColorMap
[((*Image
) >> (7 - Index
)) & 0x1].Blue
;
197 // Convert 4-bit (16 colors) BMP Palette to 24-bit color
199 Index
= (*Image
) >> 4;
200 Blt
->Red
= BmpColorMap
[Index
].Red
;
201 Blt
->Green
= BmpColorMap
[Index
].Green
;
202 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
203 if (Width
< (BmpHeader
->PixelWidth
- 1)) {
206 Index
= (*Image
) & 0x0f;
207 Blt
->Red
= BmpColorMap
[Index
].Red
;
208 Blt
->Green
= BmpColorMap
[Index
].Green
;
209 Blt
->Blue
= BmpColorMap
[Index
].Blue
;
215 // Convert 8-bit (256 colors) BMP Palette to 24-bit color
217 Blt
->Red
= BmpColorMap
[*Image
].Red
;
218 Blt
->Green
= BmpColorMap
[*Image
].Green
;
219 Blt
->Blue
= BmpColorMap
[*Image
].Blue
;
226 Blt
->Blue
= *Image
++;
227 Blt
->Green
= *Image
++;
233 // Other bit format BMP is not supported.
235 return EFI_UNSUPPORTED
;
241 ImageIndex
= (UINTN
) (Image
- ImageHeader
);
242 if ((ImageIndex
% 4) != 0) {
244 // Bmp Image starts each row on a 32-bit boundary!
246 Image
= Image
+ (4 - (ImageIndex
% 4));
254 Initialize BmpImageDecoderLib library.
256 @param ImageHandle The image handle.
257 @param SystemTable The system table.
259 @retval EFI_SUCCESS The BmpImageDecoderLib library is initialized correctly.
260 @return Other value if failed to initialize the BmpImageDecoderLib library.
264 BmpImageDecoderLibConstructor (
265 IN EFI_HANDLE ImageHandle
,
266 IN EFI_SYSTEM_TABLE
*SystemTable
269 RegisterImageDecoder (BmpImageDecoderLibConvertBmpToGopBlt
);