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