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