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"
19 #define MAX_UINT24 0xFFFFFF
22 Get the imageid of last image block: EFI_HII_IIBT_END_BLOCK when input
23 ImageId is zero, otherwise return the address of the
24 corresponding image block with identifier specified by ImageId.
26 This is a internal function.
28 @param ImageBlocks Points to the beginning of a series of image blocks stored in order.
29 @param ImageId If input ImageId is 0, output the image id of the EFI_HII_IIBT_END_BLOCK;
30 else use this id to find its corresponding image block address.
32 @return The image block address when input ImageId is not zero; otherwise return NULL.
37 IN EFI_HII_IMAGE_BLOCK
*ImageBlocks
,
38 IN OUT EFI_IMAGE_ID
*ImageId
41 EFI_IMAGE_ID ImageIdCurrent
;
42 EFI_HII_IMAGE_BLOCK
*CurrentImageBlock
;
45 ASSERT (ImageBlocks
!= NULL
&& ImageId
!= NULL
);
46 CurrentImageBlock
= ImageBlocks
;
49 while (CurrentImageBlock
->BlockType
!= EFI_HII_IIBT_END
) {
51 if (*ImageId
== ImageIdCurrent
) {
53 // If the found image block is a duplicate block, update the ImageId to
54 // find the previous defined image block.
56 if (CurrentImageBlock
->BlockType
== EFI_HII_IIBT_DUPLICATE
) {
57 *ImageId
= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_DUPLICATE_BLOCK
*) CurrentImageBlock
)->ImageId
);
58 ASSERT (*ImageId
!= ImageIdCurrent
);
59 ASSERT (*ImageId
!= 0);
60 CurrentImageBlock
= ImageBlocks
;
65 return CurrentImageBlock
;
67 if (*ImageId
< ImageIdCurrent
) {
69 // Can not find the specified image block in this image.
74 switch (CurrentImageBlock
->BlockType
) {
75 case EFI_HII_IIBT_EXT1
:
76 Length
= ((EFI_HII_IIBT_EXT1_BLOCK
*) CurrentImageBlock
)->Length
;
78 case EFI_HII_IIBT_EXT2
:
79 Length
= ReadUnaligned16 (&((EFI_HII_IIBT_EXT2_BLOCK
*) CurrentImageBlock
)->Length
);
81 case EFI_HII_IIBT_EXT4
:
82 Length
= ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_EXT4_BLOCK
*) CurrentImageBlock
)->Length
);
85 case EFI_HII_IIBT_IMAGE_1BIT
:
86 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
87 Length
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
89 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
90 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
95 case EFI_HII_IIBT_IMAGE_4BIT
:
96 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
97 Length
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
99 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
100 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
105 case EFI_HII_IIBT_IMAGE_8BIT
:
106 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
107 Length
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
109 (UINT32
) ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
110 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
115 case EFI_HII_IIBT_IMAGE_24BIT
:
116 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
117 Length
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
119 (UINT32
) ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
120 ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
125 case EFI_HII_IIBT_DUPLICATE
:
126 Length
= sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK
);
130 case EFI_HII_IIBT_IMAGE_JPEG
:
131 Length
= OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
);
135 case EFI_HII_IIBT_IMAGE_PNG
:
136 Length
= OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Size
);
140 case EFI_HII_IIBT_SKIP1
:
141 Length
= sizeof (EFI_HII_IIBT_SKIP1_BLOCK
);
142 ImageIdCurrent
+= ((EFI_HII_IIBT_SKIP1_BLOCK
*) CurrentImageBlock
)->SkipCount
;
145 case EFI_HII_IIBT_SKIP2
:
146 Length
= sizeof (EFI_HII_IIBT_SKIP2_BLOCK
);
147 ImageIdCurrent
+= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_SKIP2_BLOCK
*) CurrentImageBlock
)->SkipCount
);
152 // Unknown image blocks can not be skipped, processing halts.
159 CurrentImageBlock
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) CurrentImageBlock
+ Length
);
164 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
167 *ImageId
= ImageIdCurrent
;
168 return CurrentImageBlock
;
177 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
179 This is a internal function.
182 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
183 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
184 @param PixelNum The number of pixels to be converted.
190 OUT EFI_HII_RGB_PIXEL
*BitMapOut
,
191 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapIn
,
197 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
199 for (Index
= 0; Index
< PixelNum
; Index
++) {
200 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
206 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
208 This is a internal function.
211 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
212 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
213 @param PixelNum The number of pixels to be converted.
219 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapOut
,
220 IN EFI_HII_RGB_PIXEL
*BitMapIn
,
226 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
228 for (Index
= 0; Index
< PixelNum
; Index
++) {
229 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
235 Output pixels in "1 bit per pixel" format to an image.
237 This is a internal function.
240 @param Image Points to the image which will store the pixels.
241 @param Data Stores the value of output pixels, 0 or 1.
242 @param PaletteInfo PaletteInfo which stores the color of the output
243 pixels. First entry corresponds to color 0 and
244 second one to color 1.
250 IN OUT EFI_IMAGE_INPUT
*Image
,
252 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
259 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
260 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[2];
261 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
265 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
267 BitMapPtr
= Image
->Bitmap
;
270 // First entry corresponds to color 0 and second entry corresponds to color 1.
273 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
274 PaletteSize
+= sizeof (UINT16
);
275 Palette
= AllocateZeroPool (PaletteSize
);
276 ASSERT (Palette
!= NULL
);
277 if (Palette
== NULL
) {
280 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
282 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
283 CopyRgbToGopPixel (&PaletteValue
[0], &Palette
->PaletteValue
[0], 1);
284 CopyRgbToGopPixel (&PaletteValue
[1], &Palette
->PaletteValue
[1], 1);
288 // Convert the pixel from one bit to corresponding color.
290 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
291 OffsetY
= BITMAP_LEN_1_BIT (Image
->Width
, Ypos
);
293 // All bits in these bytes are meaningful
295 for (Xpos
= 0; Xpos
< Image
->Width
/ 8; Xpos
++) {
296 Byte
= *(Data
+ OffsetY
+ Xpos
);
297 for (Index
= 0; Index
< 8; Index
++) {
298 if ((Byte
& (1 << Index
)) != 0) {
299 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[1];
301 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + (8 - Index
- 1)] = PaletteValue
[0];
306 if (Image
->Width
% 8 != 0) {
308 // Padding bits in this byte should be ignored.
310 Byte
= *(Data
+ OffsetY
+ Xpos
);
311 for (Index
= 0; Index
< Image
->Width
% 8; Index
++) {
312 if ((Byte
& (1 << (8 - Index
- 1))) != 0) {
313 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[1];
315 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 8 + Index
] = PaletteValue
[0];
324 Output pixels in "4 bit per pixel" format to an image.
326 This is a internal function.
329 @param Image Points to the image which will store the pixels.
330 @param Data Stores the value of output pixels, 0 ~ 15.
331 @param[in] PaletteInfo PaletteInfo which stores the color of the output
332 pixels. Each entry corresponds to a color within
339 IN OUT EFI_IMAGE_INPUT
*Image
,
341 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
347 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
348 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[16];
349 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
354 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
356 BitMapPtr
= Image
->Bitmap
;
359 // The bitmap should allocate each color index starting from 0.
362 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
363 PaletteSize
+= sizeof (UINT16
);
364 Palette
= AllocateZeroPool (PaletteSize
);
365 ASSERT (Palette
!= NULL
);
366 if (Palette
== NULL
) {
369 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
370 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
372 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
373 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
377 // Convert the pixel from 4 bit to corresponding color.
379 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
380 OffsetY
= BITMAP_LEN_4_BIT (Image
->Width
, Ypos
);
382 // All bits in these bytes are meaningful
384 for (Xpos
= 0; Xpos
< Image
->Width
/ 2; Xpos
++) {
385 Byte
= *(Data
+ OffsetY
+ Xpos
);
386 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
387 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2 + 1] = PaletteValue
[Byte
& 0x0F];
390 if (Image
->Width
% 2 != 0) {
392 // Padding bits in this byte should be ignored.
394 Byte
= *(Data
+ OffsetY
+ Xpos
);
395 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
402 Output pixels in "8 bit per pixel" format to an image.
404 This is a internal function.
407 @param Image Points to the image which will store the pixels.
408 @param Data Stores the value of output pixels, 0 ~ 255.
409 @param[in] PaletteInfo PaletteInfo which stores the color of the output
410 pixels. Each entry corresponds to a color within
417 IN OUT EFI_IMAGE_INPUT
*Image
,
419 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
425 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
426 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[256];
427 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
432 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
434 BitMapPtr
= Image
->Bitmap
;
437 // The bitmap should allocate each color index starting from 0.
440 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
441 PaletteSize
+= sizeof (UINT16
);
442 Palette
= AllocateZeroPool (PaletteSize
);
443 ASSERT (Palette
!= NULL
);
444 if (Palette
== NULL
) {
447 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
448 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
449 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
450 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
454 // Convert the pixel from 8 bits to corresponding color.
456 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
457 OffsetY
= BITMAP_LEN_8_BIT ((UINT32
) Image
->Width
, Ypos
);
459 // All bits are meaningful since the bitmap is 8 bits per pixel.
461 for (Xpos
= 0; Xpos
< Image
->Width
; Xpos
++) {
462 Byte
= *(Data
+ OffsetY
+ Xpos
);
463 BitMapPtr
[OffsetY
+ Xpos
] = PaletteValue
[Byte
];
471 Output pixels in "24 bit per pixel" format to an image.
473 This is a internal function.
476 @param Image Points to the image which will store the pixels.
477 @param Data Stores the color of output pixels, allowing 16.8
484 IN OUT EFI_IMAGE_INPUT
*Image
,
485 IN EFI_HII_RGB_PIXEL
*Data
490 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
492 ASSERT (Image
!= NULL
&& Data
!= NULL
);
494 BitMapPtr
= Image
->Bitmap
;
496 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
497 OffsetY
= BITMAP_LEN_8_BIT ((UINT32
) Image
->Width
, Ypos
);
498 CopyRgbToGopPixel (&BitMapPtr
[OffsetY
], &Data
[OffsetY
], Image
->Width
);
505 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
507 This is a internal function.
510 @param BltBuffer Buffer points to bitmap data of incoming image.
511 @param BltX Specifies the offset from the left and top edge of
512 the output image of the first pixel in the image.
513 @param BltY Specifies the offset from the left and top edge of
514 the output image of the first pixel in the image.
515 @param Width Width of the incoming image, in pixels.
516 @param Height Height of the incoming image, in pixels.
517 @param Transparent If TRUE, all "off" pixels in the image will be
518 drawn using the pixel value from blt and all other
519 pixels will be copied.
520 @param Blt Buffer points to bitmap data of output image.
522 @retval EFI_SUCCESS The image was successfully converted.
523 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
528 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
533 IN BOOLEAN Transparent
,
534 IN OUT EFI_IMAGE_OUTPUT
**Blt
537 EFI_IMAGE_OUTPUT
*ImageOut
;
540 UINTN OffsetY1
; // src buffer
541 UINTN OffsetY2
; // dest buffer
542 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel
;
543 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel
;
545 if (BltBuffer
== NULL
|| Blt
== NULL
|| *Blt
== NULL
) {
546 return EFI_INVALID_PARAMETER
;
551 if (Width
+ BltX
> ImageOut
->Width
) {
552 return EFI_INVALID_PARAMETER
;
554 if (Height
+ BltY
> ImageOut
->Height
) {
555 return EFI_INVALID_PARAMETER
;
558 ZeroMem (&ZeroPixel
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
560 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
561 OffsetY1
= Width
* Ypos
;
562 OffsetY2
= ImageOut
->Width
* (BltY
+ Ypos
);
563 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
564 SrcPixel
= BltBuffer
[OffsetY1
+ Xpos
];
566 if (CompareMem (&SrcPixel
, &ZeroPixel
, 3) != 0) {
567 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
570 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
579 Return the HII package list identified by PackageList HII handle.
581 @param Database Pointer to HII database list header.
582 @param PackageList HII handle of the package list to locate.
584 @retval The HII package list instance.
586 HII_DATABASE_PACKAGE_LIST_INSTANCE
*
588 IN LIST_ENTRY
*Database
,
589 IN EFI_HII_HANDLE PackageList
593 HII_DATABASE_RECORD
*Record
;
596 // Get the specified package list and image package.
598 for (Link
= GetFirstNode (Database
);
599 !IsNull (Database
, Link
);
600 Link
= GetNextNode (Database
, Link
)
602 Record
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
603 if (Record
->Handle
== PackageList
) {
604 return Record
->PackageList
;
611 This function adds the image Image to the group of images owned by PackageList, and returns
612 a new image identifier (ImageId).
614 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
615 @param PackageList Handle of the package list where this image will
617 @param ImageId On return, contains the new image id, which is
618 unique within PackageList.
619 @param Image Points to the image.
621 @retval EFI_SUCCESS The new image was added successfully.
622 @retval EFI_NOT_FOUND The specified PackageList could not be found in
624 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
625 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
631 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
632 IN EFI_HII_HANDLE PackageList
,
633 OUT EFI_IMAGE_ID
*ImageId
,
634 IN CONST EFI_IMAGE_INPUT
*Image
637 HII_DATABASE_PRIVATE_DATA
*Private
;
638 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
639 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
640 EFI_HII_IMAGE_BLOCK
*ImageBlocks
;
643 if (This
== NULL
|| ImageId
== NULL
|| Image
== NULL
|| Image
->Bitmap
== NULL
) {
644 return EFI_INVALID_PARAMETER
;
647 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
648 PackageListNode
= LocatePackageList (&Private
->DatabaseList
, PackageList
);
649 if (PackageListNode
== NULL
) {
650 return EFI_NOT_FOUND
;
653 EfiAcquireLock (&mHiiDatabaseLock
);
656 // Calcuate the size of new image.
657 // Make sure the size doesn't overflow UINT32.
658 // Note: 24Bit BMP occpuies 3 bytes per pixel.
660 NewBlockSize
= (UINT32
)Image
->Width
* Image
->Height
;
661 if (NewBlockSize
> (MAX_UINT32
- (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
))) / 3) {
662 return EFI_OUT_OF_RESOURCES
;
664 NewBlockSize
= NewBlockSize
* 3 + (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
));
667 // Get the image package in the package list,
668 // or create a new image package if image package does not exist.
670 if (PackageListNode
->ImagePkg
!= NULL
) {
671 ImagePackage
= PackageListNode
->ImagePkg
;
674 // Output the image id of the incoming image being inserted, which is the
675 // image id of the EFI_HII_IIBT_END block of old image package.
678 GetImageIdOrAddress (ImagePackage
->ImageBlock
, ImageId
);
681 // Update the package's image block by appending the new block to the end.
685 // Make sure the final package length doesn't overflow.
686 // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
688 if (NewBlockSize
> MAX_UINT24
- ImagePackage
->ImagePkgHdr
.Header
.Length
) {
689 return EFI_OUT_OF_RESOURCES
;
692 // Because ImagePackage->ImageBlockSize < ImagePackage->ImagePkgHdr.Header.Length,
693 // So (ImagePackage->ImageBlockSize + NewBlockSize) <= MAX_UINT24
695 ImageBlocks
= AllocatePool (ImagePackage
->ImageBlockSize
+ NewBlockSize
);
696 if (ImageBlocks
== NULL
) {
697 EfiReleaseLock (&mHiiDatabaseLock
);
698 return EFI_OUT_OF_RESOURCES
;
701 // Copy the original content.
705 ImagePackage
->ImageBlock
,
706 ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
708 FreePool (ImagePackage
->ImageBlock
);
709 ImagePackage
->ImageBlock
= ImageBlocks
;
712 // Point to the very last block.
714 ImageBlocks
= (EFI_HII_IMAGE_BLOCK
*) (
715 (UINT8
*) ImageBlocks
+ ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
718 // Update the length record.
720 ImagePackage
->ImageBlockSize
+= NewBlockSize
;
721 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
;
722 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
;
726 // Make sure the final package length doesn't overflow.
727 // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
729 if (NewBlockSize
> MAX_UINT24
- (sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) + sizeof (EFI_HII_IIBT_END_BLOCK
))) {
730 return EFI_OUT_OF_RESOURCES
;
733 // The specified package list does not contain image package.
734 // Create one to add this image block.
736 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
737 if (ImagePackage
== NULL
) {
738 EfiReleaseLock (&mHiiDatabaseLock
);
739 return EFI_OUT_OF_RESOURCES
;
742 // Output the image id of the incoming image being inserted, which is the
743 // first image block so that id is initially to one.
747 // Fill in image package header.
749 ImagePackage
->ImagePkgHdr
.Header
.Length
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
) + NewBlockSize
+ sizeof (EFI_HII_IIBT_END_BLOCK
);
750 ImagePackage
->ImagePkgHdr
.Header
.Type
= EFI_HII_PACKAGE_IMAGES
;
751 ImagePackage
->ImagePkgHdr
.ImageInfoOffset
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
752 ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
= 0;
755 // Fill in palette info.
757 ImagePackage
->PaletteBlock
= NULL
;
758 ImagePackage
->PaletteInfoSize
= 0;
761 // Fill in image blocks.
763 ImagePackage
->ImageBlockSize
= NewBlockSize
+ sizeof (EFI_HII_IIBT_END_BLOCK
);
764 ImagePackage
->ImageBlock
= AllocateZeroPool (NewBlockSize
+ sizeof (EFI_HII_IIBT_END_BLOCK
));
765 if (ImagePackage
->ImageBlock
== NULL
) {
766 FreePool (ImagePackage
);
767 EfiReleaseLock (&mHiiDatabaseLock
);
768 return EFI_OUT_OF_RESOURCES
;
770 ImageBlocks
= ImagePackage
->ImageBlock
;
773 // Insert this image package.
775 PackageListNode
->ImagePkg
= ImagePackage
;
776 PackageListNode
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
780 // Append the new block here
782 if (Image
->Flags
== EFI_IMAGE_TRANSPARENT
) {
783 ImageBlocks
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
785 ImageBlocks
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT
;
787 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) ImageBlocks
)->Bitmap
.Width
, Image
->Width
);
788 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) ImageBlocks
)->Bitmap
.Height
, Image
->Height
);
789 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) ImageBlocks
)->Bitmap
.Bitmap
, Image
->Bitmap
, (UINT32
) Image
->Width
* Image
->Height
);
792 // Append the block end
794 ImageBlocks
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) ImageBlocks
+ NewBlockSize
);
795 ImageBlocks
->BlockType
= EFI_HII_IIBT_END
;
798 // Check whether need to get the contents of HiiDataBase.
799 // Only after ReadyToBoot to do the export.
801 if (gExportAfterReadyToBoot
) {
802 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
805 EfiReleaseLock (&mHiiDatabaseLock
);
812 This function retrieves the image specified by ImageId which is associated with
813 the specified PackageList and copies it into the buffer specified by Image.
815 @param Database A pointer to the database list header.
816 @param PackageList Handle of the package list where this image will
818 @param ImageId The image's id,, which is unique within
820 @param Image Points to the image.
821 @param BitmapOnly TRUE to only return the bitmap type image.
822 FALSE to locate image decoder instance to decode image.
824 @retval EFI_SUCCESS The new image was returned successfully.
825 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
826 database. The specified PackageList is not in the database.
827 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
829 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
830 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
835 IN LIST_ENTRY
*Database
,
836 IN EFI_HII_HANDLE PackageList
,
837 IN EFI_IMAGE_ID ImageId
,
838 OUT EFI_IMAGE_INPUT
*Image
,
839 IN BOOLEAN BitmapOnly
843 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
844 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
845 EFI_HII_IMAGE_BLOCK
*CurrentImageBlock
;
846 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
853 EFI_HII_IMAGE_DECODER_PROTOCOL
*Decoder
;
854 EFI_IMAGE_OUTPUT
*ImageOut
;
856 if (Image
== NULL
|| ImageId
== 0) {
857 return EFI_INVALID_PARAMETER
;
860 PackageListNode
= LocatePackageList (Database
, PackageList
);
861 if (PackageListNode
== NULL
) {
862 return EFI_NOT_FOUND
;
864 ImagePackage
= PackageListNode
->ImagePkg
;
865 if (ImagePackage
== NULL
) {
866 return EFI_NOT_FOUND
;
870 // Find the image block specified by ImageId
872 CurrentImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &ImageId
);
873 if (CurrentImageBlock
== NULL
) {
874 return EFI_NOT_FOUND
;
878 switch (CurrentImageBlock
->BlockType
) {
879 case EFI_HII_IIBT_IMAGE_JPEG
:
880 case EFI_HII_IIBT_IMAGE_PNG
:
882 return EFI_UNSUPPORTED
;
886 Decoder
= LocateHiiImageDecoder (CurrentImageBlock
->BlockType
);
887 if (Decoder
== NULL
) {
888 return EFI_UNSUPPORTED
;
891 // Use the common block code since the definition of two structures is the same.
893 ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Data
) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Data
));
894 ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Data
) ==
895 sizeof (((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Data
));
896 ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Size
) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Size
));
897 ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
) ==
898 sizeof (((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Size
));
899 Status
= Decoder
->DecodeImage (
901 ((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Data
,
902 ((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
,
908 // Spec requires to use the first capable image decoder instance.
909 // The first image decoder instance may fail to decode the image.
911 if (!EFI_ERROR (Status
)) {
912 Image
->Bitmap
= ImageOut
->Image
.Bitmap
;
913 Image
->Height
= ImageOut
->Height
;
914 Image
->Width
= ImageOut
->Width
;
919 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
920 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
921 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
922 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
926 case EFI_HII_IIBT_IMAGE_1BIT
:
927 case EFI_HII_IIBT_IMAGE_4BIT
:
928 case EFI_HII_IIBT_IMAGE_8BIT
:
930 // Use the common block code since the definition of these structures is the same.
932 CopyMem (&Iibt1bit
, CurrentImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
933 ImageLength
= (UINTN
) Iibt1bit
.Bitmap
.Width
* Iibt1bit
.Bitmap
.Height
;
934 if (ImageLength
> MAX_UINTN
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
935 return EFI_OUT_OF_RESOURCES
;
937 ImageLength
*= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
938 Image
->Bitmap
= AllocateZeroPool (ImageLength
);
939 if (Image
->Bitmap
== NULL
) {
940 return EFI_OUT_OF_RESOURCES
;
943 Image
->Width
= Iibt1bit
.Bitmap
.Width
;
944 Image
->Height
= Iibt1bit
.Bitmap
.Height
;
946 PaletteInfo
= ImagePackage
->PaletteBlock
+ sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
947 for (PaletteIndex
= 1; PaletteIndex
< Iibt1bit
.PaletteIndex
; PaletteIndex
++) {
948 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
949 PaletteInfo
+= PaletteSize
+ sizeof (UINT16
);
951 ASSERT (PaletteIndex
== Iibt1bit
.PaletteIndex
);
954 // Output bitmap data
956 if (CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_1BIT
||
957 CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_1BIT_TRANS
) {
960 ((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Data
,
961 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
963 } else if (CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_4BIT
||
964 CurrentImageBlock
->BlockType
== EFI_HII_IIBT_IMAGE_4BIT_TRANS
) {
967 ((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Data
,
968 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
973 ((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Data
,
974 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
980 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
981 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
985 case EFI_HII_IIBT_IMAGE_24BIT
:
986 Width
= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
);
987 Height
= ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
);
988 ImageLength
= (UINTN
)Width
* Height
;
989 if (ImageLength
> MAX_UINTN
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
990 return EFI_OUT_OF_RESOURCES
;
992 ImageLength
*= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
993 Image
->Bitmap
= AllocateZeroPool (ImageLength
);
994 if (Image
->Bitmap
== NULL
) {
995 return EFI_OUT_OF_RESOURCES
;
998 Image
->Width
= Width
;
999 Image
->Height
= Height
;
1002 // Output the bitmap data directly.
1006 ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Bitmap
1011 return EFI_NOT_FOUND
;
1016 This function retrieves the image specified by ImageId which is associated with
1017 the specified PackageList and copies it into the buffer specified by Image.
1019 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1020 @param PackageList Handle of the package list where this image will
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 returned 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_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
1031 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
1032 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
1039 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1040 IN EFI_HII_HANDLE PackageList
,
1041 IN EFI_IMAGE_ID ImageId
,
1042 OUT EFI_IMAGE_INPUT
*Image
1045 HII_DATABASE_PRIVATE_DATA
*Private
;
1046 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1047 return IGetImage (&Private
->DatabaseList
, PackageList
, ImageId
, Image
, TRUE
);
1052 This function updates the image specified by ImageId in the specified PackageListHandle to
1053 the image specified by Image.
1055 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1056 @param PackageList The package list containing the images.
1057 @param ImageId The image's id,, which is unique within
1059 @param Image Points to the image.
1061 @retval EFI_SUCCESS The new image was updated successfully.
1062 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
1063 database. The specified PackageList is not in the database.
1064 @retval EFI_INVALID_PARAMETER The Image was NULL.
1070 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1071 IN EFI_HII_HANDLE PackageList
,
1072 IN EFI_IMAGE_ID ImageId
,
1073 IN CONST EFI_IMAGE_INPUT
*Image
1076 HII_DATABASE_PRIVATE_DATA
*Private
;
1077 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1078 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
1079 EFI_HII_IMAGE_BLOCK
*CurrentImageBlock
;
1080 EFI_HII_IMAGE_BLOCK
*ImageBlocks
;
1081 EFI_HII_IMAGE_BLOCK
*NewImageBlock
;
1082 UINT32 NewBlockSize
;
1083 UINT32 OldBlockSize
;
1087 if (This
== NULL
|| Image
== NULL
|| ImageId
== 0 || Image
->Bitmap
== NULL
) {
1088 return EFI_INVALID_PARAMETER
;
1091 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1092 PackageListNode
= LocatePackageList (&Private
->DatabaseList
, PackageList
);
1093 if (PackageListNode
== NULL
) {
1094 return EFI_NOT_FOUND
;
1096 ImagePackage
= PackageListNode
->ImagePkg
;
1097 if (ImagePackage
== NULL
) {
1098 return EFI_NOT_FOUND
;
1102 // Find the image block specified by ImageId
1104 CurrentImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &ImageId
);
1105 if (CurrentImageBlock
== NULL
) {
1106 return EFI_NOT_FOUND
;
1109 EfiAcquireLock (&mHiiDatabaseLock
);
1112 // Get the size of original image block. Use some common block code here
1113 // since the definition of some structures is the same.
1115 switch (CurrentImageBlock
->BlockType
) {
1116 case EFI_HII_IIBT_IMAGE_JPEG
:
1117 OldBlockSize
= OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_JPEG_BLOCK
*) CurrentImageBlock
)->Size
);
1119 case EFI_HII_IIBT_IMAGE_PNG
:
1120 OldBlockSize
= OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK
, Data
) + ReadUnaligned32 ((VOID
*) &((EFI_HII_IIBT_PNG_BLOCK
*) CurrentImageBlock
)->Size
);
1122 case EFI_HII_IIBT_IMAGE_1BIT
:
1123 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
1124 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
1126 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1127 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1130 case EFI_HII_IIBT_IMAGE_4BIT
:
1131 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
1132 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
1134 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1135 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1138 case EFI_HII_IIBT_IMAGE_8BIT
:
1139 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
1140 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
1142 (UINT32
) ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1143 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1146 case EFI_HII_IIBT_IMAGE_24BIT
:
1147 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
1148 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1150 (UINT32
) ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Width
),
1151 ReadUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) CurrentImageBlock
)->Bitmap
.Height
)
1155 EfiReleaseLock (&mHiiDatabaseLock
);
1156 return EFI_NOT_FOUND
;
1160 // Create the new image block according to input image.
1164 // Make sure the final package length doesn't overflow.
1165 // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
1166 // 24Bit BMP occpuies 3 bytes per pixel.
1168 NewBlockSize
= (UINT32
)Image
->Width
* Image
->Height
;
1169 if (NewBlockSize
> (MAX_UINT32
- (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
))) / 3) {
1170 return EFI_OUT_OF_RESOURCES
;
1172 NewBlockSize
= NewBlockSize
* 3 + (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
));
1173 if ((NewBlockSize
> OldBlockSize
) &&
1174 (NewBlockSize
- OldBlockSize
> MAX_UINT24
- ImagePackage
->ImagePkgHdr
.Header
.Length
)
1176 return EFI_OUT_OF_RESOURCES
;
1180 // Adjust the image package to remove the original block firstly then add the new block.
1182 ImageBlocks
= AllocateZeroPool (ImagePackage
->ImageBlockSize
+ NewBlockSize
- OldBlockSize
);
1183 if (ImageBlocks
== NULL
) {
1184 EfiReleaseLock (&mHiiDatabaseLock
);
1185 return EFI_OUT_OF_RESOURCES
;
1188 Part1Size
= (UINT32
) ((UINTN
) CurrentImageBlock
- (UINTN
) ImagePackage
->ImageBlock
);
1189 Part2Size
= ImagePackage
->ImageBlockSize
- Part1Size
- OldBlockSize
;
1190 CopyMem (ImageBlocks
, ImagePackage
->ImageBlock
, Part1Size
);
1193 // Set the new image block
1195 NewImageBlock
= (EFI_HII_IMAGE_BLOCK
*) ((UINT8
*) ImageBlocks
+ Part1Size
);
1196 if ((Image
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1197 NewImageBlock
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
1199 NewImageBlock
->BlockType
= EFI_HII_IIBT_IMAGE_24BIT
;
1201 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) NewImageBlock
)->Bitmap
.Width
, Image
->Width
);
1202 WriteUnaligned16 ((VOID
*) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) NewImageBlock
)->Bitmap
.Height
, Image
->Height
);
1203 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK
*) NewImageBlock
)->Bitmap
.Bitmap
,
1204 Image
->Bitmap
, (UINT32
) Image
->Width
* Image
->Height
);
1206 CopyMem ((UINT8
*) NewImageBlock
+ NewBlockSize
, (UINT8
*) CurrentImageBlock
+ OldBlockSize
, Part2Size
);
1208 FreePool (ImagePackage
->ImageBlock
);
1209 ImagePackage
->ImageBlock
= ImageBlocks
;
1210 ImagePackage
->ImageBlockSize
+= NewBlockSize
- OldBlockSize
;
1211 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
- OldBlockSize
;
1212 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
- OldBlockSize
;
1215 // Check whether need to get the contents of HiiDataBase.
1216 // Only after ReadyToBoot to do the export.
1218 if (gExportAfterReadyToBoot
) {
1219 HiiGetDatabaseInfo(&Private
->HiiDatabase
);
1222 EfiReleaseLock (&mHiiDatabaseLock
);
1229 This function renders an image to a bitmap or the screen using the specified
1230 color and options. It draws the image on an existing bitmap, allocates a new
1231 bitmap or uses the screen. The images can be clipped.
1233 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1234 @param Flags Describes how the image is to be drawn.
1235 @param Image Points to the image to be displayed.
1236 @param Blt If this points to a non-NULL on entry, this points
1237 to the image, which is Width pixels wide and
1238 Height pixels high. The image will be drawn onto
1239 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1240 If this points to a NULL on entry, then a buffer
1241 will be allocated to hold the generated image and
1242 the pointer updated on exit. It is the caller's
1243 responsibility to free this buffer.
1244 @param BltX Specifies the offset from the left and top edge of
1245 the output image of the first pixel in the image.
1246 @param BltY Specifies the offset from the left and top edge of
1247 the output image of the first pixel in the image.
1249 @retval EFI_SUCCESS The image was successfully drawn.
1250 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1251 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1252 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1258 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1259 IN EFI_HII_DRAW_FLAGS Flags
,
1260 IN CONST EFI_IMAGE_INPUT
*Image
,
1261 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1267 HII_DATABASE_PRIVATE_DATA
*Private
;
1268 BOOLEAN Transparent
;
1269 EFI_IMAGE_OUTPUT
*ImageOut
;
1270 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
1278 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1281 if (This
== NULL
|| Image
== NULL
|| Blt
== NULL
) {
1282 return EFI_INVALID_PARAMETER
;
1285 if ((Flags
& EFI_HII_DRAW_FLAG_CLIP
) == EFI_HII_DRAW_FLAG_CLIP
&& *Blt
== NULL
) {
1286 return EFI_INVALID_PARAMETER
;
1289 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_TRANSPARENT
) {
1290 return EFI_INVALID_PARAMETER
;
1296 // Check whether the image will be drawn transparently or opaquely.
1298 Transparent
= FALSE
;
1299 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_TRANS
) {
1301 } else if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE
){
1302 Transparent
= FALSE
;
1305 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1306 // on the image's transparency setting.
1308 if ((Image
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1314 // Image cannot be drawn transparently if Blt points to NULL on entry.
1315 // Currently output to Screen transparently is not supported, either.
1319 return EFI_INVALID_PARAMETER
;
1320 } else if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1321 return EFI_INVALID_PARAMETER
;
1325 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1328 // When Blt points to a non-NULL on entry, this image will be drawn onto
1329 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1330 // Otherwise a new bitmap will be allocated to hold this image.
1334 // Make sure the BltX and BltY is inside the Blt area.
1336 if ((BltX
>= (*Blt
)->Width
) || (BltY
>= (*Blt
)->Height
)) {
1337 return EFI_INVALID_PARAMETER
;
1341 // Clip the image by (Width, Height)
1344 Width
= Image
->Width
;
1345 Height
= Image
->Height
;
1347 if (Width
> (*Blt
)->Width
- (UINT16
)BltX
) {
1348 Width
= (*Blt
)->Width
- (UINT16
)BltX
;
1350 if (Height
> (*Blt
)->Height
- (UINT16
)BltY
) {
1351 Height
= (*Blt
)->Height
- (UINT16
)BltY
;
1355 // Prepare the buffer for the temporary image.
1356 // Make sure the buffer size doesn't overflow UINTN.
1358 BufferLen
= Width
* Height
;
1359 if (BufferLen
> MAX_UINTN
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
1360 return EFI_OUT_OF_RESOURCES
;
1362 BufferLen
*= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1363 BltBuffer
= AllocateZeroPool (BufferLen
);
1364 if (BltBuffer
== NULL
) {
1365 return EFI_OUT_OF_RESOURCES
;
1368 if (Width
== Image
->Width
&& Height
== Image
->Height
) {
1369 CopyMem (BltBuffer
, Image
->Bitmap
, BufferLen
);
1371 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
1372 OffsetY1
= Image
->Width
* Ypos
;
1373 OffsetY2
= Width
* Ypos
;
1374 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
1375 BltBuffer
[OffsetY2
+ Xpos
] = Image
->Bitmap
[OffsetY1
+ Xpos
];
1381 // Draw the image to existing bitmap or screen depending on flag.
1383 if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1385 // Caller should make sure the current UGA console is grarphic mode.
1389 // Write the image directly to the output device specified by Screen.
1391 Status
= (*Blt
)->Image
.Screen
->Blt (
1392 (*Blt
)->Image
.Screen
,
1394 EfiBltBufferToVideo
,
1405 // Draw the image onto the existing bitmap specified by Bitmap.
1407 Status
= ImageToBlt (
1419 FreePool (BltBuffer
);
1424 // Allocate a new bitmap to hold the incoming image.
1428 // Make sure the final width and height doesn't overflow UINT16.
1430 if ((BltX
> (UINTN
)MAX_UINT16
- Image
->Width
) || (BltY
> (UINTN
)MAX_UINT16
- Image
->Height
)) {
1431 return EFI_INVALID_PARAMETER
;
1434 Width
= Image
->Width
+ (UINT16
)BltX
;
1435 Height
= Image
->Height
+ (UINT16
)BltY
;
1438 // Make sure the output image size doesn't overflow UINTN.
1440 BufferLen
= Width
* Height
;
1441 if (BufferLen
> MAX_UINTN
/ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)) {
1442 return EFI_OUT_OF_RESOURCES
;
1444 BufferLen
*= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1445 BltBuffer
= AllocateZeroPool (BufferLen
);
1446 if (BltBuffer
== NULL
) {
1447 return EFI_OUT_OF_RESOURCES
;
1450 ImageOut
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1451 if (ImageOut
== NULL
) {
1452 FreePool (BltBuffer
);
1453 return EFI_OUT_OF_RESOURCES
;
1455 ImageOut
->Width
= Width
;
1456 ImageOut
->Height
= Height
;
1457 ImageOut
->Image
.Bitmap
= BltBuffer
;
1460 // BUGBUG: Now all the "blank" pixels are filled with system default background
1461 // color. Not sure if it need to be updated or not.
1463 Status
= GetSystemFont (Private
, &FontInfo
, NULL
);
1464 if (EFI_ERROR (Status
)) {
1465 FreePool (BltBuffer
);
1466 FreePool (ImageOut
);
1469 ASSERT (FontInfo
!= NULL
);
1470 for (Index
= 0; Index
< (UINTN
)Width
* Height
; Index
++) {
1471 BltBuffer
[Index
] = FontInfo
->BackgroundColor
;
1473 FreePool (FontInfo
);
1476 // Draw the incoming image to the new created image.
1494 This function renders an image to a bitmap or the screen using the specified
1495 color and options. It draws the image on an existing bitmap, allocates a new
1496 bitmap or uses the screen. The images can be clipped.
1498 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1499 @param Flags Describes how the image is to be drawn.
1500 @param PackageList The package list in the HII database to search for
1501 the specified image.
1502 @param ImageId The image's id, which is unique within
1504 @param Blt If this points to a non-NULL on entry, this points
1505 to the image, which is Width pixels wide and
1506 Height pixels high. The image will be drawn onto
1508 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1509 to a NULL on entry, then a buffer will be
1510 allocated to hold the generated image and the
1511 pointer updated on exit. It is the caller's
1512 responsibility to free this buffer.
1513 @param BltX Specifies the offset from the left and top edge of
1514 the output image of the first pixel in the image.
1515 @param BltY Specifies the offset from the left and top edge of
1516 the output image of the first pixel in the image.
1518 @retval EFI_SUCCESS The image was successfully drawn.
1519 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1520 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1521 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1522 The specified PackageList is not in the database.
1528 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1529 IN EFI_HII_DRAW_FLAGS Flags
,
1530 IN EFI_HII_HANDLE PackageList
,
1531 IN EFI_IMAGE_ID ImageId
,
1532 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1538 EFI_IMAGE_INPUT Image
;
1541 // Check input parameter.
1543 if (This
== NULL
|| Blt
== NULL
) {
1544 return EFI_INVALID_PARAMETER
;
1548 // Get the specified Image.
1550 Status
= HiiGetImage (This
, PackageList
, ImageId
, &Image
);
1551 if (EFI_ERROR (Status
)) {
1558 Status
= HiiDrawImage (This
, Flags
, &Image
, Blt
, BltX
, BltY
);
1559 if (Image
.Bitmap
!= NULL
) {
1560 FreePool (Image
.Bitmap
);