]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
MdeModulePkg/HiiDB: Make sure database update behaviors are atomic
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Image.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_IMAGE_PROTOCOL.\r
3\r
93e3992d 4\r
d1102dba 5Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 6This program and the accompanying materials\r
93e3992d 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
e90b081a 14**/\r
93e3992d 15\r
93e3992d 16\r
e90b081a 17#include "HiiDatabase.h"\r
93e3992d 18\r
19\r
e90b081a 20/**\r
21 Get the imageid of last image block: EFI_HII_IIBT_END_BLOCK when input\r
22 ImageId is zero, otherwise return the address of the\r
23 corresponding image block with identifier specified by ImageId.\r
93e3992d 24\r
e90b081a 25 This is a internal function.\r
93e3992d 26\r
7c28fcb8 27 @param ImageBlocks Points to the beginning of a series of image blocks stored in order.\r
e90b081a 28 @param ImageId If input ImageId is 0, output the image id of the EFI_HII_IIBT_END_BLOCK;\r
29 else use this id to find its corresponding image block address.\r
93e3992d 30\r
e90b081a 31 @return The image block address when input ImageId is not zero; otherwise return NULL.\r
93e3992d 32\r
e90b081a 33**/\r
7c28fcb8 34EFI_HII_IMAGE_BLOCK *\r
93e3992d 35GetImageIdOrAddress (\r
7c28fcb8
RN
36 IN EFI_HII_IMAGE_BLOCK *ImageBlocks,\r
37 IN OUT EFI_IMAGE_ID *ImageId\r
93e3992d 38 )\r
93e3992d 39{\r
40 EFI_IMAGE_ID ImageIdCurrent;\r
7c28fcb8
RN
41 EFI_HII_IMAGE_BLOCK *CurrentImageBlock;\r
42 UINTN Length;\r
43\r
44 ASSERT (ImageBlocks != NULL && ImageId != NULL);\r
45 CurrentImageBlock = ImageBlocks;\r
46 ImageIdCurrent = 1;\r
47\r
48 while (CurrentImageBlock->BlockType != EFI_HII_IIBT_END) {\r
49 if (*ImageId != 0) {\r
93e3992d 50 if (*ImageId == ImageIdCurrent) {\r
51 //\r
52 // If the found image block is a duplicate block, update the ImageId to\r
53 // find the previous defined image block.\r
54 //\r
7c28fcb8
RN
55 if (CurrentImageBlock->BlockType == EFI_HII_IIBT_DUPLICATE) {\r
56 *ImageId = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_DUPLICATE_BLOCK *) CurrentImageBlock)->ImageId);\r
93e3992d 57 ASSERT (*ImageId != ImageIdCurrent);\r
7c28fcb8
RN
58 ASSERT (*ImageId != 0);\r
59 CurrentImageBlock = ImageBlocks;\r
93e3992d 60 ImageIdCurrent = 1;\r
61 continue;\r
62 }\r
63\r
7c28fcb8 64 return CurrentImageBlock;\r
93e3992d 65 }\r
66 if (*ImageId < ImageIdCurrent) {\r
67 //\r
68 // Can not find the specified image block in this image.\r
69 //\r
70 return NULL;\r
71 }\r
72 }\r
7c28fcb8 73 switch (CurrentImageBlock->BlockType) {\r
93e3992d 74 case EFI_HII_IIBT_EXT1:\r
7c28fcb8 75 Length = ((EFI_HII_IIBT_EXT1_BLOCK *) CurrentImageBlock)->Length;\r
93e3992d 76 break;\r
77 case EFI_HII_IIBT_EXT2:\r
7c28fcb8 78 Length = ReadUnaligned16 (&((EFI_HII_IIBT_EXT2_BLOCK *) CurrentImageBlock)->Length);\r
93e3992d 79 break;\r
80 case EFI_HII_IIBT_EXT4:\r
7c28fcb8 81 Length = ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_EXT4_BLOCK *) CurrentImageBlock)->Length);\r
93e3992d 82 break;\r
83\r
84 case EFI_HII_IIBT_IMAGE_1BIT:\r
85 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:\r
7c28fcb8
RN
86 Length = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +\r
87 BITMAP_LEN_1_BIT (\r
88 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
89 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
90 );\r
93e3992d 91 ImageIdCurrent++;\r
92 break;\r
93\r
94 case EFI_HII_IIBT_IMAGE_4BIT:\r
95 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:\r
7c28fcb8
RN
96 Length = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +\r
97 BITMAP_LEN_4_BIT (\r
98 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
99 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
100 );\r
93e3992d 101 ImageIdCurrent++;\r
102 break;\r
103\r
104 case EFI_HII_IIBT_IMAGE_8BIT:\r
105 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:\r
7c28fcb8
RN
106 Length = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +\r
107 BITMAP_LEN_8_BIT (\r
f76bc443 108 (UINT32) ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
7c28fcb8
RN
109 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
110 );\r
93e3992d 111 ImageIdCurrent++;\r
112 break;\r
113\r
114 case EFI_HII_IIBT_IMAGE_24BIT:\r
115 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
7c28fcb8
RN
116 Length = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
117 BITMAP_LEN_24_BIT (\r
f76bc443 118 (UINT32) ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
7c28fcb8
RN
119 ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
120 );\r
93e3992d 121 ImageIdCurrent++;\r
122 break;\r
123\r
124 case EFI_HII_IIBT_DUPLICATE:\r
7c28fcb8 125 Length = sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK);\r
93e3992d 126 ImageIdCurrent++;\r
127 break;\r
128\r
129 case EFI_HII_IIBT_IMAGE_JPEG:\r
c0c7d58d
RN
130 Length = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size);\r
131 ImageIdCurrent++;\r
132 break;\r
133\r
134 case EFI_HII_IIBT_IMAGE_PNG:\r
135 Length = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size);\r
93e3992d 136 ImageIdCurrent++;\r
137 break;\r
138\r
139 case EFI_HII_IIBT_SKIP1:\r
7c28fcb8
RN
140 Length = sizeof (EFI_HII_IIBT_SKIP1_BLOCK);\r
141 ImageIdCurrent += ((EFI_HII_IIBT_SKIP1_BLOCK *) CurrentImageBlock)->SkipCount;\r
93e3992d 142 break;\r
143\r
144 case EFI_HII_IIBT_SKIP2:\r
7c28fcb8
RN
145 Length = sizeof (EFI_HII_IIBT_SKIP2_BLOCK);\r
146 ImageIdCurrent += ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_SKIP2_BLOCK *) CurrentImageBlock)->SkipCount);\r
93e3992d 147 break;\r
148\r
149 default:\r
150 //\r
151 // Unknown image blocks can not be skipped, processing halts.\r
152 //\r
153 ASSERT (FALSE);\r
7c28fcb8
RN
154 Length = 0;\r
155 break;\r
93e3992d 156 }\r
7c28fcb8
RN
157\r
158 CurrentImageBlock = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) CurrentImageBlock + Length);\r
159\r
93e3992d 160 }\r
161\r
162 //\r
163 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.\r
164 //\r
165 if (*ImageId == 0) {\r
166 *ImageId = ImageIdCurrent;\r
7c28fcb8 167 return CurrentImageBlock;\r
93e3992d 168 }\r
169\r
170 return NULL;\r
171}\r
172\r
173\r
174\r
175/**\r
176 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.\r
177\r
e90b081a 178 This is a internal function.\r
179\r
180\r
93e3992d 181 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.\r
182 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.\r
183 @param PixelNum The number of pixels to be converted.\r
184\r
185\r
186**/\r
93e3992d 187VOID\r
188CopyGopToRgbPixel (\r
189 OUT EFI_HII_RGB_PIXEL *BitMapOut,\r
190 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapIn,\r
191 IN UINTN PixelNum\r
192 )\r
193{\r
194 UINTN Index;\r
195\r
196 ASSERT (BitMapOut != NULL && BitMapIn != NULL);\r
197\r
198 for (Index = 0; Index < PixelNum; Index++) {\r
199 CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));\r
200 }\r
201}\r
202\r
203\r
204/**\r
205 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.\r
206\r
e90b081a 207 This is a internal function.\r
208\r
209\r
93e3992d 210 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.\r
211 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.\r
212 @param PixelNum The number of pixels to be converted.\r
213\r
214\r
215**/\r
93e3992d 216VOID\r
217CopyRgbToGopPixel (\r
218 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapOut,\r
219 IN EFI_HII_RGB_PIXEL *BitMapIn,\r
220 IN UINTN PixelNum\r
221 )\r
222{\r
223 UINTN Index;\r
224\r
225 ASSERT (BitMapOut != NULL && BitMapIn != NULL);\r
226\r
227 for (Index = 0; Index < PixelNum; Index++) {\r
228 CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));\r
229 }\r
230}\r
231\r
232\r
233/**\r
234 Output pixels in "1 bit per pixel" format to an image.\r
235\r
e90b081a 236 This is a internal function.\r
237\r
238\r
93e3992d 239 @param Image Points to the image which will store the pixels.\r
240 @param Data Stores the value of output pixels, 0 or 1.\r
241 @param PaletteInfo PaletteInfo which stores the color of the output\r
242 pixels. First entry corresponds to color 0 and\r
243 second one to color 1.\r
244\r
245\r
246**/\r
93e3992d 247VOID\r
248Output1bitPixel (\r
249 IN OUT EFI_IMAGE_INPUT *Image,\r
250 IN UINT8 *Data,\r
251 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo\r
252 )\r
253{\r
e90b081a 254 UINT16 Xpos;\r
255 UINT16 Ypos;\r
93e3992d 256 UINTN OffsetY;\r
257 UINT8 Index;\r
258 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;\r
259 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[2];\r
260 EFI_HII_IMAGE_PALETTE_INFO *Palette;\r
2a244a5d 261 UINTN PaletteSize;\r
93e3992d 262 UINT8 Byte;\r
263\r
264 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);\r
265\r
266 BitMapPtr = Image->Bitmap;\r
267\r
268 //\r
269 // First entry corresponds to color 0 and second entry corresponds to color 1.\r
270 //\r
2a244a5d 271 PaletteSize = 0;\r
93e3992d 272 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
273 PaletteSize += sizeof (UINT16);\r
274 Palette = AllocateZeroPool (PaletteSize);\r
275 ASSERT (Palette != NULL);\r
2a244a5d
ED
276 if (Palette == NULL) {\r
277 return;\r
278 }\r
93e3992d 279 CopyMem (Palette, PaletteInfo, PaletteSize);\r
280\r
281 ZeroMem (PaletteValue, sizeof (PaletteValue));\r
282 CopyRgbToGopPixel (&PaletteValue[0], &Palette->PaletteValue[0], 1);\r
283 CopyRgbToGopPixel (&PaletteValue[1], &Palette->PaletteValue[1], 1);\r
676df92c 284 FreePool (Palette);\r
93e3992d 285\r
286 //\r
287 // Convert the pixel from one bit to corresponding color.\r
288 //\r
e90b081a 289 for (Ypos = 0; Ypos < Image->Height; Ypos++) {\r
290 OffsetY = BITMAP_LEN_1_BIT (Image->Width, Ypos);\r
93e3992d 291 //\r
292 // All bits in these bytes are meaningful\r
293 //\r
e90b081a 294 for (Xpos = 0; Xpos < Image->Width / 8; Xpos++) {\r
295 Byte = *(Data + OffsetY + Xpos);\r
93e3992d 296 for (Index = 0; Index < 8; Index++) {\r
297 if ((Byte & (1 << Index)) != 0) {\r
e90b081a 298 BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[1];\r
93e3992d 299 } else {\r
e90b081a 300 BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[0];\r
93e3992d 301 }\r
302 }\r
303 }\r
304\r
305 if (Image->Width % 8 != 0) {\r
306 //\r
307 // Padding bits in this byte should be ignored.\r
308 //\r
e90b081a 309 Byte = *(Data + OffsetY + Xpos);\r
93e3992d 310 for (Index = 0; Index < Image->Width % 8; Index++) {\r
311 if ((Byte & (1 << (8 - Index - 1))) != 0) {\r
e90b081a 312 BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[1];\r
93e3992d 313 } else {\r
e90b081a 314 BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[0];\r
93e3992d 315 }\r
316 }\r
317 }\r
318 }\r
319}\r
320\r
321\r
322/**\r
323 Output pixels in "4 bit per pixel" format to an image.\r
324\r
e90b081a 325 This is a internal function.\r
326\r
327\r
93e3992d 328 @param Image Points to the image which will store the pixels.\r
329 @param Data Stores the value of output pixels, 0 ~ 15.\r
e90b081a 330 @param[in] PaletteInfo PaletteInfo which stores the color of the output\r
93e3992d 331 pixels. Each entry corresponds to a color within\r
332 [0, 15].\r
333\r
334\r
335**/\r
93e3992d 336VOID\r
337Output4bitPixel (\r
338 IN OUT EFI_IMAGE_INPUT *Image,\r
339 IN UINT8 *Data,\r
340 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo\r
341 )\r
342{\r
e90b081a 343 UINT16 Xpos;\r
344 UINT16 Ypos;\r
93e3992d 345 UINTN OffsetY;\r
346 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;\r
347 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[16];\r
348 EFI_HII_IMAGE_PALETTE_INFO *Palette;\r
2a244a5d 349 UINTN PaletteSize;\r
93e3992d 350 UINT16 PaletteNum;\r
351 UINT8 Byte;\r
352\r
353 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);\r
354\r
355 BitMapPtr = Image->Bitmap;\r
356\r
357 //\r
358 // The bitmap should allocate each color index starting from 0.\r
359 //\r
2a244a5d 360 PaletteSize = 0;\r
93e3992d 361 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
362 PaletteSize += sizeof (UINT16);\r
363 Palette = AllocateZeroPool (PaletteSize);\r
364 ASSERT (Palette != NULL);\r
2a244a5d
ED
365 if (Palette == NULL) {\r
366 return;\r
367 }\r
93e3992d 368 CopyMem (Palette, PaletteInfo, PaletteSize);\r
369 PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));\r
370\r
371 ZeroMem (PaletteValue, sizeof (PaletteValue));\r
372 CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);\r
676df92c 373 FreePool (Palette);\r
93e3992d 374\r
375 //\r
376 // Convert the pixel from 4 bit to corresponding color.\r
377 //\r
e90b081a 378 for (Ypos = 0; Ypos < Image->Height; Ypos++) {\r
379 OffsetY = BITMAP_LEN_4_BIT (Image->Width, Ypos);\r
93e3992d 380 //\r
381 // All bits in these bytes are meaningful\r
382 //\r
e90b081a 383 for (Xpos = 0; Xpos < Image->Width / 2; Xpos++) {\r
384 Byte = *(Data + OffsetY + Xpos);\r
385 BitMapPtr[Ypos * Image->Width + Xpos * 2] = PaletteValue[Byte >> 4];\r
386 BitMapPtr[Ypos * Image->Width + Xpos * 2 + 1] = PaletteValue[Byte & 0x0F];\r
93e3992d 387 }\r
388\r
389 if (Image->Width % 2 != 0) {\r
390 //\r
391 // Padding bits in this byte should be ignored.\r
392 //\r
e90b081a 393 Byte = *(Data + OffsetY + Xpos);\r
394 BitMapPtr[Ypos * Image->Width + Xpos * 2] = PaletteValue[Byte >> 4];\r
93e3992d 395 }\r
396 }\r
397}\r
398\r
399\r
400/**\r
401 Output pixels in "8 bit per pixel" format to an image.\r
402\r
e90b081a 403 This is a internal function.\r
404\r
405\r
93e3992d 406 @param Image Points to the image which will store the pixels.\r
407 @param Data Stores the value of output pixels, 0 ~ 255.\r
e90b081a 408 @param[in] PaletteInfo PaletteInfo which stores the color of the output\r
93e3992d 409 pixels. Each entry corresponds to a color within\r
410 [0, 255].\r
411\r
412\r
413**/\r
93e3992d 414VOID\r
415Output8bitPixel (\r
416 IN OUT EFI_IMAGE_INPUT *Image,\r
417 IN UINT8 *Data,\r
418 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo\r
419 )\r
420{\r
e90b081a 421 UINT16 Xpos;\r
422 UINT16 Ypos;\r
93e3992d 423 UINTN OffsetY;\r
424 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;\r
425 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[256];\r
426 EFI_HII_IMAGE_PALETTE_INFO *Palette;\r
2a244a5d 427 UINTN PaletteSize;\r
93e3992d 428 UINT16 PaletteNum;\r
429 UINT8 Byte;\r
430\r
431 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);\r
432\r
433 BitMapPtr = Image->Bitmap;\r
434\r
435 //\r
436 // The bitmap should allocate each color index starting from 0.\r
437 //\r
2a244a5d 438 PaletteSize = 0;\r
93e3992d 439 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
440 PaletteSize += sizeof (UINT16);\r
441 Palette = AllocateZeroPool (PaletteSize);\r
442 ASSERT (Palette != NULL);\r
2a244a5d
ED
443 if (Palette == NULL) {\r
444 return;\r
445 }\r
93e3992d 446 CopyMem (Palette, PaletteInfo, PaletteSize);\r
447 PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));\r
448 ZeroMem (PaletteValue, sizeof (PaletteValue));\r
449 CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);\r
676df92c 450 FreePool (Palette);\r
93e3992d 451\r
452 //\r
453 // Convert the pixel from 8 bits to corresponding color.\r
454 //\r
e90b081a 455 for (Ypos = 0; Ypos < Image->Height; Ypos++) {\r
f76bc443 456 OffsetY = BITMAP_LEN_8_BIT ((UINT32) Image->Width, Ypos);\r
93e3992d 457 //\r
458 // All bits are meaningful since the bitmap is 8 bits per pixel.\r
459 //\r
e90b081a 460 for (Xpos = 0; Xpos < Image->Width; Xpos++) {\r
461 Byte = *(Data + OffsetY + Xpos);\r
462 BitMapPtr[OffsetY + Xpos] = PaletteValue[Byte];\r
93e3992d 463 }\r
464 }\r
465\r
466}\r
467\r
468\r
469/**\r
470 Output pixels in "24 bit per pixel" format to an image.\r
471\r
e90b081a 472 This is a internal function.\r
473\r
474\r
93e3992d 475 @param Image Points to the image which will store the pixels.\r
476 @param Data Stores the color of output pixels, allowing 16.8\r
477 millions colors.\r
478\r
479\r
480**/\r
93e3992d 481VOID\r
482Output24bitPixel (\r
483 IN OUT EFI_IMAGE_INPUT *Image,\r
484 IN EFI_HII_RGB_PIXEL *Data\r
485 )\r
486{\r
e90b081a 487 UINT16 Ypos;\r
93e3992d 488 UINTN OffsetY;\r
489 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapPtr;\r
490\r
491 ASSERT (Image != NULL && Data != NULL);\r
492\r
493 BitMapPtr = Image->Bitmap;\r
494\r
e90b081a 495 for (Ypos = 0; Ypos < Image->Height; Ypos++) {\r
f76bc443 496 OffsetY = BITMAP_LEN_8_BIT ((UINT32) Image->Width, Ypos);\r
93e3992d 497 CopyRgbToGopPixel (&BitMapPtr[OffsetY], &Data[OffsetY], Image->Width);\r
498 }\r
499\r
500}\r
501\r
502\r
503/**\r
504 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.\r
505\r
e90b081a 506 This is a internal function.\r
507\r
508\r
93e3992d 509 @param BltBuffer Buffer points to bitmap data of incoming image.\r
e90b081a 510 @param BltX Specifies the offset from the left and top edge of\r
511 the output image of the first pixel in the image.\r
93e3992d 512 @param BltY Specifies the offset from the left and top edge of\r
513 the output image of the first pixel in the image.\r
514 @param Width Width of the incoming image, in pixels.\r
515 @param Height Height of the incoming image, in pixels.\r
516 @param Transparent If TRUE, all "off" pixels in the image will be\r
517 drawn using the pixel value from blt and all other\r
518 pixels will be copied.\r
519 @param Blt Buffer points to bitmap data of output image.\r
520\r
521 @retval EFI_SUCCESS The image was successfully converted.\r
522 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.\r
523\r
524**/\r
93e3992d 525EFI_STATUS\r
526ImageToBlt (\r
527 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,\r
528 IN UINTN BltX,\r
529 IN UINTN BltY,\r
530 IN UINTN Width,\r
531 IN UINTN Height,\r
532 IN BOOLEAN Transparent,\r
533 IN OUT EFI_IMAGE_OUTPUT **Blt\r
534 )\r
535{\r
536 EFI_IMAGE_OUTPUT *ImageOut;\r
e90b081a 537 UINTN Xpos;\r
538 UINTN Ypos;\r
93e3992d 539 UINTN OffsetY1; // src buffer\r
540 UINTN OffsetY2; // dest buffer\r
541 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel;\r
542 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel;\r
543\r
544 if (BltBuffer == NULL || Blt == NULL || *Blt == NULL) {\r
545 return EFI_INVALID_PARAMETER;\r
546 }\r
547\r
548 ImageOut = *Blt;\r
549\r
550 if (Width + BltX > ImageOut->Width) {\r
551 return EFI_INVALID_PARAMETER;\r
552 }\r
553 if (Height + BltY > ImageOut->Height) {\r
554 return EFI_INVALID_PARAMETER;\r
555 }\r
556\r
557 ZeroMem (&ZeroPixel, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
558\r
e90b081a 559 for (Ypos = 0; Ypos < Height; Ypos++) {\r
560 OffsetY1 = Width * Ypos;\r
561 OffsetY2 = ImageOut->Width * (BltY + Ypos);\r
562 for (Xpos = 0; Xpos < Width; Xpos++) {\r
563 SrcPixel = BltBuffer[OffsetY1 + Xpos];\r
93e3992d 564 if (Transparent) {\r
565 if (CompareMem (&SrcPixel, &ZeroPixel, 3) != 0) {\r
e90b081a 566 ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;\r
93e3992d 567 }\r
568 } else {\r
e90b081a 569 ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;\r
93e3992d 570 }\r
571 }\r
572 }\r
573\r
574 return EFI_SUCCESS;\r
575}\r
576\r
9d91ff0e
RN
577/**\r
578 Return the HII package list identified by PackageList HII handle.\r
579\r
580 @param Database Pointer to HII database list header.\r
581 @param PackageList HII handle of the package list to locate.\r
582\r
583 @retval The HII package list instance.\r
584**/\r
585HII_DATABASE_PACKAGE_LIST_INSTANCE *\r
586LocatePackageList (\r
587 IN LIST_ENTRY *Database,\r
588 IN EFI_HII_HANDLE PackageList\r
589 )\r
590{\r
591 LIST_ENTRY *Link;\r
592 HII_DATABASE_RECORD *Record;\r
593\r
594 //\r
595 // Get the specified package list and image package.\r
596 //\r
597 for (Link = GetFirstNode (Database);\r
598 !IsNull (Database, Link);\r
599 Link = GetNextNode (Database, Link)\r
600 ) {\r
601 Record = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
602 if (Record->Handle == PackageList) {\r
603 return Record->PackageList;\r
604 }\r
605 }\r
606 return NULL;\r
607}\r
93e3992d 608\r
609/**\r
610 This function adds the image Image to the group of images owned by PackageList, and returns\r
611 a new image identifier (ImageId).\r
612\r
613 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
614 @param PackageList Handle of the package list where this image will\r
615 be added.\r
616 @param ImageId On return, contains the new image id, which is\r
617 unique within PackageList.\r
618 @param Image Points to the image.\r
619\r
620 @retval EFI_SUCCESS The new image was added successfully.\r
621 @retval EFI_NOT_FOUND The specified PackageList could not be found in\r
622 database.\r
623 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.\r
624 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.\r
625\r
626**/\r
627EFI_STATUS\r
628EFIAPI\r
629HiiNewImage (\r
630 IN CONST EFI_HII_IMAGE_PROTOCOL *This,\r
631 IN EFI_HII_HANDLE PackageList,\r
632 OUT EFI_IMAGE_ID *ImageId,\r
633 IN CONST EFI_IMAGE_INPUT *Image\r
634 )\r
635{\r
636 HII_DATABASE_PRIVATE_DATA *Private;\r
93e3992d 637 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
638 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
4518ff61
RN
639 EFI_HII_IMAGE_BLOCK *ImageBlocks;\r
640 UINT32 NewBlockSize;\r
93e3992d 641\r
813acf3a 642 if (This == NULL || ImageId == NULL || Image == NULL || Image->Bitmap == NULL) {\r
93e3992d 643 return EFI_INVALID_PARAMETER;\r
644 }\r
645\r
93e3992d 646 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
9d91ff0e 647 PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
93e3992d 648 if (PackageListNode == NULL) {\r
649 return EFI_NOT_FOUND;\r
650 }\r
651\r
979b7d80
DB
652 EfiAcquireLock (&mHiiDatabaseLock);\r
653\r
93e3992d 654 NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
f76bc443 655 BITMAP_LEN_24_BIT ((UINT32) Image->Width, Image->Height);\r
93e3992d 656\r
657 //\r
658 // Get the image package in the package list,\r
659 // or create a new image package if image package does not exist.\r
660 //\r
661 if (PackageListNode->ImagePkg != NULL) {\r
662 ImagePackage = PackageListNode->ImagePkg;\r
663\r
664 //\r
665 // Output the image id of the incoming image being inserted, which is the\r
666 // image id of the EFI_HII_IIBT_END block of old image package.\r
667 //\r
668 *ImageId = 0;\r
669 GetImageIdOrAddress (ImagePackage->ImageBlock, ImageId);\r
670\r
671 //\r
672 // Update the package's image block by appending the new block to the end.\r
673 //\r
4518ff61
RN
674 ImageBlocks = AllocatePool (ImagePackage->ImageBlockSize + NewBlockSize);\r
675 if (ImageBlocks == NULL) {\r
979b7d80 676 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 677 return EFI_OUT_OF_RESOURCES;\r
678 }\r
679 //\r
680 // Copy the original content.\r
681 //\r
682 CopyMem (\r
4518ff61 683 ImageBlocks,\r
93e3992d 684 ImagePackage->ImageBlock,\r
685 ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)\r
686 );\r
676df92c 687 FreePool (ImagePackage->ImageBlock);\r
4518ff61
RN
688 ImagePackage->ImageBlock = ImageBlocks;\r
689\r
93e3992d 690 //\r
4518ff61 691 // Point to the very last block.\r
93e3992d 692 //\r
4518ff61
RN
693 ImageBlocks = (EFI_HII_IMAGE_BLOCK *) (\r
694 (UINT8 *) ImageBlocks + ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)\r
695 );\r
93e3992d 696 //\r
697 // Update the length record.\r
698 //\r
4518ff61
RN
699 ImagePackage->ImageBlockSize += NewBlockSize;\r
700 ImagePackage->ImagePkgHdr.Header.Length += NewBlockSize;\r
701 PackageListNode->PackageListHdr.PackageLength += NewBlockSize;\r
93e3992d 702\r
703 } else {\r
704 //\r
705 // The specified package list does not contain image package.\r
706 // Create one to add this image block.\r
707 //\r
708 ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));\r
709 if (ImagePackage == NULL) {\r
979b7d80 710 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 711 return EFI_OUT_OF_RESOURCES;\r
712 }\r
713 //\r
714 // Output the image id of the incoming image being inserted, which is the\r
715 // first image block so that id is initially to one.\r
716 //\r
717 *ImageId = 1;\r
93e3992d 718 //\r
719 // Fill in image package header.\r
720 //\r
4518ff61 721 ImagePackage->ImagePkgHdr.Header.Length = sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);\r
93e3992d 722 ImagePackage->ImagePkgHdr.Header.Type = EFI_HII_PACKAGE_IMAGES;\r
723 ImagePackage->ImagePkgHdr.ImageInfoOffset = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
724 ImagePackage->ImagePkgHdr.PaletteInfoOffset = 0;\r
725\r
726 //\r
727 // Fill in palette info.\r
728 //\r
729 ImagePackage->PaletteBlock = NULL;\r
730 ImagePackage->PaletteInfoSize = 0;\r
731\r
732 //\r
733 // Fill in image blocks.\r
734 //\r
4518ff61
RN
735 ImagePackage->ImageBlockSize = NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);\r
736 ImagePackage->ImageBlock = AllocateZeroPool (NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK));\r
93e3992d 737 if (ImagePackage->ImageBlock == NULL) {\r
676df92c 738 FreePool (ImagePackage);\r
979b7d80 739 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 740 return EFI_OUT_OF_RESOURCES;\r
741 }\r
4518ff61 742 ImageBlocks = ImagePackage->ImageBlock;\r
93e3992d 743\r
744 //\r
745 // Insert this image package.\r
746 //\r
747 PackageListNode->ImagePkg = ImagePackage;\r
748 PackageListNode->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;\r
749 }\r
750\r
751 //\r
752 // Append the new block here\r
753 //\r
4518ff61
RN
754 if (Image->Flags == EFI_IMAGE_TRANSPARENT) {\r
755 ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT_TRANS;\r
93e3992d 756 } else {\r
4518ff61 757 ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT;\r
93e3992d 758 }\r
4518ff61
RN
759 WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Width, Image->Width);\r
760 WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Height, Image->Height);\r
f76bc443 761 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Bitmap, Image->Bitmap, (UINT32) Image->Width * Image->Height);\r
93e3992d 762\r
763 //\r
764 // Append the block end\r
765 //\r
4518ff61
RN
766 ImageBlocks = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) ImageBlocks + NewBlockSize);\r
767 ImageBlocks->BlockType = EFI_HII_IIBT_END;\r
93e3992d 768\r
8a45f80e
DB
769 //\r
770 // Check whether need to get the contents of HiiDataBase.\r
771 // Only after ReadyToBoot to do the export.\r
772 //\r
773 if (gExportAfterReadyToBoot) {\r
774 HiiGetDatabaseInfo(&Private->HiiDatabase);\r
775 }\r
776\r
979b7d80
DB
777 EfiReleaseLock (&mHiiDatabaseLock);\r
778\r
93e3992d 779 return EFI_SUCCESS;\r
780}\r
781\r
782\r
783/**\r
784 This function retrieves the image specified by ImageId which is associated with\r
785 the specified PackageList and copies it into the buffer specified by Image.\r
786\r
101a1122 787 @param Database A pointer to the database list header.\r
93e3992d 788 @param PackageList Handle of the package list where this image will\r
789 be searched.\r
ac644614 790 @param ImageId The image's id,, which is unique within\r
93e3992d 791 PackageList.\r
792 @param Image Points to the image.\r
101a1122
RN
793 @param BitmapOnly TRUE to only return the bitmap type image.\r
794 FALSE to locate image decoder instance to decode image.\r
93e3992d 795\r
796 @retval EFI_SUCCESS The new image was returned successfully.\r
101a1122
RN
797 @retval EFI_NOT_FOUND The image specified by ImageId is not in the\r
798 database. The specified PackageList is not in the database.\r
93e3992d 799 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to\r
800 hold the image.\r
801 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.\r
813acf3a 802 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not\r
101a1122 803 enough memory.\r
93e3992d 804**/\r
805EFI_STATUS\r
101a1122
RN
806IGetImage (\r
807 IN LIST_ENTRY *Database,\r
93e3992d 808 IN EFI_HII_HANDLE PackageList,\r
809 IN EFI_IMAGE_ID ImageId,\r
101a1122
RN
810 OUT EFI_IMAGE_INPUT *Image,\r
811 IN BOOLEAN BitmapOnly\r
93e3992d 812 )\r
813{\r
101a1122 814 EFI_STATUS Status;\r
93e3992d 815 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
816 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
ca1d86e3 817 EFI_HII_IMAGE_BLOCK *CurrentImageBlock;\r
93e3992d 818 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit;\r
819 UINT16 Width;\r
820 UINT16 Height;\r
821 UINTN ImageLength;\r
93e3992d 822 UINT8 *PaletteInfo;\r
823 UINT8 PaletteIndex;\r
824 UINT16 PaletteSize;\r
101a1122
RN
825 EFI_HII_IMAGE_DECODER_PROTOCOL *Decoder;\r
826 EFI_IMAGE_OUTPUT *ImageOut;\r
93e3992d 827\r
101a1122 828 if (Image == NULL || ImageId == 0) {\r
93e3992d 829 return EFI_INVALID_PARAMETER;\r
830 }\r
831\r
101a1122 832 PackageListNode = LocatePackageList (Database, PackageList);\r
93e3992d 833 if (PackageListNode == NULL) {\r
834 return EFI_NOT_FOUND;\r
835 }\r
836 ImagePackage = PackageListNode->ImagePkg;\r
837 if (ImagePackage == NULL) {\r
838 return EFI_NOT_FOUND;\r
839 }\r
840\r
841 //\r
842 // Find the image block specified by ImageId\r
843 //\r
ca1d86e3
RN
844 CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);\r
845 if (CurrentImageBlock == NULL) {\r
93e3992d 846 return EFI_NOT_FOUND;\r
847 }\r
848\r
101a1122 849 Image->Flags = 0;\r
ca1d86e3 850 switch (CurrentImageBlock->BlockType) {\r
93e3992d 851 case EFI_HII_IIBT_IMAGE_JPEG:\r
c0c7d58d 852 case EFI_HII_IIBT_IMAGE_PNG:\r
101a1122
RN
853 if (BitmapOnly) {\r
854 return EFI_UNSUPPORTED;\r
855 }\r
856\r
857 ImageOut = NULL;\r
858 Decoder = LocateHiiImageDecoder (CurrentImageBlock->BlockType);\r
859 if (Decoder == NULL) {\r
860 return EFI_UNSUPPORTED;\r
861 }\r
93e3992d 862 //\r
101a1122 863 // Use the common block code since the definition of two structures is the same.\r
93e3992d 864 //\r
101a1122
RN
865 ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data));\r
866 ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data) ==\r
867 sizeof (((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Data));\r
868 ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Size) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Size));\r
869 ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size) ==\r
870 sizeof (((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size));\r
871 Status = Decoder->DecodeImage (\r
872 Decoder,\r
873 ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data,\r
874 ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size,\r
875 &ImageOut,\r
876 FALSE\r
877 );\r
878\r
879 //\r
880 // Spec requires to use the first capable image decoder instance.\r
881 // The first image decoder instance may fail to decode the image.\r
882 //\r
883 if (!EFI_ERROR (Status)) {\r
884 Image->Bitmap = ImageOut->Image.Bitmap;\r
885 Image->Height = ImageOut->Height;\r
886 Image->Width = ImageOut->Width;\r
887 FreePool (ImageOut);\r
888 }\r
889 return Status;\r
93e3992d 890\r
891 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:\r
892 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:\r
893 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:\r
ca1d86e3 894 Image->Flags = EFI_IMAGE_TRANSPARENT;\r
93e3992d 895 //\r
896 // fall through\r
897 //\r
898 case EFI_HII_IIBT_IMAGE_1BIT:\r
899 case EFI_HII_IIBT_IMAGE_4BIT:\r
900 case EFI_HII_IIBT_IMAGE_8BIT:\r
901 //\r
902 // Use the common block code since the definition of these structures is the same.\r
903 //\r
ca1d86e3 904 CopyMem (&Iibt1bit, CurrentImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));\r
813acf3a 905 ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *\r
f76bc443 906 ((UINT32) Iibt1bit.Bitmap.Width * Iibt1bit.Bitmap.Height);\r
101a1122 907 Image->Bitmap = AllocateZeroPool (ImageLength);\r
813acf3a 908 if (Image->Bitmap == NULL) {\r
909 return EFI_OUT_OF_RESOURCES;\r
93e3992d 910 }\r
93e3992d 911\r
93e3992d 912 Image->Width = Iibt1bit.Bitmap.Width;\r
913 Image->Height = Iibt1bit.Bitmap.Height;\r
914\r
915 PaletteInfo = ImagePackage->PaletteBlock + sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);\r
916 for (PaletteIndex = 1; PaletteIndex < Iibt1bit.PaletteIndex; PaletteIndex++) {\r
917 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
918 PaletteInfo += PaletteSize + sizeof (UINT16);\r
919 }\r
920 ASSERT (PaletteIndex == Iibt1bit.PaletteIndex);\r
921\r
922 //\r
923 // Output bitmap data\r
924 //\r
ca1d86e3
RN
925 if (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT ||\r
926 CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT_TRANS) {\r
93e3992d 927 Output1bitPixel (\r
928 Image,\r
ca1d86e3 929 ((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,\r
93e3992d 930 (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo\r
931 );\r
ca1d86e3
RN
932 } else if (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT ||\r
933 CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT_TRANS) {\r
93e3992d 934 Output4bitPixel (\r
935 Image,\r
ca1d86e3 936 ((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,\r
93e3992d 937 (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo\r
938 );\r
939 } else {\r
940 Output8bitPixel (\r
941 Image,\r
ca1d86e3 942 ((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,\r
93e3992d 943 (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo\r
944 );\r
945 }\r
946\r
947 return EFI_SUCCESS;\r
93e3992d 948\r
949 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
ca1d86e3 950 Image->Flags = EFI_IMAGE_TRANSPARENT;\r
93e3992d 951 //\r
952 // fall through\r
953 //\r
954 case EFI_HII_IIBT_IMAGE_24BIT:\r
ca1d86e3
RN
955 Width = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width);\r
956 Height = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height);\r
f76bc443 957 ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ((UINT32) Width * Height);\r
ca1d86e3 958 Image->Bitmap = AllocateZeroPool (ImageLength);\r
813acf3a 959 if (Image->Bitmap == NULL) {\r
960 return EFI_OUT_OF_RESOURCES;\r
93e3992d 961 }\r
93e3992d 962\r
93e3992d 963 Image->Width = Width;\r
964 Image->Height = Height;\r
965\r
966 //\r
ca1d86e3 967 // Output the bitmap data directly.\r
93e3992d 968 //\r
969 Output24bitPixel (\r
970 Image,\r
ca1d86e3 971 ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Bitmap\r
93e3992d 972 );\r
973 return EFI_SUCCESS;\r
93e3992d 974\r
975 default:\r
976 return EFI_NOT_FOUND;\r
93e3992d 977 }\r
978}\r
979\r
101a1122
RN
980/**\r
981 This function retrieves the image specified by ImageId which is associated with\r
982 the specified PackageList and copies it into the buffer specified by Image.\r
983\r
984 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
985 @param PackageList Handle of the package list where this image will\r
986 be searched.\r
987 @param ImageId The image's id,, which is unique within\r
988 PackageList.\r
989 @param Image Points to the image.\r
990\r
991 @retval EFI_SUCCESS The new image was returned successfully.\r
992 @retval EFI_NOT_FOUND The image specified by ImageId is not in the\r
993 database. The specified PackageList is not in the database.\r
994 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to\r
995 hold the image.\r
996 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.\r
997 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not\r
998 enough memory.\r
999\r
1000**/\r
1001EFI_STATUS\r
1002EFIAPI\r
1003HiiGetImage (\r
1004 IN CONST EFI_HII_IMAGE_PROTOCOL *This,\r
1005 IN EFI_HII_HANDLE PackageList,\r
1006 IN EFI_IMAGE_ID ImageId,\r
1007 OUT EFI_IMAGE_INPUT *Image\r
1008 )\r
1009{\r
1010 HII_DATABASE_PRIVATE_DATA *Private;\r
1011 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1012 return IGetImage (&Private->DatabaseList, PackageList, ImageId, Image, TRUE);\r
1013}\r
1014\r
93e3992d 1015\r
1016/**\r
1017 This function updates the image specified by ImageId in the specified PackageListHandle to\r
1018 the image specified by Image.\r
1019\r
1020 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
1021 @param PackageList The package list containing the images.\r
ac644614 1022 @param ImageId The image's id,, which is unique within\r
93e3992d 1023 PackageList.\r
1024 @param Image Points to the image.\r
1025\r
1026 @retval EFI_SUCCESS The new image was updated successfully.\r
1027 @retval EFI_NOT_FOUND The image specified by ImageId is not in the\r
d1102dba 1028 database. The specified PackageList is not in the database.\r
93e3992d 1029 @retval EFI_INVALID_PARAMETER The Image was NULL.\r
1030\r
1031**/\r
1032EFI_STATUS\r
1033EFIAPI\r
1034HiiSetImage (\r
1035 IN CONST EFI_HII_IMAGE_PROTOCOL *This,\r
1036 IN EFI_HII_HANDLE PackageList,\r
1037 IN EFI_IMAGE_ID ImageId,\r
1038 IN CONST EFI_IMAGE_INPUT *Image\r
1039 )\r
1040{\r
1041 HII_DATABASE_PRIVATE_DATA *Private;\r
93e3992d 1042 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;\r
1043 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;\r
7ca5b466
RN
1044 EFI_HII_IMAGE_BLOCK *CurrentImageBlock;\r
1045 EFI_HII_IMAGE_BLOCK *ImageBlocks;\r
1046 EFI_HII_IMAGE_BLOCK *NewImageBlock;\r
93e3992d 1047 UINT32 NewBlockSize;\r
1048 UINT32 OldBlockSize;\r
93e3992d 1049 UINT32 Part1Size;\r
1050 UINT32 Part2Size;\r
1051\r
7ca5b466 1052 if (This == NULL || Image == NULL || ImageId == 0 || Image->Bitmap == NULL) {\r
93e3992d 1053 return EFI_INVALID_PARAMETER;\r
1054 }\r
1055\r
93e3992d 1056 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
9d91ff0e 1057 PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
93e3992d 1058 if (PackageListNode == NULL) {\r
1059 return EFI_NOT_FOUND;\r
1060 }\r
1061 ImagePackage = PackageListNode->ImagePkg;\r
1062 if (ImagePackage == NULL) {\r
1063 return EFI_NOT_FOUND;\r
1064 }\r
1065\r
1066 //\r
1067 // Find the image block specified by ImageId\r
1068 //\r
7ca5b466
RN
1069 CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);\r
1070 if (CurrentImageBlock == NULL) {\r
93e3992d 1071 return EFI_NOT_FOUND;\r
1072 }\r
1073\r
979b7d80
DB
1074 EfiAcquireLock (&mHiiDatabaseLock);\r
1075\r
93e3992d 1076 //\r
1077 // Get the size of original image block. Use some common block code here\r
1078 // since the definition of some structures is the same.\r
1079 //\r
7ca5b466 1080 switch (CurrentImageBlock->BlockType) {\r
93e3992d 1081 case EFI_HII_IIBT_IMAGE_JPEG:\r
c0c7d58d
RN
1082 OldBlockSize = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size);\r
1083 break;\r
1084 case EFI_HII_IIBT_IMAGE_PNG:\r
1085 OldBlockSize = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size);\r
1086 break;\r
93e3992d 1087 case EFI_HII_IIBT_IMAGE_1BIT:\r
1088 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:\r
93e3992d 1089 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +\r
7ca5b466
RN
1090 BITMAP_LEN_1_BIT (\r
1091 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
1092 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
1093 );\r
93e3992d 1094 break;\r
1095 case EFI_HII_IIBT_IMAGE_4BIT:\r
1096 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:\r
93e3992d 1097 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +\r
7ca5b466
RN
1098 BITMAP_LEN_4_BIT (\r
1099 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
1100 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
1101 );\r
93e3992d 1102 break;\r
1103 case EFI_HII_IIBT_IMAGE_8BIT:\r
1104 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:\r
93e3992d 1105 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +\r
7ca5b466 1106 BITMAP_LEN_8_BIT (\r
f76bc443 1107 (UINT32) ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
7ca5b466
RN
1108 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
1109 );\r
93e3992d 1110 break;\r
1111 case EFI_HII_IIBT_IMAGE_24BIT:\r
1112 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
93e3992d 1113 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
7ca5b466 1114 BITMAP_LEN_24_BIT (\r
f76bc443 1115 (UINT32) ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
7ca5b466
RN
1116 ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
1117 );\r
93e3992d 1118 break;\r
1119 default:\r
979b7d80 1120 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 1121 return EFI_NOT_FOUND;\r
93e3992d 1122 }\r
1123\r
1124 //\r
1125 // Create the new image block according to input image.\r
1126 //\r
93e3992d 1127 NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
f76bc443 1128 BITMAP_LEN_24_BIT ((UINT32) Image->Width, Image->Height);\r
7ca5b466
RN
1129 //\r
1130 // Adjust the image package to remove the original block firstly then add the new block.\r
1131 //\r
1132 ImageBlocks = AllocateZeroPool (ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize);\r
1133 if (ImageBlocks == NULL) {\r
979b7d80 1134 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 1135 return EFI_OUT_OF_RESOURCES;\r
1136 }\r
1137\r
809e2bbf 1138 Part1Size = (UINT32) ((UINTN) CurrentImageBlock - (UINTN) ImagePackage->ImageBlock);\r
7ca5b466
RN
1139 Part2Size = ImagePackage->ImageBlockSize - Part1Size - OldBlockSize;\r
1140 CopyMem (ImageBlocks, ImagePackage->ImageBlock, Part1Size);\r
93e3992d 1141\r
1142 //\r
7ca5b466 1143 // Set the new image block\r
93e3992d 1144 //\r
7ca5b466
RN
1145 NewImageBlock = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) ImageBlocks + Part1Size);\r
1146 if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {\r
1147 NewImageBlock->BlockType= EFI_HII_IIBT_IMAGE_24BIT_TRANS;\r
1148 } else {\r
1149 NewImageBlock->BlockType = EFI_HII_IIBT_IMAGE_24BIT;\r
93e3992d 1150 }\r
7ca5b466
RN
1151 WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Width, Image->Width);\r
1152 WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Height, Image->Height);\r
1153 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Bitmap,\r
f76bc443 1154 Image->Bitmap, (UINT32) Image->Width * Image->Height);\r
93e3992d 1155\r
7ca5b466 1156 CopyMem ((UINT8 *) NewImageBlock + NewBlockSize, (UINT8 *) CurrentImageBlock + OldBlockSize, Part2Size);\r
93e3992d 1157\r
676df92c 1158 FreePool (ImagePackage->ImageBlock);\r
7ca5b466
RN
1159 ImagePackage->ImageBlock = ImageBlocks;\r
1160 ImagePackage->ImageBlockSize += NewBlockSize - OldBlockSize;\r
1161 ImagePackage->ImagePkgHdr.Header.Length += NewBlockSize - OldBlockSize;\r
93e3992d 1162 PackageListNode->PackageListHdr.PackageLength += NewBlockSize - OldBlockSize;\r
1163\r
8a45f80e
DB
1164 //\r
1165 // Check whether need to get the contents of HiiDataBase.\r
1166 // Only after ReadyToBoot to do the export.\r
1167 //\r
1168 if (gExportAfterReadyToBoot) {\r
1169 HiiGetDatabaseInfo(&Private->HiiDatabase);\r
1170 }\r
1171\r
979b7d80 1172 EfiReleaseLock (&mHiiDatabaseLock);\r
93e3992d 1173 return EFI_SUCCESS;\r
1174\r
1175}\r
1176\r
1177\r
1178/**\r
1179 This function renders an image to a bitmap or the screen using the specified\r
1180 color and options. It draws the image on an existing bitmap, allocates a new\r
1181 bitmap or uses the screen. The images can be clipped.\r
1182\r
1183 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
1184 @param Flags Describes how the image is to be drawn.\r
1185 @param Image Points to the image to be displayed.\r
1186 @param Blt If this points to a non-NULL on entry, this points\r
1187 to the image, which is Width pixels wide and\r
1188 Height pixels high. The image will be drawn onto\r
1189 this image and EFI_HII_DRAW_FLAG_CLIP is implied.\r
1190 If this points to a NULL on entry, then a buffer\r
1191 will be allocated to hold the generated image and\r
ac644614 1192 the pointer updated on exit. It is the caller's\r
93e3992d 1193 responsibility to free this buffer.\r
e90b081a 1194 @param BltX Specifies the offset from the left and top edge of\r
1195 the output image of the first pixel in the image.\r
93e3992d 1196 @param BltY Specifies the offset from the left and top edge of\r
1197 the output image of the first pixel in the image.\r
1198\r
1199 @retval EFI_SUCCESS The image was successfully drawn.\r
1200 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.\r
1201 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.\r
1202 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.\r
1203\r
1204**/\r
1205EFI_STATUS\r
1206EFIAPI\r
1207HiiDrawImage (\r
1208 IN CONST EFI_HII_IMAGE_PROTOCOL *This,\r
1209 IN EFI_HII_DRAW_FLAGS Flags,\r
1210 IN CONST EFI_IMAGE_INPUT *Image,\r
1211 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
1212 IN UINTN BltX,\r
1213 IN UINTN BltY\r
1214 )\r
1215{\r
1216 EFI_STATUS Status;\r
1217 HII_DATABASE_PRIVATE_DATA *Private;\r
1218 BOOLEAN Transparent;\r
93e3992d 1219 EFI_IMAGE_OUTPUT *ImageOut;\r
1220 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
1221 UINTN BufferLen;\r
1222 UINTN Width;\r
1223 UINTN Height;\r
e90b081a 1224 UINTN Xpos;\r
1225 UINTN Ypos;\r
93e3992d 1226 UINTN OffsetY1;\r
1227 UINTN OffsetY2;\r
1228 EFI_FONT_DISPLAY_INFO *FontInfo;\r
1229 UINTN Index;\r
93e3992d 1230\r
1231 if (This == NULL || Image == NULL || Blt == NULL) {\r
1232 return EFI_INVALID_PARAMETER;\r
1233 }\r
1234\r
1235 if ((Flags & EFI_HII_DRAW_FLAG_CLIP) == EFI_HII_DRAW_FLAG_CLIP && *Blt == NULL) {\r
1236 return EFI_INVALID_PARAMETER;\r
1237 }\r
1238\r
1239 if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_TRANSPARENT) {\r
1240 return EFI_INVALID_PARAMETER;\r
1241 }\r
1242\r
523f48e7 1243 FontInfo = NULL;\r
93e3992d 1244\r
1245 //\r
1246 // Check whether the image will be drawn transparently or opaquely.\r
1247 //\r
1248 Transparent = FALSE;\r
1249 if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_TRANS) {\r
1250 Transparent = TRUE;\r
1251 } else if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE){\r
1252 Transparent = FALSE;\r
1253 } else {\r
1254 //\r
1255 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending\r
1256 // on the image's transparency setting.\r
1257 //\r
c0be50f0 1258 if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {\r
93e3992d 1259 Transparent = TRUE;\r
1260 }\r
1261 }\r
1262\r
1263 //\r
1264 // Image cannot be drawn transparently if Blt points to NULL on entry.\r
1265 // Currently output to Screen transparently is not supported, either.\r
1266 //\r
1267 if (Transparent) {\r
1268 if (*Blt == NULL) {\r
1269 return EFI_INVALID_PARAMETER;\r
1270 } else if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
1271 return EFI_INVALID_PARAMETER;\r
1272 }\r
1273 }\r
1274\r
1275 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1276\r
1277 //\r
1278 // When Blt points to a non-NULL on entry, this image will be drawn onto\r
1279 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.\r
1280 // Otherwise a new bitmap will be allocated to hold this image.\r
1281 //\r
1282 if (*Blt != NULL) {\r
1283 //\r
1284 // Clip the image by (Width, Height)\r
1285 //\r
1286\r
c0be50f0
RN
1287 Width = Image->Width;\r
1288 Height = Image->Height;\r
93e3992d 1289\r
1290 if (Width > (*Blt)->Width - BltX) {\r
1291 Width = (*Blt)->Width - BltX;\r
1292 }\r
1293 if (Height > (*Blt)->Height - BltY) {\r
1294 Height = (*Blt)->Height - BltY;\r
1295 }\r
1296\r
1297 BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
1298 BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);\r
1299 if (BltBuffer == NULL) {\r
1300 return EFI_OUT_OF_RESOURCES;\r
1301 }\r
1302\r
c0be50f0
RN
1303 if (Width == Image->Width && Height == Image->Height) {\r
1304 CopyMem (BltBuffer, Image->Bitmap, BufferLen);\r
93e3992d 1305 } else {\r
e90b081a 1306 for (Ypos = 0; Ypos < Height; Ypos++) {\r
c0be50f0 1307 OffsetY1 = Image->Width * Ypos;\r
e90b081a 1308 OffsetY2 = Width * Ypos;\r
1309 for (Xpos = 0; Xpos < Width; Xpos++) {\r
c0be50f0 1310 BltBuffer[OffsetY2 + Xpos] = Image->Bitmap[OffsetY1 + Xpos];\r
93e3992d 1311 }\r
1312 }\r
1313 }\r
1314\r
1315 //\r
1316 // Draw the image to existing bitmap or screen depending on flag.\r
1317 //\r
1318 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
3f57706f 1319 //\r
1320 // Caller should make sure the current UGA console is grarphic mode.\r
1321 //\r
93e3992d 1322\r
93e3992d 1323 //\r
1324 // Write the image directly to the output device specified by Screen.\r
1325 //\r
1326 Status = (*Blt)->Image.Screen->Blt (\r
1327 (*Blt)->Image.Screen,\r
1328 BltBuffer,\r
1329 EfiBltBufferToVideo,\r
1330 0,\r
1331 0,\r
1332 BltX,\r
1333 BltY,\r
1334 Width,\r
1335 Height,\r
1336 0\r
1337 );\r
1338 } else {\r
1339 //\r
1340 // Draw the image onto the existing bitmap specified by Bitmap.\r
1341 //\r
1342 Status = ImageToBlt (\r
1343 BltBuffer,\r
1344 BltX,\r
1345 BltY,\r
1346 Width,\r
1347 Height,\r
1348 Transparent,\r
1349 Blt\r
1350 );\r
1351\r
1352 }\r
1353\r
676df92c 1354 FreePool (BltBuffer);\r
93e3992d 1355 return Status;\r
1356\r
1357 } else {\r
1358 //\r
1359 // Allocate a new bitmap to hold the incoming image.\r
1360 //\r
c0be50f0
RN
1361 Width = Image->Width + BltX;\r
1362 Height = Image->Height + BltY;\r
93e3992d 1363\r
1364 BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
1365 BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);\r
1366 if (BltBuffer == NULL) {\r
1367 return EFI_OUT_OF_RESOURCES;\r
1368 }\r
1369\r
1370 ImageOut = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1371 if (ImageOut == NULL) {\r
676df92c 1372 FreePool (BltBuffer);\r
93e3992d 1373 return EFI_OUT_OF_RESOURCES;\r
1374 }\r
1375 ImageOut->Width = (UINT16) Width;\r
1376 ImageOut->Height = (UINT16) Height;\r
1377 ImageOut->Image.Bitmap = BltBuffer;\r
1378\r
1379 //\r
1380 // BUGBUG: Now all the "blank" pixels are filled with system default background\r
1381 // color. Not sure if it need to be updated or not.\r
1382 //\r
1383 Status = GetSystemFont (Private, &FontInfo, NULL);\r
1384 if (EFI_ERROR (Status)) {\r
676df92c 1385 FreePool (BltBuffer);\r
1386 FreePool (ImageOut);\r
93e3992d 1387 return Status;\r
1388 }\r
523f48e7 1389 ASSERT (FontInfo != NULL);\r
93e3992d 1390 for (Index = 0; Index < Width * Height; Index++) {\r
1391 BltBuffer[Index] = FontInfo->BackgroundColor;\r
1392 }\r
676df92c 1393 FreePool (FontInfo);\r
93e3992d 1394\r
1395 //\r
1396 // Draw the incoming image to the new created image.\r
1397 //\r
1398 *Blt = ImageOut;\r
1399 return ImageToBlt (\r
c0be50f0 1400 Image->Bitmap,\r
93e3992d 1401 BltX,\r
1402 BltY,\r
c0be50f0
RN
1403 Image->Width,\r
1404 Image->Height,\r
93e3992d 1405 Transparent,\r
1406 Blt\r
1407 );\r
1408\r
1409 }\r
1410}\r
1411\r
1412\r
1413/**\r
1414 This function renders an image to a bitmap or the screen using the specified\r
1415 color and options. It draws the image on an existing bitmap, allocates a new\r
1416 bitmap or uses the screen. The images can be clipped.\r
1417\r
1418 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
1419 @param Flags Describes how the image is to be drawn.\r
1420 @param PackageList The package list in the HII database to search for\r
1421 the specified image.\r
1422 @param ImageId The image's id, which is unique within\r
1423 PackageList.\r
1424 @param Blt If this points to a non-NULL on entry, this points\r
1425 to the image, which is Width pixels wide and\r
1426 Height pixels high. The image will be drawn onto\r
1427 this image and\r
1428 EFI_HII_DRAW_FLAG_CLIP is implied. If this points\r
1429 to a NULL on entry, then a buffer will be\r
1430 allocated to hold the generated image and the\r
ac644614 1431 pointer updated on exit. It is the caller's\r
93e3992d 1432 responsibility to free this buffer.\r
e90b081a 1433 @param BltX Specifies the offset from the left and top edge of\r
1434 the output image of the first pixel in the image.\r
93e3992d 1435 @param BltY Specifies the offset from the left and top edge of\r
1436 the output image of the first pixel in the image.\r
1437\r
1438 @retval EFI_SUCCESS The image was successfully drawn.\r
1439 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.\r
813acf3a 1440 @retval EFI_INVALID_PARAMETER The Blt was NULL.\r
d1102dba
LG
1441 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.\r
1442 The specified PackageList is not in the database.\r
93e3992d 1443\r
1444**/\r
1445EFI_STATUS\r
1446EFIAPI\r
1447HiiDrawImageId (\r
1448 IN CONST EFI_HII_IMAGE_PROTOCOL *This,\r
1449 IN EFI_HII_DRAW_FLAGS Flags,\r
1450 IN EFI_HII_HANDLE PackageList,\r
1451 IN EFI_IMAGE_ID ImageId,\r
1452 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
1453 IN UINTN BltX,\r
1454 IN UINTN BltY\r
1455 )\r
1456{\r
1457 EFI_STATUS Status;\r
813acf3a 1458 EFI_IMAGE_INPUT Image;\r
93e3992d 1459\r
1460 //\r
1461 // Check input parameter.\r
1462 //\r
813acf3a 1463 if (This == NULL || Blt == NULL) {\r
93e3992d 1464 return EFI_INVALID_PARAMETER;\r
1465 }\r
1466\r
93e3992d 1467 //\r
1468 // Get the specified Image.\r
1469 //\r
813acf3a 1470 Status = HiiGetImage (This, PackageList, ImageId, &Image);\r
1471 if (EFI_ERROR (Status)) {\r
93e3992d 1472 return Status;\r
1473 }\r
1474\r
93e3992d 1475 //\r
1476 // Draw this image.\r
1477 //\r
813acf3a 1478 Status = HiiDrawImage (This, Flags, &Image, Blt, BltX, BltY);\r
676df92c 1479 if (Image.Bitmap != NULL) {\r
1480 FreePool (Image.Bitmap);\r
1481 }\r
93e3992d 1482 return Status;\r
1483}\r
1484\r