2 Implementation for EFI_HII_IMAGE_PROTOCOL.
5 Copyright (c) 2007 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "HiiDatabase.h"
19 #ifndef _DISABLE_UNUSED_HII_PROTOCOLS_
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 ImageBlock 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.
38 IN OUT EFI_IMAGE_ID
*ImageId
41 EFI_IMAGE_ID ImageIdCurrent
;
46 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
47 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit
;
48 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit
;
52 ASSERT (ImageBlock
!= NULL
&& ImageId
!= NULL
);
54 ImageBlockHdr
= ImageBlock
;
57 while (((EFI_HII_IMAGE_BLOCK
*) ImageBlock
)->BlockType
!= EFI_HII_IIBT_END
) {
59 if (*ImageId
== ImageIdCurrent
) {
61 // If the found image block is a duplicate block, update the ImageId to
62 // find the previous defined image block.
64 if (((EFI_HII_IMAGE_BLOCK
*) ImageBlock
)->BlockType
== EFI_HII_IIBT_DUPLICATE
) {
65 CopyMem (ImageId
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (EFI_IMAGE_ID
));
66 ASSERT (*ImageId
!= ImageIdCurrent
);
67 ImageBlock
= ImageBlockHdr
;
74 if (*ImageId
< ImageIdCurrent
) {
76 // Can not find the specified image block in this image.
81 switch (((EFI_HII_IMAGE_BLOCK
*) ImageBlock
)->BlockType
) {
82 case EFI_HII_IIBT_EXT1
:
83 Length8
= *(ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
));
84 ImageBlock
+= Length8
;
87 case EFI_HII_IIBT_EXT2
:
90 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
),
93 ImageBlock
+= Length16
;
96 case EFI_HII_IIBT_EXT4
:
99 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT8
),
102 ImageBlock
+= Length32
;
106 case EFI_HII_IIBT_IMAGE_1BIT
:
107 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
108 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
109 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
110 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
114 case EFI_HII_IIBT_IMAGE_4BIT
:
115 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
116 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
117 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
118 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
122 case EFI_HII_IIBT_IMAGE_8BIT
:
123 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
124 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
125 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
126 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
130 case EFI_HII_IIBT_IMAGE_24BIT
:
131 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
132 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
135 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
138 ImageBlock
+= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
139 BITMAP_LEN_24_BIT (Width
, Height
);
143 case EFI_HII_IIBT_DUPLICATE
:
144 ImageBlock
+= sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK
);
148 case EFI_HII_IIBT_IMAGE_JPEG
:
149 CopyMem (&Length32
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT32
));
150 ImageBlock
+= Length32
;
154 case EFI_HII_IIBT_SKIP1
:
155 Length8
= *(ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
));
156 ImageBlock
+= sizeof (EFI_HII_IIBT_SKIP1_BLOCK
);
157 ImageIdCurrent
= (UINT16
) (ImageIdCurrent
+ Length8
);
160 case EFI_HII_IIBT_SKIP2
:
161 CopyMem (&Length16
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
162 ImageBlock
+= sizeof (EFI_HII_IIBT_SKIP2_BLOCK
);
163 ImageIdCurrent
= (UINT16
) (ImageIdCurrent
+ Length16
);
168 // Unknown image blocks can not be skipped, processing halts.
175 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
178 *ImageId
= ImageIdCurrent
;
188 Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
190 This is a internal function.
193 @param BitMapOut Pixels in EFI_HII_RGB_PIXEL format.
194 @param BitMapIn Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
195 @param PixelNum The number of pixels to be converted.
201 OUT EFI_HII_RGB_PIXEL
*BitMapOut
,
202 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapIn
,
208 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
210 for (Index
= 0; Index
< PixelNum
; Index
++) {
211 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
217 Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
219 This is a internal function.
222 @param BitMapOut Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
223 @param BitMapIn Pixels in EFI_HII_RGB_PIXEL format.
224 @param PixelNum The number of pixels to be converted.
230 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapOut
,
231 IN EFI_HII_RGB_PIXEL
*BitMapIn
,
237 ASSERT (BitMapOut
!= NULL
&& BitMapIn
!= NULL
);
239 for (Index
= 0; Index
< PixelNum
; Index
++) {
240 CopyMem (BitMapOut
+ Index
, BitMapIn
+ Index
, sizeof (EFI_HII_RGB_PIXEL
));
246 Output pixels in "1 bit per pixel" format to an image.
248 This is a internal function.
251 @param Image Points to the image which will store the pixels.
252 @param Data Stores the value of output pixels, 0 or 1.
253 @param PaletteInfo PaletteInfo which stores the color of the output
254 pixels. First entry corresponds to color 0 and
255 second one to color 1.
261 IN OUT EFI_IMAGE_INPUT
*Image
,
263 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
270 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
271 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[2];
272 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
276 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
278 BitMapPtr
= Image
->Bitmap
;
281 // First entry corresponds to color 0 and second entry corresponds to color 1.
283 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
284 PaletteSize
+= sizeof (UINT16
);
285 Palette
= AllocateZeroPool (PaletteSize
);
286 ASSERT (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);
292 SafeFreePool (Palette
);
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.
368 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
369 PaletteSize
+= sizeof (UINT16
);
370 Palette
= AllocateZeroPool (PaletteSize
);
371 ASSERT (Palette
!= NULL
);
372 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
373 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
375 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
376 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
377 SafeFreePool (Palette
);
380 // Convert the pixel from 4 bit to corresponding color.
382 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
383 OffsetY
= BITMAP_LEN_4_BIT (Image
->Width
, Ypos
);
385 // All bits in these bytes are meaningful
387 for (Xpos
= 0; Xpos
< Image
->Width
/ 2; Xpos
++) {
388 Byte
= *(Data
+ OffsetY
+ Xpos
);
389 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
390 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2 + 1] = PaletteValue
[Byte
& 0x0F];
393 if (Image
->Width
% 2 != 0) {
395 // Padding bits in this byte should be ignored.
397 Byte
= *(Data
+ OffsetY
+ Xpos
);
398 BitMapPtr
[Ypos
* Image
->Width
+ Xpos
* 2] = PaletteValue
[Byte
>> 4];
405 Output pixels in "8 bit per pixel" format to an image.
407 This is a internal function.
410 @param Image Points to the image which will store the pixels.
411 @param Data Stores the value of output pixels, 0 ~ 255.
412 @param[in] PaletteInfo PaletteInfo which stores the color of the output
413 pixels. Each entry corresponds to a color within
420 IN OUT EFI_IMAGE_INPUT
*Image
,
422 IN EFI_HII_IMAGE_PALETTE_INFO
*PaletteInfo
428 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
429 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue
[256];
430 EFI_HII_IMAGE_PALETTE_INFO
*Palette
;
435 ASSERT (Image
!= NULL
&& Data
!= NULL
&& PaletteInfo
!= NULL
);
437 BitMapPtr
= Image
->Bitmap
;
440 // The bitmap should allocate each color index starting from 0.
442 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
443 PaletteSize
+= sizeof (UINT16
);
444 Palette
= AllocateZeroPool (PaletteSize
);
445 ASSERT (Palette
!= NULL
);
446 CopyMem (Palette
, PaletteInfo
, PaletteSize
);
447 PaletteNum
= (UINT16
)(Palette
->PaletteSize
/ sizeof (EFI_HII_RGB_PIXEL
));
448 ZeroMem (PaletteValue
, sizeof (PaletteValue
));
449 CopyRgbToGopPixel (PaletteValue
, Palette
->PaletteValue
, PaletteNum
);
450 SafeFreePool (Palette
);
453 // Convert the pixel from 8 bits to corresponding color.
455 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
456 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
458 // All bits are meaningful since the bitmap is 8 bits per pixel.
460 for (Xpos
= 0; Xpos
< Image
->Width
; Xpos
++) {
461 Byte
= *(Data
+ OffsetY
+ Xpos
);
462 BitMapPtr
[OffsetY
+ Xpos
] = PaletteValue
[Byte
];
470 Output pixels in "24 bit per pixel" format to an image.
472 This is a internal function.
475 @param Image Points to the image which will store the pixels.
476 @param Data Stores the color of output pixels, allowing 16.8
483 IN OUT EFI_IMAGE_INPUT
*Image
,
484 IN EFI_HII_RGB_PIXEL
*Data
489 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BitMapPtr
;
491 ASSERT (Image
!= NULL
&& Data
!= NULL
);
493 BitMapPtr
= Image
->Bitmap
;
495 for (Ypos
= 0; Ypos
< Image
->Height
; Ypos
++) {
496 OffsetY
= BITMAP_LEN_8_BIT (Image
->Width
, Ypos
);
497 CopyRgbToGopPixel (&BitMapPtr
[OffsetY
], &Data
[OffsetY
], Image
->Width
);
504 Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
506 This is a internal function.
509 @param BltBuffer Buffer points to bitmap data of incoming image.
510 @param BltX Specifies the offset from the left and top edge of
511 the output image of the first pixel in the image.
512 @param BltY Specifies the offset from the left and top edge of
513 the output image of the first pixel in the image.
514 @param Width Width of the incoming image, in pixels.
515 @param Height Height of the incoming image, in pixels.
516 @param Transparent If TRUE, all "off" pixels in the image will be
517 drawn using the pixel value from blt and all other
518 pixels will be copied.
519 @param Blt Buffer points to bitmap data of output image.
521 @retval EFI_SUCCESS The image was successfully converted.
522 @retval EFI_INVALID_PARAMETER Any incoming parameter is invalid.
527 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
,
532 IN BOOLEAN Transparent
,
533 IN OUT EFI_IMAGE_OUTPUT
**Blt
536 EFI_IMAGE_OUTPUT
*ImageOut
;
539 UINTN OffsetY1
; // src buffer
540 UINTN OffsetY2
; // dest buffer
541 EFI_GRAPHICS_OUTPUT_BLT_PIXEL SrcPixel
;
542 EFI_GRAPHICS_OUTPUT_BLT_PIXEL ZeroPixel
;
544 if (BltBuffer
== NULL
|| Blt
== NULL
|| *Blt
== NULL
) {
545 return EFI_INVALID_PARAMETER
;
550 if (Width
+ BltX
> ImageOut
->Width
) {
551 return EFI_INVALID_PARAMETER
;
553 if (Height
+ BltY
> ImageOut
->Height
) {
554 return EFI_INVALID_PARAMETER
;
557 ZeroMem (&ZeroPixel
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
559 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
560 OffsetY1
= Width
* Ypos
;
561 OffsetY2
= ImageOut
->Width
* (BltY
+ Ypos
);
562 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
563 SrcPixel
= BltBuffer
[OffsetY1
+ Xpos
];
565 if (CompareMem (&SrcPixel
, &ZeroPixel
, 3) != 0) {
566 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
569 ImageOut
->Image
.Bitmap
[OffsetY2
+ BltX
+ Xpos
] = SrcPixel
;
579 This function adds the image Image to the group of images owned by PackageList, and returns
580 a new image identifier (ImageId).
582 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
583 @param PackageList Handle of the package list where this image will
585 @param ImageId On return, contains the new image id, which is
586 unique within PackageList.
587 @param Image Points to the image.
589 @retval EFI_SUCCESS The new image was added successfully.
590 @retval EFI_NOT_FOUND The specified PackageList could not be found in
592 @retval EFI_OUT_OF_RESOURCES Could not add the image due to lack of resources.
593 @retval EFI_INVALID_PARAMETER Image is NULL or ImageId is NULL.
599 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
600 IN EFI_HII_HANDLE PackageList
,
601 OUT EFI_IMAGE_ID
*ImageId
,
602 IN CONST EFI_IMAGE_INPUT
*Image
605 HII_DATABASE_PRIVATE_DATA
*Private
;
607 HII_DATABASE_RECORD
*DatabaseRecord
;
608 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
609 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
615 EFI_IMAGE_INPUT
*ImageIn
;
617 if (This
== NULL
|| ImageId
== NULL
|| Image
== NULL
|| Image
->Bitmap
== NULL
) {
618 return EFI_INVALID_PARAMETER
;
621 if (!IsHiiHandleValid (PackageList
)) {
622 return EFI_NOT_FOUND
;
625 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
628 // Get the specified package list
631 PackageListNode
= NULL
;
633 for (Link
= Private
->DatabaseList
.ForwardLink
;
634 Link
!= &Private
->DatabaseList
;
635 Link
= Link
->ForwardLink
637 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
638 if (DatabaseRecord
->Handle
== PackageList
) {
639 PackageListNode
= DatabaseRecord
->PackageList
;
644 if (PackageListNode
== NULL
) {
645 return EFI_NOT_FOUND
;
648 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
650 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
651 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
654 // Get the image package in the package list,
655 // or create a new image package if image package does not exist.
657 if (PackageListNode
->ImagePkg
!= NULL
) {
658 ImagePackage
= PackageListNode
->ImagePkg
;
661 // Output the image id of the incoming image being inserted, which is the
662 // image id of the EFI_HII_IIBT_END block of old image package.
665 GetImageIdOrAddress (ImagePackage
->ImageBlock
, ImageId
);
668 // Update the package's image block by appending the new block to the end.
670 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
;
671 ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
672 if (ImageBlock
== NULL
) {
673 return EFI_OUT_OF_RESOURCES
;
676 // Copy the original content.
680 ImagePackage
->ImageBlock
,
681 ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
)
683 SafeFreePool (ImagePackage
->ImageBlock
);
684 ImagePackage
->ImageBlock
= ImageBlock
;
685 ImageBlock
+= ImagePackage
->ImageBlockSize
- sizeof (EFI_HII_IIBT_END_BLOCK
);
687 // Temp memory to store new block.
689 NewBlock
= AllocateZeroPool (NewBlockSize
);
690 if (NewBlock
== NULL
) {
691 SafeFreePool (ImagePackage
->ImageBlock
);
692 ImagePackage
->ImageBlock
= NULL
;
693 return EFI_OUT_OF_RESOURCES
;
695 NewBlockPtr
= NewBlock
;
698 // Update the length record.
700 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
701 ImagePackage
->ImagePkgHdr
.Header
.Length
+= (UINT32
) NewBlockSize
;
702 PackageListNode
->PackageListHdr
.PackageLength
+= (UINT32
) NewBlockSize
;
706 // The specified package list does not contain image package.
707 // Create one to add this image block.
709 ImagePackage
= (HII_IMAGE_PACKAGE_INSTANCE
*) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE
));
710 if (ImagePackage
== NULL
) {
711 return EFI_OUT_OF_RESOURCES
;
714 // Output the image id of the incoming image being inserted, which is the
715 // first image block so that id is initially to one.
718 BlockSize
= sizeof (EFI_HII_IIBT_END_BLOCK
) + NewBlockSize
;
720 // Fill in image package header.
722 ImagePackage
->ImagePkgHdr
.Header
.Length
= (UINT32
) BlockSize
+ sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
723 ImagePackage
->ImagePkgHdr
.Header
.Type
= EFI_HII_PACKAGE_IMAGES
;
724 ImagePackage
->ImagePkgHdr
.ImageInfoOffset
= sizeof (EFI_HII_IMAGE_PACKAGE_HDR
);
725 ImagePackage
->ImagePkgHdr
.PaletteInfoOffset
= 0;
728 // Fill in palette info.
730 ImagePackage
->PaletteBlock
= NULL
;
731 ImagePackage
->PaletteInfoSize
= 0;
734 // Fill in image blocks.
736 ImagePackage
->ImageBlockSize
= (UINT32
) BlockSize
;
737 ImagePackage
->ImageBlock
= (UINT8
*) AllocateZeroPool (BlockSize
);
738 if (ImagePackage
->ImageBlock
== NULL
) {
739 SafeFreePool (ImagePackage
);
740 return EFI_OUT_OF_RESOURCES
;
742 ImageBlock
= ImagePackage
->ImageBlock
;
745 // Temp memory to store new block.
747 NewBlock
= AllocateZeroPool (NewBlockSize
);
748 if (NewBlock
== NULL
) {
749 SafeFreePool (ImagePackage
->ImageBlock
);
750 SafeFreePool (ImagePackage
);
751 return EFI_OUT_OF_RESOURCES
;
753 NewBlockPtr
= NewBlock
;
756 // Insert this image package.
758 PackageListNode
->ImagePkg
= ImagePackage
;
759 PackageListNode
->PackageListHdr
.PackageLength
+= ImagePackage
->ImagePkgHdr
.Header
.Length
;
763 // Append the new block here
765 if (ImageIn
->Flags
== EFI_IMAGE_TRANSPARENT
) {
766 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
768 *NewBlock
= EFI_HII_IIBT_IMAGE_24BIT
;
771 CopyMem (NewBlock
, &ImageIn
->Width
, sizeof (UINT16
));
772 NewBlock
+= sizeof (UINT16
);
773 CopyMem (NewBlock
, &ImageIn
->Height
, sizeof (UINT16
));
774 NewBlock
+= sizeof (UINT16
);
775 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlock
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
777 CopyMem (ImageBlock
, NewBlockPtr
, NewBlockSize
);
778 SafeFreePool (NewBlockPtr
);
781 // Append the block end
783 ImageBlock
+= NewBlockSize
;
784 ((EFI_HII_IIBT_END_BLOCK
*) (ImageBlock
))->Header
.BlockType
= EFI_HII_IIBT_END
;
791 This function retrieves the image specified by ImageId which is associated with
792 the specified PackageList and copies it into the buffer specified by Image.
794 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
795 @param PackageList Handle of the package list where this image will
797 @param ImageId The image's id,, which is unique within
799 @param Image Points to the image.
801 @retval EFI_SUCCESS The new image was returned successfully.
802 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
803 database. The specified PackageList is not in the database.
804 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to
806 @retval EFI_INVALID_PARAMETER The Image or ImageSize was NULL.
807 @retval EFI_OUT_OF_RESOURCES The bitmap could not be retrieved because there was not
814 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
815 IN EFI_HII_HANDLE PackageList
,
816 IN EFI_IMAGE_ID ImageId
,
817 OUT EFI_IMAGE_INPUT
*Image
820 HII_DATABASE_PRIVATE_DATA
*Private
;
822 HII_DATABASE_RECORD
*DatabaseRecord
;
823 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
824 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
826 EFI_IMAGE_ID LocalImageId
;
828 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
837 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1) {
838 return EFI_INVALID_PARAMETER
;
841 if (!IsHiiHandleValid (PackageList
)) {
842 return EFI_NOT_FOUND
;
845 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
848 // Get the specified package list and image package.
850 PackageListNode
= NULL
;
851 for (Link
= Private
->DatabaseList
.ForwardLink
;
852 Link
!= &Private
->DatabaseList
;
853 Link
= Link
->ForwardLink
855 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
856 if (DatabaseRecord
->Handle
== PackageList
) {
857 PackageListNode
= DatabaseRecord
->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 LocalImageId
= ImageId
;
873 ImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
874 if (ImageBlock
== NULL
) {
875 return EFI_NOT_FOUND
;
879 BlockType
= *ImageBlock
;
882 case EFI_HII_IIBT_IMAGE_JPEG
:
884 // BUGBUG: need to be supported as soon as image tool is designed.
886 return EFI_UNSUPPORTED
;
889 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
890 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
891 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
896 case EFI_HII_IIBT_IMAGE_1BIT
:
897 case EFI_HII_IIBT_IMAGE_4BIT
:
898 case EFI_HII_IIBT_IMAGE_8BIT
:
900 // Use the common block code since the definition of these structures is the same.
902 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
903 ImageLength
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) *
904 (Iibt1bit
.Bitmap
.Width
* Iibt1bit
.Bitmap
.Height
);
905 Image
->Bitmap
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (ImageLength
);
906 if (Image
->Bitmap
== NULL
) {
907 return EFI_OUT_OF_RESOURCES
;
911 Image
->Flags
= EFI_IMAGE_TRANSPARENT
;
913 Image
->Width
= Iibt1bit
.Bitmap
.Width
;
914 Image
->Height
= Iibt1bit
.Bitmap
.Height
;
916 PaletteInfo
= ImagePackage
->PaletteBlock
+ sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER
);
917 for (PaletteIndex
= 1; PaletteIndex
< Iibt1bit
.PaletteIndex
; PaletteIndex
++) {
918 CopyMem (&PaletteSize
, PaletteInfo
, sizeof (UINT16
));
919 PaletteInfo
+= PaletteSize
+ sizeof (UINT16
);
921 ASSERT (PaletteIndex
== Iibt1bit
.PaletteIndex
);
924 // Output bitmap data
926 if (BlockType
== EFI_HII_IIBT_IMAGE_1BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_1BIT_TRANS
) {
929 (UINT8
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
)),
930 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
932 } else if (BlockType
== EFI_HII_IIBT_IMAGE_4BIT
|| BlockType
== EFI_HII_IIBT_IMAGE_4BIT_TRANS
) {
935 (UINT8
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
)),
936 (EFI_HII_IMAGE_PALETTE_INFO
*) PaletteInfo
941 (UINT8
*) (ImageBlock
+ sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
)),
942 (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
))
984 return EFI_NOT_FOUND
;
991 This function updates the image specified by ImageId in the specified PackageListHandle to
992 the image specified by Image.
994 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
995 @param PackageList The package list containing the images.
996 @param ImageId The image's id,, which is unique within
998 @param Image Points to the image.
1000 @retval EFI_SUCCESS The new image was updated successfully.
1001 @retval EFI_NOT_FOUND The image specified by ImageId is not in the
1002 database. The specified PackageList is not in the database.
1003 @retval EFI_INVALID_PARAMETER The Image was NULL.
1009 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1010 IN EFI_HII_HANDLE PackageList
,
1011 IN EFI_IMAGE_ID ImageId
,
1012 IN CONST EFI_IMAGE_INPUT
*Image
1015 HII_DATABASE_PRIVATE_DATA
*Private
;
1017 HII_DATABASE_RECORD
*DatabaseRecord
;
1018 HII_DATABASE_PACKAGE_LIST_INSTANCE
*PackageListNode
;
1019 HII_IMAGE_PACKAGE_INSTANCE
*ImagePackage
;
1021 EFI_IMAGE_ID LocalImageId
;
1023 EFI_HII_IIBT_IMAGE_1BIT_BLOCK Iibt1bit
;
1024 EFI_HII_IIBT_IMAGE_4BIT_BLOCK Iibt4bit
;
1025 EFI_HII_IIBT_IMAGE_8BIT_BLOCK Iibt8bit
;
1029 UINT32 NewBlockSize
;
1030 UINT32 OldBlockSize
;
1031 EFI_IMAGE_INPUT
*ImageIn
;
1039 if (This
== NULL
|| Image
== NULL
|| ImageId
< 1 || Image
->Bitmap
== NULL
) {
1040 return EFI_INVALID_PARAMETER
;
1043 if (!IsHiiHandleValid (PackageList
)) {
1044 return EFI_NOT_FOUND
;
1047 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1050 // Get the specified package list and image package.
1052 PackageListNode
= NULL
;
1053 for (Link
= Private
->DatabaseList
.ForwardLink
;
1054 Link
!= &Private
->DatabaseList
;
1055 Link
= Link
->ForwardLink
1057 DatabaseRecord
= CR (Link
, HII_DATABASE_RECORD
, DatabaseEntry
, HII_DATABASE_RECORD_SIGNATURE
);
1058 if (DatabaseRecord
->Handle
== PackageList
) {
1059 PackageListNode
= DatabaseRecord
->PackageList
;
1063 if (PackageListNode
== NULL
) {
1064 return EFI_NOT_FOUND
;
1066 ImagePackage
= PackageListNode
->ImagePkg
;
1067 if (ImagePackage
== NULL
) {
1068 return EFI_NOT_FOUND
;
1072 // Find the image block specified by ImageId
1074 LocalImageId
= ImageId
;
1075 ImageBlock
= GetImageIdOrAddress (ImagePackage
->ImageBlock
, &LocalImageId
);
1076 if (ImageBlock
== NULL
) {
1077 return EFI_NOT_FOUND
;
1080 BlockType
= *ImageBlock
;
1083 // Get the size of original image block. Use some common block code here
1084 // since the definition of some structures is the same.
1086 switch (BlockType
) {
1087 case EFI_HII_IIBT_IMAGE_JPEG
:
1089 // BUGBUG: need to be supported as soon as image tool is designed.
1091 return EFI_UNSUPPORTED
;
1094 case EFI_HII_IIBT_IMAGE_1BIT
:
1095 case EFI_HII_IIBT_IMAGE_1BIT_TRANS
:
1096 CopyMem (&Iibt1bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
));
1097 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK
) - sizeof (UINT8
) +
1098 BITMAP_LEN_1_BIT (Iibt1bit
.Bitmap
.Width
, Iibt1bit
.Bitmap
.Height
);
1100 case EFI_HII_IIBT_IMAGE_4BIT
:
1101 case EFI_HII_IIBT_IMAGE_4BIT_TRANS
:
1102 CopyMem (&Iibt4bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
));
1103 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK
) - sizeof (UINT8
) +
1104 BITMAP_LEN_4_BIT (Iibt4bit
.Bitmap
.Width
, Iibt4bit
.Bitmap
.Height
);
1106 case EFI_HII_IIBT_IMAGE_8BIT
:
1107 case EFI_HII_IIBT_IMAGE_8BIT_TRANS
:
1108 CopyMem (&Iibt8bit
, ImageBlock
, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
));
1109 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK
) - sizeof (UINT8
) +
1110 BITMAP_LEN_8_BIT (Iibt8bit
.Bitmap
.Width
, Iibt8bit
.Bitmap
.Height
);
1112 case EFI_HII_IIBT_IMAGE_24BIT
:
1113 case EFI_HII_IIBT_IMAGE_24BIT_TRANS
:
1114 CopyMem (&Width
, ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
), sizeof (UINT16
));
1117 ImageBlock
+ sizeof (EFI_HII_IMAGE_BLOCK
) + sizeof (UINT16
),
1120 OldBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1121 BITMAP_LEN_24_BIT (Width
, Height
);
1124 return EFI_NOT_FOUND
;
1129 // Create the new image block according to input image.
1131 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1132 NewBlockSize
= sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK
) - sizeof (EFI_HII_RGB_PIXEL
) +
1133 BITMAP_LEN_24_BIT (ImageIn
->Width
, ImageIn
->Height
);
1134 NewBlock
= (UINT8
*) AllocateZeroPool (NewBlockSize
);
1135 if (NewBlock
== NULL
) {
1136 return EFI_OUT_OF_RESOURCES
;
1139 NewBlockPtr
= NewBlock
;
1140 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1141 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT_TRANS
;
1143 *NewBlockPtr
= EFI_HII_IIBT_IMAGE_24BIT
;
1147 CopyMem (NewBlockPtr
, &ImageIn
->Width
, sizeof (UINT16
));
1148 NewBlockPtr
+= sizeof (UINT16
);
1149 CopyMem (NewBlockPtr
, &ImageIn
->Height
, sizeof (UINT16
));
1150 NewBlockPtr
+= sizeof (UINT16
);
1152 CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL
*) NewBlockPtr
, ImageIn
->Bitmap
, ImageIn
->Width
* ImageIn
->Height
);
1155 // Adjust the image package to remove the original block firstly then add the new block.
1157 BlockSize
= ImagePackage
->ImageBlockSize
+ NewBlockSize
- OldBlockSize
;
1158 Block
= (UINT8
*) AllocateZeroPool (BlockSize
);
1159 if (Block
== NULL
) {
1160 SafeFreePool (NewBlock
);
1161 return EFI_OUT_OF_RESOURCES
;
1165 Part1Size
= (UINT32
) (ImageBlock
- ImagePackage
->ImageBlock
);
1166 Part2Size
= ImagePackage
->ImageBlockSize
- Part1Size
- OldBlockSize
;
1167 CopyMem (BlockPtr
, ImagePackage
->ImageBlock
, Part1Size
);
1168 BlockPtr
+= Part1Size
;
1169 CopyMem (BlockPtr
, NewBlock
, NewBlockSize
);
1170 BlockPtr
+= NewBlockSize
;
1171 CopyMem (BlockPtr
, ImageBlock
+ OldBlockSize
, Part2Size
);
1173 SafeFreePool (ImagePackage
->ImageBlock
);
1174 SafeFreePool (NewBlock
);
1175 ImagePackage
->ImageBlock
= Block
;
1176 ImagePackage
->ImageBlockSize
= BlockSize
;
1177 ImagePackage
->ImagePkgHdr
.Header
.Length
+= NewBlockSize
- OldBlockSize
;
1178 PackageListNode
->PackageListHdr
.PackageLength
+= NewBlockSize
- OldBlockSize
;
1186 This function renders an image to a bitmap or the screen using the specified
1187 color and options. It draws the image on an existing bitmap, allocates a new
1188 bitmap or uses the screen. The images can be clipped.
1190 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1191 @param Flags Describes how the image is to be drawn.
1192 @param Image Points to the image to be displayed.
1193 @param Blt If this points to a non-NULL on entry, this points
1194 to the image, which is Width pixels wide and
1195 Height pixels high. The image will be drawn onto
1196 this image and EFI_HII_DRAW_FLAG_CLIP is implied.
1197 If this points to a NULL on entry, then a buffer
1198 will be allocated to hold the generated image and
1199 the pointer updated on exit. It is the caller's
1200 responsibility to free this buffer.
1201 @param BltX Specifies the offset from the left and top edge of
1202 the output image of the first pixel in the image.
1203 @param BltY Specifies the offset from the left and top edge of
1204 the output image of the first pixel in the image.
1206 @retval EFI_SUCCESS The image was successfully drawn.
1207 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1208 @retval EFI_INVALID_PARAMETER The Image or Blt was NULL.
1209 @retval EFI_INVALID_PARAMETER Any combination of Flags is invalid.
1215 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1216 IN EFI_HII_DRAW_FLAGS Flags
,
1217 IN CONST EFI_IMAGE_INPUT
*Image
,
1218 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1224 HII_DATABASE_PRIVATE_DATA
*Private
;
1225 BOOLEAN Transparent
;
1226 EFI_IMAGE_INPUT
*ImageIn
;
1227 EFI_IMAGE_OUTPUT
*ImageOut
;
1228 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
;
1236 EFI_FONT_DISPLAY_INFO
*FontInfo
;
1238 EFI_CONSOLE_CONTROL_PROTOCOL
*Console
;
1240 if (This
== NULL
|| Image
== NULL
|| Blt
== NULL
) {
1241 return EFI_INVALID_PARAMETER
;
1244 if ((Flags
& EFI_HII_DRAW_FLAG_CLIP
) == EFI_HII_DRAW_FLAG_CLIP
&& *Blt
== NULL
) {
1245 return EFI_INVALID_PARAMETER
;
1248 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_TRANSPARENT
) {
1249 return EFI_INVALID_PARAMETER
;
1252 ImageIn
= (EFI_IMAGE_INPUT
*) Image
;
1255 // Check whether the image will be drawn transparently or opaquely.
1257 Transparent
= FALSE
;
1258 if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_TRANS
) {
1260 } else if ((Flags
& EFI_HII_DRAW_FLAG_TRANSPARENT
) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE
){
1261 Transparent
= FALSE
;
1264 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1265 // on the image's transparency setting.
1267 if ((ImageIn
->Flags
& EFI_IMAGE_TRANSPARENT
) == EFI_IMAGE_TRANSPARENT
) {
1273 // Image cannot be drawn transparently if Blt points to NULL on entry.
1274 // Currently output to Screen transparently is not supported, either.
1278 return EFI_INVALID_PARAMETER
;
1279 } else if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1280 return EFI_INVALID_PARAMETER
;
1284 Private
= HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This
);
1287 // When Blt points to a non-NULL on entry, this image will be drawn onto
1288 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1289 // Otherwise a new bitmap will be allocated to hold this image.
1293 // Clip the image by (Width, Height)
1296 Width
= ImageIn
->Width
;
1297 Height
= ImageIn
->Height
;
1299 if (Width
> (*Blt
)->Width
- BltX
) {
1300 Width
= (*Blt
)->Width
- BltX
;
1302 if (Height
> (*Blt
)->Height
- BltY
) {
1303 Height
= (*Blt
)->Height
- BltY
;
1306 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1307 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1308 if (BltBuffer
== NULL
) {
1309 return EFI_OUT_OF_RESOURCES
;
1312 if (Width
== ImageIn
->Width
&& Height
== ImageIn
->Height
) {
1313 CopyMem (BltBuffer
, ImageIn
->Bitmap
, BufferLen
);
1315 for (Ypos
= 0; Ypos
< Height
; Ypos
++) {
1316 OffsetY1
= ImageIn
->Width
* Ypos
;
1317 OffsetY2
= Width
* Ypos
;
1318 for (Xpos
= 0; Xpos
< Width
; Xpos
++) {
1319 BltBuffer
[OffsetY2
+ Xpos
] = ImageIn
->Bitmap
[OffsetY1
+ Xpos
];
1325 // Draw the image to existing bitmap or screen depending on flag.
1327 if ((Flags
& EFI_HII_DIRECT_TO_SCREEN
) == EFI_HII_DIRECT_TO_SCREEN
) {
1328 Status
= gBS
->LocateProtocol (
1329 &gEfiConsoleControlProtocolGuid
,
1334 if (EFI_ERROR (Status
)) {
1338 Console
->SetMode (Console
, EfiConsoleControlScreenGraphics
);
1340 // Write the image directly to the output device specified by Screen.
1342 Status
= (*Blt
)->Image
.Screen
->Blt (
1343 (*Blt
)->Image
.Screen
,
1345 EfiBltBufferToVideo
,
1356 // Draw the image onto the existing bitmap specified by Bitmap.
1358 Status
= ImageToBlt (
1370 SafeFreePool (BltBuffer
);
1375 // Allocate a new bitmap to hold the incoming image.
1377 Width
= ImageIn
->Width
+ BltX
;
1378 Height
= ImageIn
->Height
+ BltY
;
1380 BufferLen
= Width
* Height
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
);
1381 BltBuffer
= (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*) AllocateZeroPool (BufferLen
);
1382 if (BltBuffer
== NULL
) {
1383 return EFI_OUT_OF_RESOURCES
;
1386 ImageOut
= (EFI_IMAGE_OUTPUT
*) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
1387 if (ImageOut
== NULL
) {
1388 SafeFreePool (BltBuffer
);
1389 return EFI_OUT_OF_RESOURCES
;
1391 ImageOut
->Width
= (UINT16
) Width
;
1392 ImageOut
->Height
= (UINT16
) Height
;
1393 ImageOut
->Image
.Bitmap
= BltBuffer
;
1396 // BUGBUG: Now all the "blank" pixels are filled with system default background
1397 // color. Not sure if it need to be updated or not.
1399 Status
= GetSystemFont (Private
, &FontInfo
, NULL
);
1400 if (EFI_ERROR (Status
)) {
1401 SafeFreePool (BltBuffer
);
1402 SafeFreePool (ImageOut
);
1405 for (Index
= 0; Index
< Width
* Height
; Index
++) {
1406 BltBuffer
[Index
] = FontInfo
->BackgroundColor
;
1408 SafeFreePool (FontInfo
);
1411 // Draw the incoming image to the new created image.
1429 This function renders an image to a bitmap or the screen using the specified
1430 color and options. It draws the image on an existing bitmap, allocates a new
1431 bitmap or uses the screen. The images can be clipped.
1433 @param This A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
1434 @param Flags Describes how the image is to be drawn.
1435 @param PackageList The package list in the HII database to search for
1436 the specified image.
1437 @param ImageId The image's id, which is unique within
1439 @param Blt If this points to a non-NULL on entry, this points
1440 to the image, which is Width pixels wide and
1441 Height pixels high. The image will be drawn onto
1443 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
1444 to a NULL on entry, then a buffer will be
1445 allocated to hold the generated image and the
1446 pointer updated on exit. It is the caller's
1447 responsibility to free this buffer.
1448 @param BltX Specifies the offset from the left and top edge of
1449 the output image of the first pixel in the image.
1450 @param BltY Specifies the offset from the left and top edge of
1451 the output image of the first pixel in the image.
1453 @retval EFI_SUCCESS The image was successfully drawn.
1454 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for Blt.
1455 @retval EFI_INVALID_PARAMETER The Blt was NULL.
1456 @retval EFI_NOT_FOUND The image specified by ImageId is not in the database.
1457 The specified PackageList is not in the database.
1463 IN CONST EFI_HII_IMAGE_PROTOCOL
*This
,
1464 IN EFI_HII_DRAW_FLAGS Flags
,
1465 IN EFI_HII_HANDLE PackageList
,
1466 IN EFI_IMAGE_ID ImageId
,
1467 IN OUT EFI_IMAGE_OUTPUT
**Blt
,
1473 EFI_IMAGE_INPUT Image
;
1476 // Check input parameter.
1478 if (This
== NULL
|| Blt
== NULL
) {
1479 return EFI_INVALID_PARAMETER
;
1482 if (!IsHiiHandleValid (PackageList
)) {
1483 return EFI_NOT_FOUND
;
1487 // Get the specified Image.
1489 Status
= HiiGetImage (This
, PackageList
, ImageId
, &Image
);
1490 if (EFI_ERROR (Status
)) {
1497 Status
= HiiDrawImage (This
, Flags
, &Image
, Blt
, BltX
, BltY
);
1498 SafeFreePool (Image
.Bitmap
);