2 Implementation for EFI_HII_IMAGE_PROTOCOL.
5 Copyright (c) 2007 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "HiiDatabase.h"
21 Get the imageid of last image block: EFI_HII_IIBT_END_BLOCK when input
22 ImageId is zero, otherwise return the address of the
23 corresponding image block with identifier specified by ImageId.
25 This is a internal function.
27 @param ImageBlock Points to the beginning of a series of image blocks stored in order.
28 @param ImageId If input ImageId is 0, output the image id of the EFI_HII_IIBT_END_BLOCK;
29 else use this id to find its corresponding image block address.
31 @return The image block address when input ImageId is not zero; otherwise return NULL.
37 IN OUT EFI_IMAGE_ID
*ImageId
40 EFI_IMAGE_ID ImageIdCurrent
;
45 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
46 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit
;
47 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit
;
51 ASSERT (ImageBlock
!= NULL
&& ImageId
!= NULL
);
53 ImageBlockHdr
= ImageBlock
;
56 while (((EFI_HII_IMAGE_BLOCK
*) ImageBlock
)->BlockType
!= EFI_HII_IIBT_END
) {
58 if (*ImageId
== ImageIdCurrent
) {
60 // If the found image block is a duplicate block, update the ImageId to
61 // find the previous defined image block.
63 if (((EFI_HII_IMAGE_BLOCK
*) ImageBlock
)->BlockType
== EFI_HII_IIBT_DUPLICATE
) {
64 CopyMem (ImageId
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (EFI_IMAGE_ID
));
65 ASSERT (*ImageId
!= ImageIdCurrent
);
66 ImageBlock
= ImageBlockHdr
;
73 if (*ImageId
< ImageIdCurrent
) {
75 // Can not find the specified image block in this image.
80 switch (((EFI_HII_IMAGE_BLOCK
*) ImageBlock
)->BlockType
) {
81 case EFI_HII_IIBT_EXT1
:
82 Length8
= *(ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
));
83 ImageBlock
+= Length8
;
86 case EFI_HII_IIBT_EXT2
:
89 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
),
92 ImageBlock
+= Length16
;
95 case EFI_HII_IIBT_EXT4
:
98 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
),
101 ImageBlock
+= Length32
;
105 case EFI_HII_IIBT_IMAGE_1BIT
:
106 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
107 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
108 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
109 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
113 case EFI_HII_IIBT_IMAGE_4BIT
:
114 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
115 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
116 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
117 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
121 case EFI_HII_IIBT_IMAGE_8BIT
:
122 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
123 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
124 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
125 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
129 case EFI_HII_IIBT_IMAGE_24BIT
:
130 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
131 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
134 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
137 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
138 BITMAP_LEN_24_BIT (Width
, Height
);
142 case EFI_HII_IIBT_DUPLICATE
:
143 ImageBlock
+= sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK
);
147 case EFI_HII_IIBT_IMAGE_JPEG
:
148 CopyMem (&Length32
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT32
));
149 ImageBlock
+= Length32
;
153 case EFI_HII_IIBT_SKIP1
:
154 Length8
= *(ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
));
155 ImageBlock
+= sizeof (EFI_HII_IIBT_SKIP1_BLOCK
);
156 ImageIdCurrent
= (UINT16
) (ImageIdCurrent
+ Length8
);
159 case EFI_HII_IIBT_SKIP2
:
160 CopyMem (&Length16
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
161 ImageBlock
+= sizeof (EFI_HII_IIBT_SKIP2_BLOCK
);
162 ImageIdCurrent
= (UINT16
) (ImageIdCurrent
+ Length16
);
167 // Unknown image blocks can not be skipped, processing halts.
174 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
177 *ImageId
= ImageIdCurrent
;
187 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
189 This is a internal function.
192 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
193 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
194 @param PixelNum The number of pixels to be converted.
200 OUT EFI_HII_RGB_PIXEL
*BitMapOut
,
201 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapIn
,
207 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
209 for (Index
= 0; Index
< PixelNum
; Index
++) {
210 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
216 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
218 This is a internal function.
221 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
222 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
223 @param PixelNum The number of pixels to be converted.
229 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapOut
,
230 IN EFI_HII_RGB_PIXEL
*BitMapIn
,
236 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
238 for (Index
= 0; Index
< PixelNum
; Index
++) {
239 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
245 Output pixels in "1 bit per pixel" format to an image.
247 This is a internal function.
250 @param Image Points to the image which will store the pixels.
251 @param Data Stores the value of output pixels, 0 or 1.
252 @param PaletteInfo PaletteInfo which stores the color of the output
253 pixels. First entry corresponds to color 0 and
254 second one to color 1.
260 IN OUT EFI_IMAGE_INPUT
*Image
,
262 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
269 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
270 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[2];
271 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
275 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
277 BitMapPtr
= Image
->Bitmap
;
280 // First entry corresponds to color 0 and second entry corresponds to color 1.
282 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
283 PaletteSize
+= sizeof (UINT16
);
284 Palette
= AllocateZeroPool (PaletteSize
);
285 ASSERT (Palette
!= NULL
);
286 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
288 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
289 CopyRgbToGopPixel (&PaletteValue
[0], &Palette
->PaletteValue
[0], 1);
290 CopyRgbToGopPixel (&PaletteValue
[1], &Palette
->PaletteValue
[1], 1);
291 SafeFreePool (Palette
);
294 // Convert the pixel from one bit to corresponding color.
296 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
297 OffsetY
= BITMAP_LEN_1_BIT (Image
->Width
, Ypos
);
299 // All bits in these bytes are meaningful
301 for (Xpos
= 0; Xpos
< Image
->Width
/ 8; Xpos
++) {
302 Byte
= *(Data
+ OffsetY
+ Xpos
);
303 for (Index
= 0; Index
< 8; Index
++) {
304 if ((Byte
& (1 << Index
)) != 0) {
305 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[1];
307 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[0];
312 if (Image
->Width
% 8 != 0) {
314 // Padding bits in this byte should be ignored.
316 Byte
= *(Data
+ OffsetY
+ Xpos
);
317 for (Index
= 0; Index
< Image
->Width
% 8; Index
++) {
318 if ((Byte
& (1 << (8 - Index
- 1))) != 0) {
319 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[1];
321 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[0];
330 Output pixels in "4 bit per pixel" format to an image.
332 This is a internal function.
335 @param Image Points to the image which will store the pixels.
336 @param Data Stores the value of output pixels, 0 ~ 15.
337 @param[in] PaletteInfo PaletteInfo which stores the color of the output
338 pixels. Each entry corresponds to a color within
345 IN OUT EFI_IMAGE_INPUT
*Image
,
347 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
353 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
354 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[16];
355 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
360 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
362 BitMapPtr
= Image
->Bitmap
;
365 // The bitmap should allocate each color index starting from 0.
367 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
368 PaletteSize
+= sizeof (UINT16
);
369 Palette
= AllocateZeroPool (PaletteSize
);
370 ASSERT (Palette
!= NULL
);
371 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
372 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
374 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
375 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
376 SafeFreePool (Palette
);
379 // Convert the pixel from 4 bit to corresponding color.
381 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
382 OffsetY
= BITMAP_LEN_4_BIT (Image
->Width
, Ypos
);
384 // All bits in these bytes are meaningful
386 for (Xpos
= 0; Xpos
< Image
->Width
/ 2; Xpos
++) {
387 Byte
= *(Data
+ OffsetY
+ Xpos
);
388 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
389 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2 + 1] = PaletteValue
[Byte
& 0x0F];
392 if (Image
->Width
% 2 != 0) {
394 // Padding bits in this byte should be ignored.
396 Byte
= *(Data
+ OffsetY
+ Xpos
);
397 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
404 Output pixels in "8 bit per pixel" format to an image.
406 This is a internal function.
409 @param Image Points to the image which will store the pixels.
410 @param Data Stores the value of output pixels, 0 ~ 255.
411 @param[in] PaletteInfo PaletteInfo which stores the color of the output
412 pixels. Each entry corresponds to a color within
419 IN OUT EFI_IMAGE_INPUT
*Image
,
421 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
427 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
428 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[256];
429 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
434 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
436 BitMapPtr
= Image
->Bitmap
;
439 // The bitmap should allocate each color index starting from 0.
441 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
442 PaletteSize
+= sizeof (UINT16
);
443 Palette
= AllocateZeroPool (PaletteSize
);
444 ASSERT (Palette
!= NULL
);
445 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
446 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
447 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
448 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
449 SafeFreePool (Palette
);
452 // Convert the pixel from 8 bits to corresponding color.
454 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
455 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
457 // All bits are meaningful since the bitmap is 8 bits per pixel.
459 for (Xpos
= 0; Xpos
< Image
->Width
; Xpos
++) {
460 Byte
= *(Data
+ OffsetY
+ Xpos
);
461 BitMapPtr
[OffsetY
+ Xpos
] = PaletteValue
[Byte
];
469 Output pixels in "24 bit per pixel" format to an image.
471 This is a internal function.
474 @param Image Points to the image which will store the pixels.
475 @param Data Stores the color of output pixels, allowing 16.8
482 IN OUT EFI_IMAGE_INPUT
*Image
,
483 IN EFI_HII_RGB_PIXEL
*Data
488 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
490 ASSERT (Image
!= NULL
&& Data
!= NULL
);
492 BitMapPtr
= Image
->Bitmap
;
494 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
495 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
496 CopyRgbToGopPixel (&BitMapPtr
[OffsetY
], &Data
[OffsetY
], Image
->Width
);
503 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
505 This is a internal function.
508 @param BltBuffer Buffer points to bitmap data of incoming image.
509 @param BltX Specifies the offset from the left and top edge of
510 the output image of the first pixel in the image.
511 @param BltY Specifies the offset from the left and top edge of
512 the output image of the first pixel in the image.
513 @param Width Width of the incoming image, in pixels.
514 @param Height Height of the incoming image, in pixels.
515 @param Transparent If TRUE, all "off" pixels in the image will be
516 drawn using the pixel value from blt and all other
517 pixels will be copied.
518 @param Blt Buffer points to bitmap data of output image.
520 @retval EFI_SUCCESS The image was successfully converted.
521 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
526 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
531 IN BOOLEAN Transparent
,
532 IN OUT EFI_IMAGE_OUTPUT
**Blt
535 EFI_IMAGE_OUTPUT
*ImageOut
;
538 UINTN OffsetY1
; // src buffer
539 UINTN OffsetY2
; // dest buffer
540 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel
;
541 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel
;
543 if (BltBuffer
== NULL
|| Blt
== NULL
|| *Blt
== NULL
) {
544 return EFI_INVALID_PARAMETER
;
549 if (Width
+ BltX
> ImageOut
->Width
) {
550 return EFI_INVALID_PARAMETER
;
552 if (Height
+ BltY
> ImageOut
->Height
) {
553 return EFI_INVALID_PARAMETER
;
556 ZeroMem (&ZeroPixel
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
558 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
559 OffsetY1
= Width
* Ypos
;
560 OffsetY2
= ImageOut
->Width
* (BltY
+ Ypos
);
561 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
562 SrcPixel
= BltBuffer
[OffsetY1
+ Xpos
];
564 if (CompareMem (&SrcPixel
, &ZeroPixel
, 3) != 0) {
565 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
568 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
578 This function adds the image Image to the group of images owned by PackageList, and returns
579 a new image identifier (ImageId).
581 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
582 @param PackageList Handle of the package list where this image will
584 @param ImageId On return, contains the new image id, which is
585 unique within PackageList.
586 @param Image Points to the image.
588 @retval EFI_SUCCESS The new image was added successfully.
589 @retval EFI_NOT_FOUND The specified PackageList could not be found in
591 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
592 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
598 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
599 IN EFI_HII_HANDLE PackageList
,
600 OUT EFI_IMAGE_ID
*ImageId
,
601 IN CONST EFI_IMAGE_INPUT
*Image
604 HII_DATABASE_PRIVATE_DATA
*Private
;
606 HII_DATABASE_RECORD
*DatabaseRecord
;
607 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
608 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
614 EFI_IMAGE_INPUT
*ImageIn
;
616 if (This
== NULL
|| ImageId
== NULL
|| Image
== NULL
|| Image
->Bitmap
== NULL
) {
617 return EFI_INVALID_PARAMETER
;
620 if (!IsHiiHandleValid (PackageList
)) {
621 return EFI_NOT_FOUND
;
624 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
627 // Get the specified package list
630 PackageListNode
= NULL
;
632 for (Link
= Private
->DatabaseList
.ForwardLink
;
633 Link
!= &Private
->DatabaseList
;
634 Link
= Link
->ForwardLink
636 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
637 if (DatabaseRecord
->Handle
== PackageList
) {
638 PackageListNode
= DatabaseRecord
->PackageList
;
643 if (PackageListNode
== NULL
) {
644 return EFI_NOT_FOUND
;
647 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
649 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
650 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
653 // Get the image package in the package list,
654 // or create a new image package if image package does not exist.
656 if (PackageListNode
->ImagePkg
!= NULL
) {
657 ImagePackage
= PackageListNode
->ImagePkg
;
660 // Output the image id of the incoming image being inserted, which is the
661 // image id of the EFI_HII_IIBT_END block of old image package.
664 GetImageIdOrAddress (ImagePackage
->ImageBlock
, ImageId
);
667 // Update the package's image block by appending the new block to the end.
669 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
;
670 ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
671 if (ImageBlock
== NULL
) {
672 return EFI_OUT_OF_RESOURCES
;
675 // Copy the original content.
679 ImagePackage
->ImageBlock
,
680 ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
682 SafeFreePool (ImagePackage
->ImageBlock
);
683 ImagePackage
->ImageBlock
= ImageBlock
;
684 ImageBlock
+= ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
);
686 // Temp memory to store new block.
688 NewBlock
= AllocateZeroPool (NewBlockSize
);
689 if (NewBlock
== NULL
) {
690 SafeFreePool (ImagePackage
->ImageBlock
);
691 ImagePackage
->ImageBlock
= NULL
;
692 return EFI_OUT_OF_RESOURCES
;
694 NewBlockPtr
= NewBlock
;
697 // Update the length record.
699 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
700 ImagePackage
->ImagePkgHdr
.Header
.Length
+= (UINT32
) NewBlockSize
;
701 PackageListNode
->PackageListHdr
.PackageLength
+= (UINT32
) NewBlockSize
;
705 // The specified package list does not contain image package.
706 // Create one to add this image block.
708 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
709 if (ImagePackage
== NULL
) {
710 return EFI_OUT_OF_RESOURCES
;
713 // Output the image id of the incoming image being inserted, which is the
714 // first image block so that id is initially to one.
717 BlockSize
= sizeof (EFI_HII_IIBT_END_BLOCK
) + NewBlockSize
;
719 // Fill in image package header.
721 ImagePackage
->ImagePkgHdr
.Header
.Length
= (UINT32
) BlockSize
+ sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
722 ImagePackage
->ImagePkgHdr
.Header
.Type
= EFI_HII_PACKAGE_IMAGES
;
723 ImagePackage
->ImagePkgHdr
.ImageInfoOffset
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
724 ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
= 0;
727 // Fill in palette info.
729 ImagePackage
->PaletteBlock
= NULL
;
730 ImagePackage
->PaletteInfoSize
= 0;
733 // Fill in image blocks.
735 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
736 ImagePackage
->ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
737 if (ImagePackage
->ImageBlock
== NULL
) {
738 SafeFreePool (ImagePackage
);
739 return EFI_OUT_OF_RESOURCES
;
741 ImageBlock
= ImagePackage
->ImageBlock
;
744 // Temp memory to store new block.
746 NewBlock
= AllocateZeroPool (NewBlockSize
);
747 if (NewBlock
== NULL
) {
748 SafeFreePool (ImagePackage
->ImageBlock
);
749 SafeFreePool (ImagePackage
);
750 return EFI_OUT_OF_RESOURCES
;
752 NewBlockPtr
= NewBlock
;
755 // Insert this image package.
757 PackageListNode
->ImagePkg
= ImagePackage
;
758 PackageListNode
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
762 // Append the new block here
764 if (ImageIn
->Flags
== EFI_IMAGE_TRANSPARENT
) {
765 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
767 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT
;
770 CopyMem (NewBlock
, &ImageIn
->Width
, sizeof (UINT16
));
771 NewBlock
+= sizeof (UINT16
);
772 CopyMem (NewBlock
, &ImageIn
->Height
, sizeof (UINT16
));
773 NewBlock
+= sizeof (UINT16
);
774 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlock
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
776 CopyMem (ImageBlock
, NewBlockPtr
, NewBlockSize
);
777 SafeFreePool (NewBlockPtr
);
780 // Append the block end
782 ImageBlock
+= NewBlockSize
;
783 ((EFI_HII_IIBT_END_BLOCK
*) (ImageBlock
))->Header
.BlockType
= EFI_HII_IIBT_END
;
790 This function retrieves the image specified by ImageId which is associated with
791 the specified PackageList and copies it into the buffer specified by Image.
793 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
794 @param PackageList Handle of the package list where this image will
796 @param ImageId The image's id,, which is unique within
798 @param Image Points to the image.
800 @retval EFI_SUCCESS The new image was returned successfully.
801 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
802 database. The specified PackageList is not in the database.
803 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
805 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
806 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
813 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
814 IN EFI_HII_HANDLE PackageList
,
815 IN EFI_IMAGE_ID ImageId
,
816 OUT EFI_IMAGE_INPUT
*Image
819 HII_DATABASE_PRIVATE_DATA
*Private
;
821 HII_DATABASE_RECORD
*DatabaseRecord
;
822 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
823 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
825 EFI_IMAGE_ID LocalImageId
;
827 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
836 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1) {
837 return EFI_INVALID_PARAMETER
;
840 if (!IsHiiHandleValid (PackageList
)) {
841 return EFI_NOT_FOUND
;
844 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
847 // Get the specified package list and image package.
849 PackageListNode
= NULL
;
850 for (Link
= Private
->DatabaseList
.ForwardLink
;
851 Link
!= &Private
->DatabaseList
;
852 Link
= Link
->ForwardLink
854 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
855 if (DatabaseRecord
->Handle
== PackageList
) {
856 PackageListNode
= DatabaseRecord
->PackageList
;
860 if (PackageListNode
== NULL
) {
861 return EFI_NOT_FOUND
;
863 ImagePackage
= PackageListNode
->ImagePkg
;
864 if (ImagePackage
== NULL
) {
865 return EFI_NOT_FOUND
;
869 // Find the image block specified by ImageId
871 LocalImageId
= ImageId
;
872 ImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
873 if (ImageBlock
== NULL
) {
874 return EFI_NOT_FOUND
;
878 BlockType
= *ImageBlock
;
881 case EFI_HII_IIBT_IMAGE_JPEG
:
883 // BUGBUG: need to be supported as soon as image tool is designed.
885 return EFI_UNSUPPORTED
;
888 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
889 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
890 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
895 case EFI_HII_IIBT_IMAGE_1BIT
:
896 case EFI_HII_IIBT_IMAGE_4BIT
:
897 case EFI_HII_IIBT_IMAGE_8BIT
:
899 // Use the common block code since the definition of these structures is the same.
901 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
902 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) *
903 (Iibt1bit
.Bitmap
.Width
* Iibt1bit
.Bitmap
.Height
);
904 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
905 if (Image
->Bitmap
== NULL
) {
906 return EFI_OUT_OF_RESOURCES
;
910 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
912 Image
->Width
= Iibt1bit
.Bitmap
.Width
;
913 Image
->Height
= Iibt1bit
.Bitmap
.Height
;
915 PaletteInfo
= ImagePackage
->PaletteBlock
+ sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
916 for (PaletteIndex
= 1; PaletteIndex
< Iibt1bit
.PaletteIndex
; PaletteIndex
++) {
917 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
918 PaletteInfo
+= PaletteSize
+ sizeof (UINT16
);
920 ASSERT (PaletteIndex
== Iibt1bit
.PaletteIndex
);
923 // Output bitmap data
925 if (BlockType
== EFI_HII_IIBT_IMAGE_1BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_1BIT_TRANS
) {
928 (UINT8
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
)),
929 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
931 } else if (BlockType
== EFI_HII_IIBT_IMAGE_4BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_4BIT_TRANS
) {
934 (UINT8
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
)),
935 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
940 (UINT8
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
)),
941 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
948 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
953 case EFI_HII_IIBT_IMAGE_24BIT
:
954 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
957 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
960 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * (Width
* Height
);
961 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
962 if (Image
->Bitmap
== NULL
) {
963 return EFI_OUT_OF_RESOURCES
;
967 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
969 Image
->Width
= Width
;
970 Image
->Height
= Height
;
973 // Output the bimap data directly.
977 (EFI_HII_RGB_PIXEL
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
))
983 return EFI_NOT_FOUND
;
990 This function updates the image specified by ImageId in the specified PackageListHandle to
991 the image specified by Image.
993 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
994 @param PackageList The package list containing the images.
995 @param ImageId The image's id,, which is unique within
997 @param Image Points to the image.
999 @retval EFI_SUCCESS The new image was updated successfully.
1000 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
1001 database. The specified PackageList is not in the database.
1002 @retval EFI_INVALID_PARAMETER The Image was NULL.
1008 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1009 IN EFI_HII_HANDLE PackageList
,
1010 IN EFI_IMAGE_ID ImageId
,
1011 IN CONST EFI_IMAGE_INPUT
*Image
1014 HII_DATABASE_PRIVATE_DATA
*Private
;
1016 HII_DATABASE_RECORD
*DatabaseRecord
;
1017 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1018 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
1020 EFI_IMAGE_ID LocalImageId
;
1022 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
1023 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit
;
1024 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit
;
1028 UINT32 NewBlockSize
;
1029 UINT32 OldBlockSize
;
1030 EFI_IMAGE_INPUT
*ImageIn
;
1038 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1 || Image
->Bitmap
== NULL
) {
1039 return EFI_INVALID_PARAMETER
;
1042 if (!IsHiiHandleValid (PackageList
)) {
1043 return EFI_NOT_FOUND
;
1046 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1049 // Get the specified package list and image package.
1051 PackageListNode
= NULL
;
1052 for (Link
= Private
->DatabaseList
.ForwardLink
;
1053 Link
!= &Private
->DatabaseList
;
1054 Link
= Link
->ForwardLink
1056 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1057 if (DatabaseRecord
->Handle
== PackageList
) {
1058 PackageListNode
= DatabaseRecord
->PackageList
;
1062 if (PackageListNode
== NULL
) {
1063 return EFI_NOT_FOUND
;
1065 ImagePackage
= PackageListNode
->ImagePkg
;
1066 if (ImagePackage
== NULL
) {
1067 return EFI_NOT_FOUND
;
1071 // Find the image block specified by ImageId
1073 LocalImageId
= ImageId
;
1074 ImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
1075 if (ImageBlock
== NULL
) {
1076 return EFI_NOT_FOUND
;
1079 BlockType
= *ImageBlock
;
1082 // Get the size of original image block. Use some common block code here
1083 // since the definition of some structures is the same.
1085 switch (BlockType
) {
1086 case EFI_HII_IIBT_IMAGE_JPEG
:
1088 // BUGBUG: need to be supported as soon as image tool is designed.
1090 return EFI_UNSUPPORTED
;
1093 case EFI_HII_IIBT_IMAGE_1BIT
:
1094 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
1095 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
1096 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
1097 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
1099 case EFI_HII_IIBT_IMAGE_4BIT
:
1100 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
1101 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
1102 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
1103 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
1105 case EFI_HII_IIBT_IMAGE_8BIT
:
1106 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
1107 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
1108 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
1109 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
1111 case EFI_HII_IIBT_IMAGE_24BIT
:
1112 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
1113 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
1116 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
1119 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1120 BITMAP_LEN_24_BIT (Width
, Height
);
1123 return EFI_NOT_FOUND
;
1128 // Create the new image block according to input image.
1130 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1131 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1132 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
1133 NewBlock
= (UINT8
*) AllocateZeroPool (NewBlockSize
);
1134 if (NewBlock
== NULL
) {
1135 return EFI_OUT_OF_RESOURCES
;
1138 NewBlockPtr
= NewBlock
;
1139 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1140 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
1142 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT
;
1146 CopyMem (NewBlockPtr
, &ImageIn
->Width
, sizeof (UINT16
));
1147 NewBlockPtr
+= sizeof (UINT16
);
1148 CopyMem (NewBlockPtr
, &ImageIn
->Height
, sizeof (UINT16
));
1149 NewBlockPtr
+= sizeof (UINT16
);
1151 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlockPtr
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
1154 // Adjust the image package to remove the original block firstly then add the new block.
1156 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
- OldBlockSize
;
1157 Block
= (UINT8
*) AllocateZeroPool (BlockSize
);
1158 if (Block
== NULL
) {
1159 SafeFreePool (NewBlock
);
1160 return EFI_OUT_OF_RESOURCES
;
1164 Part1Size
= (UINT32
) (ImageBlock
- ImagePackage
->ImageBlock
);
1165 Part2Size
= ImagePackage
->ImageBlockSize
- Part1Size
- OldBlockSize
;
1166 CopyMem (BlockPtr
, ImagePackage
->ImageBlock
, Part1Size
);
1167 BlockPtr
+= Part1Size
;
1168 CopyMem (BlockPtr
, NewBlock
, NewBlockSize
);
1169 BlockPtr
+= NewBlockSize
;
1170 CopyMem (BlockPtr
, ImageBlock
+ OldBlockSize
, Part2Size
);
1172 SafeFreePool (ImagePackage
->ImageBlock
);
1173 SafeFreePool (NewBlock
);
1174 ImagePackage
->ImageBlock
= Block
;
1175 ImagePackage
->ImageBlockSize
= BlockSize
;
1176 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
- OldBlockSize
;
1177 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
- OldBlockSize
;
1185 This function renders an image to a bitmap or the screen using the specified
1186 color and options. It draws the image on an existing bitmap, allocates a new
1187 bitmap or uses the screen. The images can be clipped.
1189 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1190 @param Flags Describes how the image is to be drawn.
1191 @param Image Points to the image to be displayed.
1192 @param Blt If this points to a non-NULL on entry, this points
1193 to the image, which is Width pixels wide and
1194 Height pixels high. The image will be drawn onto
1195 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1196 If this points to a NULL on entry, then a buffer
1197 will be allocated to hold the generated image and
1198 the pointer updated on exit. It is the caller's
1199 responsibility to free this buffer.
1200 @param BltX Specifies the offset from the left and top edge of
1201 the output image of the first pixel in the image.
1202 @param BltY Specifies the offset from the left and top edge of
1203 the output image of the first pixel in the image.
1205 @retval EFI_SUCCESS The image was successfully drawn.
1206 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1207 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1208 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1214 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1215 IN EFI_HII_DRAW_FLAGS Flags
,
1216 IN CONST EFI_IMAGE_INPUT
*Image
,
1217 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1223 HII_DATABASE_PRIVATE_DATA
*Private
;
1224 BOOLEAN Transparent
;
1225 EFI_IMAGE_INPUT
*ImageIn
;
1226 EFI_IMAGE_OUTPUT
*ImageOut
;
1227 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
1235 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1237 EFI_CONSOLE_CONTROL_PROTOCOL
*Console
;
1239 if (This
== NULL
|| Image
== NULL
|| Blt
== NULL
) {
1240 return EFI_INVALID_PARAMETER
;
1243 if ((Flags
& EFI_HII_DRAW_FLAG_CLIP
) == EFI_HII_DRAW_FLAG_CLIP
&& *Blt
== NULL
) {
1244 return EFI_INVALID_PARAMETER
;
1247 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_TRANSPARENT
) {
1248 return EFI_INVALID_PARAMETER
;
1251 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1254 // Check whether the image will be drawn transparently or opaquely.
1256 Transparent
= FALSE
;
1257 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_TRANS
) {
1259 } else if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE
){
1260 Transparent
= FALSE
;
1263 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1264 // on the image's transparency setting.
1266 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1272 // Image cannot be drawn transparently if Blt points to NULL on entry.
1273 // Currently output to Screen transparently is not supported, either.
1277 return EFI_INVALID_PARAMETER
;
1278 } else if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1279 return EFI_INVALID_PARAMETER
;
1283 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1286 // When Blt points to a non-NULL on entry, this image will be drawn onto
1287 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1288 // Otherwise a new bitmap will be allocated to hold this image.
1292 // Clip the image by (Width, Height)
1295 Width
= ImageIn
->Width
;
1296 Height
= ImageIn
->Height
;
1298 if (Width
> (*Blt
)->Width
- BltX
) {
1299 Width
= (*Blt
)->Width
- BltX
;
1301 if (Height
> (*Blt
)->Height
- BltY
) {
1302 Height
= (*Blt
)->Height
- BltY
;
1305 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1306 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1307 if (BltBuffer
== NULL
) {
1308 return EFI_OUT_OF_RESOURCES
;
1311 if (Width
== ImageIn
->Width
&& Height
== ImageIn
->Height
) {
1312 CopyMem (BltBuffer
, ImageIn
->Bitmap
, BufferLen
);
1314 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
1315 OffsetY1
= ImageIn
->Width
* Ypos
;
1316 OffsetY2
= Width
* Ypos
;
1317 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
1318 BltBuffer
[OffsetY2
+ Xpos
] = ImageIn
->Bitmap
[OffsetY1
+ Xpos
];
1324 // Draw the image to existing bitmap or screen depending on flag.
1326 if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1327 Status
= gBS
->LocateProtocol (
1328 &gEfiConsoleControlProtocolGuid
,
1333 if (EFI_ERROR (Status
)) {
1337 Console
->SetMode (Console
, EfiConsoleControlScreenGraphics
);
1339 // Write the image directly to the output device specified by Screen.
1341 Status
= (*Blt
)->Image
.Screen
->Blt (
1342 (*Blt
)->Image
.Screen
,
1344 EfiBltBufferToVideo
,
1355 // Draw the image onto the existing bitmap specified by Bitmap.
1357 Status
= ImageToBlt (
1369 SafeFreePool (BltBuffer
);
1374 // Allocate a new bitmap to hold the incoming image.
1376 Width
= ImageIn
->Width
+ BltX
;
1377 Height
= ImageIn
->Height
+ BltY
;
1379 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1380 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1381 if (BltBuffer
== NULL
) {
1382 return EFI_OUT_OF_RESOURCES
;
1385 ImageOut
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1386 if (ImageOut
== NULL
) {
1387 SafeFreePool (BltBuffer
);
1388 return EFI_OUT_OF_RESOURCES
;
1390 ImageOut
->Width
= (UINT16
) Width
;
1391 ImageOut
->Height
= (UINT16
) Height
;
1392 ImageOut
->Image
.Bitmap
= BltBuffer
;
1395 // BUGBUG: Now all the "blank" pixels are filled with system default background
1396 // color. Not sure if it need to be updated or not.
1398 Status
= GetSystemFont (Private
, &FontInfo
, NULL
);
1399 if (EFI_ERROR (Status
)) {
1400 SafeFreePool (BltBuffer
);
1401 SafeFreePool (ImageOut
);
1404 for (Index
= 0; Index
< Width
* Height
; Index
++) {
1405 BltBuffer
[Index
] = FontInfo
->BackgroundColor
;
1407 SafeFreePool (FontInfo
);
1410 // Draw the incoming image to the new created image.
1428 This function renders an image to a bitmap or the screen using the specified
1429 color and options. It draws the image on an existing bitmap, allocates a new
1430 bitmap or uses the screen. The images can be clipped.
1432 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1433 @param Flags Describes how the image is to be drawn.
1434 @param PackageList The package list in the HII database to search for
1435 the specified image.
1436 @param ImageId The image's id, which is unique within
1438 @param Blt If this points to a non-NULL on entry, this points
1439 to the image, which is Width pixels wide and
1440 Height pixels high. The image will be drawn onto
1442 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1443 to a NULL on entry, then a buffer will be
1444 allocated to hold the generated image and the
1445 pointer updated on exit. It is the caller's
1446 responsibility to free this buffer.
1447 @param BltX Specifies the offset from the left and top edge of
1448 the output image of the first pixel in the image.
1449 @param BltY Specifies the offset from the left and top edge of
1450 the output image of the first pixel in the image.
1452 @retval EFI_SUCCESS The image was successfully drawn.
1453 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1454 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1455 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1456 The specified PackageList is not in the database.
1462 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1463 IN EFI_HII_DRAW_FLAGS Flags
,
1464 IN EFI_HII_HANDLE PackageList
,
1465 IN EFI_IMAGE_ID ImageId
,
1466 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1472 EFI_IMAGE_INPUT Image
;
1475 // Check input parameter.
1477 if (This
== NULL
|| Blt
== NULL
) {
1478 return EFI_INVALID_PARAMETER
;
1481 if (!IsHiiHandleValid (PackageList
)) {
1482 return EFI_NOT_FOUND
;
1486 // Get the specified Image.
1488 Status
= HiiGetImage (This
, PackageList
, ImageId
, &Image
);
1489 if (EFI_ERROR (Status
)) {
1496 Status
= HiiDrawImage (This
, Flags
, &Image
, Blt
, BltX
, BltY
);
1497 SafeFreePool (Image
.Bitmap
);