TianoCore EDK2 master
Loading...
Searching...
No Matches
Image.c
Go to the documentation of this file.
1
10#include "HiiDatabase.h"
11
12#define MAX_UINT24 0xFFFFFF
13
30 IN EFI_HII_IMAGE_BLOCK *ImageBlocks,
31 IN OUT EFI_IMAGE_ID *ImageId
32 )
33{
34 EFI_IMAGE_ID ImageIdCurrent;
35 EFI_HII_IMAGE_BLOCK *CurrentImageBlock;
36 UINTN Length;
37
38 ASSERT (ImageBlocks != NULL && ImageId != NULL);
39 CurrentImageBlock = ImageBlocks;
40 ImageIdCurrent = 1;
41
42 while (CurrentImageBlock->BlockType != EFI_HII_IIBT_END) {
43 if (*ImageId != 0) {
44 if (*ImageId == ImageIdCurrent) {
45 //
46 // If the found image block is a duplicate block, update the ImageId to
47 // find the previous defined image block.
48 //
49 if (CurrentImageBlock->BlockType == EFI_HII_IIBT_DUPLICATE) {
50 *ImageId = ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_DUPLICATE_BLOCK *)CurrentImageBlock)->ImageId);
51 ASSERT (*ImageId != ImageIdCurrent);
52 ASSERT (*ImageId != 0);
53 CurrentImageBlock = ImageBlocks;
54 ImageIdCurrent = 1;
55 continue;
56 }
57
58 return CurrentImageBlock;
59 }
60
61 if (*ImageId < ImageIdCurrent) {
62 //
63 // Can not find the specified image block in this image.
64 //
65 return NULL;
66 }
67 }
68
69 switch (CurrentImageBlock->BlockType) {
70 case EFI_HII_IIBT_EXT1:
71 Length = ((EFI_HII_IIBT_EXT1_BLOCK *)CurrentImageBlock)->Length;
72 break;
73 case EFI_HII_IIBT_EXT2:
74 Length = ReadUnaligned16 (&((EFI_HII_IIBT_EXT2_BLOCK *)CurrentImageBlock)->Length);
75 break;
76 case EFI_HII_IIBT_EXT4:
77 Length = ReadUnaligned32 ((VOID *)&((EFI_HII_IIBT_EXT4_BLOCK *)CurrentImageBlock)->Length);
78 break;
79
80 case EFI_HII_IIBT_IMAGE_1BIT:
81 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
82 Length = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +
83 BITMAP_LEN_1_BIT (
84 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
85 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
86 );
87 ImageIdCurrent++;
88 break;
89
90 case EFI_HII_IIBT_IMAGE_4BIT:
91 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
92 Length = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +
93 BITMAP_LEN_4_BIT (
94 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
95 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
96 );
97 ImageIdCurrent++;
98 break;
99
100 case EFI_HII_IIBT_IMAGE_8BIT:
101 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
102 Length = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +
103 BITMAP_LEN_8_BIT (
104 (UINT32)ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
105 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
106 );
107 ImageIdCurrent++;
108 break;
109
110 case EFI_HII_IIBT_IMAGE_24BIT:
111 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
112 Length = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
113 BITMAP_LEN_24_BIT (
114 (UINT32)ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
115 ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
116 );
117 ImageIdCurrent++;
118 break;
119
120 case EFI_HII_IIBT_DUPLICATE:
121 Length = sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK);
122 ImageIdCurrent++;
123 break;
124
125 case EFI_HII_IIBT_IMAGE_JPEG:
126 Length = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *)&((EFI_HII_IIBT_JPEG_BLOCK *)CurrentImageBlock)->Size);
127 ImageIdCurrent++;
128 break;
129
130 case EFI_HII_IIBT_IMAGE_PNG:
131 Length = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *)&((EFI_HII_IIBT_PNG_BLOCK *)CurrentImageBlock)->Size);
132 ImageIdCurrent++;
133 break;
134
135 case EFI_HII_IIBT_SKIP1:
136 Length = sizeof (EFI_HII_IIBT_SKIP1_BLOCK);
137 ImageIdCurrent += ((EFI_HII_IIBT_SKIP1_BLOCK *)CurrentImageBlock)->SkipCount;
138 break;
139
140 case EFI_HII_IIBT_SKIP2:
141 Length = sizeof (EFI_HII_IIBT_SKIP2_BLOCK);
142 ImageIdCurrent += ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_SKIP2_BLOCK *)CurrentImageBlock)->SkipCount);
143 break;
144
145 default:
146 //
147 // Unknown image blocks can not be skipped, processing halts.
148 //
149 ASSERT (FALSE);
150 Length = 0;
151 break;
152 }
153
154 CurrentImageBlock = (EFI_HII_IMAGE_BLOCK *)((UINT8 *)CurrentImageBlock + Length);
155 }
156
157 //
158 // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
159 //
160 if (*ImageId == 0) {
161 *ImageId = ImageIdCurrent;
162 return CurrentImageBlock;
163 }
164
165 return NULL;
166}
167
180VOID
182 OUT EFI_HII_RGB_PIXEL *BitMapOut,
184 IN UINTN PixelNum
185 )
186{
187 UINTN Index;
188
189 ASSERT (BitMapOut != NULL && BitMapIn != NULL);
190
191 for (Index = 0; Index < PixelNum; Index++) {
192 CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));
193 }
194}
195
208VOID
211 IN EFI_HII_RGB_PIXEL *BitMapIn,
212 IN UINTN PixelNum
213 )
214{
215 UINTN Index;
216
217 ASSERT (BitMapOut != NULL && BitMapIn != NULL);
218
219 for (Index = 0; Index < PixelNum; Index++) {
220 CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));
221 }
222}
223
238VOID
240 IN OUT EFI_IMAGE_INPUT *Image,
241 IN UINT8 *Data,
242 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo
243 )
244{
245 UINT16 Xpos;
246 UINT16 Ypos;
247 UINTN OffsetY;
248 UINT8 Index;
250 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[2];
252 UINTN PaletteSize;
253 UINT8 Byte;
254
255 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
256
257 BitMapPtr = Image->Bitmap;
258
259 //
260 // First entry corresponds to color 0 and second entry corresponds to color 1.
261 //
262 PaletteSize = 0;
263 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
264 PaletteSize += sizeof (UINT16);
265 Palette = AllocateZeroPool (PaletteSize);
266 ASSERT (Palette != NULL);
267 if (Palette == NULL) {
268 return;
269 }
270
271 CopyMem (Palette, PaletteInfo, PaletteSize);
272
273 ZeroMem (PaletteValue, sizeof (PaletteValue));
274 CopyRgbToGopPixel (&PaletteValue[0], &Palette->PaletteValue[0], 1);
275 CopyRgbToGopPixel (&PaletteValue[1], &Palette->PaletteValue[1], 1);
276 FreePool (Palette);
277
278 //
279 // Convert the pixel from one bit to corresponding color.
280 //
281 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
282 OffsetY = BITMAP_LEN_1_BIT (Image->Width, Ypos);
283 //
284 // All bits in these bytes are meaningful
285 //
286 for (Xpos = 0; Xpos < Image->Width / 8; Xpos++) {
287 Byte = *(Data + OffsetY + Xpos);
288 for (Index = 0; Index < 8; Index++) {
289 if ((Byte & (1 << Index)) != 0) {
290 BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[1];
291 } else {
292 BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[0];
293 }
294 }
295 }
296
297 if (Image->Width % 8 != 0) {
298 //
299 // Padding bits in this byte should be ignored.
300 //
301 Byte = *(Data + OffsetY + Xpos);
302 for (Index = 0; Index < Image->Width % 8; Index++) {
303 if ((Byte & (1 << (8 - Index - 1))) != 0) {
304 BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[1];
305 } else {
306 BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[0];
307 }
308 }
309 }
310 }
311}
312
327VOID
329 IN OUT EFI_IMAGE_INPUT *Image,
330 IN UINT8 *Data,
331 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo
332 )
333{
334 UINT16 Xpos;
335 UINT16 Ypos;
336 UINTN OffsetY;
338 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[16];
340 UINTN PaletteSize;
341 UINT16 PaletteNum;
342 UINT8 Byte;
343
344 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
345
346 BitMapPtr = Image->Bitmap;
347
348 //
349 // The bitmap should allocate each color index starting from 0.
350 //
351 PaletteSize = 0;
352 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
353 PaletteSize += sizeof (UINT16);
354 Palette = AllocateZeroPool (PaletteSize);
355 ASSERT (Palette != NULL);
356 if (Palette == NULL) {
357 return;
358 }
359
360 CopyMem (Palette, PaletteInfo, PaletteSize);
361 PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));
362
363 ZeroMem (PaletteValue, sizeof (PaletteValue));
364 CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, MIN (PaletteNum, ARRAY_SIZE (PaletteValue)));
365 FreePool (Palette);
366
367 //
368 // Convert the pixel from 4 bit to corresponding color.
369 //
370 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
371 OffsetY = BITMAP_LEN_4_BIT (Image->Width, Ypos);
372 //
373 // All bits in these bytes are meaningful
374 //
375 for (Xpos = 0; Xpos < Image->Width / 2; Xpos++) {
376 Byte = *(Data + OffsetY + Xpos);
377 BitMapPtr[Ypos * Image->Width + Xpos * 2] = PaletteValue[Byte >> 4];
378 BitMapPtr[Ypos * Image->Width + Xpos * 2 + 1] = PaletteValue[Byte & 0x0F];
379 }
380
381 if (Image->Width % 2 != 0) {
382 //
383 // Padding bits in this byte should be ignored.
384 //
385 Byte = *(Data + OffsetY + Xpos);
386 BitMapPtr[Ypos * Image->Width + Xpos * 2] = PaletteValue[Byte >> 4];
387 }
388 }
389}
390
405VOID
407 IN OUT EFI_IMAGE_INPUT *Image,
408 IN UINT8 *Data,
409 IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo
410 )
411{
412 UINT16 Xpos;
413 UINT16 Ypos;
414 UINTN OffsetY;
416 EFI_GRAPHICS_OUTPUT_BLT_PIXEL PaletteValue[256];
418 UINTN PaletteSize;
419 UINT16 PaletteNum;
420 UINT8 Byte;
421
422 ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
423
424 BitMapPtr = Image->Bitmap;
425
426 //
427 // The bitmap should allocate each color index starting from 0.
428 //
429 PaletteSize = 0;
430 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
431 PaletteSize += sizeof (UINT16);
432 Palette = AllocateZeroPool (PaletteSize);
433 ASSERT (Palette != NULL);
434 if (Palette == NULL) {
435 return;
436 }
437
438 CopyMem (Palette, PaletteInfo, PaletteSize);
439 PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));
440 ZeroMem (PaletteValue, sizeof (PaletteValue));
441 CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, MIN (PaletteNum, ARRAY_SIZE (PaletteValue)));
442 FreePool (Palette);
443
444 //
445 // Convert the pixel from 8 bits to corresponding color.
446 //
447 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
448 OffsetY = BITMAP_LEN_8_BIT ((UINT32)Image->Width, Ypos);
449 //
450 // All bits are meaningful since the bitmap is 8 bits per pixel.
451 //
452 for (Xpos = 0; Xpos < Image->Width; Xpos++) {
453 Byte = *(Data + OffsetY + Xpos);
454 BitMapPtr[OffsetY + Xpos] = PaletteValue[Byte];
455 }
456 }
457}
458
471VOID
473 IN OUT EFI_IMAGE_INPUT *Image,
475 )
476{
477 UINT16 Ypos;
478 UINTN OffsetY;
480
481 ASSERT (Image != NULL && Data != NULL);
482
483 BitMapPtr = Image->Bitmap;
484
485 for (Ypos = 0; Ypos < Image->Height; Ypos++) {
486 OffsetY = BITMAP_LEN_8_BIT ((UINT32)Image->Width, Ypos);
487 CopyRgbToGopPixel (&BitMapPtr[OffsetY], &Data[OffsetY], Image->Width);
488 }
489}
490
516 IN UINTN BltX,
517 IN UINTN BltY,
518 IN UINTN Width,
519 IN UINTN Height,
520 IN BOOLEAN Transparent,
522 )
523{
524 EFI_IMAGE_OUTPUT *ImageOut;
525 UINTN Xpos;
526 UINTN Ypos;
527 UINTN OffsetY1; // src buffer
528 UINTN OffsetY2; // dest buffer
531
532 if ((BltBuffer == NULL) || (Blt == NULL) || (*Blt == NULL)) {
533 return EFI_INVALID_PARAMETER;
534 }
535
536 ImageOut = *Blt;
537
538 if (Width + BltX > ImageOut->Width) {
539 return EFI_INVALID_PARAMETER;
540 }
541
542 if (Height + BltY > ImageOut->Height) {
543 return EFI_INVALID_PARAMETER;
544 }
545
546 ZeroMem (&ZeroPixel, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
547
548 for (Ypos = 0; Ypos < Height; Ypos++) {
549 OffsetY1 = Width * Ypos;
550 OffsetY2 = ImageOut->Width * (BltY + Ypos);
551 for (Xpos = 0; Xpos < Width; Xpos++) {
552 SrcPixel = BltBuffer[OffsetY1 + Xpos];
553 if (Transparent) {
554 if (CompareMem (&SrcPixel, &ZeroPixel, 3) != 0) {
555 ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;
556 }
557 } else {
558 ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;
559 }
560 }
561 }
562
563 return EFI_SUCCESS;
564}
565
576 IN LIST_ENTRY *Database,
577 IN EFI_HII_HANDLE PackageList
578 )
579{
580 LIST_ENTRY *Link;
581 HII_DATABASE_RECORD *Record;
582
583 //
584 // Get the specified package list and image package.
585 //
586 for (Link = GetFirstNode (Database);
587 !IsNull (Database, Link);
588 Link = GetNextNode (Database, Link)
589 )
590 {
591 Record = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
592 if (Record->Handle == PackageList) {
593 return Record->PackageList;
594 }
595 }
596
597 return NULL;
598}
599
619EFIAPI
622 IN EFI_HII_HANDLE PackageList,
623 OUT EFI_IMAGE_ID *ImageId,
625 )
626{
628 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
629 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
630 EFI_HII_IMAGE_BLOCK *ImageBlocks;
631 UINT32 NewBlockSize;
632
633 if ((This == NULL) || (ImageId == NULL) || (Image == NULL) || (Image->Bitmap == NULL)) {
634 return EFI_INVALID_PARAMETER;
635 }
636
637 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
638 PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);
639 if (PackageListNode == NULL) {
640 return EFI_NOT_FOUND;
641 }
642
643 EfiAcquireLock (&mHiiDatabaseLock);
644
645 //
646 // Calcuate the size of new image.
647 // Make sure the size doesn't overflow UINT32.
648 // Note: 24Bit BMP occpuies 3 bytes per pixel.
649 //
650 NewBlockSize = (UINT32)Image->Width * Image->Height;
651 if (NewBlockSize > (MAX_UINT32 - (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL))) / 3) {
652 EfiReleaseLock (&mHiiDatabaseLock);
653 return EFI_OUT_OF_RESOURCES;
654 }
655
656 NewBlockSize = NewBlockSize * 3 + (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL));
657
658 //
659 // Get the image package in the package list,
660 // or create a new image package if image package does not exist.
661 //
662 if (PackageListNode->ImagePkg != NULL) {
663 ImagePackage = PackageListNode->ImagePkg;
664
665 //
666 // Output the image id of the incoming image being inserted, which is the
667 // image id of the EFI_HII_IIBT_END block of old image package.
668 //
669 *ImageId = 0;
670 GetImageIdOrAddress (ImagePackage->ImageBlock, ImageId);
671
672 //
673 // Update the package's image block by appending the new block to the end.
674 //
675
676 //
677 // Make sure the final package length doesn't overflow.
678 // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
679 //
680 if (NewBlockSize > MAX_UINT24 - ImagePackage->ImagePkgHdr.Header.Length) {
681 EfiReleaseLock (&mHiiDatabaseLock);
682 return EFI_OUT_OF_RESOURCES;
683 }
684
685 //
686 // Because ImagePackage->ImageBlockSize < ImagePackage->ImagePkgHdr.Header.Length,
687 // So (ImagePackage->ImageBlockSize + NewBlockSize) <= MAX_UINT24
688 //
689 ImageBlocks = AllocatePool (ImagePackage->ImageBlockSize + NewBlockSize);
690 if (ImageBlocks == NULL) {
691 EfiReleaseLock (&mHiiDatabaseLock);
692 return EFI_OUT_OF_RESOURCES;
693 }
694
695 //
696 // Copy the original content.
697 //
698 CopyMem (
699 ImageBlocks,
700 ImagePackage->ImageBlock,
701 ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)
702 );
703 FreePool (ImagePackage->ImageBlock);
704 ImagePackage->ImageBlock = ImageBlocks;
705
706 //
707 // Point to the very last block.
708 //
709 ImageBlocks = (EFI_HII_IMAGE_BLOCK *)(
710 (UINT8 *)ImageBlocks + ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)
711 );
712 //
713 // Update the length record.
714 //
715 ImagePackage->ImageBlockSize += NewBlockSize;
716 ImagePackage->ImagePkgHdr.Header.Length += NewBlockSize;
717 PackageListNode->PackageListHdr.PackageLength += NewBlockSize;
718 } else {
719 //
720 // Make sure the final package length doesn't overflow.
721 // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
722 //
723 if (NewBlockSize > MAX_UINT24 - (sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + sizeof (EFI_HII_IIBT_END_BLOCK))) {
724 EfiReleaseLock (&mHiiDatabaseLock);
725 return EFI_OUT_OF_RESOURCES;
726 }
727
728 //
729 // The specified package list does not contain image package.
730 // Create one to add this image block.
731 //
733 if (ImagePackage == NULL) {
734 EfiReleaseLock (&mHiiDatabaseLock);
735 return EFI_OUT_OF_RESOURCES;
736 }
737
738 //
739 // Output the image id of the incoming image being inserted, which is the
740 // first image block so that id is initially to one.
741 //
742 *ImageId = 1;
743 //
744 // Fill in image package header.
745 //
746 ImagePackage->ImagePkgHdr.Header.Length = sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);
747 ImagePackage->ImagePkgHdr.Header.Type = EFI_HII_PACKAGE_IMAGES;
748 ImagePackage->ImagePkgHdr.ImageInfoOffset = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
749 ImagePackage->ImagePkgHdr.PaletteInfoOffset = 0;
750
751 //
752 // Fill in palette info.
753 //
754 ImagePackage->PaletteBlock = NULL;
755 ImagePackage->PaletteInfoSize = 0;
756
757 //
758 // Fill in image blocks.
759 //
760 ImagePackage->ImageBlockSize = NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);
761 ImagePackage->ImageBlock = AllocateZeroPool (NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK));
762 if (ImagePackage->ImageBlock == NULL) {
763 FreePool (ImagePackage);
764 EfiReleaseLock (&mHiiDatabaseLock);
765 return EFI_OUT_OF_RESOURCES;
766 }
767
768 ImageBlocks = ImagePackage->ImageBlock;
769
770 //
771 // Insert this image package.
772 //
773 PackageListNode->ImagePkg = ImagePackage;
774 PackageListNode->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
775 }
776
777 //
778 // Append the new block here
779 //
780 if (Image->Flags == EFI_IMAGE_TRANSPARENT) {
781 ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT_TRANS;
782 } else {
783 ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT;
784 }
785
786 WriteUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)ImageBlocks)->Bitmap.Width, Image->Width);
787 WriteUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)ImageBlocks)->Bitmap.Height, Image->Height);
788 CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)ImageBlocks)->Bitmap.Bitmap, Image->Bitmap, (UINT32)Image->Width * Image->Height);
789
790 //
791 // Append the block end
792 //
793 ImageBlocks = (EFI_HII_IMAGE_BLOCK *)((UINT8 *)ImageBlocks + NewBlockSize);
794 ImageBlocks->BlockType = EFI_HII_IIBT_END;
795
796 //
797 // Check whether need to get the contents of HiiDataBase.
798 // Only after ReadyToBoot to do the export.
799 //
800 if (gExportAfterReadyToBoot) {
801 HiiGetDatabaseInfo (&Private->HiiDatabase);
802 }
803
804 EfiReleaseLock (&mHiiDatabaseLock);
805
806 return EFI_SUCCESS;
807}
808
833 IN LIST_ENTRY *Database,
834 IN EFI_HII_HANDLE PackageList,
835 IN EFI_IMAGE_ID ImageId,
836 OUT EFI_IMAGE_INPUT *Image,
837 IN BOOLEAN BitmapOnly
838 )
839{
840 EFI_STATUS Status;
841 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
842 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
843 EFI_HII_IMAGE_BLOCK *CurrentImageBlock;
845 UINT16 Width;
846 UINT16 Height;
847 UINTN ImageLength;
848 UINT8 *PaletteInfo;
849 UINT8 PaletteIndex;
850 UINT16 PaletteSize;
852 EFI_IMAGE_OUTPUT *ImageOut;
853
854 if ((Image == NULL) || (ImageId == 0)) {
855 return EFI_INVALID_PARAMETER;
856 }
857
858 PackageListNode = LocatePackageList (Database, PackageList);
859 if (PackageListNode == NULL) {
860 return EFI_NOT_FOUND;
861 }
862
863 ImagePackage = PackageListNode->ImagePkg;
864 if (ImagePackage == NULL) {
865 return EFI_NOT_FOUND;
866 }
867
868 //
869 // Find the image block specified by ImageId
870 //
871 CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);
872 if (CurrentImageBlock == NULL) {
873 return EFI_NOT_FOUND;
874 }
875
876 Image->Flags = 0;
877 switch (CurrentImageBlock->BlockType) {
878 case EFI_HII_IIBT_IMAGE_JPEG:
879 case EFI_HII_IIBT_IMAGE_PNG:
880 if (BitmapOnly) {
881 return EFI_UNSUPPORTED;
882 }
883
884 ImageOut = NULL;
885 Decoder = LocateHiiImageDecoder (CurrentImageBlock->BlockType);
886 if (Decoder == NULL) {
887 return EFI_UNSUPPORTED;
888 }
889
890 //
891 // Use the common block code since the definition of two structures is the same.
892 //
894 ASSERT (
895 sizeof (((EFI_HII_IIBT_JPEG_BLOCK *)CurrentImageBlock)->Data) ==
896 sizeof (((EFI_HII_IIBT_PNG_BLOCK *)CurrentImageBlock)->Data)
897 );
899 ASSERT (
900 sizeof (((EFI_HII_IIBT_JPEG_BLOCK *)CurrentImageBlock)->Size) ==
901 sizeof (((EFI_HII_IIBT_PNG_BLOCK *)CurrentImageBlock)->Size)
902 );
903 Status = Decoder->DecodeImage (
904 Decoder,
905 ((EFI_HII_IIBT_JPEG_BLOCK *)CurrentImageBlock)->Data,
906 ((EFI_HII_IIBT_JPEG_BLOCK *)CurrentImageBlock)->Size,
907 &ImageOut,
908 FALSE
909 );
910
911 //
912 // Spec requires to use the first capable image decoder instance.
913 // The first image decoder instance may fail to decode the image.
914 //
915 if (!EFI_ERROR (Status)) {
916 Image->Bitmap = ImageOut->Image.Bitmap;
917 Image->Height = ImageOut->Height;
918 Image->Width = ImageOut->Width;
919 FreePool (ImageOut);
920 }
921
922 return Status;
923
924 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
925 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
926 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
927 Image->Flags = EFI_IMAGE_TRANSPARENT;
928 //
929 // fall through
930 //
931 case EFI_HII_IIBT_IMAGE_1BIT:
932 case EFI_HII_IIBT_IMAGE_4BIT:
933 case EFI_HII_IIBT_IMAGE_8BIT:
934 //
935 // Use the common block code since the definition of these structures is the same.
936 //
937 CopyMem (&Iibt1bit, CurrentImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));
938 ImageLength = (UINTN)Iibt1bit.Bitmap.Width * Iibt1bit.Bitmap.Height;
939 if (ImageLength > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
940 return EFI_OUT_OF_RESOURCES;
941 }
942
943 ImageLength *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
944 Image->Bitmap = AllocateZeroPool (ImageLength);
945 if (Image->Bitmap == NULL) {
946 return EFI_OUT_OF_RESOURCES;
947 }
948
949 Image->Width = Iibt1bit.Bitmap.Width;
950 Image->Height = Iibt1bit.Bitmap.Height;
951
952 PaletteInfo = ImagePackage->PaletteBlock + sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
953 for (PaletteIndex = 1; PaletteIndex < Iibt1bit.PaletteIndex; PaletteIndex++) {
954 CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
955 PaletteInfo += PaletteSize + sizeof (UINT16);
956 }
957
958 ASSERT (PaletteIndex == Iibt1bit.PaletteIndex);
959
960 //
961 // Output bitmap data
962 //
963 if ((CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT) ||
964 (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT_TRANS))
965 {
967 Image,
968 ((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *)CurrentImageBlock)->Bitmap.Data,
969 (EFI_HII_IMAGE_PALETTE_INFO *)PaletteInfo
970 );
971 } else if ((CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT) ||
972 (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT_TRANS))
973 {
975 Image,
976 ((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *)CurrentImageBlock)->Bitmap.Data,
977 (EFI_HII_IMAGE_PALETTE_INFO *)PaletteInfo
978 );
979 } else {
981 Image,
982 ((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *)CurrentImageBlock)->Bitmap.Data,
983 (EFI_HII_IMAGE_PALETTE_INFO *)PaletteInfo
984 );
985 }
986
987 return EFI_SUCCESS;
988
989 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
990 Image->Flags = EFI_IMAGE_TRANSPARENT;
991 //
992 // fall through
993 //
994 case EFI_HII_IIBT_IMAGE_24BIT:
995 Width = ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width);
996 Height = ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height);
997 ImageLength = (UINTN)Width * Height;
998 if (ImageLength > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
999 return EFI_OUT_OF_RESOURCES;
1000 }
1001
1002 ImageLength *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
1003 Image->Bitmap = AllocateZeroPool (ImageLength);
1004 if (Image->Bitmap == NULL) {
1005 return EFI_OUT_OF_RESOURCES;
1006 }
1007
1008 Image->Width = Width;
1009 Image->Height = Height;
1010
1011 //
1012 // Output the bitmap data directly.
1013 //
1015 Image,
1016 ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Bitmap
1017 );
1018 return EFI_SUCCESS;
1019
1020 default:
1021 return EFI_NOT_FOUND;
1022 }
1023}
1024
1047EFIAPI
1050 IN EFI_HII_HANDLE PackageList,
1051 IN EFI_IMAGE_ID ImageId,
1052 OUT EFI_IMAGE_INPUT *Image
1053 )
1054{
1056
1057 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1058 return IGetImage (&Private->DatabaseList, PackageList, ImageId, Image, TRUE);
1059}
1060
1078EFIAPI
1081 IN EFI_HII_HANDLE PackageList,
1082 IN EFI_IMAGE_ID ImageId,
1083 IN CONST EFI_IMAGE_INPUT *Image
1084 )
1085{
1087 HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode;
1088 HII_IMAGE_PACKAGE_INSTANCE *ImagePackage;
1089 EFI_HII_IMAGE_BLOCK *CurrentImageBlock;
1090 EFI_HII_IMAGE_BLOCK *ImageBlocks;
1091 EFI_HII_IMAGE_BLOCK *NewImageBlock;
1092 UINT32 NewBlockSize;
1093 UINT32 OldBlockSize;
1094 UINT32 Part1Size;
1095 UINT32 Part2Size;
1096
1097 if ((This == NULL) || (Image == NULL) || (ImageId == 0) || (Image->Bitmap == NULL)) {
1098 return EFI_INVALID_PARAMETER;
1099 }
1100
1101 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1102 PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);
1103 if (PackageListNode == NULL) {
1104 return EFI_NOT_FOUND;
1105 }
1106
1107 ImagePackage = PackageListNode->ImagePkg;
1108 if (ImagePackage == NULL) {
1109 return EFI_NOT_FOUND;
1110 }
1111
1112 //
1113 // Find the image block specified by ImageId
1114 //
1115 CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);
1116 if (CurrentImageBlock == NULL) {
1117 return EFI_NOT_FOUND;
1118 }
1119
1120 EfiAcquireLock (&mHiiDatabaseLock);
1121
1122 //
1123 // Get the size of original image block. Use some common block code here
1124 // since the definition of some structures is the same.
1125 //
1126 switch (CurrentImageBlock->BlockType) {
1127 case EFI_HII_IIBT_IMAGE_JPEG:
1128 OldBlockSize = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *)&((EFI_HII_IIBT_JPEG_BLOCK *)CurrentImageBlock)->Size);
1129 break;
1130 case EFI_HII_IIBT_IMAGE_PNG:
1131 OldBlockSize = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *)&((EFI_HII_IIBT_PNG_BLOCK *)CurrentImageBlock)->Size);
1132 break;
1133 case EFI_HII_IIBT_IMAGE_1BIT:
1134 case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
1135 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +
1136 BITMAP_LEN_1_BIT (
1137 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
1138 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
1139 );
1140 break;
1141 case EFI_HII_IIBT_IMAGE_4BIT:
1142 case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
1143 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +
1144 BITMAP_LEN_4_BIT (
1145 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
1146 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
1147 );
1148 break;
1149 case EFI_HII_IIBT_IMAGE_8BIT:
1150 case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
1151 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +
1152 BITMAP_LEN_8_BIT (
1153 (UINT32)ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
1154 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
1155 );
1156 break;
1157 case EFI_HII_IIBT_IMAGE_24BIT:
1158 case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
1159 OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
1160 BITMAP_LEN_24_BIT (
1161 (UINT32)ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
1162 ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
1163 );
1164 break;
1165 default:
1166 EfiReleaseLock (&mHiiDatabaseLock);
1167 return EFI_NOT_FOUND;
1168 }
1169
1170 //
1171 // Create the new image block according to input image.
1172 //
1173
1174 //
1175 // Make sure the final package length doesn't overflow.
1176 // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
1177 // 24Bit BMP occpuies 3 bytes per pixel.
1178 //
1179 NewBlockSize = (UINT32)Image->Width * Image->Height;
1180 if (NewBlockSize > (MAX_UINT32 - (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL))) / 3) {
1181 EfiReleaseLock (&mHiiDatabaseLock);
1182 return EFI_OUT_OF_RESOURCES;
1183 }
1184
1185 NewBlockSize = NewBlockSize * 3 + (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL));
1186 if ((NewBlockSize > OldBlockSize) &&
1187 (NewBlockSize - OldBlockSize > MAX_UINT24 - ImagePackage->ImagePkgHdr.Header.Length)
1188 )
1189 {
1190 EfiReleaseLock (&mHiiDatabaseLock);
1191 return EFI_OUT_OF_RESOURCES;
1192 }
1193
1194 //
1195 // Adjust the image package to remove the original block firstly then add the new block.
1196 //
1197 ImageBlocks = AllocateZeroPool (ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize);
1198 if (ImageBlocks == NULL) {
1199 EfiReleaseLock (&mHiiDatabaseLock);
1200 return EFI_OUT_OF_RESOURCES;
1201 }
1202
1203 Part1Size = (UINT32)((UINTN)CurrentImageBlock - (UINTN)ImagePackage->ImageBlock);
1204 Part2Size = ImagePackage->ImageBlockSize - Part1Size - OldBlockSize;
1205 CopyMem (ImageBlocks, ImagePackage->ImageBlock, Part1Size);
1206
1207 //
1208 // Set the new image block
1209 //
1210 NewImageBlock = (EFI_HII_IMAGE_BLOCK *)((UINT8 *)ImageBlocks + Part1Size);
1211 if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {
1212 NewImageBlock->BlockType = EFI_HII_IIBT_IMAGE_24BIT_TRANS;
1213 } else {
1214 NewImageBlock->BlockType = EFI_HII_IIBT_IMAGE_24BIT;
1215 }
1216
1217 WriteUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)NewImageBlock)->Bitmap.Width, Image->Width);
1218 WriteUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)NewImageBlock)->Bitmap.Height, Image->Height);
1220 ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)NewImageBlock)->Bitmap.Bitmap,
1221 Image->Bitmap,
1222 (UINT32)Image->Width * Image->Height
1223 );
1224
1225 CopyMem ((UINT8 *)NewImageBlock + NewBlockSize, (UINT8 *)CurrentImageBlock + OldBlockSize, Part2Size);
1226
1227 FreePool (ImagePackage->ImageBlock);
1228 ImagePackage->ImageBlock = ImageBlocks;
1229 ImagePackage->ImageBlockSize += NewBlockSize - OldBlockSize;
1230 ImagePackage->ImagePkgHdr.Header.Length += NewBlockSize - OldBlockSize;
1231 PackageListNode->PackageListHdr.PackageLength += NewBlockSize - OldBlockSize;
1232
1233 //
1234 // Check whether need to get the contents of HiiDataBase.
1235 // Only after ReadyToBoot to do the export.
1236 //
1237 if (gExportAfterReadyToBoot) {
1238 HiiGetDatabaseInfo (&Private->HiiDatabase);
1239 }
1240
1241 EfiReleaseLock (&mHiiDatabaseLock);
1242 return EFI_SUCCESS;
1243}
1244
1273EFIAPI
1276 IN EFI_HII_DRAW_FLAGS Flags,
1277 IN CONST EFI_IMAGE_INPUT *Image,
1278 IN OUT EFI_IMAGE_OUTPUT **Blt,
1279 IN UINTN BltX,
1280 IN UINTN BltY
1281 )
1282{
1283 EFI_STATUS Status;
1285 BOOLEAN Transparent;
1286 EFI_IMAGE_OUTPUT *ImageOut;
1288 UINTN BufferLen;
1289 UINT16 Width;
1290 UINT16 Height;
1291 UINTN Ypos;
1292 UINTN OffsetY1;
1293 UINTN OffsetY2;
1294 EFI_FONT_DISPLAY_INFO *FontInfo;
1295 UINTN Index;
1296
1297 if ((This == NULL) || (Image == NULL) || (Blt == NULL)) {
1298 return EFI_INVALID_PARAMETER;
1299 }
1300
1301 if (((Flags & EFI_HII_DRAW_FLAG_CLIP) == EFI_HII_DRAW_FLAG_CLIP) && (*Blt == NULL)) {
1302 return EFI_INVALID_PARAMETER;
1303 }
1304
1305 if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_TRANSPARENT) {
1306 return EFI_INVALID_PARAMETER;
1307 }
1308
1309 FontInfo = NULL;
1310
1311 //
1312 // Check whether the image will be drawn transparently or opaquely.
1313 //
1314 Transparent = FALSE;
1315 if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_TRANS) {
1316 Transparent = TRUE;
1317 } else if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE) {
1318 Transparent = FALSE;
1319 } else {
1320 //
1321 // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
1322 // on the image's transparency setting.
1323 //
1324 if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {
1325 Transparent = TRUE;
1326 }
1327 }
1328
1329 //
1330 // Image cannot be drawn transparently if Blt points to NULL on entry.
1331 // Currently output to Screen transparently is not supported, either.
1332 //
1333 if (Transparent) {
1334 if (*Blt == NULL) {
1335 return EFI_INVALID_PARAMETER;
1336 } else if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
1337 return EFI_INVALID_PARAMETER;
1338 }
1339 }
1340
1341 Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1342
1343 //
1344 // When Blt points to a non-NULL on entry, this image will be drawn onto
1345 // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
1346 // Otherwise a new bitmap will be allocated to hold this image.
1347 //
1348 if (*Blt != NULL) {
1349 //
1350 // Make sure the BltX and BltY is inside the Blt area.
1351 //
1352 if ((BltX >= (*Blt)->Width) || (BltY >= (*Blt)->Height)) {
1353 return EFI_INVALID_PARAMETER;
1354 }
1355
1356 //
1357 // Clip the image by (Width, Height)
1358 //
1359
1360 Width = Image->Width;
1361 Height = Image->Height;
1362
1363 if (Width > (*Blt)->Width - (UINT16)BltX) {
1364 Width = (*Blt)->Width - (UINT16)BltX;
1365 }
1366
1367 if (Height > (*Blt)->Height - (UINT16)BltY) {
1368 Height = (*Blt)->Height - (UINT16)BltY;
1369 }
1370
1371 //
1372 // Prepare the buffer for the temporary image.
1373 // Make sure the buffer size doesn't overflow UINTN.
1374 //
1375 BufferLen = Width * Height;
1376 if (BufferLen > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
1377 return EFI_OUT_OF_RESOURCES;
1378 }
1379
1380 BufferLen *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
1381 BltBuffer = AllocateZeroPool (BufferLen);
1382 if (BltBuffer == NULL) {
1383 return EFI_OUT_OF_RESOURCES;
1384 }
1385
1386 if ((Width == Image->Width) && (Height == Image->Height)) {
1387 CopyMem (BltBuffer, Image->Bitmap, BufferLen);
1388 } else {
1389 for (Ypos = 0; Ypos < Height; Ypos++) {
1390 OffsetY1 = Image->Width * Ypos;
1391 OffsetY2 = Width * Ypos;
1392 CopyMem (
1393 &BltBuffer[OffsetY2],
1394 &Image->Bitmap[OffsetY1],
1395 Width * sizeof (*BltBuffer)
1396 );
1397 }
1398 }
1399
1400 //
1401 // Draw the image to existing bitmap or screen depending on flag.
1402 //
1403 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
1404 //
1405 // Caller should make sure the current UGA console is grarphic mode.
1406 //
1407
1408 //
1409 // Write the image directly to the output device specified by Screen.
1410 //
1411 Status = (*Blt)->Image.Screen->Blt (
1412 (*Blt)->Image.Screen,
1413 BltBuffer,
1415 0,
1416 0,
1417 BltX,
1418 BltY,
1419 Width,
1420 Height,
1421 0
1422 );
1423 } else {
1424 //
1425 // Draw the image onto the existing bitmap specified by Bitmap.
1426 //
1427 Status = ImageToBlt (
1428 BltBuffer,
1429 BltX,
1430 BltY,
1431 Width,
1432 Height,
1433 Transparent,
1434 Blt
1435 );
1436 }
1437
1438 FreePool (BltBuffer);
1439 return Status;
1440 } else {
1441 //
1442 // Allocate a new bitmap to hold the incoming image.
1443 //
1444
1445 //
1446 // Make sure the final width and height doesn't overflow UINT16.
1447 //
1448 if ((BltX > (UINTN)MAX_UINT16 - Image->Width) || (BltY > (UINTN)MAX_UINT16 - Image->Height)) {
1449 return EFI_INVALID_PARAMETER;
1450 }
1451
1452 Width = Image->Width + (UINT16)BltX;
1453 Height = Image->Height + (UINT16)BltY;
1454
1455 //
1456 // Make sure the output image size doesn't overflow UINTN.
1457 //
1458 BufferLen = Width * Height;
1459 if (BufferLen > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
1460 return EFI_OUT_OF_RESOURCES;
1461 }
1462
1463 BufferLen *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
1464 BltBuffer = AllocateZeroPool (BufferLen);
1465 if (BltBuffer == NULL) {
1466 return EFI_OUT_OF_RESOURCES;
1467 }
1468
1469 ImageOut = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
1470 if (ImageOut == NULL) {
1471 FreePool (BltBuffer);
1472 return EFI_OUT_OF_RESOURCES;
1473 }
1474
1475 ImageOut->Width = Width;
1476 ImageOut->Height = Height;
1477 ImageOut->Image.Bitmap = BltBuffer;
1478
1479 //
1480 // BUGBUG: Now all the "blank" pixels are filled with system default background
1481 // color. Not sure if it need to be updated or not.
1482 //
1483 Status = GetSystemFont (Private, &FontInfo, NULL);
1484 if (EFI_ERROR (Status)) {
1485 FreePool (BltBuffer);
1486 FreePool (ImageOut);
1487 return Status;
1488 }
1489
1490 ASSERT (FontInfo != NULL);
1491 for (Index = 0; Index < (UINTN)Width * Height; Index++) {
1492 BltBuffer[Index] = FontInfo->BackgroundColor;
1493 }
1494
1495 FreePool (FontInfo);
1496
1497 //
1498 // Draw the incoming image to the new created image.
1499 //
1500 *Blt = ImageOut;
1501 return ImageToBlt (
1502 Image->Bitmap,
1503 BltX,
1504 BltY,
1505 Image->Width,
1506 Image->Height,
1507 Transparent,
1508 Blt
1509 );
1510 }
1511}
1512
1546EFIAPI
1549 IN EFI_HII_DRAW_FLAGS Flags,
1550 IN EFI_HII_HANDLE PackageList,
1551 IN EFI_IMAGE_ID ImageId,
1552 IN OUT EFI_IMAGE_OUTPUT **Blt,
1553 IN UINTN BltX,
1554 IN UINTN BltY
1555 )
1556{
1557 EFI_STATUS Status;
1558 EFI_IMAGE_INPUT Image;
1559
1560 //
1561 // Check input parameter.
1562 //
1563 if ((This == NULL) || (Blt == NULL)) {
1564 return EFI_INVALID_PARAMETER;
1565 }
1566
1567 //
1568 // Get the specified Image.
1569 //
1570 Status = HiiGetImage (This, PackageList, ImageId, &Image);
1571 if (EFI_ERROR (Status)) {
1572 return Status;
1573 }
1574
1575 //
1576 // Draw this image.
1577 //
1578 Status = HiiDrawImage (This, Flags, &Image, Blt, BltX, BltY);
1579 if (Image.Bitmap != NULL) {
1580 FreePool (Image.Bitmap);
1581 }
1582
1583 return Status;
1584}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
Definition: Unaligned.c:29
UINT16 EFIAPI WriteUnaligned16(OUT UINT16 *Buffer, IN UINT16 Value)
Definition: Unaligned.c:61
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS HiiGetDatabaseInfo(IN CONST EFI_HII_DATABASE_PROTOCOL *This)
Definition: Database.c:3549
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS GetSystemFont(IN HII_DATABASE_PRIVATE_DATA *Private, OUT EFI_FONT_DISPLAY_INFO **FontInfo, OUT UINTN *FontInfoSize OPTIONAL)
Definition: Font.c:993
UINT32 EFI_HII_DRAW_FLAGS
Definition: HiiImage.h:163
#define EFI_IMAGE_TRANSPARENT
Definition: HiiImage.h:25
EFI_HII_IMAGE_DECODER_PROTOCOL * LocateHiiImageDecoder(UINT8 BlockType)
Definition: ImageEx.c:247
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
@ EfiBltBufferToVideo
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID * EFI_HII_HANDLE
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:434
VOID Output4bitPixel(IN OUT EFI_IMAGE_INPUT *Image, IN UINT8 *Data, IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo)
Definition: Image.c:328
EFI_HII_IMAGE_BLOCK * GetImageIdOrAddress(IN EFI_HII_IMAGE_BLOCK *ImageBlocks, IN OUT EFI_IMAGE_ID *ImageId)
Definition: Image.c:29
VOID Output1bitPixel(IN OUT EFI_IMAGE_INPUT *Image, IN UINT8 *Data, IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo)
Definition: Image.c:239
EFI_STATUS IGetImage(IN LIST_ENTRY *Database, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, OUT EFI_IMAGE_INPUT *Image, IN BOOLEAN BitmapOnly)
Definition: Image.c:832
EFI_STATUS ImageToBlt(IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, IN UINTN BltX, IN UINTN BltY, IN UINTN Width, IN UINTN Height, IN BOOLEAN Transparent, IN OUT EFI_IMAGE_OUTPUT **Blt)
Definition: Image.c:514
VOID Output8bitPixel(IN OUT EFI_IMAGE_INPUT *Image, IN UINT8 *Data, IN EFI_HII_IMAGE_PALETTE_INFO *PaletteInfo)
Definition: Image.c:406
VOID CopyGopToRgbPixel(OUT EFI_HII_RGB_PIXEL *BitMapOut, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapIn, IN UINTN PixelNum)
Definition: Image.c:181
HII_DATABASE_PACKAGE_LIST_INSTANCE * LocatePackageList(IN LIST_ENTRY *Database, IN EFI_HII_HANDLE PackageList)
Definition: Image.c:575
VOID CopyRgbToGopPixel(OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BitMapOut, IN EFI_HII_RGB_PIXEL *BitMapIn, IN UINTN PixelNum)
Definition: Image.c:209
EFI_STATUS EFIAPI HiiDrawImage(IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_DRAW_FLAGS Flags, IN CONST EFI_IMAGE_INPUT *Image, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY)
Definition: Image.c:1274
VOID Output24bitPixel(IN OUT EFI_IMAGE_INPUT *Image, IN EFI_HII_RGB_PIXEL *Data)
Definition: Image.c:472
EFI_STATUS EFIAPI HiiDrawImageId(IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_DRAW_FLAGS Flags, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY)
Definition: Image.c:1547
EFI_STATUS EFIAPI HiiNewImage(IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, OUT EFI_IMAGE_ID *ImageId, IN CONST EFI_IMAGE_INPUT *Image)
Definition: Image.c:620
EFI_STATUS EFIAPI HiiGetImage(IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, OUT EFI_IMAGE_INPUT *Image)
Definition: Image.c:1048
EFI_STATUS EFIAPI HiiSetImage(IN CONST EFI_HII_IMAGE_PROTOCOL *This, IN EFI_HII_HANDLE PackageList, IN EFI_IMAGE_ID ImageId, IN CONST EFI_IMAGE_INPUT *Image)
Definition: Image.c:1079