2 Implementation for EFI_HII_IMAGE_PROTOCOL.
5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 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 ImageBlocks 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.
36 IN EFI_HII_IMAGE_BLOCK
*ImageBlocks
,
37 IN OUT EFI_IMAGE_ID
*ImageId
40 EFI_IMAGE_ID ImageIdCurrent
;
41 EFI_HII_IMAGE_BLOCK
*CurrentImageBlock
;
44 ASSERT (ImageBlocks
!= NULL
&& ImageId
!= NULL
);
45 CurrentImageBlock
= ImageBlocks
;
48 while (CurrentImageBlock
->BlockType
!= EFI_HII_IIBT_END
) {
50 if (*ImageId
== ImageIdCurrent
) {
52 // If the found image block is a duplicate block, update the ImageId to
53 // find the previous defined image block.
55 if (CurrentImageBlock
->BlockType
== EFI_HII_IIBT_DUPLICATE
) {
56 *ImageId
= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_DUPLICATE_BLOCK
*) CurrentImageBlock
)->ImageId
);
57 ASSERT (*ImageId
!= ImageIdCurrent
);
58 ASSERT (*ImageId
!= 0);
59 CurrentImageBlock
= ImageBlocks
;
64 return CurrentImageBlock
;
66 if (*ImageId
< ImageIdCurrent
) {
68 // Can not find the specified image block in this image.
73 switch (CurrentImageBlock
->BlockType
) {
74 case EFI_HII_IIBT_EXT1
:
75 Length
= ((EFI_HII_IIBT_EXT1_BLOCK
*) CurrentImageBlock
)->Length
;
77 case EFI_HII_IIBT_EXT2
:
78 Length
= ReadUnaligned16 (&((EFI_HII_IIBT_EXT2_BLOCK
*) CurrentImageBlock
)->Length
);
80 case EFI_HII_IIBT_EXT4
:
81 Length
= ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_EXT4_BLOCK
*) CurrentImageBlock
)->Length
);
84 case EFI_HII_IIBT_IMAGE_1BIT
:
85 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
86 Length
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
88 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
89 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
94 case EFI_HII_IIBT_IMAGE_4BIT
:
95 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
96 Length
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
98 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
99 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
104 case EFI_HII_IIBT_IMAGE_8BIT
:
105 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
106 Length
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
108 (UINT32
) ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
109 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
114 case EFI_HII_IIBT_IMAGE_24BIT
:
115 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
116 Length
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
118 (UINT32
) ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
119 ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
124 case EFI_HII_IIBT_DUPLICATE
:
125 Length
= sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK
);
129 case EFI_HII_IIBT_IMAGE_JPEG
:
130 Length
= OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
);
134 case EFI_HII_IIBT_IMAGE_PNG
:
135 Length
= OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Size
);
139 case EFI_HII_IIBT_SKIP1
:
140 Length
= sizeof (EFI_HII_IIBT_SKIP1_BLOCK
);
141 ImageIdCurrent
+= ((EFI_HII_IIBT_SKIP1_BLOCK
*) CurrentImageBlock
)->SkipCount
;
144 case EFI_HII_IIBT_SKIP2
:
145 Length
= sizeof (EFI_HII_IIBT_SKIP2_BLOCK
);
146 ImageIdCurrent
+= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_SKIP2_BLOCK
*) CurrentImageBlock
)->SkipCount
);
151 // Unknown image blocks can not be skipped, processing halts.
158 CurrentImageBlock
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) CurrentImageBlock
+ Length
);
163 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
166 *ImageId
= ImageIdCurrent
;
167 return CurrentImageBlock
;
176 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
178 This is a internal function.
181 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
182 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
183 @param PixelNum The number of pixels to be converted.
189 OUT EFI_HII_RGB_PIXEL
*BitMapOut
,
190 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapIn
,
196 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
198 for (Index
= 0; Index
< PixelNum
; Index
++) {
199 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
205 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
207 This is a internal function.
210 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
211 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
212 @param PixelNum The number of pixels to be converted.
218 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapOut
,
219 IN EFI_HII_RGB_PIXEL
*BitMapIn
,
225 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
227 for (Index
= 0; Index
< PixelNum
; Index
++) {
228 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
234 Output pixels in "1 bit per pixel" format to an image.
236 This is a internal function.
239 @param Image Points to the image which will store the pixels.
240 @param Data Stores the value of output pixels, 0 or 1.
241 @param PaletteInfo PaletteInfo which stores the color of the output
242 pixels. First entry corresponds to color 0 and
243 second one to color 1.
249 IN OUT EFI_IMAGE_INPUT
*Image
,
251 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
258 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
259 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[2];
260 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
264 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
266 BitMapPtr
= Image
->Bitmap
;
269 // First entry corresponds to color 0 and second entry corresponds to color 1.
272 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
273 PaletteSize
+= sizeof (UINT16
);
274 Palette
= AllocateZeroPool (PaletteSize
);
275 ASSERT (Palette
!= NULL
);
276 if (Palette
== NULL
) {
279 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
281 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
282 CopyRgbToGopPixel (&PaletteValue
[0], &Palette
->PaletteValue
[0], 1);
283 CopyRgbToGopPixel (&PaletteValue
[1], &Palette
->PaletteValue
[1], 1);
287 // Convert the pixel from one bit to corresponding color.
289 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
290 OffsetY
= BITMAP_LEN_1_BIT (Image
->Width
, Ypos
);
292 // All bits in these bytes are meaningful
294 for (Xpos
= 0; Xpos
< Image
->Width
/ 8; Xpos
++) {
295 Byte
= *(Data
+ OffsetY
+ Xpos
);
296 for (Index
= 0; Index
< 8; Index
++) {
297 if ((Byte
& (1 << Index
)) != 0) {
298 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[1];
300 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[0];
305 if (Image
->Width
% 8 != 0) {
307 // Padding bits in this byte should be ignored.
309 Byte
= *(Data
+ OffsetY
+ Xpos
);
310 for (Index
= 0; Index
< Image
->Width
% 8; Index
++) {
311 if ((Byte
& (1 << (8 - Index
- 1))) != 0) {
312 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[1];
314 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[0];
323 Output pixels in "4 bit per pixel" format to an image.
325 This is a internal function.
328 @param Image Points to the image which will store the pixels.
329 @param Data Stores the value of output pixels, 0 ~ 15.
330 @param[in] PaletteInfo PaletteInfo which stores the color of the output
331 pixels. Each entry corresponds to a color within
338 IN OUT EFI_IMAGE_INPUT
*Image
,
340 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
346 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
347 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[16];
348 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
353 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
355 BitMapPtr
= Image
->Bitmap
;
358 // The bitmap should allocate each color index starting from 0.
361 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
362 PaletteSize
+= sizeof (UINT16
);
363 Palette
= AllocateZeroPool (PaletteSize
);
364 ASSERT (Palette
!= NULL
);
365 if (Palette
== NULL
) {
368 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
369 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
371 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
372 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
376 // Convert the pixel from 4 bit to corresponding color.
378 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
379 OffsetY
= BITMAP_LEN_4_BIT (Image
->Width
, Ypos
);
381 // All bits in these bytes are meaningful
383 for (Xpos
= 0; Xpos
< Image
->Width
/ 2; Xpos
++) {
384 Byte
= *(Data
+ OffsetY
+ Xpos
);
385 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
386 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2 + 1] = PaletteValue
[Byte
& 0x0F];
389 if (Image
->Width
% 2 != 0) {
391 // Padding bits in this byte should be ignored.
393 Byte
= *(Data
+ OffsetY
+ Xpos
);
394 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
401 Output pixels in "8 bit per pixel" format to an image.
403 This is a internal function.
406 @param Image Points to the image which will store the pixels.
407 @param Data Stores the value of output pixels, 0 ~ 255.
408 @param[in] PaletteInfo PaletteInfo which stores the color of the output
409 pixels. Each entry corresponds to a color within
416 IN OUT EFI_IMAGE_INPUT
*Image
,
418 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
424 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
425 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[256];
426 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
431 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
433 BitMapPtr
= Image
->Bitmap
;
436 // The bitmap should allocate each color index starting from 0.
439 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
440 PaletteSize
+= sizeof (UINT16
);
441 Palette
= AllocateZeroPool (PaletteSize
);
442 ASSERT (Palette
!= NULL
);
443 if (Palette
== NULL
) {
446 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
447 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
448 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
449 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
453 // Convert the pixel from 8 bits to corresponding color.
455 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
456 OffsetY
= BITMAP_LEN_8_BIT ((UINT32
) Image
->Width
, Ypos
);
458 // All bits are meaningful since the bitmap is 8 bits per pixel.
460 for (Xpos
= 0; Xpos
< Image
->Width
; Xpos
++) {
461 Byte
= *(Data
+ OffsetY
+ Xpos
);
462 BitMapPtr
[OffsetY
+ Xpos
] = PaletteValue
[Byte
];
470 Output pixels in "24 bit per pixel" format to an image.
472 This is a internal function.
475 @param Image Points to the image which will store the pixels.
476 @param Data Stores the color of output pixels, allowing 16.8
483 IN OUT EFI_IMAGE_INPUT
*Image
,
484 IN EFI_HII_RGB_PIXEL
*Data
489 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
491 ASSERT (Image
!= NULL
&& Data
!= NULL
);
493 BitMapPtr
= Image
->Bitmap
;
495 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
496 OffsetY
= BITMAP_LEN_8_BIT ((UINT32
) Image
->Width
, Ypos
);
497 CopyRgbToGopPixel (&BitMapPtr
[OffsetY
], &Data
[OffsetY
], Image
->Width
);
504 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
506 This is a internal function.
509 @param BltBuffer Buffer points to bitmap data of incoming image.
510 @param BltX Specifies the offset from the left and top edge of
511 the output image of the first pixel in the image.
512 @param BltY Specifies the offset from the left and top edge of
513 the output image of the first pixel in the image.
514 @param Width Width of the incoming image, in pixels.
515 @param Height Height of the incoming image, in pixels.
516 @param Transparent If TRUE, all "off" pixels in the image will be
517 drawn using the pixel value from blt and all other
518 pixels will be copied.
519 @param Blt Buffer points to bitmap data of output image.
521 @retval EFI_SUCCESS The image was successfully converted.
522 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
527 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
532 IN BOOLEAN Transparent
,
533 IN OUT EFI_IMAGE_OUTPUT
**Blt
536 EFI_IMAGE_OUTPUT
*ImageOut
;
539 UINTN OffsetY1
; // src buffer
540 UINTN OffsetY2
; // dest buffer
541 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel
;
542 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel
;
544 if (BltBuffer
== NULL
|| Blt
== NULL
|| *Blt
== NULL
) {
545 return EFI_INVALID_PARAMETER
;
550 if (Width
+ BltX
> ImageOut
->Width
) {
551 return EFI_INVALID_PARAMETER
;
553 if (Height
+ BltY
> ImageOut
->Height
) {
554 return EFI_INVALID_PARAMETER
;
557 ZeroMem (&ZeroPixel
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
559 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
560 OffsetY1
= Width
* Ypos
;
561 OffsetY2
= ImageOut
->Width
* (BltY
+ Ypos
);
562 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
563 SrcPixel
= BltBuffer
[OffsetY1
+ Xpos
];
565 if (CompareMem (&SrcPixel
, &ZeroPixel
, 3) != 0) {
566 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
569 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
578 Return the HII package list identified by PackageList HII handle.
580 @param Database Pointer to HII database list header.
581 @param PackageList HII handle of the package list to locate.
583 @retval The HII package list instance.
585 HII_DATABASE_PACKAGE_LIST_INSTANCE
*
587 IN LIST_ENTRY
*Database
,
588 IN EFI_HII_HANDLE PackageList
592 HII_DATABASE_RECORD
*Record
;
595 // Get the specified package list and image package.
597 for (Link
= GetFirstNode (Database
);
598 !IsNull (Database
, Link
);
599 Link
= GetNextNode (Database
, Link
)
601 Record
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
602 if (Record
->Handle
== PackageList
) {
603 return Record
->PackageList
;
610 This function adds the image Image to the group of images owned by PackageList, and returns
611 a new image identifier (ImageId).
613 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
614 @param PackageList Handle of the package list where this image will
616 @param ImageId On return, contains the new image id, which is
617 unique within PackageList.
618 @param Image Points to the image.
620 @retval EFI_SUCCESS The new image was added successfully.
621 @retval EFI_NOT_FOUND The specified PackageList could not be found in
623 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
624 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
630 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
631 IN EFI_HII_HANDLE PackageList
,
632 OUT EFI_IMAGE_ID
*ImageId
,
633 IN CONST EFI_IMAGE_INPUT
*Image
636 HII_DATABASE_PRIVATE_DATA
*Private
;
637 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
638 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
639 EFI_HII_IMAGE_BLOCK
*ImageBlocks
;
642 if (This
== NULL
|| ImageId
== NULL
|| Image
== NULL
|| Image
->Bitmap
== NULL
) {
643 return EFI_INVALID_PARAMETER
;
646 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
647 PackageListNode
= LocatePackageList (&Private
->DatabaseList
, PackageList
);
648 if (PackageListNode
== NULL
) {
649 return EFI_NOT_FOUND
;
652 EfiAcquireLock (&mHiiDatabaseLock
);
654 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
655 BITMAP_LEN_24_BIT ((UINT32
) Image
->Width
, Image
->Height
);
658 // Get the image package in the package list,
659 // or create a new image package if image package does not exist.
661 if (PackageListNode
->ImagePkg
!= NULL
) {
662 ImagePackage
= PackageListNode
->ImagePkg
;
665 // Output the image id of the incoming image being inserted, which is the
666 // image id of the EFI_HII_IIBT_END block of old image package.
669 GetImageIdOrAddress (ImagePackage
->ImageBlock
, ImageId
);
672 // Update the package's image block by appending the new block to the end.
674 ImageBlocks
= AllocatePool (ImagePackage
->ImageBlockSize
+ NewBlockSize
);
675 if (ImageBlocks
== NULL
) {
676 EfiReleaseLock (&mHiiDatabaseLock
);
677 return EFI_OUT_OF_RESOURCES
;
680 // Copy the original content.
684 ImagePackage
->ImageBlock
,
685 ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
687 FreePool (ImagePackage
->ImageBlock
);
688 ImagePackage
->ImageBlock
= ImageBlocks
;
691 // Point to the very last block.
693 ImageBlocks
= (EFI_HII_IMAGE_BLOCK
*) (
694 (UINT8
*) ImageBlocks
+ ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
697 // Update the length record.
699 ImagePackage
->ImageBlockSize
+= NewBlockSize
;
700 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
;
701 PackageListNode
->PackageListHdr
.PackageLength
+= 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 EfiReleaseLock (&mHiiDatabaseLock
);
711 return EFI_OUT_OF_RESOURCES
;
714 // Output the image id of the incoming image being inserted, which is the
715 // first image block so that id is initially to one.
719 // Fill in image package header.
721 ImagePackage
->ImagePkgHdr
.Header
.Length
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) + NewBlockSize
+ sizeof (EFI_HII_IIBT_END_BLOCK
);
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
= NewBlockSize
+ sizeof (EFI_HII_IIBT_END_BLOCK
);
736 ImagePackage
->ImageBlock
= AllocateZeroPool (NewBlockSize
+ sizeof (EFI_HII_IIBT_END_BLOCK
));
737 if (ImagePackage
->ImageBlock
== NULL
) {
738 FreePool (ImagePackage
);
739 EfiReleaseLock (&mHiiDatabaseLock
);
740 return EFI_OUT_OF_RESOURCES
;
742 ImageBlocks
= ImagePackage
->ImageBlock
;
745 // Insert this image package.
747 PackageListNode
->ImagePkg
= ImagePackage
;
748 PackageListNode
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
752 // Append the new block here
754 if (Image
->Flags
== EFI_IMAGE_TRANSPARENT
) {
755 ImageBlocks
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
757 ImageBlocks
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT
;
759 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) ImageBlocks
)->Bitmap
.Width
, Image
->Width
);
760 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) ImageBlocks
)->Bitmap
.Height
, Image
->Height
);
761 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) ImageBlocks
)->Bitmap
.Bitmap
, Image
->Bitmap
, (UINT32
) Image
->Width
* Image
->Height
);
764 // Append the block end
766 ImageBlocks
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) ImageBlocks
+ NewBlockSize
);
767 ImageBlocks
->BlockType
= EFI_HII_IIBT_END
;
770 // Check whether need to get the contents of HiiDataBase.
771 // Only after ReadyToBoot to do the export.
773 if (gExportAfterReadyToBoot
) {
774 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
777 EfiReleaseLock (&mHiiDatabaseLock
);
784 This function retrieves the image specified by ImageId which is associated with
785 the specified PackageList and copies it into the buffer specified by Image.
787 @param Database A pointer to the database list header.
788 @param PackageList Handle of the package list where this image will
790 @param ImageId The image's id,, which is unique within
792 @param Image Points to the image.
793 @param BitmapOnly TRUE to only return the bitmap type image.
794 FALSE to locate image decoder instance to decode image.
796 @retval EFI_SUCCESS The new image was returned successfully.
797 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
798 database. The specified PackageList is not in the database.
799 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
801 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
802 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
807 IN LIST_ENTRY
*Database
,
808 IN EFI_HII_HANDLE PackageList
,
809 IN EFI_IMAGE_ID ImageId
,
810 OUT EFI_IMAGE_INPUT
*Image
,
811 IN BOOLEAN BitmapOnly
815 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
816 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
817 EFI_HII_IMAGE_BLOCK
*CurrentImageBlock
;
818 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
825 EFI_HII_IMAGE_DECODER_PROTOCOL
*Decoder
;
826 EFI_IMAGE_OUTPUT
*ImageOut
;
828 if (Image
== NULL
|| ImageId
== 0) {
829 return EFI_INVALID_PARAMETER
;
832 PackageListNode
= LocatePackageList (Database
, PackageList
);
833 if (PackageListNode
== NULL
) {
834 return EFI_NOT_FOUND
;
836 ImagePackage
= PackageListNode
->ImagePkg
;
837 if (ImagePackage
== NULL
) {
838 return EFI_NOT_FOUND
;
842 // Find the image block specified by ImageId
844 CurrentImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &ImageId
);
845 if (CurrentImageBlock
== NULL
) {
846 return EFI_NOT_FOUND
;
850 switch (CurrentImageBlock
->BlockType
) {
851 case EFI_HII_IIBT_IMAGE_JPEG
:
852 case EFI_HII_IIBT_IMAGE_PNG
:
854 return EFI_UNSUPPORTED
;
858 Decoder
= LocateHiiImageDecoder (CurrentImageBlock
->BlockType
);
859 if (Decoder
== NULL
) {
860 return EFI_UNSUPPORTED
;
863 // Use the common block code since the definition of two structures is the same.
865 ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Data
) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Data
));
866 ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Data
) ==
867 sizeof (((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Data
));
868 ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Size
) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Size
));
869 ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
) ==
870 sizeof (((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Size
));
871 Status
= Decoder
->DecodeImage (
873 ((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Data
,
874 ((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
,
880 // Spec requires to use the first capable image decoder instance.
881 // The first image decoder instance may fail to decode the image.
883 if (!EFI_ERROR (Status
)) {
884 Image
->Bitmap
= ImageOut
->Image
.Bitmap
;
885 Image
->Height
= ImageOut
->Height
;
886 Image
->Width
= ImageOut
->Width
;
891 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
892 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
893 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
894 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
898 case EFI_HII_IIBT_IMAGE_1BIT
:
899 case EFI_HII_IIBT_IMAGE_4BIT
:
900 case EFI_HII_IIBT_IMAGE_8BIT
:
902 // Use the common block code since the definition of these structures is the same.
904 CopyMem (&Iibt1bit
, CurrentImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
905 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) *
906 ((UINT32
) Iibt1bit
.Bitmap
.Width
* Iibt1bit
.Bitmap
.Height
);
907 Image
->Bitmap
= AllocateZeroPool (ImageLength
);
908 if (Image
->Bitmap
== NULL
) {
909 return EFI_OUT_OF_RESOURCES
;
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 (CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_1BIT
||
926 CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_1BIT_TRANS
) {
929 ((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Data
,
930 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
932 } else if (CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_4BIT
||
933 CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_4BIT_TRANS
) {
936 ((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Data
,
937 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
942 ((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Data
,
943 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
949 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
950 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
954 case EFI_HII_IIBT_IMAGE_24BIT
:
955 Width
= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
);
956 Height
= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
);
957 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * ((UINT32
) Width
* Height
);
958 Image
->Bitmap
= AllocateZeroPool (ImageLength
);
959 if (Image
->Bitmap
== NULL
) {
960 return EFI_OUT_OF_RESOURCES
;
963 Image
->Width
= Width
;
964 Image
->Height
= Height
;
967 // Output the bitmap data directly.
971 ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Bitmap
976 return EFI_NOT_FOUND
;
981 This function retrieves the image specified by ImageId which is associated with
982 the specified PackageList and copies it into the buffer specified by Image.
984 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
985 @param PackageList Handle of the package list where this image will
987 @param ImageId The image's id,, which is unique within
989 @param Image Points to the image.
991 @retval EFI_SUCCESS The new image was returned successfully.
992 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
993 database. The specified PackageList is not in the database.
994 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
996 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
997 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
1004 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1005 IN EFI_HII_HANDLE PackageList
,
1006 IN EFI_IMAGE_ID ImageId
,
1007 OUT EFI_IMAGE_INPUT
*Image
1010 HII_DATABASE_PRIVATE_DATA
*Private
;
1011 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1012 return IGetImage (&Private
->DatabaseList
, PackageList
, ImageId
, Image
, TRUE
);
1017 This function updates the image specified by ImageId in the specified PackageListHandle to
1018 the image specified by Image.
1020 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1021 @param PackageList The package list containing the images.
1022 @param ImageId The image's id,, which is unique within
1024 @param Image Points to the image.
1026 @retval EFI_SUCCESS The new image was updated successfully.
1027 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
1028 database. The specified PackageList is not in the database.
1029 @retval EFI_INVALID_PARAMETER The Image was NULL.
1035 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1036 IN EFI_HII_HANDLE PackageList
,
1037 IN EFI_IMAGE_ID ImageId
,
1038 IN CONST EFI_IMAGE_INPUT
*Image
1041 HII_DATABASE_PRIVATE_DATA
*Private
;
1042 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1043 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
1044 EFI_HII_IMAGE_BLOCK
*CurrentImageBlock
;
1045 EFI_HII_IMAGE_BLOCK
*ImageBlocks
;
1046 EFI_HII_IMAGE_BLOCK
*NewImageBlock
;
1047 UINT32 NewBlockSize
;
1048 UINT32 OldBlockSize
;
1052 if (This
== NULL
|| Image
== NULL
|| ImageId
== 0 || Image
->Bitmap
== NULL
) {
1053 return EFI_INVALID_PARAMETER
;
1056 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1057 PackageListNode
= LocatePackageList (&Private
->DatabaseList
, PackageList
);
1058 if (PackageListNode
== NULL
) {
1059 return EFI_NOT_FOUND
;
1061 ImagePackage
= PackageListNode
->ImagePkg
;
1062 if (ImagePackage
== NULL
) {
1063 return EFI_NOT_FOUND
;
1067 // Find the image block specified by ImageId
1069 CurrentImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &ImageId
);
1070 if (CurrentImageBlock
== NULL
) {
1071 return EFI_NOT_FOUND
;
1074 EfiAcquireLock (&mHiiDatabaseLock
);
1077 // Get the size of original image block. Use some common block code here
1078 // since the definition of some structures is the same.
1080 switch (CurrentImageBlock
->BlockType
) {
1081 case EFI_HII_IIBT_IMAGE_JPEG
:
1082 OldBlockSize
= OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
);
1084 case EFI_HII_IIBT_IMAGE_PNG
:
1085 OldBlockSize
= OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Size
);
1087 case EFI_HII_IIBT_IMAGE_1BIT
:
1088 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
1089 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
1091 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1092 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1095 case EFI_HII_IIBT_IMAGE_4BIT
:
1096 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
1097 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
1099 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1100 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1103 case EFI_HII_IIBT_IMAGE_8BIT
:
1104 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
1105 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
1107 (UINT32
) ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1108 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1111 case EFI_HII_IIBT_IMAGE_24BIT
:
1112 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
1113 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1115 (UINT32
) ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1116 ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1120 EfiReleaseLock (&mHiiDatabaseLock
);
1121 return EFI_NOT_FOUND
;
1125 // Create the new image block according to input image.
1127 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1128 BITMAP_LEN_24_BIT ((UINT32
) Image
->Width
, Image
->Height
);
1130 // Adjust the image package to remove the original block firstly then add the new block.
1132 ImageBlocks
= AllocateZeroPool (ImagePackage
->ImageBlockSize
+ NewBlockSize
- OldBlockSize
);
1133 if (ImageBlocks
== NULL
) {
1134 EfiReleaseLock (&mHiiDatabaseLock
);
1135 return EFI_OUT_OF_RESOURCES
;
1138 Part1Size
= (UINT32
) ((UINTN
) CurrentImageBlock
- (UINTN
) ImagePackage
->ImageBlock
);
1139 Part2Size
= ImagePackage
->ImageBlockSize
- Part1Size
- OldBlockSize
;
1140 CopyMem (ImageBlocks
, ImagePackage
->ImageBlock
, Part1Size
);
1143 // Set the new image block
1145 NewImageBlock
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) ImageBlocks
+ Part1Size
);
1146 if ((Image
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1147 NewImageBlock
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
1149 NewImageBlock
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT
;
1151 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) NewImageBlock
)->Bitmap
.Width
, Image
->Width
);
1152 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) NewImageBlock
)->Bitmap
.Height
, Image
->Height
);
1153 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) NewImageBlock
)->Bitmap
.Bitmap
,
1154 Image
->Bitmap
, (UINT32
) Image
->Width
* Image
->Height
);
1156 CopyMem ((UINT8
*) NewImageBlock
+ NewBlockSize
, (UINT8
*) CurrentImageBlock
+ OldBlockSize
, Part2Size
);
1158 FreePool (ImagePackage
->ImageBlock
);
1159 ImagePackage
->ImageBlock
= ImageBlocks
;
1160 ImagePackage
->ImageBlockSize
+= NewBlockSize
- OldBlockSize
;
1161 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
- OldBlockSize
;
1162 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
- OldBlockSize
;
1165 // Check whether need to get the contents of HiiDataBase.
1166 // Only after ReadyToBoot to do the export.
1168 if (gExportAfterReadyToBoot
) {
1169 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
1172 EfiReleaseLock (&mHiiDatabaseLock
);
1179 This function renders an image to a bitmap or the screen using the specified
1180 color and options. It draws the image on an existing bitmap, allocates a new
1181 bitmap or uses the screen. The images can be clipped.
1183 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1184 @param Flags Describes how the image is to be drawn.
1185 @param Image Points to the image to be displayed.
1186 @param Blt If this points to a non-NULL on entry, this points
1187 to the image, which is Width pixels wide and
1188 Height pixels high. The image will be drawn onto
1189 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1190 If this points to a NULL on entry, then a buffer
1191 will be allocated to hold the generated image and
1192 the pointer updated on exit. It is the caller's
1193 responsibility to free this buffer.
1194 @param BltX Specifies the offset from the left and top edge of
1195 the output image of the first pixel in the image.
1196 @param BltY Specifies the offset from the left and top edge of
1197 the output image of the first pixel in the image.
1199 @retval EFI_SUCCESS The image was successfully drawn.
1200 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1201 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1202 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1208 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1209 IN EFI_HII_DRAW_FLAGS Flags
,
1210 IN CONST EFI_IMAGE_INPUT
*Image
,
1211 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1217 HII_DATABASE_PRIVATE_DATA
*Private
;
1218 BOOLEAN Transparent
;
1219 EFI_IMAGE_OUTPUT
*ImageOut
;
1220 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
1228 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1231 if (This
== NULL
|| Image
== NULL
|| Blt
== NULL
) {
1232 return EFI_INVALID_PARAMETER
;
1235 if ((Flags
& EFI_HII_DRAW_FLAG_CLIP
) == EFI_HII_DRAW_FLAG_CLIP
&& *Blt
== NULL
) {
1236 return EFI_INVALID_PARAMETER
;
1239 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_TRANSPARENT
) {
1240 return EFI_INVALID_PARAMETER
;
1246 // Check whether the image will be drawn transparently or opaquely.
1248 Transparent
= FALSE
;
1249 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_TRANS
) {
1251 } else if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE
){
1252 Transparent
= FALSE
;
1255 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1256 // on the image's transparency setting.
1258 if ((Image
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1264 // Image cannot be drawn transparently if Blt points to NULL on entry.
1265 // Currently output to Screen transparently is not supported, either.
1269 return EFI_INVALID_PARAMETER
;
1270 } else if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1271 return EFI_INVALID_PARAMETER
;
1275 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1278 // When Blt points to a non-NULL on entry, this image will be drawn onto
1279 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1280 // Otherwise a new bitmap will be allocated to hold this image.
1284 // Clip the image by (Width, Height)
1287 Width
= Image
->Width
;
1288 Height
= Image
->Height
;
1290 if (Width
> (*Blt
)->Width
- BltX
) {
1291 Width
= (*Blt
)->Width
- BltX
;
1293 if (Height
> (*Blt
)->Height
- BltY
) {
1294 Height
= (*Blt
)->Height
- BltY
;
1297 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1298 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1299 if (BltBuffer
== NULL
) {
1300 return EFI_OUT_OF_RESOURCES
;
1303 if (Width
== Image
->Width
&& Height
== Image
->Height
) {
1304 CopyMem (BltBuffer
, Image
->Bitmap
, BufferLen
);
1306 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
1307 OffsetY1
= Image
->Width
* Ypos
;
1308 OffsetY2
= Width
* Ypos
;
1309 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
1310 BltBuffer
[OffsetY2
+ Xpos
] = Image
->Bitmap
[OffsetY1
+ Xpos
];
1316 // Draw the image to existing bitmap or screen depending on flag.
1318 if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1320 // Caller should make sure the current UGA console is grarphic mode.
1324 // Write the image directly to the output device specified by Screen.
1326 Status
= (*Blt
)->Image
.Screen
->Blt (
1327 (*Blt
)->Image
.Screen
,
1329 EfiBltBufferToVideo
,
1340 // Draw the image onto the existing bitmap specified by Bitmap.
1342 Status
= ImageToBlt (
1354 FreePool (BltBuffer
);
1359 // Allocate a new bitmap to hold the incoming image.
1361 Width
= Image
->Width
+ BltX
;
1362 Height
= Image
->Height
+ BltY
;
1364 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1365 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1366 if (BltBuffer
== NULL
) {
1367 return EFI_OUT_OF_RESOURCES
;
1370 ImageOut
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1371 if (ImageOut
== NULL
) {
1372 FreePool (BltBuffer
);
1373 return EFI_OUT_OF_RESOURCES
;
1375 ImageOut
->Width
= (UINT16
) Width
;
1376 ImageOut
->Height
= (UINT16
) Height
;
1377 ImageOut
->Image
.Bitmap
= BltBuffer
;
1380 // BUGBUG: Now all the "blank" pixels are filled with system default background
1381 // color. Not sure if it need to be updated or not.
1383 Status
= GetSystemFont (Private
, &FontInfo
, NULL
);
1384 if (EFI_ERROR (Status
)) {
1385 FreePool (BltBuffer
);
1386 FreePool (ImageOut
);
1389 ASSERT (FontInfo
!= NULL
);
1390 for (Index
= 0; Index
< Width
* Height
; Index
++) {
1391 BltBuffer
[Index
] = FontInfo
->BackgroundColor
;
1393 FreePool (FontInfo
);
1396 // Draw the incoming image to the new created image.
1414 This function renders an image to a bitmap or the screen using the specified
1415 color and options. It draws the image on an existing bitmap, allocates a new
1416 bitmap or uses the screen. The images can be clipped.
1418 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1419 @param Flags Describes how the image is to be drawn.
1420 @param PackageList The package list in the HII database to search for
1421 the specified image.
1422 @param ImageId The image's id, which is unique within
1424 @param Blt If this points to a non-NULL on entry, this points
1425 to the image, which is Width pixels wide and
1426 Height pixels high. The image will be drawn onto
1428 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1429 to a NULL on entry, then a buffer will be
1430 allocated to hold the generated image and the
1431 pointer updated on exit. It is the caller's
1432 responsibility to free this buffer.
1433 @param BltX Specifies the offset from the left and top edge of
1434 the output image of the first pixel in the image.
1435 @param BltY Specifies the offset from the left and top edge of
1436 the output image of the first pixel in the image.
1438 @retval EFI_SUCCESS The image was successfully drawn.
1439 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1440 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1441 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1442 The specified PackageList is not in the database.
1448 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1449 IN EFI_HII_DRAW_FLAGS Flags
,
1450 IN EFI_HII_HANDLE PackageList
,
1451 IN EFI_IMAGE_ID ImageId
,
1452 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1458 EFI_IMAGE_INPUT Image
;
1461 // Check input parameter.
1463 if (This
== NULL
|| Blt
== NULL
) {
1464 return EFI_INVALID_PARAMETER
;
1468 // Get the specified Image.
1470 Status
= HiiGetImage (This
, PackageList
, ImageId
, &Image
);
1471 if (EFI_ERROR (Status
)) {
1478 Status
= HiiDrawImage (This
, Flags
, &Image
, Blt
, BltX
, BltY
);
1479 if (Image
.Bitmap
!= NULL
) {
1480 FreePool (Image
.Bitmap
);