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