]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c
MdeModulePkg/BmpImageDecoderLib: Fix function header comments
[mirror_edk2.git] / MdeModulePkg / Library / BmpImageDecoderLib / BmpImageDecoderLib.c
CommitLineData
328de7ae
RN
1/** @file\r
2 This library provides BMP image decoding capability.\r
3\r
4Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials are licensed and made available under\r
6the terms and conditions of the BSD License that accompanies this distribution.\r
7The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php.\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Uefi.h>\r
16#include <IndustryStandard/Bmp.h>\r
17#include <Protocol/GraphicsOutput.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/ImageDecoderLib.h>\r
22\r
23/**\r
24 Convert a *.BMP graphics image to a callee allocated GOP blt buffer.\r
25\r
26 @param ImageFormat Format of the image file.\r
ecbff749
RN
27 @param BmpImage Pointer to BMP file.\r
28 @param BmpImageSize Number of bytes in BmpImage.\r
328de7ae
RN
29 @param GopBlt Buffer containing GOP version of BmpImage.\r
30 @param GopBltSize Size of GopBlt in bytes.\r
ecbff749
RN
31 @param PixelWidth Width of GopBlt/BmpImage in pixels.\r
32 @param PixelHeight Height of GopBlt/BmpImage in pixels.\r
328de7ae
RN
33\r
34 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.\r
35 @retval EFI_INVALID_PARAMETER GopBlt or GopBltSize is NULL.\r
36 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image\r
37 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.\r
38\r
39**/\r
40EFI_STATUS\r
41EFIAPI\r
42BmpImageDecoderLibConvertBmpToGopBlt (\r
43 IN IMAGE_FORMAT ImageFormat,\r
44 IN UINT8 *BmpImage,\r
45 IN UINTN BmpImageSize,\r
46 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **GopBlt,\r
47 OUT UINTN *GopBltSize,\r
48 OUT UINTN *PixelWidth,\r
49 OUT UINTN *PixelHeight\r
50 )\r
51{\r
52 UINT8 *Image;\r
53 UINT8 *ImageHeader;\r
54 BMP_IMAGE_HEADER *BmpHeader;\r
55 BMP_COLOR_MAP *BmpColorMap;\r
56 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
57 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
58 UINT64 BltBufferSize;\r
59 UINTN Index;\r
60 UINTN Height;\r
61 UINTN Width;\r
62 UINTN ImageIndex;\r
63 UINT32 DataSizePerLine;\r
64 UINT32 ColorMapNum;\r
65\r
66 ASSERT ((GopBlt != NULL) && (GopBltSize != NULL));\r
67\r
b3535ab4 68 if ((ImageFormat != ImageFormatBmp) && (ImageFormat != ImageFormatUnknown)) {\r
328de7ae
RN
69 return EFI_UNSUPPORTED;\r
70 }\r
71\r
72 if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {\r
73 return EFI_UNSUPPORTED;\r
74 }\r
75\r
76 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
77\r
78 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
79 return EFI_UNSUPPORTED;\r
80 }\r
81\r
82 //\r
83 // Doesn't support compress.\r
84 //\r
85 if (BmpHeader->CompressionType != 0) {\r
86 return EFI_UNSUPPORTED;\r
87 }\r
88\r
89 //\r
90 // Only support BITMAPINFOHEADER format.\r
91 // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER\r
92 //\r
93 if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {\r
94 return EFI_UNSUPPORTED;\r
95 }\r
96\r
97 //\r
98 // The data size in each line must be 4 byte alignment.\r
99 //\r
100 DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);\r
101 BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);\r
102 if (BltBufferSize > (UINT32) ~0) {\r
103 return EFI_INVALID_PARAMETER;\r
104 }\r
105\r
106 if ((BmpHeader->Size != BmpImageSize) || \r
107 (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
108 (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {\r
109 return EFI_INVALID_PARAMETER;\r
110 }\r
111\r
112 //\r
113 // Calculate Color Map offset in the image.\r
114 //\r
115 Image = BmpImage;\r
116 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
117 if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {\r
118 return EFI_INVALID_PARAMETER;\r
119 }\r
120\r
121 if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {\r
122 switch (BmpHeader->BitPerPixel) {\r
123 case 1:\r
124 ColorMapNum = 2;\r
125 break;\r
126 case 4:\r
127 ColorMapNum = 16;\r
128 break;\r
129 case 8:\r
130 ColorMapNum = 256;\r
131 break;\r
132 default:\r
133 ColorMapNum = 0;\r
134 break;\r
135 }\r
136 //\r
137 // BMP file may has padding data between the bmp header section and the bmp data section.\r
138 //\r
139 if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
140 return EFI_INVALID_PARAMETER;\r
141 }\r
142 }\r
143\r
144 //\r
145 // Calculate graphics image data address in the image\r
146 //\r
147 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
148 ImageHeader = Image;\r
149\r
150 //\r
151 // Calculate the BltBuffer needed size.\r
152 //\r
153 BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
154 //\r
155 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
156 //\r
157 if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
158 return EFI_UNSUPPORTED;\r
159 }\r
160 BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
161\r
162 *GopBltSize = (UINTN) BltBufferSize;\r
163 *GopBlt = AllocatePool (*GopBltSize);\r
164 if (*GopBlt == NULL) {\r
165 return EFI_OUT_OF_RESOURCES;\r
166 }\r
167\r
168 *PixelWidth = BmpHeader->PixelWidth;\r
169 *PixelHeight = BmpHeader->PixelHeight;\r
170\r
171 //\r
172 // Convert image from BMP to Blt buffer format\r
173 //\r
174 BltBuffer = *GopBlt;\r
175 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
176 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
177 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
178 switch (BmpHeader->BitPerPixel) {\r
179 case 1:\r
180 //\r
181 // Convert 1-bit (2 colors) BMP to 24-bit color\r
182 //\r
183 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
184 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
185 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
186 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
187 Blt++;\r
188 Width++;\r
189 }\r
190\r
191 Blt--;\r
192 Width--;\r
193 break;\r
194\r
195 case 4:\r
196 //\r
197 // Convert 4-bit (16 colors) BMP Palette to 24-bit color\r
198 //\r
199 Index = (*Image) >> 4;\r
200 Blt->Red = BmpColorMap[Index].Red;\r
201 Blt->Green = BmpColorMap[Index].Green;\r
202 Blt->Blue = BmpColorMap[Index].Blue;\r
203 if (Width < (BmpHeader->PixelWidth - 1)) {\r
204 Blt++;\r
205 Width++;\r
206 Index = (*Image) & 0x0f;\r
207 Blt->Red = BmpColorMap[Index].Red;\r
208 Blt->Green = BmpColorMap[Index].Green;\r
209 Blt->Blue = BmpColorMap[Index].Blue;\r
210 }\r
211 break;\r
212\r
213 case 8:\r
214 //\r
215 // Convert 8-bit (256 colors) BMP Palette to 24-bit color\r
216 //\r
217 Blt->Red = BmpColorMap[*Image].Red;\r
218 Blt->Green = BmpColorMap[*Image].Green;\r
219 Blt->Blue = BmpColorMap[*Image].Blue;\r
220 break;\r
221\r
222 case 24:\r
223 //\r
224 // It is 24-bit BMP.\r
225 //\r
226 Blt->Blue = *Image++;\r
227 Blt->Green = *Image++;\r
228 Blt->Red = *Image;\r
229 break;\r
230\r
231 default:\r
232 //\r
233 // Other bit format BMP is not supported.\r
234 //\r
235 return EFI_UNSUPPORTED;\r
236 break;\r
237 };\r
238\r
239 }\r
240\r
241 ImageIndex = (UINTN) (Image - ImageHeader);\r
242 if ((ImageIndex % 4) != 0) {\r
243 //\r
244 // Bmp Image starts each row on a 32-bit boundary!\r
245 //\r
246 Image = Image + (4 - (ImageIndex % 4));\r
247 }\r
248 }\r
249\r
250 return EFI_SUCCESS;\r
251}\r
252\r
253/**\r
254 Initialize BmpImageDecoderLib library.\r
255\r
256 @param ImageHandle The image handle.\r
257 @param SystemTable The system table.\r
258\r
259 @retval EFI_SUCCESS The BmpImageDecoderLib library is initialized correctly.\r
260 @return Other value if failed to initialize the BmpImageDecoderLib library.\r
261**/\r
262EFI_STATUS\r
263EFIAPI\r
264BmpImageDecoderLibConstructor (\r
265 IN EFI_HANDLE ImageHandle,\r
266 IN EFI_SYSTEM_TABLE *SystemTable\r
267)\r
268{\r
269 RegisterImageDecoder (BmpImageDecoderLibConvertBmpToGopBlt);\r
270 return EFI_SUCCESS;\r
271}\r
272\r