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