2 Implementation for EFI_HII_IMAGE_PROTOCOL.
5 Copyright (c) 2007 - 2016, 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 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
= *(UINT8
*)((UINTN
)ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
));
83 ImageBlock
+= Length8
;
85 case EFI_HII_IIBT_EXT2
:
88 (UINT8
*)((UINTN
)ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
)),
91 ImageBlock
+= Length16
;
93 case EFI_HII_IIBT_EXT4
:
96 (UINT8
*)((UINTN
)ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
)),
99 ImageBlock
+= Length32
;
102 case EFI_HII_IIBT_IMAGE_1BIT
:
103 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
104 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
105 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
106 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
110 case EFI_HII_IIBT_IMAGE_4BIT
:
111 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
112 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
113 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
114 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
118 case EFI_HII_IIBT_IMAGE_8BIT
:
119 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
120 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
121 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
122 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
126 case EFI_HII_IIBT_IMAGE_24BIT
:
127 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
128 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
131 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
134 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
135 BITMAP_LEN_24_BIT (Width
, Height
);
139 case EFI_HII_IIBT_DUPLICATE
:
140 ImageBlock
+= sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK
);
144 case EFI_HII_IIBT_IMAGE_JPEG
:
145 CopyMem (&Length32
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT32
));
146 ImageBlock
+= Length32
;
150 case EFI_HII_IIBT_SKIP1
:
151 Length8
= *(ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
));
152 ImageBlock
+= sizeof (EFI_HII_IIBT_SKIP1_BLOCK
);
153 ImageIdCurrent
= (UINT16
) (ImageIdCurrent
+ Length8
);
156 case EFI_HII_IIBT_SKIP2
:
157 CopyMem (&Length16
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
158 ImageBlock
+= sizeof (EFI_HII_IIBT_SKIP2_BLOCK
);
159 ImageIdCurrent
= (UINT16
) (ImageIdCurrent
+ Length16
);
164 // Unknown image blocks can not be skipped, processing halts.
171 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
174 *ImageId
= ImageIdCurrent
;
184 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
186 This is a internal function.
189 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
190 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
191 @param PixelNum The number of pixels to be converted.
197 OUT EFI_HII_RGB_PIXEL
*BitMapOut
,
198 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapIn
,
204 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
206 for (Index
= 0; Index
< PixelNum
; Index
++) {
207 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
213 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
215 This is a internal function.
218 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
219 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
220 @param PixelNum The number of pixels to be converted.
226 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapOut
,
227 IN EFI_HII_RGB_PIXEL
*BitMapIn
,
233 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
235 for (Index
= 0; Index
< PixelNum
; Index
++) {
236 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
242 Output pixels in "1 bit per pixel" format to an image.
244 This is a internal function.
247 @param Image Points to the image which will store the pixels.
248 @param Data Stores the value of output pixels, 0 or 1.
249 @param PaletteInfo PaletteInfo which stores the color of the output
250 pixels. First entry corresponds to color 0 and
251 second one to color 1.
257 IN OUT EFI_IMAGE_INPUT
*Image
,
259 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
266 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
267 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[2];
268 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
272 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
274 BitMapPtr
= Image
->Bitmap
;
277 // First entry corresponds to color 0 and second entry corresponds to color 1.
280 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
281 PaletteSize
+= sizeof (UINT16
);
282 Palette
= AllocateZeroPool (PaletteSize
);
283 ASSERT (Palette
!= NULL
);
284 if (Palette
== NULL
) {
287 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
289 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
290 CopyRgbToGopPixel (&PaletteValue
[0], &Palette
->PaletteValue
[0], 1);
291 CopyRgbToGopPixel (&PaletteValue
[1], &Palette
->PaletteValue
[1], 1);
295 // Convert the pixel from one bit to corresponding color.
297 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
298 OffsetY
= BITMAP_LEN_1_BIT (Image
->Width
, Ypos
);
300 // All bits in these bytes are meaningful
302 for (Xpos
= 0; Xpos
< Image
->Width
/ 8; Xpos
++) {
303 Byte
= *(Data
+ OffsetY
+ Xpos
);
304 for (Index
= 0; Index
< 8; Index
++) {
305 if ((Byte
& (1 << Index
)) != 0) {
306 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[1];
308 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[0];
313 if (Image
->Width
% 8 != 0) {
315 // Padding bits in this byte should be ignored.
317 Byte
= *(Data
+ OffsetY
+ Xpos
);
318 for (Index
= 0; Index
< Image
->Width
% 8; Index
++) {
319 if ((Byte
& (1 << (8 - Index
- 1))) != 0) {
320 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[1];
322 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[0];
331 Output pixels in "4 bit per pixel" format to an image.
333 This is a internal function.
336 @param Image Points to the image which will store the pixels.
337 @param Data Stores the value of output pixels, 0 ~ 15.
338 @param[in] PaletteInfo PaletteInfo which stores the color of the output
339 pixels. Each entry corresponds to a color within
346 IN OUT EFI_IMAGE_INPUT
*Image
,
348 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
354 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
355 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[16];
356 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
361 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
363 BitMapPtr
= Image
->Bitmap
;
366 // The bitmap should allocate each color index starting from 0.
369 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
370 PaletteSize
+= sizeof (UINT16
);
371 Palette
= AllocateZeroPool (PaletteSize
);
372 ASSERT (Palette
!= NULL
);
373 if (Palette
== NULL
) {
376 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
377 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
379 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
380 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
384 // Convert the pixel from 4 bit to corresponding color.
386 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
387 OffsetY
= BITMAP_LEN_4_BIT (Image
->Width
, Ypos
);
389 // All bits in these bytes are meaningful
391 for (Xpos
= 0; Xpos
< Image
->Width
/ 2; Xpos
++) {
392 Byte
= *(Data
+ OffsetY
+ Xpos
);
393 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
394 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2 + 1] = PaletteValue
[Byte
& 0x0F];
397 if (Image
->Width
% 2 != 0) {
399 // Padding bits in this byte should be ignored.
401 Byte
= *(Data
+ OffsetY
+ Xpos
);
402 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
409 Output pixels in "8 bit per pixel" format to an image.
411 This is a internal function.
414 @param Image Points to the image which will store the pixels.
415 @param Data Stores the value of output pixels, 0 ~ 255.
416 @param[in] PaletteInfo PaletteInfo which stores the color of the output
417 pixels. Each entry corresponds to a color within
424 IN OUT EFI_IMAGE_INPUT
*Image
,
426 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
432 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
433 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[256];
434 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
439 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
441 BitMapPtr
= Image
->Bitmap
;
444 // The bitmap should allocate each color index starting from 0.
447 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
448 PaletteSize
+= sizeof (UINT16
);
449 Palette
= AllocateZeroPool (PaletteSize
);
450 ASSERT (Palette
!= NULL
);
451 if (Palette
== NULL
) {
454 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
455 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
456 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
457 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
461 // Convert the pixel from 8 bits to corresponding color.
463 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
464 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
466 // All bits are meaningful since the bitmap is 8 bits per pixel.
468 for (Xpos
= 0; Xpos
< Image
->Width
; Xpos
++) {
469 Byte
= *(Data
+ OffsetY
+ Xpos
);
470 BitMapPtr
[OffsetY
+ Xpos
] = PaletteValue
[Byte
];
478 Output pixels in "24 bit per pixel" format to an image.
480 This is a internal function.
483 @param Image Points to the image which will store the pixels.
484 @param Data Stores the color of output pixels, allowing 16.8
491 IN OUT EFI_IMAGE_INPUT
*Image
,
492 IN EFI_HII_RGB_PIXEL
*Data
497 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
499 ASSERT (Image
!= NULL
&& Data
!= NULL
);
501 BitMapPtr
= Image
->Bitmap
;
503 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
504 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
505 CopyRgbToGopPixel (&BitMapPtr
[OffsetY
], &Data
[OffsetY
], Image
->Width
);
512 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
514 This is a internal function.
517 @param BltBuffer Buffer points to bitmap data of incoming image.
518 @param BltX Specifies the offset from the left and top edge of
519 the output image of the first pixel in the image.
520 @param BltY Specifies the offset from the left and top edge of
521 the output image of the first pixel in the image.
522 @param Width Width of the incoming image, in pixels.
523 @param Height Height of the incoming image, in pixels.
524 @param Transparent If TRUE, all "off" pixels in the image will be
525 drawn using the pixel value from blt and all other
526 pixels will be copied.
527 @param Blt Buffer points to bitmap data of output image.
529 @retval EFI_SUCCESS The image was successfully converted.
530 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
535 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
540 IN BOOLEAN Transparent
,
541 IN OUT EFI_IMAGE_OUTPUT
**Blt
544 EFI_IMAGE_OUTPUT
*ImageOut
;
547 UINTN OffsetY1
; // src buffer
548 UINTN OffsetY2
; // dest buffer
549 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel
;
550 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel
;
552 if (BltBuffer
== NULL
|| Blt
== NULL
|| *Blt
== NULL
) {
553 return EFI_INVALID_PARAMETER
;
558 if (Width
+ BltX
> ImageOut
->Width
) {
559 return EFI_INVALID_PARAMETER
;
561 if (Height
+ BltY
> ImageOut
->Height
) {
562 return EFI_INVALID_PARAMETER
;
565 ZeroMem (&ZeroPixel
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
567 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
568 OffsetY1
= Width
* Ypos
;
569 OffsetY2
= ImageOut
->Width
* (BltY
+ Ypos
);
570 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
571 SrcPixel
= BltBuffer
[OffsetY1
+ Xpos
];
573 if (CompareMem (&SrcPixel
, &ZeroPixel
, 3) != 0) {
574 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
577 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
587 This function adds the image Image to the group of images owned by PackageList, and returns
588 a new image identifier (ImageId).
590 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
591 @param PackageList Handle of the package list where this image will
593 @param ImageId On return, contains the new image id, which is
594 unique within PackageList.
595 @param Image Points to the image.
597 @retval EFI_SUCCESS The new image was added successfully.
598 @retval EFI_NOT_FOUND The specified PackageList could not be found in
600 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
601 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
607 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
608 IN EFI_HII_HANDLE PackageList
,
609 OUT EFI_IMAGE_ID
*ImageId
,
610 IN CONST EFI_IMAGE_INPUT
*Image
613 HII_DATABASE_PRIVATE_DATA
*Private
;
615 HII_DATABASE_RECORD
*DatabaseRecord
;
616 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
617 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
623 EFI_IMAGE_INPUT
*ImageIn
;
625 if (This
== NULL
|| ImageId
== NULL
|| Image
== NULL
|| Image
->Bitmap
== NULL
) {
626 return EFI_INVALID_PARAMETER
;
629 if (!IsHiiHandleValid (PackageList
)) {
630 return EFI_NOT_FOUND
;
633 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
636 // Get the specified package list
639 PackageListNode
= NULL
;
641 for (Link
= Private
->DatabaseList
.ForwardLink
;
642 Link
!= &Private
->DatabaseList
;
643 Link
= Link
->ForwardLink
645 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
646 if (DatabaseRecord
->Handle
== PackageList
) {
647 PackageListNode
= DatabaseRecord
->PackageList
;
652 if (PackageListNode
== NULL
) {
653 return EFI_NOT_FOUND
;
656 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
658 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
659 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
662 // Get the image package in the package list,
663 // or create a new image package if image package does not exist.
665 if (PackageListNode
->ImagePkg
!= NULL
) {
666 ImagePackage
= PackageListNode
->ImagePkg
;
669 // Output the image id of the incoming image being inserted, which is the
670 // image id of the EFI_HII_IIBT_END block of old image package.
673 GetImageIdOrAddress (ImagePackage
->ImageBlock
, ImageId
);
676 // Update the package's image block by appending the new block to the end.
678 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
;
679 ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
680 if (ImageBlock
== NULL
) {
681 return EFI_OUT_OF_RESOURCES
;
684 // Copy the original content.
688 ImagePackage
->ImageBlock
,
689 ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
691 FreePool (ImagePackage
->ImageBlock
);
692 ImagePackage
->ImageBlock
= ImageBlock
;
693 ImageBlock
+= ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
);
695 // Temp memory to store new block.
697 NewBlock
= AllocateZeroPool (NewBlockSize
);
698 if (NewBlock
== NULL
) {
699 FreePool (ImagePackage
->ImageBlock
);
700 return EFI_OUT_OF_RESOURCES
;
702 NewBlockPtr
= NewBlock
;
705 // Update the length record.
707 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
708 ImagePackage
->ImagePkgHdr
.Header
.Length
+= (UINT32
) NewBlockSize
;
709 PackageListNode
->PackageListHdr
.PackageLength
+= (UINT32
) NewBlockSize
;
713 // The specified package list does not contain image package.
714 // Create one to add this image block.
716 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
717 if (ImagePackage
== NULL
) {
718 return EFI_OUT_OF_RESOURCES
;
721 // Output the image id of the incoming image being inserted, which is the
722 // first image block so that id is initially to one.
725 BlockSize
= sizeof (EFI_HII_IIBT_END_BLOCK
) + NewBlockSize
;
727 // Fill in image package header.
729 ImagePackage
->ImagePkgHdr
.Header
.Length
= (UINT32
) BlockSize
+ sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
730 ImagePackage
->ImagePkgHdr
.Header
.Type
= EFI_HII_PACKAGE_IMAGES
;
731 ImagePackage
->ImagePkgHdr
.ImageInfoOffset
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
732 ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
= 0;
735 // Fill in palette info.
737 ImagePackage
->PaletteBlock
= NULL
;
738 ImagePackage
->PaletteInfoSize
= 0;
741 // Fill in image blocks.
743 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
744 ImagePackage
->ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
745 if (ImagePackage
->ImageBlock
== NULL
) {
746 FreePool (ImagePackage
);
747 return EFI_OUT_OF_RESOURCES
;
749 ImageBlock
= ImagePackage
->ImageBlock
;
752 // Temp memory to store new block.
754 NewBlock
= AllocateZeroPool (NewBlockSize
);
755 if (NewBlock
== NULL
) {
756 FreePool (ImagePackage
->ImageBlock
);
757 FreePool (ImagePackage
);
758 return EFI_OUT_OF_RESOURCES
;
760 NewBlockPtr
= NewBlock
;
763 // Insert this image package.
765 PackageListNode
->ImagePkg
= ImagePackage
;
766 PackageListNode
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
770 // Append the new block here
772 if (ImageIn
->Flags
== EFI_IMAGE_TRANSPARENT
) {
773 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
775 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT
;
778 CopyMem (NewBlock
, &ImageIn
->Width
, sizeof (UINT16
));
779 NewBlock
+= sizeof (UINT16
);
780 CopyMem (NewBlock
, &ImageIn
->Height
, sizeof (UINT16
));
781 NewBlock
+= sizeof (UINT16
);
782 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlock
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
784 CopyMem (ImageBlock
, NewBlockPtr
, NewBlockSize
);
785 FreePool (NewBlockPtr
);
788 // Append the block end
790 ImageBlock
+= NewBlockSize
;
791 ((EFI_HII_IIBT_END_BLOCK
*) (ImageBlock
))->Header
.BlockType
= EFI_HII_IIBT_END
;
794 // Check whether need to get the contents of HiiDataBase.
795 // Only after ReadyToBoot to do the export.
797 if (gExportAfterReadyToBoot
) {
798 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
806 This function retrieves the image specified by ImageId which is associated with
807 the specified PackageList and copies it into the buffer specified by Image.
809 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
810 @param PackageList Handle of the package list where this image will
812 @param ImageId The image's id,, which is unique within
814 @param Image Points to the image.
816 @retval EFI_SUCCESS The new image was returned successfully.
817 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
818 database. The specified PackageList is not in the database.
819 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
821 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
822 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
829 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
830 IN EFI_HII_HANDLE PackageList
,
831 IN EFI_IMAGE_ID ImageId
,
832 OUT EFI_IMAGE_INPUT
*Image
835 HII_DATABASE_PRIVATE_DATA
*Private
;
837 HII_DATABASE_RECORD
*DatabaseRecord
;
838 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
839 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
841 EFI_IMAGE_ID LocalImageId
;
843 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
852 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1) {
853 return EFI_INVALID_PARAMETER
;
856 if (!IsHiiHandleValid (PackageList
)) {
857 return EFI_NOT_FOUND
;
860 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
863 // Get the specified package list and image package.
865 PackageListNode
= NULL
;
866 for (Link
= Private
->DatabaseList
.ForwardLink
;
867 Link
!= &Private
->DatabaseList
;
868 Link
= Link
->ForwardLink
870 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
871 if (DatabaseRecord
->Handle
== PackageList
) {
872 PackageListNode
= DatabaseRecord
->PackageList
;
876 if (PackageListNode
== NULL
) {
877 return EFI_NOT_FOUND
;
879 ImagePackage
= PackageListNode
->ImagePkg
;
880 if (ImagePackage
== NULL
) {
881 return EFI_NOT_FOUND
;
885 // Find the image block specified by ImageId
887 LocalImageId
= ImageId
;
888 ImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
889 if (ImageBlock
== NULL
) {
890 return EFI_NOT_FOUND
;
894 BlockType
= *ImageBlock
;
897 case EFI_HII_IIBT_IMAGE_JPEG
:
899 // BUGBUG: need to be supported as soon as image tool is designed.
901 return EFI_UNSUPPORTED
;
903 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
904 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
905 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
910 case EFI_HII_IIBT_IMAGE_1BIT
:
911 case EFI_HII_IIBT_IMAGE_4BIT
:
912 case EFI_HII_IIBT_IMAGE_8BIT
:
914 // Use the common block code since the definition of these structures is the same.
916 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
917 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) *
918 (Iibt1bit
.Bitmap
.Width
* Iibt1bit
.Bitmap
.Height
);
919 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
920 if (Image
->Bitmap
== NULL
) {
921 return EFI_OUT_OF_RESOURCES
;
925 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
927 Image
->Width
= Iibt1bit
.Bitmap
.Width
;
928 Image
->Height
= Iibt1bit
.Bitmap
.Height
;
930 PaletteInfo
= ImagePackage
->PaletteBlock
+ sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
931 for (PaletteIndex
= 1; PaletteIndex
< Iibt1bit
.PaletteIndex
; PaletteIndex
++) {
932 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
933 PaletteInfo
+= PaletteSize
+ sizeof (UINT16
);
935 ASSERT (PaletteIndex
== Iibt1bit
.PaletteIndex
);
938 // Output bitmap data
940 if (BlockType
== EFI_HII_IIBT_IMAGE_1BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_1BIT_TRANS
) {
943 (UINT8
*) ((UINTN
)ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
)),
944 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
946 } else if (BlockType
== EFI_HII_IIBT_IMAGE_4BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_4BIT_TRANS
) {
949 (UINT8
*) ((UINTN
)ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
)),
950 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
955 (UINT8
*) ((UINTN
)ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
)),
956 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
962 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
967 case EFI_HII_IIBT_IMAGE_24BIT
:
968 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
971 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
974 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * (Width
* Height
);
975 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
976 if (Image
->Bitmap
== NULL
) {
977 return EFI_OUT_OF_RESOURCES
;
981 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
983 Image
->Width
= Width
;
984 Image
->Height
= Height
;
987 // Output the bimap data directly.
991 (EFI_HII_RGB_PIXEL
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
))
996 return EFI_NOT_FOUND
;
1002 This function updates the image specified by ImageId in the specified PackageListHandle to
1003 the image specified by Image.
1005 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1006 @param PackageList The package list containing the images.
1007 @param ImageId The image's id,, which is unique within
1009 @param Image Points to the image.
1011 @retval EFI_SUCCESS The new image was updated successfully.
1012 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
1013 database. The specified PackageList is not in the database.
1014 @retval EFI_INVALID_PARAMETER The Image was NULL.
1020 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1021 IN EFI_HII_HANDLE PackageList
,
1022 IN EFI_IMAGE_ID ImageId
,
1023 IN CONST EFI_IMAGE_INPUT
*Image
1026 HII_DATABASE_PRIVATE_DATA
*Private
;
1028 HII_DATABASE_RECORD
*DatabaseRecord
;
1029 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1030 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
1032 EFI_IMAGE_ID LocalImageId
;
1034 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
1035 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit
;
1036 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit
;
1040 UINT32 NewBlockSize
;
1041 UINT32 OldBlockSize
;
1042 EFI_IMAGE_INPUT
*ImageIn
;
1050 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1 || Image
->Bitmap
== NULL
) {
1051 return EFI_INVALID_PARAMETER
;
1054 if (!IsHiiHandleValid (PackageList
)) {
1055 return EFI_NOT_FOUND
;
1058 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1061 // Get the specified package list and image package.
1063 PackageListNode
= NULL
;
1064 for (Link
= Private
->DatabaseList
.ForwardLink
;
1065 Link
!= &Private
->DatabaseList
;
1066 Link
= Link
->ForwardLink
1068 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1069 if (DatabaseRecord
->Handle
== PackageList
) {
1070 PackageListNode
= DatabaseRecord
->PackageList
;
1074 if (PackageListNode
== NULL
) {
1075 return EFI_NOT_FOUND
;
1077 ImagePackage
= PackageListNode
->ImagePkg
;
1078 if (ImagePackage
== NULL
) {
1079 return EFI_NOT_FOUND
;
1083 // Find the image block specified by ImageId
1085 LocalImageId
= ImageId
;
1086 ImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
1087 if (ImageBlock
== NULL
) {
1088 return EFI_NOT_FOUND
;
1091 BlockType
= *ImageBlock
;
1094 // Get the size of original image block. Use some common block code here
1095 // since the definition of some structures is the same.
1097 switch (BlockType
) {
1098 case EFI_HII_IIBT_IMAGE_JPEG
:
1100 // BUGBUG: need to be supported as soon as image tool is designed.
1102 return EFI_UNSUPPORTED
;
1104 case EFI_HII_IIBT_IMAGE_1BIT
:
1105 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
1106 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
1107 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
1108 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
1110 case EFI_HII_IIBT_IMAGE_4BIT
:
1111 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
1112 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
1113 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
1114 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
1116 case EFI_HII_IIBT_IMAGE_8BIT
:
1117 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
1118 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
1119 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
1120 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
1122 case EFI_HII_IIBT_IMAGE_24BIT
:
1123 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
1124 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
1127 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
1130 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1131 BITMAP_LEN_24_BIT (Width
, Height
);
1134 return EFI_NOT_FOUND
;
1138 // Create the new image block according to input image.
1140 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1141 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1142 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
1143 NewBlock
= (UINT8
*) AllocateZeroPool (NewBlockSize
);
1144 if (NewBlock
== NULL
) {
1145 return EFI_OUT_OF_RESOURCES
;
1148 NewBlockPtr
= NewBlock
;
1149 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1150 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
1152 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT
;
1156 CopyMem (NewBlockPtr
, &ImageIn
->Width
, sizeof (UINT16
));
1157 NewBlockPtr
+= sizeof (UINT16
);
1158 CopyMem (NewBlockPtr
, &ImageIn
->Height
, sizeof (UINT16
));
1159 NewBlockPtr
+= sizeof (UINT16
);
1161 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlockPtr
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
1164 // Adjust the image package to remove the original block firstly then add the new block.
1166 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
- OldBlockSize
;
1167 Block
= (UINT8
*) AllocateZeroPool (BlockSize
);
1168 if (Block
== NULL
) {
1169 FreePool (NewBlock
);
1170 return EFI_OUT_OF_RESOURCES
;
1174 Part1Size
= (UINT32
) (ImageBlock
- ImagePackage
->ImageBlock
);
1175 Part2Size
= ImagePackage
->ImageBlockSize
- Part1Size
- OldBlockSize
;
1176 CopyMem (BlockPtr
, ImagePackage
->ImageBlock
, Part1Size
);
1177 BlockPtr
+= Part1Size
;
1178 CopyMem (BlockPtr
, NewBlock
, NewBlockSize
);
1179 BlockPtr
+= NewBlockSize
;
1180 CopyMem (BlockPtr
, ImageBlock
+ OldBlockSize
, Part2Size
);
1182 FreePool (ImagePackage
->ImageBlock
);
1183 FreePool (NewBlock
);
1184 ImagePackage
->ImageBlock
= Block
;
1185 ImagePackage
->ImageBlockSize
= BlockSize
;
1186 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
- OldBlockSize
;
1187 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
- OldBlockSize
;
1190 // Check whether need to get the contents of HiiDataBase.
1191 // Only after ReadyToBoot to do the export.
1193 if (gExportAfterReadyToBoot
) {
1194 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
1203 This function renders an image to a bitmap or the screen using the specified
1204 color and options. It draws the image on an existing bitmap, allocates a new
1205 bitmap or uses the screen. The images can be clipped.
1207 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1208 @param Flags Describes how the image is to be drawn.
1209 @param Image Points to the image to be displayed.
1210 @param Blt If this points to a non-NULL on entry, this points
1211 to the image, which is Width pixels wide and
1212 Height pixels high. The image will be drawn onto
1213 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1214 If this points to a NULL on entry, then a buffer
1215 will be allocated to hold the generated image and
1216 the pointer updated on exit. It is the caller's
1217 responsibility to free this buffer.
1218 @param BltX Specifies the offset from the left and top edge of
1219 the output image of the first pixel in the image.
1220 @param BltY Specifies the offset from the left and top edge of
1221 the output image of the first pixel in the image.
1223 @retval EFI_SUCCESS The image was successfully drawn.
1224 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1225 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1226 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1232 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1233 IN EFI_HII_DRAW_FLAGS Flags
,
1234 IN CONST EFI_IMAGE_INPUT
*Image
,
1235 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1241 HII_DATABASE_PRIVATE_DATA
*Private
;
1242 BOOLEAN Transparent
;
1243 EFI_IMAGE_INPUT
*ImageIn
;
1244 EFI_IMAGE_OUTPUT
*ImageOut
;
1245 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
1253 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1256 if (This
== NULL
|| Image
== NULL
|| Blt
== NULL
) {
1257 return EFI_INVALID_PARAMETER
;
1260 if ((Flags
& EFI_HII_DRAW_FLAG_CLIP
) == EFI_HII_DRAW_FLAG_CLIP
&& *Blt
== NULL
) {
1261 return EFI_INVALID_PARAMETER
;
1264 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_TRANSPARENT
) {
1265 return EFI_INVALID_PARAMETER
;
1269 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1272 // Check whether the image will be drawn transparently or opaquely.
1274 Transparent
= FALSE
;
1275 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_TRANS
) {
1277 } else if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE
){
1278 Transparent
= FALSE
;
1281 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1282 // on the image's transparency setting.
1284 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1290 // Image cannot be drawn transparently if Blt points to NULL on entry.
1291 // Currently output to Screen transparently is not supported, either.
1295 return EFI_INVALID_PARAMETER
;
1296 } else if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1297 return EFI_INVALID_PARAMETER
;
1301 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1304 // When Blt points to a non-NULL on entry, this image will be drawn onto
1305 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1306 // Otherwise a new bitmap will be allocated to hold this image.
1310 // Clip the image by (Width, Height)
1313 Width
= ImageIn
->Width
;
1314 Height
= ImageIn
->Height
;
1316 if (Width
> (*Blt
)->Width
- BltX
) {
1317 Width
= (*Blt
)->Width
- BltX
;
1319 if (Height
> (*Blt
)->Height
- BltY
) {
1320 Height
= (*Blt
)->Height
- BltY
;
1323 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1324 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1325 if (BltBuffer
== NULL
) {
1326 return EFI_OUT_OF_RESOURCES
;
1329 if (Width
== ImageIn
->Width
&& Height
== ImageIn
->Height
) {
1330 CopyMem (BltBuffer
, ImageIn
->Bitmap
, BufferLen
);
1332 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
1333 OffsetY1
= ImageIn
->Width
* Ypos
;
1334 OffsetY2
= Width
* Ypos
;
1335 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
1336 BltBuffer
[OffsetY2
+ Xpos
] = ImageIn
->Bitmap
[OffsetY1
+ Xpos
];
1342 // Draw the image to existing bitmap or screen depending on flag.
1344 if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1346 // Caller should make sure the current UGA console is grarphic mode.
1350 // Write the image directly to the output device specified by Screen.
1352 Status
= (*Blt
)->Image
.Screen
->Blt (
1353 (*Blt
)->Image
.Screen
,
1355 EfiBltBufferToVideo
,
1366 // Draw the image onto the existing bitmap specified by Bitmap.
1368 Status
= ImageToBlt (
1380 FreePool (BltBuffer
);
1385 // Allocate a new bitmap to hold the incoming image.
1387 Width
= ImageIn
->Width
+ BltX
;
1388 Height
= ImageIn
->Height
+ BltY
;
1390 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1391 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1392 if (BltBuffer
== NULL
) {
1393 return EFI_OUT_OF_RESOURCES
;
1396 ImageOut
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1397 if (ImageOut
== NULL
) {
1398 FreePool (BltBuffer
);
1399 return EFI_OUT_OF_RESOURCES
;
1401 ImageOut
->Width
= (UINT16
) Width
;
1402 ImageOut
->Height
= (UINT16
) Height
;
1403 ImageOut
->Image
.Bitmap
= BltBuffer
;
1406 // BUGBUG: Now all the "blank" pixels are filled with system default background
1407 // color. Not sure if it need to be updated or not.
1409 Status
= GetSystemFont (Private
, &FontInfo
, NULL
);
1410 if (EFI_ERROR (Status
)) {
1411 FreePool (BltBuffer
);
1412 FreePool (ImageOut
);
1415 ASSERT (FontInfo
!= NULL
);
1416 for (Index
= 0; Index
< Width
* Height
; Index
++) {
1417 BltBuffer
[Index
] = FontInfo
->BackgroundColor
;
1419 FreePool (FontInfo
);
1422 // Draw the incoming image to the new created image.
1440 This function renders an image to a bitmap or the screen using the specified
1441 color and options. It draws the image on an existing bitmap, allocates a new
1442 bitmap or uses the screen. The images can be clipped.
1444 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1445 @param Flags Describes how the image is to be drawn.
1446 @param PackageList The package list in the HII database to search for
1447 the specified image.
1448 @param ImageId The image's id, which is unique within
1450 @param Blt If this points to a non-NULL on entry, this points
1451 to the image, which is Width pixels wide and
1452 Height pixels high. The image will be drawn onto
1454 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1455 to a NULL on entry, then a buffer will be
1456 allocated to hold the generated image and the
1457 pointer updated on exit. It is the caller's
1458 responsibility to free this buffer.
1459 @param BltX Specifies the offset from the left and top edge of
1460 the output image of the first pixel in the image.
1461 @param BltY Specifies the offset from the left and top edge of
1462 the output image of the first pixel in the image.
1464 @retval EFI_SUCCESS The image was successfully drawn.
1465 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1466 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1467 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1468 The specified PackageList is not in the database.
1474 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1475 IN EFI_HII_DRAW_FLAGS Flags
,
1476 IN EFI_HII_HANDLE PackageList
,
1477 IN EFI_IMAGE_ID ImageId
,
1478 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1484 EFI_IMAGE_INPUT Image
;
1487 // Check input parameter.
1489 if (This
== NULL
|| Blt
== NULL
) {
1490 return EFI_INVALID_PARAMETER
;
1493 if (!IsHiiHandleValid (PackageList
)) {
1494 return EFI_NOT_FOUND
;
1498 // Get the specified Image.
1500 Status
= HiiGetImage (This
, PackageList
, ImageId
, &Image
);
1501 if (EFI_ERROR (Status
)) {
1508 Status
= HiiDrawImage (This
, Flags
, &Image
, Blt
, BltX
, BltY
);
1509 if (Image
.Bitmap
!= NULL
) {
1510 FreePool (Image
.Bitmap
);