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 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 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 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
= ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
);
134 case EFI_HII_IIBT_SKIP1
:
135 Length
= sizeof (EFI_HII_IIBT_SKIP1_BLOCK
);
136 ImageIdCurrent
+= ((EFI_HII_IIBT_SKIP1_BLOCK
*) CurrentImageBlock
)->SkipCount
;
139 case EFI_HII_IIBT_SKIP2
:
140 Length
= sizeof (EFI_HII_IIBT_SKIP2_BLOCK
);
141 ImageIdCurrent
+= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_SKIP2_BLOCK
*) CurrentImageBlock
)->SkipCount
);
146 // Unknown image blocks can not be skipped, processing halts.
153 CurrentImageBlock
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) CurrentImageBlock
+ Length
);
158 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
161 *ImageId
= ImageIdCurrent
;
162 return CurrentImageBlock
;
171 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
173 This is a internal function.
176 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
177 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
178 @param PixelNum The number of pixels to be converted.
184 OUT EFI_HII_RGB_PIXEL
*BitMapOut
,
185 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapIn
,
191 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
193 for (Index
= 0; Index
< PixelNum
; Index
++) {
194 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
200 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
202 This is a internal function.
205 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
206 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
207 @param PixelNum The number of pixels to be converted.
213 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapOut
,
214 IN EFI_HII_RGB_PIXEL
*BitMapIn
,
220 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
222 for (Index
= 0; Index
< PixelNum
; Index
++) {
223 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
229 Output pixels in "1 bit per pixel" format to an image.
231 This is a internal function.
234 @param Image Points to the image which will store the pixels.
235 @param Data Stores the value of output pixels, 0 or 1.
236 @param PaletteInfo PaletteInfo which stores the color of the output
237 pixels. First entry corresponds to color 0 and
238 second one to color 1.
244 IN OUT EFI_IMAGE_INPUT
*Image
,
246 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
253 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
254 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[2];
255 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
259 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
261 BitMapPtr
= Image
->Bitmap
;
264 // First entry corresponds to color 0 and second entry corresponds to color 1.
267 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
268 PaletteSize
+= sizeof (UINT16
);
269 Palette
= AllocateZeroPool (PaletteSize
);
270 ASSERT (Palette
!= NULL
);
271 if (Palette
== NULL
) {
274 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
276 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
277 CopyRgbToGopPixel (&PaletteValue
[0], &Palette
->PaletteValue
[0], 1);
278 CopyRgbToGopPixel (&PaletteValue
[1], &Palette
->PaletteValue
[1], 1);
282 // Convert the pixel from one bit to corresponding color.
284 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
285 OffsetY
= BITMAP_LEN_1_BIT (Image
->Width
, Ypos
);
287 // All bits in these bytes are meaningful
289 for (Xpos
= 0; Xpos
< Image
->Width
/ 8; Xpos
++) {
290 Byte
= *(Data
+ OffsetY
+ Xpos
);
291 for (Index
= 0; Index
< 8; Index
++) {
292 if ((Byte
& (1 << Index
)) != 0) {
293 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[1];
295 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[0];
300 if (Image
->Width
% 8 != 0) {
302 // Padding bits in this byte should be ignored.
304 Byte
= *(Data
+ OffsetY
+ Xpos
);
305 for (Index
= 0; Index
< Image
->Width
% 8; Index
++) {
306 if ((Byte
& (1 << (8 - Index
- 1))) != 0) {
307 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[1];
309 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[0];
318 Output pixels in "4 bit per pixel" format to an image.
320 This is a internal function.
323 @param Image Points to the image which will store the pixels.
324 @param Data Stores the value of output pixels, 0 ~ 15.
325 @param[in] PaletteInfo PaletteInfo which stores the color of the output
326 pixels. Each entry corresponds to a color within
333 IN OUT EFI_IMAGE_INPUT
*Image
,
335 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
341 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
342 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[16];
343 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
348 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
350 BitMapPtr
= Image
->Bitmap
;
353 // The bitmap should allocate each color index starting from 0.
356 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
357 PaletteSize
+= sizeof (UINT16
);
358 Palette
= AllocateZeroPool (PaletteSize
);
359 ASSERT (Palette
!= NULL
);
360 if (Palette
== NULL
) {
363 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
364 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
366 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
367 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
371 // Convert the pixel from 4 bit to corresponding color.
373 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
374 OffsetY
= BITMAP_LEN_4_BIT (Image
->Width
, Ypos
);
376 // All bits in these bytes are meaningful
378 for (Xpos
= 0; Xpos
< Image
->Width
/ 2; Xpos
++) {
379 Byte
= *(Data
+ OffsetY
+ Xpos
);
380 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
381 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2 + 1] = PaletteValue
[Byte
& 0x0F];
384 if (Image
->Width
% 2 != 0) {
386 // Padding bits in this byte should be ignored.
388 Byte
= *(Data
+ OffsetY
+ Xpos
);
389 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
396 Output pixels in "8 bit per pixel" format to an image.
398 This is a internal function.
401 @param Image Points to the image which will store the pixels.
402 @param Data Stores the value of output pixels, 0 ~ 255.
403 @param[in] PaletteInfo PaletteInfo which stores the color of the output
404 pixels. Each entry corresponds to a color within
411 IN OUT EFI_IMAGE_INPUT
*Image
,
413 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
419 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
420 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[256];
421 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
426 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
428 BitMapPtr
= Image
->Bitmap
;
431 // The bitmap should allocate each color index starting from 0.
434 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
435 PaletteSize
+= sizeof (UINT16
);
436 Palette
= AllocateZeroPool (PaletteSize
);
437 ASSERT (Palette
!= NULL
);
438 if (Palette
== NULL
) {
441 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
442 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
443 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
444 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
448 // Convert the pixel from 8 bits to corresponding color.
450 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
451 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
453 // All bits are meaningful since the bitmap is 8 bits per pixel.
455 for (Xpos
= 0; Xpos
< Image
->Width
; Xpos
++) {
456 Byte
= *(Data
+ OffsetY
+ Xpos
);
457 BitMapPtr
[OffsetY
+ Xpos
] = PaletteValue
[Byte
];
465 Output pixels in "24 bit per pixel" format to an image.
467 This is a internal function.
470 @param Image Points to the image which will store the pixels.
471 @param Data Stores the color of output pixels, allowing 16.8
478 IN OUT EFI_IMAGE_INPUT
*Image
,
479 IN EFI_HII_RGB_PIXEL
*Data
484 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
486 ASSERT (Image
!= NULL
&& Data
!= NULL
);
488 BitMapPtr
= Image
->Bitmap
;
490 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
491 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
492 CopyRgbToGopPixel (&BitMapPtr
[OffsetY
], &Data
[OffsetY
], Image
->Width
);
499 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
501 This is a internal function.
504 @param BltBuffer Buffer points to bitmap data of incoming image.
505 @param BltX Specifies the offset from the left and top edge of
506 the output image of the first pixel in the image.
507 @param BltY Specifies the offset from the left and top edge of
508 the output image of the first pixel in the image.
509 @param Width Width of the incoming image, in pixels.
510 @param Height Height of the incoming image, in pixels.
511 @param Transparent If TRUE, all "off" pixels in the image will be
512 drawn using the pixel value from blt and all other
513 pixels will be copied.
514 @param Blt Buffer points to bitmap data of output image.
516 @retval EFI_SUCCESS The image was successfully converted.
517 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
522 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
527 IN BOOLEAN Transparent
,
528 IN OUT EFI_IMAGE_OUTPUT
**Blt
531 EFI_IMAGE_OUTPUT
*ImageOut
;
534 UINTN OffsetY1
; // src buffer
535 UINTN OffsetY2
; // dest buffer
536 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel
;
537 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel
;
539 if (BltBuffer
== NULL
|| Blt
== NULL
|| *Blt
== NULL
) {
540 return EFI_INVALID_PARAMETER
;
545 if (Width
+ BltX
> ImageOut
->Width
) {
546 return EFI_INVALID_PARAMETER
;
548 if (Height
+ BltY
> ImageOut
->Height
) {
549 return EFI_INVALID_PARAMETER
;
552 ZeroMem (&ZeroPixel
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
554 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
555 OffsetY1
= Width
* Ypos
;
556 OffsetY2
= ImageOut
->Width
* (BltY
+ Ypos
);
557 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
558 SrcPixel
= BltBuffer
[OffsetY1
+ Xpos
];
560 if (CompareMem (&SrcPixel
, &ZeroPixel
, 3) != 0) {
561 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
564 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
574 This function adds the image Image to the group of images owned by PackageList, and returns
575 a new image identifier (ImageId).
577 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
578 @param PackageList Handle of the package list where this image will
580 @param ImageId On return, contains the new image id, which is
581 unique within PackageList.
582 @param Image Points to the image.
584 @retval EFI_SUCCESS The new image was added successfully.
585 @retval EFI_NOT_FOUND The specified PackageList could not be found in
587 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
588 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
594 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
595 IN EFI_HII_HANDLE PackageList
,
596 OUT EFI_IMAGE_ID
*ImageId
,
597 IN CONST EFI_IMAGE_INPUT
*Image
600 HII_DATABASE_PRIVATE_DATA
*Private
;
602 HII_DATABASE_RECORD
*DatabaseRecord
;
603 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
604 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
610 EFI_IMAGE_INPUT
*ImageIn
;
612 if (This
== NULL
|| ImageId
== NULL
|| Image
== NULL
|| Image
->Bitmap
== NULL
) {
613 return EFI_INVALID_PARAMETER
;
616 if (!IsHiiHandleValid (PackageList
)) {
617 return EFI_NOT_FOUND
;
620 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
623 // Get the specified package list
626 PackageListNode
= NULL
;
628 for (Link
= Private
->DatabaseList
.ForwardLink
;
629 Link
!= &Private
->DatabaseList
;
630 Link
= Link
->ForwardLink
632 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
633 if (DatabaseRecord
->Handle
== PackageList
) {
634 PackageListNode
= DatabaseRecord
->PackageList
;
639 if (PackageListNode
== NULL
) {
640 return EFI_NOT_FOUND
;
643 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
645 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
646 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
649 // Get the image package in the package list,
650 // or create a new image package if image package does not exist.
652 if (PackageListNode
->ImagePkg
!= NULL
) {
653 ImagePackage
= PackageListNode
->ImagePkg
;
656 // Output the image id of the incoming image being inserted, which is the
657 // image id of the EFI_HII_IIBT_END block of old image package.
660 GetImageIdOrAddress (ImagePackage
->ImageBlock
, ImageId
);
663 // Update the package's image block by appending the new block to the end.
665 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
;
666 ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
667 if (ImageBlock
== NULL
) {
668 return EFI_OUT_OF_RESOURCES
;
671 // Copy the original content.
675 ImagePackage
->ImageBlock
,
676 ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
678 FreePool (ImagePackage
->ImageBlock
);
679 ImagePackage
->ImageBlock
= (EFI_HII_IMAGE_BLOCK
*) ImageBlock
;
680 ImageBlock
+= ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
);
682 // Temp memory to store new block.
684 NewBlock
= AllocateZeroPool (NewBlockSize
);
685 if (NewBlock
== NULL
) {
686 FreePool (ImagePackage
->ImageBlock
);
687 return EFI_OUT_OF_RESOURCES
;
689 NewBlockPtr
= NewBlock
;
692 // Update the length record.
694 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
695 ImagePackage
->ImagePkgHdr
.Header
.Length
+= (UINT32
) NewBlockSize
;
696 PackageListNode
->PackageListHdr
.PackageLength
+= (UINT32
) NewBlockSize
;
700 // The specified package list does not contain image package.
701 // Create one to add this image block.
703 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
704 if (ImagePackage
== NULL
) {
705 return EFI_OUT_OF_RESOURCES
;
708 // Output the image id of the incoming image being inserted, which is the
709 // first image block so that id is initially to one.
712 BlockSize
= sizeof (EFI_HII_IIBT_END_BLOCK
) + NewBlockSize
;
714 // Fill in image package header.
716 ImagePackage
->ImagePkgHdr
.Header
.Length
= (UINT32
) BlockSize
+ sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
717 ImagePackage
->ImagePkgHdr
.Header
.Type
= EFI_HII_PACKAGE_IMAGES
;
718 ImagePackage
->ImagePkgHdr
.ImageInfoOffset
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
719 ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
= 0;
722 // Fill in palette info.
724 ImagePackage
->PaletteBlock
= NULL
;
725 ImagePackage
->PaletteInfoSize
= 0;
728 // Fill in image blocks.
730 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
731 ImagePackage
->ImageBlock
= AllocateZeroPool (BlockSize
);
732 if (ImagePackage
->ImageBlock
== NULL
) {
733 FreePool (ImagePackage
);
734 return EFI_OUT_OF_RESOURCES
;
736 ImageBlock
= (UINT8
*) ImagePackage
->ImageBlock
;
739 // Temp memory to store new block.
741 NewBlock
= AllocateZeroPool (NewBlockSize
);
742 if (NewBlock
== NULL
) {
743 FreePool (ImagePackage
->ImageBlock
);
744 FreePool (ImagePackage
);
745 return EFI_OUT_OF_RESOURCES
;
747 NewBlockPtr
= NewBlock
;
750 // Insert this image package.
752 PackageListNode
->ImagePkg
= ImagePackage
;
753 PackageListNode
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
757 // Append the new block here
759 if (ImageIn
->Flags
== EFI_IMAGE_TRANSPARENT
) {
760 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
762 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT
;
765 CopyMem (NewBlock
, &ImageIn
->Width
, sizeof (UINT16
));
766 NewBlock
+= sizeof (UINT16
);
767 CopyMem (NewBlock
, &ImageIn
->Height
, sizeof (UINT16
));
768 NewBlock
+= sizeof (UINT16
);
769 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlock
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
771 CopyMem (ImageBlock
, NewBlockPtr
, NewBlockSize
);
772 FreePool (NewBlockPtr
);
775 // Append the block end
777 ImageBlock
+= NewBlockSize
;
778 ((EFI_HII_IIBT_END_BLOCK
*) (ImageBlock
))->Header
.BlockType
= EFI_HII_IIBT_END
;
781 // Check whether need to get the contents of HiiDataBase.
782 // Only after ReadyToBoot to do the export.
784 if (gExportAfterReadyToBoot
) {
785 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
793 This function retrieves the image specified by ImageId which is associated with
794 the specified PackageList and copies it into the buffer specified by Image.
796 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
797 @param PackageList Handle of the package list where this image will
799 @param ImageId The image's id,, which is unique within
801 @param Image Points to the image.
803 @retval EFI_SUCCESS The new image was returned successfully.
804 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
805 database. The specified PackageList is not in the database.
806 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
808 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
809 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
816 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
817 IN EFI_HII_HANDLE PackageList
,
818 IN EFI_IMAGE_ID ImageId
,
819 OUT EFI_IMAGE_INPUT
*Image
822 HII_DATABASE_PRIVATE_DATA
*Private
;
824 HII_DATABASE_RECORD
*DatabaseRecord
;
825 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
826 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
828 EFI_IMAGE_ID LocalImageId
;
830 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
839 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1) {
840 return EFI_INVALID_PARAMETER
;
843 if (!IsHiiHandleValid (PackageList
)) {
844 return EFI_NOT_FOUND
;
847 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
850 // Get the specified package list and image package.
852 PackageListNode
= NULL
;
853 for (Link
= Private
->DatabaseList
.ForwardLink
;
854 Link
!= &Private
->DatabaseList
;
855 Link
= Link
->ForwardLink
857 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
858 if (DatabaseRecord
->Handle
== PackageList
) {
859 PackageListNode
= DatabaseRecord
->PackageList
;
863 if (PackageListNode
== NULL
) {
864 return EFI_NOT_FOUND
;
866 ImagePackage
= PackageListNode
->ImagePkg
;
867 if (ImagePackage
== NULL
) {
868 return EFI_NOT_FOUND
;
872 // Find the image block specified by ImageId
874 LocalImageId
= ImageId
;
875 ImageBlock
= (UINT8
*) GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
876 if (ImageBlock
== NULL
) {
877 return EFI_NOT_FOUND
;
881 BlockType
= *ImageBlock
;
884 case EFI_HII_IIBT_IMAGE_JPEG
:
886 // BUGBUG: need to be supported as soon as image tool is designed.
888 return EFI_UNSUPPORTED
;
890 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
891 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
892 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
897 case EFI_HII_IIBT_IMAGE_1BIT
:
898 case EFI_HII_IIBT_IMAGE_4BIT
:
899 case EFI_HII_IIBT_IMAGE_8BIT
:
901 // Use the common block code since the definition of these structures is the same.
903 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
904 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) *
905 (Iibt1bit
.Bitmap
.Width
* Iibt1bit
.Bitmap
.Height
);
906 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
907 if (Image
->Bitmap
== NULL
) {
908 return EFI_OUT_OF_RESOURCES
;
912 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
914 Image
->Width
= Iibt1bit
.Bitmap
.Width
;
915 Image
->Height
= Iibt1bit
.Bitmap
.Height
;
917 PaletteInfo
= ImagePackage
->PaletteBlock
+ sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
918 for (PaletteIndex
= 1; PaletteIndex
< Iibt1bit
.PaletteIndex
; PaletteIndex
++) {
919 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
920 PaletteInfo
+= PaletteSize
+ sizeof (UINT16
);
922 ASSERT (PaletteIndex
== Iibt1bit
.PaletteIndex
);
925 // Output bitmap data
927 if (BlockType
== EFI_HII_IIBT_IMAGE_1BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_1BIT_TRANS
) {
930 (UINT8
*) ((UINTN
)ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
)),
931 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
933 } else if (BlockType
== EFI_HII_IIBT_IMAGE_4BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_4BIT_TRANS
) {
936 (UINT8
*) ((UINTN
)ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
)),
937 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
942 (UINT8
*) ((UINTN
)ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
)),
943 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
949 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
954 case EFI_HII_IIBT_IMAGE_24BIT
:
955 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
958 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
961 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * (Width
* Height
);
962 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
963 if (Image
->Bitmap
== NULL
) {
964 return EFI_OUT_OF_RESOURCES
;
968 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
970 Image
->Width
= Width
;
971 Image
->Height
= Height
;
974 // Output the bimap data directly.
978 (EFI_HII_RGB_PIXEL
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
))
983 return EFI_NOT_FOUND
;
989 This function updates the image specified by ImageId in the specified PackageListHandle to
990 the image specified by Image.
992 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
993 @param PackageList The package list containing the images.
994 @param ImageId The image's id,, which is unique within
996 @param Image Points to the image.
998 @retval EFI_SUCCESS The new image was updated successfully.
999 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
1000 database. The specified PackageList is not in the database.
1001 @retval EFI_INVALID_PARAMETER The Image was NULL.
1007 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1008 IN EFI_HII_HANDLE PackageList
,
1009 IN EFI_IMAGE_ID ImageId
,
1010 IN CONST EFI_IMAGE_INPUT
*Image
1013 HII_DATABASE_PRIVATE_DATA
*Private
;
1015 HII_DATABASE_RECORD
*DatabaseRecord
;
1016 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1017 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
1019 EFI_IMAGE_ID LocalImageId
;
1021 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
1022 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit
;
1023 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit
;
1027 UINT32 NewBlockSize
;
1028 UINT32 OldBlockSize
;
1029 EFI_IMAGE_INPUT
*ImageIn
;
1037 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1 || Image
->Bitmap
== NULL
) {
1038 return EFI_INVALID_PARAMETER
;
1041 if (!IsHiiHandleValid (PackageList
)) {
1042 return EFI_NOT_FOUND
;
1045 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1048 // Get the specified package list and image package.
1050 PackageListNode
= NULL
;
1051 for (Link
= Private
->DatabaseList
.ForwardLink
;
1052 Link
!= &Private
->DatabaseList
;
1053 Link
= Link
->ForwardLink
1055 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1056 if (DatabaseRecord
->Handle
== PackageList
) {
1057 PackageListNode
= DatabaseRecord
->PackageList
;
1061 if (PackageListNode
== NULL
) {
1062 return EFI_NOT_FOUND
;
1064 ImagePackage
= PackageListNode
->ImagePkg
;
1065 if (ImagePackage
== NULL
) {
1066 return EFI_NOT_FOUND
;
1070 // Find the image block specified by ImageId
1072 LocalImageId
= ImageId
;
1073 ImageBlock
= (UINT8
*) GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
1074 if (ImageBlock
== NULL
) {
1075 return EFI_NOT_FOUND
;
1078 BlockType
= *ImageBlock
;
1081 // Get the size of original image block. Use some common block code here
1082 // since the definition of some structures is the same.
1084 switch (BlockType
) {
1085 case EFI_HII_IIBT_IMAGE_JPEG
:
1087 // BUGBUG: need to be supported as soon as image tool is designed.
1089 return EFI_UNSUPPORTED
;
1091 case EFI_HII_IIBT_IMAGE_1BIT
:
1092 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
1093 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
1094 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
1095 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
1097 case EFI_HII_IIBT_IMAGE_4BIT
:
1098 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
1099 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
1100 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
1101 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
1103 case EFI_HII_IIBT_IMAGE_8BIT
:
1104 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
1105 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
1106 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
1107 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
1109 case EFI_HII_IIBT_IMAGE_24BIT
:
1110 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
1111 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
1114 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
1117 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1118 BITMAP_LEN_24_BIT (Width
, Height
);
1121 return EFI_NOT_FOUND
;
1125 // Create the new image block according to input image.
1127 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1128 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1129 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
1130 NewBlock
= (UINT8
*) AllocateZeroPool (NewBlockSize
);
1131 if (NewBlock
== NULL
) {
1132 return EFI_OUT_OF_RESOURCES
;
1135 NewBlockPtr
= NewBlock
;
1136 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1137 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
1139 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT
;
1143 CopyMem (NewBlockPtr
, &ImageIn
->Width
, sizeof (UINT16
));
1144 NewBlockPtr
+= sizeof (UINT16
);
1145 CopyMem (NewBlockPtr
, &ImageIn
->Height
, sizeof (UINT16
));
1146 NewBlockPtr
+= sizeof (UINT16
);
1148 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlockPtr
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
1151 // Adjust the image package to remove the original block firstly then add the new block.
1153 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
- OldBlockSize
;
1154 Block
= (UINT8
*) AllocateZeroPool (BlockSize
);
1155 if (Block
== NULL
) {
1156 FreePool (NewBlock
);
1157 return EFI_OUT_OF_RESOURCES
;
1161 Part1Size
= (UINT32
) (ImageBlock
- (UINT8
*) ImagePackage
->ImageBlock
);
1162 Part2Size
= ImagePackage
->ImageBlockSize
- Part1Size
- OldBlockSize
;
1163 CopyMem (BlockPtr
, ImagePackage
->ImageBlock
, Part1Size
);
1164 BlockPtr
+= Part1Size
;
1165 CopyMem (BlockPtr
, NewBlock
, NewBlockSize
);
1166 BlockPtr
+= NewBlockSize
;
1167 CopyMem (BlockPtr
, ImageBlock
+ OldBlockSize
, Part2Size
);
1169 FreePool (ImagePackage
->ImageBlock
);
1170 FreePool (NewBlock
);
1171 ImagePackage
->ImageBlock
= (EFI_HII_IMAGE_BLOCK
*) Block
;
1172 ImagePackage
->ImageBlockSize
= BlockSize
;
1173 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
- OldBlockSize
;
1174 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
- OldBlockSize
;
1177 // Check whether need to get the contents of HiiDataBase.
1178 // Only after ReadyToBoot to do the export.
1180 if (gExportAfterReadyToBoot
) {
1181 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
1190 This function renders an image to a bitmap or the screen using the specified
1191 color and options. It draws the image on an existing bitmap, allocates a new
1192 bitmap or uses the screen. The images can be clipped.
1194 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1195 @param Flags Describes how the image is to be drawn.
1196 @param Image Points to the image to be displayed.
1197 @param Blt If this points to a non-NULL on entry, this points
1198 to the image, which is Width pixels wide and
1199 Height pixels high. The image will be drawn onto
1200 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1201 If this points to a NULL on entry, then a buffer
1202 will be allocated to hold the generated image and
1203 the pointer updated on exit. It is the caller's
1204 responsibility to free this buffer.
1205 @param BltX Specifies the offset from the left and top edge of
1206 the output image of the first pixel in the image.
1207 @param BltY Specifies the offset from the left and top edge of
1208 the output image of the first pixel in the image.
1210 @retval EFI_SUCCESS The image was successfully drawn.
1211 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1212 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1213 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1219 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1220 IN EFI_HII_DRAW_FLAGS Flags
,
1221 IN CONST EFI_IMAGE_INPUT
*Image
,
1222 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1228 HII_DATABASE_PRIVATE_DATA
*Private
;
1229 BOOLEAN Transparent
;
1230 EFI_IMAGE_INPUT
*ImageIn
;
1231 EFI_IMAGE_OUTPUT
*ImageOut
;
1232 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
1240 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1243 if (This
== NULL
|| Image
== NULL
|| Blt
== NULL
) {
1244 return EFI_INVALID_PARAMETER
;
1247 if ((Flags
& EFI_HII_DRAW_FLAG_CLIP
) == EFI_HII_DRAW_FLAG_CLIP
&& *Blt
== NULL
) {
1248 return EFI_INVALID_PARAMETER
;
1251 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_TRANSPARENT
) {
1252 return EFI_INVALID_PARAMETER
;
1256 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1259 // Check whether the image will be drawn transparently or opaquely.
1261 Transparent
= FALSE
;
1262 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_TRANS
) {
1264 } else if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE
){
1265 Transparent
= FALSE
;
1268 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1269 // on the image's transparency setting.
1271 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1277 // Image cannot be drawn transparently if Blt points to NULL on entry.
1278 // Currently output to Screen transparently is not supported, either.
1282 return EFI_INVALID_PARAMETER
;
1283 } else if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1284 return EFI_INVALID_PARAMETER
;
1288 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1291 // When Blt points to a non-NULL on entry, this image will be drawn onto
1292 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1293 // Otherwise a new bitmap will be allocated to hold this image.
1297 // Clip the image by (Width, Height)
1300 Width
= ImageIn
->Width
;
1301 Height
= ImageIn
->Height
;
1303 if (Width
> (*Blt
)->Width
- BltX
) {
1304 Width
= (*Blt
)->Width
- BltX
;
1306 if (Height
> (*Blt
)->Height
- BltY
) {
1307 Height
= (*Blt
)->Height
- BltY
;
1310 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1311 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1312 if (BltBuffer
== NULL
) {
1313 return EFI_OUT_OF_RESOURCES
;
1316 if (Width
== ImageIn
->Width
&& Height
== ImageIn
->Height
) {
1317 CopyMem (BltBuffer
, ImageIn
->Bitmap
, BufferLen
);
1319 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
1320 OffsetY1
= ImageIn
->Width
* Ypos
;
1321 OffsetY2
= Width
* Ypos
;
1322 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
1323 BltBuffer
[OffsetY2
+ Xpos
] = ImageIn
->Bitmap
[OffsetY1
+ Xpos
];
1329 // Draw the image to existing bitmap or screen depending on flag.
1331 if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1333 // Caller should make sure the current UGA console is grarphic mode.
1337 // Write the image directly to the output device specified by Screen.
1339 Status
= (*Blt
)->Image
.Screen
->Blt (
1340 (*Blt
)->Image
.Screen
,
1342 EfiBltBufferToVideo
,
1353 // Draw the image onto the existing bitmap specified by Bitmap.
1355 Status
= ImageToBlt (
1367 FreePool (BltBuffer
);
1372 // Allocate a new bitmap to hold the incoming image.
1374 Width
= ImageIn
->Width
+ BltX
;
1375 Height
= ImageIn
->Height
+ BltY
;
1377 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1378 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1379 if (BltBuffer
== NULL
) {
1380 return EFI_OUT_OF_RESOURCES
;
1383 ImageOut
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1384 if (ImageOut
== NULL
) {
1385 FreePool (BltBuffer
);
1386 return EFI_OUT_OF_RESOURCES
;
1388 ImageOut
->Width
= (UINT16
) Width
;
1389 ImageOut
->Height
= (UINT16
) Height
;
1390 ImageOut
->Image
.Bitmap
= BltBuffer
;
1393 // BUGBUG: Now all the "blank" pixels are filled with system default background
1394 // color. Not sure if it need to be updated or not.
1396 Status
= GetSystemFont (Private
, &FontInfo
, NULL
);
1397 if (EFI_ERROR (Status
)) {
1398 FreePool (BltBuffer
);
1399 FreePool (ImageOut
);
1402 ASSERT (FontInfo
!= NULL
);
1403 for (Index
= 0; Index
< Width
* Height
; Index
++) {
1404 BltBuffer
[Index
] = FontInfo
->BackgroundColor
;
1406 FreePool (FontInfo
);
1409 // Draw the incoming image to the new created image.
1427 This function renders an image to a bitmap or the screen using the specified
1428 color and options. It draws the image on an existing bitmap, allocates a new
1429 bitmap or uses the screen. The images can be clipped.
1431 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1432 @param Flags Describes how the image is to be drawn.
1433 @param PackageList The package list in the HII database to search for
1434 the specified image.
1435 @param ImageId The image's id, which is unique within
1437 @param Blt If this points to a non-NULL on entry, this points
1438 to the image, which is Width pixels wide and
1439 Height pixels high. The image will be drawn onto
1441 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1442 to a NULL on entry, then a buffer will be
1443 allocated to hold the generated image and the
1444 pointer updated on exit. It is the caller's
1445 responsibility to free this buffer.
1446 @param BltX Specifies the offset from the left and top edge of
1447 the output image of the first pixel in the image.
1448 @param BltY Specifies the offset from the left and top edge of
1449 the output image of the first pixel in the image.
1451 @retval EFI_SUCCESS The image was successfully drawn.
1452 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1453 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1454 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1455 The specified PackageList is not in the database.
1461 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1462 IN EFI_HII_DRAW_FLAGS Flags
,
1463 IN EFI_HII_HANDLE PackageList
,
1464 IN EFI_IMAGE_ID ImageId
,
1465 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1471 EFI_IMAGE_INPUT Image
;
1474 // Check input parameter.
1476 if (This
== NULL
|| Blt
== NULL
) {
1477 return EFI_INVALID_PARAMETER
;
1480 if (!IsHiiHandleValid (PackageList
)) {
1481 return EFI_NOT_FOUND
;
1485 // Get the specified Image.
1487 Status
= HiiGetImage (This
, PackageList
, ImageId
, &Image
);
1488 if (EFI_ERROR (Status
)) {
1495 Status
= HiiDrawImage (This
, Flags
, &Image
, Blt
, BltX
, BltY
);
1496 if (Image
.Bitmap
!= NULL
) {
1497 FreePool (Image
.Bitmap
);