mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 03:57:26 +00:00 
			
		
		
		
	According to UEFI spec, NewImageEx()/SetImageEx()/DrawImageEx() implicitly call the non-Ex version interface of HiiImage protocol. GetImageEx()/DrawImageIdEx() are the enhanced version of GetImage()/DrawImageId(), which can support decoding JPEG/PNG through the help of HiiImageDecoder protocol. Contributed-under: TianoCore Contribution Agreement 1.0 Reviewed-by: Liming Gao <liming.gao@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Dandan Bi <dandan.bi@intel.com> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
		
			
				
	
	
		
			1473 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1473 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
Implementation for EFI_HII_IMAGE_PROTOCOL.
 | 
						|
 | 
						|
 | 
						|
Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
 | 
						|
This program and the accompanying materials
 | 
						|
are licensed and made available under the terms and conditions of the BSD License
 | 
						|
which accompanies this distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
 | 
						|
#include "HiiDatabase.h"
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Get the imageid of last image block: EFI_HII_IIBT_END_BLOCK when input
 | 
						|
  ImageId is zero, otherwise return the address of the
 | 
						|
  corresponding image block with identifier specified by ImageId.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
  @param ImageBlocks     Points to the beginning of a series of image blocks stored in order.
 | 
						|
  @param ImageId         If input ImageId is 0, output the image id of the EFI_HII_IIBT_END_BLOCK;
 | 
						|
                         else use this id to find its corresponding image block address.
 | 
						|
 | 
						|
  @return The image block address when input ImageId is not zero; otherwise return NULL.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_HII_IMAGE_BLOCK *
 | 
						|
GetImageIdOrAddress (
 | 
						|
  IN EFI_HII_IMAGE_BLOCK *ImageBlocks,
 | 
						|
  IN OUT EFI_IMAGE_ID    *ImageId
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_IMAGE_ID                   ImageIdCurrent;
 | 
						|
  EFI_HII_IMAGE_BLOCK            *CurrentImageBlock;
 | 
						|
  UINTN                          Length;
 | 
						|
 | 
						|
  ASSERT (ImageBlocks != NULL && ImageId != NULL);
 | 
						|
  CurrentImageBlock = ImageBlocks;
 | 
						|
  ImageIdCurrent    = 1;
 | 
						|
 | 
						|
  while (CurrentImageBlock->BlockType != EFI_HII_IIBT_END) {
 | 
						|
    if (*ImageId != 0) {
 | 
						|
      if (*ImageId == ImageIdCurrent) {
 | 
						|
        //
 | 
						|
        // If the found image block is a duplicate block, update the ImageId to
 | 
						|
        // find the previous defined image block.
 | 
						|
        //
 | 
						|
        if (CurrentImageBlock->BlockType == EFI_HII_IIBT_DUPLICATE) {
 | 
						|
          *ImageId = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_DUPLICATE_BLOCK *) CurrentImageBlock)->ImageId);
 | 
						|
          ASSERT (*ImageId != ImageIdCurrent);
 | 
						|
          ASSERT (*ImageId != 0);
 | 
						|
          CurrentImageBlock = ImageBlocks;
 | 
						|
          ImageIdCurrent = 1;
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        return CurrentImageBlock;
 | 
						|
      }
 | 
						|
      if (*ImageId < ImageIdCurrent) {
 | 
						|
        //
 | 
						|
        // Can not find the specified image block in this image.
 | 
						|
        //
 | 
						|
        return NULL;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    switch (CurrentImageBlock->BlockType) {
 | 
						|
    case EFI_HII_IIBT_EXT1:
 | 
						|
      Length = ((EFI_HII_IIBT_EXT1_BLOCK *) CurrentImageBlock)->Length;
 | 
						|
      break;
 | 
						|
    case EFI_HII_IIBT_EXT2:
 | 
						|
      Length = ReadUnaligned16 (&((EFI_HII_IIBT_EXT2_BLOCK *) CurrentImageBlock)->Length);
 | 
						|
      break;
 | 
						|
    case EFI_HII_IIBT_EXT4:
 | 
						|
      Length = ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_EXT4_BLOCK *) CurrentImageBlock)->Length);
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_IMAGE_1BIT:
 | 
						|
    case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +
 | 
						|
               BITMAP_LEN_1_BIT (
 | 
						|
                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                 );
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_IMAGE_4BIT:
 | 
						|
    case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +
 | 
						|
               BITMAP_LEN_4_BIT (
 | 
						|
                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                 );
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_IMAGE_8BIT:
 | 
						|
    case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +
 | 
						|
               BITMAP_LEN_8_BIT (
 | 
						|
                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                 );
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_IMAGE_24BIT:
 | 
						|
    case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
 | 
						|
               BITMAP_LEN_24_BIT (
 | 
						|
                 ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                 ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                 );
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_DUPLICATE:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK);
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_IMAGE_JPEG:
 | 
						|
      Length = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size);
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_IMAGE_PNG:
 | 
						|
      Length = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size);
 | 
						|
      ImageIdCurrent++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_SKIP1:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_SKIP1_BLOCK);
 | 
						|
      ImageIdCurrent += ((EFI_HII_IIBT_SKIP1_BLOCK *) CurrentImageBlock)->SkipCount;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_HII_IIBT_SKIP2:
 | 
						|
      Length = sizeof (EFI_HII_IIBT_SKIP2_BLOCK);
 | 
						|
      ImageIdCurrent += ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_SKIP2_BLOCK *) CurrentImageBlock)->SkipCount);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      //
 | 
						|
      // Unknown image blocks can not be skipped, processing halts.
 | 
						|
      //
 | 
						|
      ASSERT (FALSE);
 | 
						|
      Length = 0;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    CurrentImageBlock = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) CurrentImageBlock + Length);
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // When ImageId is zero, return the imageid of last image block: EFI_HII_IIBT_END_BLOCK.
 | 
						|
  //
 | 
						|
  if (*ImageId == 0) {
 | 
						|
    *ImageId = ImageIdCurrent;
 | 
						|
    return CurrentImageBlock;
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Convert pixels from EFI_GRAPHICS_OUTPUT_BLT_PIXEL to EFI_HII_RGB_PIXEL style.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  BitMapOut              Pixels in EFI_HII_RGB_PIXEL format.
 | 
						|
  @param  BitMapIn               Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
 | 
						|
  @param  PixelNum               The number of pixels to be converted.
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
CopyGopToRgbPixel (
 | 
						|
  OUT EFI_HII_RGB_PIXEL              *BitMapOut,
 | 
						|
  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BitMapIn,
 | 
						|
  IN  UINTN                          PixelNum
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN Index;
 | 
						|
 | 
						|
  ASSERT (BitMapOut != NULL && BitMapIn != NULL);
 | 
						|
 | 
						|
  for (Index = 0; Index < PixelNum; Index++) {
 | 
						|
    CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Convert pixels from EFI_HII_RGB_PIXEL to EFI_GRAPHICS_OUTPUT_BLT_PIXEL style.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  BitMapOut              Pixels in EFI_GRAPHICS_OUTPUT_BLT_PIXEL format.
 | 
						|
  @param  BitMapIn               Pixels in EFI_HII_RGB_PIXEL format.
 | 
						|
  @param  PixelNum               The number of pixels to be converted.
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
CopyRgbToGopPixel (
 | 
						|
  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BitMapOut,
 | 
						|
  IN  EFI_HII_RGB_PIXEL              *BitMapIn,
 | 
						|
  IN  UINTN                          PixelNum
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN Index;
 | 
						|
 | 
						|
  ASSERT (BitMapOut != NULL && BitMapIn != NULL);
 | 
						|
 | 
						|
  for (Index = 0; Index < PixelNum; Index++) {
 | 
						|
    CopyMem (BitMapOut + Index, BitMapIn + Index, sizeof (EFI_HII_RGB_PIXEL));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output pixels in "1 bit per pixel" format to an image.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  Image                  Points to the image which will store the pixels.
 | 
						|
  @param  Data                   Stores the value of output pixels, 0 or 1.
 | 
						|
  @param  PaletteInfo            PaletteInfo which stores the color of the output
 | 
						|
                                 pixels. First entry corresponds to color 0 and
 | 
						|
                                 second one to color 1.
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
Output1bitPixel (
 | 
						|
  IN OUT EFI_IMAGE_INPUT             *Image,
 | 
						|
  IN UINT8                           *Data,
 | 
						|
  IN EFI_HII_IMAGE_PALETTE_INFO      *PaletteInfo
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16                             Xpos;
 | 
						|
  UINT16                             Ypos;
 | 
						|
  UINTN                              OffsetY;
 | 
						|
  UINT8                              Index;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      PaletteValue[2];
 | 
						|
  EFI_HII_IMAGE_PALETTE_INFO         *Palette;
 | 
						|
  UINTN                              PaletteSize;
 | 
						|
  UINT8                              Byte;
 | 
						|
 | 
						|
  ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
 | 
						|
 | 
						|
  BitMapPtr = Image->Bitmap;
 | 
						|
 | 
						|
  //
 | 
						|
  // First entry corresponds to color 0 and second entry corresponds to color 1.
 | 
						|
  //
 | 
						|
  PaletteSize = 0;
 | 
						|
  CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
 | 
						|
  PaletteSize += sizeof (UINT16);
 | 
						|
  Palette = AllocateZeroPool (PaletteSize);
 | 
						|
  ASSERT (Palette != NULL);
 | 
						|
  if (Palette == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  CopyMem (Palette, PaletteInfo, PaletteSize);
 | 
						|
 | 
						|
  ZeroMem (PaletteValue, sizeof (PaletteValue));
 | 
						|
  CopyRgbToGopPixel (&PaletteValue[0], &Palette->PaletteValue[0], 1);
 | 
						|
  CopyRgbToGopPixel (&PaletteValue[1], &Palette->PaletteValue[1], 1);
 | 
						|
  FreePool (Palette);
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert the pixel from one bit to corresponding color.
 | 
						|
  //
 | 
						|
  for (Ypos = 0; Ypos < Image->Height; Ypos++) {
 | 
						|
    OffsetY = BITMAP_LEN_1_BIT (Image->Width, Ypos);
 | 
						|
    //
 | 
						|
    // All bits in these bytes are meaningful
 | 
						|
    //
 | 
						|
    for (Xpos = 0; Xpos < Image->Width / 8; Xpos++) {
 | 
						|
      Byte = *(Data + OffsetY + Xpos);
 | 
						|
      for (Index = 0; Index < 8; Index++) {
 | 
						|
        if ((Byte & (1 << Index)) != 0) {
 | 
						|
          BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[1];
 | 
						|
        } else {
 | 
						|
          BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)] = PaletteValue[0];
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (Image->Width % 8 != 0) {
 | 
						|
      //
 | 
						|
      // Padding bits in this byte should be ignored.
 | 
						|
      //
 | 
						|
      Byte = *(Data + OffsetY + Xpos);
 | 
						|
      for (Index = 0; Index < Image->Width % 8; Index++) {
 | 
						|
        if ((Byte & (1 << (8 - Index - 1))) != 0) {
 | 
						|
          BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[1];
 | 
						|
        } else {
 | 
						|
          BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index] = PaletteValue[0];
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output pixels in "4 bit per pixel" format to an image.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  Image                  Points to the image which will store the pixels.
 | 
						|
  @param  Data                   Stores the value of output pixels, 0 ~ 15.
 | 
						|
  @param[in]  PaletteInfo            PaletteInfo which stores the color of the output
 | 
						|
                                 pixels. Each entry corresponds to a color within
 | 
						|
                                 [0, 15].
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
Output4bitPixel (
 | 
						|
  IN OUT EFI_IMAGE_INPUT             *Image,
 | 
						|
  IN UINT8                           *Data,
 | 
						|
  IN EFI_HII_IMAGE_PALETTE_INFO      *PaletteInfo
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16                             Xpos;
 | 
						|
  UINT16                             Ypos;
 | 
						|
  UINTN                              OffsetY;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      PaletteValue[16];
 | 
						|
  EFI_HII_IMAGE_PALETTE_INFO         *Palette;
 | 
						|
  UINTN                              PaletteSize;
 | 
						|
  UINT16                             PaletteNum;
 | 
						|
  UINT8                              Byte;
 | 
						|
 | 
						|
  ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
 | 
						|
 | 
						|
  BitMapPtr = Image->Bitmap;
 | 
						|
 | 
						|
  //
 | 
						|
  // The bitmap should allocate each color index starting from 0.
 | 
						|
  //
 | 
						|
  PaletteSize = 0;
 | 
						|
  CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
 | 
						|
  PaletteSize += sizeof (UINT16);
 | 
						|
  Palette = AllocateZeroPool (PaletteSize);
 | 
						|
  ASSERT (Palette != NULL);
 | 
						|
  if (Palette == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  CopyMem (Palette, PaletteInfo, PaletteSize);
 | 
						|
  PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));
 | 
						|
 | 
						|
  ZeroMem (PaletteValue, sizeof (PaletteValue));
 | 
						|
  CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);
 | 
						|
  FreePool (Palette);
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert the pixel from 4 bit to corresponding color.
 | 
						|
  //
 | 
						|
  for (Ypos = 0; Ypos < Image->Height; Ypos++) {
 | 
						|
    OffsetY = BITMAP_LEN_4_BIT (Image->Width, Ypos);
 | 
						|
    //
 | 
						|
    // All bits in these bytes are meaningful
 | 
						|
    //
 | 
						|
    for (Xpos = 0; Xpos < Image->Width / 2; Xpos++) {
 | 
						|
      Byte = *(Data + OffsetY + Xpos);
 | 
						|
      BitMapPtr[Ypos * Image->Width + Xpos * 2]     = PaletteValue[Byte >> 4];
 | 
						|
      BitMapPtr[Ypos * Image->Width + Xpos * 2 + 1] = PaletteValue[Byte & 0x0F];
 | 
						|
    }
 | 
						|
 | 
						|
    if (Image->Width % 2 != 0) {
 | 
						|
      //
 | 
						|
      // Padding bits in this byte should be ignored.
 | 
						|
      //
 | 
						|
      Byte = *(Data + OffsetY + Xpos);
 | 
						|
      BitMapPtr[Ypos * Image->Width + Xpos * 2]     = PaletteValue[Byte >> 4];
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output pixels in "8 bit per pixel" format to an image.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  Image                  Points to the image which will store the pixels.
 | 
						|
  @param  Data                   Stores the value of output pixels, 0 ~ 255.
 | 
						|
  @param[in]  PaletteInfo        PaletteInfo which stores the color of the output
 | 
						|
                                 pixels. Each entry corresponds to a color within
 | 
						|
                                 [0, 255].
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
Output8bitPixel (
 | 
						|
  IN OUT EFI_IMAGE_INPUT             *Image,
 | 
						|
  IN UINT8                           *Data,
 | 
						|
  IN EFI_HII_IMAGE_PALETTE_INFO      *PaletteInfo
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16                             Xpos;
 | 
						|
  UINT16                             Ypos;
 | 
						|
  UINTN                              OffsetY;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      PaletteValue[256];
 | 
						|
  EFI_HII_IMAGE_PALETTE_INFO         *Palette;
 | 
						|
  UINTN                              PaletteSize;
 | 
						|
  UINT16                             PaletteNum;
 | 
						|
  UINT8                              Byte;
 | 
						|
 | 
						|
  ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);
 | 
						|
 | 
						|
  BitMapPtr = Image->Bitmap;
 | 
						|
 | 
						|
  //
 | 
						|
  // The bitmap should allocate each color index starting from 0.
 | 
						|
  //
 | 
						|
  PaletteSize = 0;
 | 
						|
  CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
 | 
						|
  PaletteSize += sizeof (UINT16);
 | 
						|
  Palette = AllocateZeroPool (PaletteSize);
 | 
						|
  ASSERT (Palette != NULL);
 | 
						|
  if (Palette == NULL) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  CopyMem (Palette, PaletteInfo, PaletteSize);
 | 
						|
  PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));
 | 
						|
  ZeroMem (PaletteValue, sizeof (PaletteValue));
 | 
						|
  CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);
 | 
						|
  FreePool (Palette);
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert the pixel from 8 bits to corresponding color.
 | 
						|
  //
 | 
						|
  for (Ypos = 0; Ypos < Image->Height; Ypos++) {
 | 
						|
    OffsetY = BITMAP_LEN_8_BIT (Image->Width, Ypos);
 | 
						|
    //
 | 
						|
    // All bits are meaningful since the bitmap is 8 bits per pixel.
 | 
						|
    //
 | 
						|
    for (Xpos = 0; Xpos < Image->Width; Xpos++) {
 | 
						|
      Byte = *(Data + OffsetY + Xpos);
 | 
						|
      BitMapPtr[OffsetY + Xpos] = PaletteValue[Byte];
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output pixels in "24 bit per pixel" format to an image.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  Image                  Points to the image which will store the pixels.
 | 
						|
  @param  Data                   Stores the color of output pixels, allowing 16.8
 | 
						|
                                 millions colors.
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
Output24bitPixel (
 | 
						|
  IN OUT EFI_IMAGE_INPUT             *Image,
 | 
						|
  IN EFI_HII_RGB_PIXEL               *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16                             Ypos;
 | 
						|
  UINTN                              OffsetY;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;
 | 
						|
 | 
						|
  ASSERT (Image != NULL && Data != NULL);
 | 
						|
 | 
						|
  BitMapPtr = Image->Bitmap;
 | 
						|
 | 
						|
  for (Ypos = 0; Ypos < Image->Height; Ypos++) {
 | 
						|
    OffsetY = BITMAP_LEN_8_BIT (Image->Width, Ypos);
 | 
						|
    CopyRgbToGopPixel (&BitMapPtr[OffsetY], &Data[OffsetY], Image->Width);
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Convert the image from EFI_IMAGE_INPUT to EFI_IMAGE_OUTPUT format.
 | 
						|
 | 
						|
  This is a internal function.
 | 
						|
 | 
						|
 | 
						|
  @param  BltBuffer              Buffer points to bitmap data of incoming image.
 | 
						|
  @param  BltX                   Specifies the offset from the left and top edge of
 | 
						|
                                  the output image of the first pixel in the image.
 | 
						|
  @param  BltY                   Specifies the offset from the left and top edge of
 | 
						|
                                  the output image of the first pixel in the image.
 | 
						|
  @param  Width                  Width of the incoming image, in pixels.
 | 
						|
  @param  Height                 Height of the incoming image, in pixels.
 | 
						|
  @param  Transparent            If TRUE, all "off" pixels in the image will be
 | 
						|
                                 drawn using the pixel value from blt and all other
 | 
						|
                                 pixels will be copied.
 | 
						|
  @param  Blt                    Buffer points to bitmap data of output image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The image was successfully converted.
 | 
						|
  @retval EFI_INVALID_PARAMETER  Any incoming parameter is invalid.
 | 
						|
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_IMAGE_OUTPUT                   *ImageOut;
 | 
						|
  UINTN                              Xpos;
 | 
						|
  UINTN                              Ypos;
 | 
						|
  UINTN                              OffsetY1; // src buffer
 | 
						|
  UINTN                              OffsetY2; // dest buffer
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      SrcPixel;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      ZeroPixel;
 | 
						|
 | 
						|
  if (BltBuffer == NULL || Blt == NULL || *Blt == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ImageOut = *Blt;
 | 
						|
 | 
						|
  if (Width + BltX > ImageOut->Width) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  if (Height + BltY > ImageOut->Height) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ZeroMem (&ZeroPixel, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
 | 
						|
 | 
						|
  for (Ypos = 0; Ypos < Height; Ypos++) {
 | 
						|
    OffsetY1 = Width * Ypos;
 | 
						|
    OffsetY2 = ImageOut->Width * (BltY + Ypos);
 | 
						|
    for (Xpos = 0; Xpos < Width; Xpos++) {
 | 
						|
      SrcPixel = BltBuffer[OffsetY1 + Xpos];
 | 
						|
      if (Transparent) {
 | 
						|
        if (CompareMem (&SrcPixel, &ZeroPixel, 3) != 0) {
 | 
						|
          ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos] = SrcPixel;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Return the HII package list identified by PackageList HII handle.
 | 
						|
 | 
						|
  @param Database    Pointer to HII database list header.
 | 
						|
  @param PackageList HII handle of the package list to locate.
 | 
						|
 | 
						|
  @retval The HII package list instance.
 | 
						|
**/
 | 
						|
HII_DATABASE_PACKAGE_LIST_INSTANCE *
 | 
						|
LocatePackageList (
 | 
						|
  IN  LIST_ENTRY                     *Database,
 | 
						|
  IN  EFI_HII_HANDLE                 PackageList
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY                         *Link;
 | 
						|
  HII_DATABASE_RECORD                *Record;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the specified package list and image package.
 | 
						|
  //
 | 
						|
  for (Link = GetFirstNode (Database);
 | 
						|
       !IsNull (Database, Link);
 | 
						|
       Link = GetNextNode (Database, Link)
 | 
						|
      ) {
 | 
						|
    Record = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
 | 
						|
    if (Record->Handle == PackageList) {
 | 
						|
      return Record->PackageList;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function adds the image Image to the group of images owned by PackageList, and returns
 | 
						|
  a new image identifier (ImageId).
 | 
						|
 | 
						|
  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
 | 
						|
  @param  PackageList            Handle of the package list where this image will
 | 
						|
                                 be added.
 | 
						|
  @param  ImageId                On return, contains the new image id, which is
 | 
						|
                                 unique within PackageList.
 | 
						|
  @param  Image                  Points to the image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The new image was added successfully.
 | 
						|
  @retval EFI_NOT_FOUND          The specified PackageList could not be found in
 | 
						|
                                 database.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   Could not add the image due to lack of resources.
 | 
						|
  @retval EFI_INVALID_PARAMETER  Image is NULL or ImageId is NULL.
 | 
						|
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  HII_DATABASE_PRIVATE_DATA           *Private;
 | 
						|
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
 | 
						|
  HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;
 | 
						|
  EFI_HII_IMAGE_BLOCK                 *ImageBlocks;
 | 
						|
  UINT32                              NewBlockSize;
 | 
						|
 | 
						|
  if (This == NULL || ImageId == NULL || Image == NULL || Image->Bitmap == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);
 | 
						|
  if (PackageListNode == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
 | 
						|
                 BITMAP_LEN_24_BIT (Image->Width, Image->Height);
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the image package in the package list,
 | 
						|
  // or create a new image package if image package does not exist.
 | 
						|
  //
 | 
						|
  if (PackageListNode->ImagePkg != NULL) {
 | 
						|
    ImagePackage = PackageListNode->ImagePkg;
 | 
						|
 | 
						|
    //
 | 
						|
    // Output the image id of the incoming image being inserted, which is the
 | 
						|
    // image id of the EFI_HII_IIBT_END block of old image package.
 | 
						|
    //
 | 
						|
    *ImageId = 0;
 | 
						|
    GetImageIdOrAddress (ImagePackage->ImageBlock, ImageId);
 | 
						|
 | 
						|
    //
 | 
						|
    // Update the package's image block by appending the new block to the end.
 | 
						|
    //
 | 
						|
    ImageBlocks = AllocatePool (ImagePackage->ImageBlockSize + NewBlockSize);
 | 
						|
    if (ImageBlocks == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Copy the original content.
 | 
						|
    //
 | 
						|
    CopyMem (
 | 
						|
      ImageBlocks,
 | 
						|
      ImagePackage->ImageBlock,
 | 
						|
      ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)
 | 
						|
      );
 | 
						|
    FreePool (ImagePackage->ImageBlock);
 | 
						|
    ImagePackage->ImageBlock = ImageBlocks;
 | 
						|
 | 
						|
    //
 | 
						|
    // Point to the very last block.
 | 
						|
    //
 | 
						|
    ImageBlocks = (EFI_HII_IMAGE_BLOCK *) (
 | 
						|
                    (UINT8 *) ImageBlocks + ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)
 | 
						|
                    );
 | 
						|
    //
 | 
						|
    // Update the length record.
 | 
						|
    //
 | 
						|
    ImagePackage->ImageBlockSize                  += NewBlockSize;
 | 
						|
    ImagePackage->ImagePkgHdr.Header.Length       += NewBlockSize;
 | 
						|
    PackageListNode->PackageListHdr.PackageLength += NewBlockSize;
 | 
						|
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // The specified package list does not contain image package.
 | 
						|
    // Create one to add this image block.
 | 
						|
    //
 | 
						|
    ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));
 | 
						|
    if (ImagePackage == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Output the image id of the incoming image being inserted, which is the
 | 
						|
    // first image block so that id is initially to one.
 | 
						|
    //
 | 
						|
    *ImageId = 1;
 | 
						|
    //
 | 
						|
    // Fill in image package header.
 | 
						|
    //
 | 
						|
    ImagePackage->ImagePkgHdr.Header.Length     = sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);
 | 
						|
    ImagePackage->ImagePkgHdr.Header.Type       = EFI_HII_PACKAGE_IMAGES;
 | 
						|
    ImagePackage->ImagePkgHdr.ImageInfoOffset   = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
 | 
						|
    ImagePackage->ImagePkgHdr.PaletteInfoOffset = 0;
 | 
						|
 | 
						|
    //
 | 
						|
    // Fill in palette info.
 | 
						|
    //
 | 
						|
    ImagePackage->PaletteBlock    = NULL;
 | 
						|
    ImagePackage->PaletteInfoSize = 0;
 | 
						|
 | 
						|
    //
 | 
						|
    // Fill in image blocks.
 | 
						|
    //
 | 
						|
    ImagePackage->ImageBlockSize = NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);
 | 
						|
    ImagePackage->ImageBlock = AllocateZeroPool (NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK));
 | 
						|
    if (ImagePackage->ImageBlock == NULL) {
 | 
						|
      FreePool (ImagePackage);
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
    ImageBlocks = ImagePackage->ImageBlock;
 | 
						|
 | 
						|
    //
 | 
						|
    // Insert this image package.
 | 
						|
    //
 | 
						|
    PackageListNode->ImagePkg = ImagePackage;
 | 
						|
    PackageListNode->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Append the new block here
 | 
						|
  //
 | 
						|
  if (Image->Flags == EFI_IMAGE_TRANSPARENT) {
 | 
						|
    ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT_TRANS;
 | 
						|
  } else {
 | 
						|
    ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT;
 | 
						|
  }
 | 
						|
  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Width, Image->Width);
 | 
						|
  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Height, Image->Height);
 | 
						|
  CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Bitmap, Image->Bitmap, Image->Width * Image->Height);
 | 
						|
 | 
						|
  //
 | 
						|
  // Append the block end
 | 
						|
  //
 | 
						|
  ImageBlocks = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) ImageBlocks + NewBlockSize);
 | 
						|
  ImageBlocks->BlockType = EFI_HII_IIBT_END;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check whether need to get the contents of HiiDataBase.
 | 
						|
  // Only after ReadyToBoot to do the export.
 | 
						|
  //
 | 
						|
  if (gExportAfterReadyToBoot) {
 | 
						|
    HiiGetDatabaseInfo(&Private->HiiDatabase);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  This function retrieves the image specified by ImageId which is associated with
 | 
						|
  the specified PackageList and copies it into the buffer specified by Image.
 | 
						|
 | 
						|
  @param  Database               A pointer to the database list header.
 | 
						|
  @param  PackageList            Handle of the package list where this image will
 | 
						|
                                 be searched.
 | 
						|
  @param  ImageId                The image's id,, which is unique within
 | 
						|
                                 PackageList.
 | 
						|
  @param  Image                  Points to the image.
 | 
						|
  @param  BitmapOnly             TRUE to only return the bitmap type image.
 | 
						|
                                 FALSE to locate image decoder instance to decode image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The new image was returned successfully.
 | 
						|
  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the
 | 
						|
                                 database. The specified PackageList is not in the database.
 | 
						|
  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small to
 | 
						|
                                 hold the image.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The Image or ImageSize was NULL.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there was not
 | 
						|
                                 enough memory.
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                          Status;
 | 
						|
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
 | 
						|
  HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;
 | 
						|
  EFI_HII_IMAGE_BLOCK                 *CurrentImageBlock;
 | 
						|
  EFI_HII_IIBT_IMAGE_1BIT_BLOCK       Iibt1bit;
 | 
						|
  UINT16                              Width;
 | 
						|
  UINT16                              Height;
 | 
						|
  UINTN                               ImageLength;
 | 
						|
  UINT8                               *PaletteInfo;
 | 
						|
  UINT8                               PaletteIndex;
 | 
						|
  UINT16                              PaletteSize;
 | 
						|
  EFI_HII_IMAGE_DECODER_PROTOCOL      *Decoder;
 | 
						|
  EFI_IMAGE_OUTPUT                    *ImageOut;
 | 
						|
 | 
						|
  if (Image == NULL || ImageId == 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  PackageListNode = LocatePackageList (Database, PackageList);
 | 
						|
  if (PackageListNode == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
  ImagePackage = PackageListNode->ImagePkg;
 | 
						|
  if (ImagePackage == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Find the image block specified by ImageId
 | 
						|
  //
 | 
						|
  CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);
 | 
						|
  if (CurrentImageBlock == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  Image->Flags = 0;
 | 
						|
  switch (CurrentImageBlock->BlockType) {
 | 
						|
  case EFI_HII_IIBT_IMAGE_JPEG:
 | 
						|
  case EFI_HII_IIBT_IMAGE_PNG:
 | 
						|
    if (BitmapOnly) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    ImageOut = NULL;
 | 
						|
    Decoder = LocateHiiImageDecoder (CurrentImageBlock->BlockType);
 | 
						|
    if (Decoder == NULL) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Use the common block code since the definition of two structures is the same.
 | 
						|
    //
 | 
						|
    ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data));
 | 
						|
    ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data) ==
 | 
						|
            sizeof (((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Data));
 | 
						|
    ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Size) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Size));
 | 
						|
    ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size) ==
 | 
						|
            sizeof (((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size));
 | 
						|
    Status = Decoder->DecodeImage (
 | 
						|
      Decoder,
 | 
						|
      ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data,
 | 
						|
      ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size,
 | 
						|
      &ImageOut,
 | 
						|
      FALSE
 | 
						|
    );
 | 
						|
 | 
						|
    //
 | 
						|
    // Spec requires to use the first capable image decoder instance.
 | 
						|
    // The first image decoder instance may fail to decode the image.
 | 
						|
    //
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      Image->Bitmap = ImageOut->Image.Bitmap;
 | 
						|
      Image->Height = ImageOut->Height;
 | 
						|
      Image->Width = ImageOut->Width;
 | 
						|
      FreePool (ImageOut);
 | 
						|
    }
 | 
						|
    return Status;
 | 
						|
 | 
						|
  case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
 | 
						|
  case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
 | 
						|
  case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
 | 
						|
    Image->Flags = EFI_IMAGE_TRANSPARENT;
 | 
						|
    //
 | 
						|
    // fall through
 | 
						|
    //
 | 
						|
  case EFI_HII_IIBT_IMAGE_1BIT:
 | 
						|
  case EFI_HII_IIBT_IMAGE_4BIT:
 | 
						|
  case EFI_HII_IIBT_IMAGE_8BIT:
 | 
						|
    //
 | 
						|
    // Use the common block code since the definition of these structures is the same.
 | 
						|
    //
 | 
						|
    CopyMem (&Iibt1bit, CurrentImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));
 | 
						|
    ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *
 | 
						|
                  (Iibt1bit.Bitmap.Width * Iibt1bit.Bitmap.Height);
 | 
						|
    Image->Bitmap = AllocateZeroPool (ImageLength);
 | 
						|
    if (Image->Bitmap == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    Image->Width  = Iibt1bit.Bitmap.Width;
 | 
						|
    Image->Height = Iibt1bit.Bitmap.Height;
 | 
						|
 | 
						|
    PaletteInfo = ImagePackage->PaletteBlock + sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
 | 
						|
    for (PaletteIndex = 1; PaletteIndex < Iibt1bit.PaletteIndex; PaletteIndex++) {
 | 
						|
      CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));
 | 
						|
      PaletteInfo += PaletteSize + sizeof (UINT16);
 | 
						|
    }
 | 
						|
    ASSERT (PaletteIndex == Iibt1bit.PaletteIndex);
 | 
						|
 | 
						|
    //
 | 
						|
    // Output bitmap data
 | 
						|
    //
 | 
						|
    if (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT ||
 | 
						|
        CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT_TRANS) {
 | 
						|
      Output1bitPixel (
 | 
						|
        Image,
 | 
						|
        ((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,
 | 
						|
        (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo
 | 
						|
        );
 | 
						|
    } else if (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT ||
 | 
						|
               CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT_TRANS) {
 | 
						|
      Output4bitPixel (
 | 
						|
        Image,
 | 
						|
        ((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,
 | 
						|
        (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo
 | 
						|
        );
 | 
						|
    } else {
 | 
						|
      Output8bitPixel (
 | 
						|
        Image,
 | 
						|
        ((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,
 | 
						|
        (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    return EFI_SUCCESS;
 | 
						|
 | 
						|
  case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
 | 
						|
    Image->Flags = EFI_IMAGE_TRANSPARENT;
 | 
						|
    //
 | 
						|
    // fall through
 | 
						|
    //
 | 
						|
  case EFI_HII_IIBT_IMAGE_24BIT:
 | 
						|
    Width = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width);
 | 
						|
    Height = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height);
 | 
						|
    ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (Width * Height);
 | 
						|
    Image->Bitmap = AllocateZeroPool (ImageLength);
 | 
						|
    if (Image->Bitmap == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    Image->Width  = Width;
 | 
						|
    Image->Height = Height;
 | 
						|
 | 
						|
    //
 | 
						|
    // Output the bitmap data directly.
 | 
						|
    //
 | 
						|
    Output24bitPixel (
 | 
						|
      Image,
 | 
						|
      ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Bitmap
 | 
						|
      );
 | 
						|
    return EFI_SUCCESS;
 | 
						|
 | 
						|
  default:
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function retrieves the image specified by ImageId which is associated with
 | 
						|
  the specified PackageList and copies it into the buffer specified by Image.
 | 
						|
 | 
						|
  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
 | 
						|
  @param  PackageList            Handle of the package list where this image will
 | 
						|
                                 be searched.
 | 
						|
  @param  ImageId                The image's id,, which is unique within
 | 
						|
                                 PackageList.
 | 
						|
  @param  Image                  Points to the image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The new image was returned successfully.
 | 
						|
  @retval EFI_NOT_FOUND           The image specified by ImageId is not in the
 | 
						|
                                                database. The specified PackageList is not in the database.
 | 
						|
  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small to
 | 
						|
                                 hold the image.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The Image or ImageSize was NULL.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there was not
 | 
						|
                                 enough memory.
 | 
						|
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  HII_DATABASE_PRIVATE_DATA           *Private;
 | 
						|
  Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  return IGetImage (&Private->DatabaseList, PackageList, ImageId, Image, TRUE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  This function updates the image specified by ImageId in the specified PackageListHandle to
 | 
						|
  the image specified by Image.
 | 
						|
 | 
						|
  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
 | 
						|
  @param  PackageList            The package list containing the images.
 | 
						|
  @param  ImageId                The image's id,, which is unique within
 | 
						|
                                 PackageList.
 | 
						|
  @param  Image                  Points to the image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The new image was updated successfully.
 | 
						|
  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the
 | 
						|
                                                database. The specified PackageList is not in the database.    
 | 
						|
  @retval EFI_INVALID_PARAMETER  The Image was NULL.
 | 
						|
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  HII_DATABASE_PRIVATE_DATA           *Private;
 | 
						|
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
 | 
						|
  HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;
 | 
						|
  EFI_HII_IMAGE_BLOCK                 *CurrentImageBlock;
 | 
						|
  EFI_HII_IMAGE_BLOCK                 *ImageBlocks;
 | 
						|
  EFI_HII_IMAGE_BLOCK                 *NewImageBlock;
 | 
						|
  UINT32                              NewBlockSize;
 | 
						|
  UINT32                              OldBlockSize;
 | 
						|
  UINT32                               Part1Size;
 | 
						|
  UINT32                               Part2Size;
 | 
						|
 | 
						|
  if (This == NULL || Image == NULL || ImageId == 0 || Image->Bitmap == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
  PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);
 | 
						|
  if (PackageListNode == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
  ImagePackage = PackageListNode->ImagePkg;
 | 
						|
  if (ImagePackage == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Find the image block specified by ImageId
 | 
						|
  //
 | 
						|
  CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);
 | 
						|
  if (CurrentImageBlock == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the size of original image block. Use some common block code here
 | 
						|
  // since the definition of some structures is the same.
 | 
						|
  //
 | 
						|
  switch (CurrentImageBlock->BlockType) {
 | 
						|
  case EFI_HII_IIBT_IMAGE_JPEG:
 | 
						|
    OldBlockSize = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size);
 | 
						|
    break;
 | 
						|
  case EFI_HII_IIBT_IMAGE_PNG:
 | 
						|
    OldBlockSize = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size);
 | 
						|
    break;
 | 
						|
  case EFI_HII_IIBT_IMAGE_1BIT:
 | 
						|
  case EFI_HII_IIBT_IMAGE_1BIT_TRANS:
 | 
						|
    OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +
 | 
						|
                   BITMAP_LEN_1_BIT (
 | 
						|
                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                     );
 | 
						|
    break;
 | 
						|
  case EFI_HII_IIBT_IMAGE_4BIT:
 | 
						|
  case EFI_HII_IIBT_IMAGE_4BIT_TRANS:
 | 
						|
    OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +
 | 
						|
                   BITMAP_LEN_4_BIT (
 | 
						|
                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                     );
 | 
						|
    break;
 | 
						|
  case EFI_HII_IIBT_IMAGE_8BIT:
 | 
						|
  case EFI_HII_IIBT_IMAGE_8BIT_TRANS:
 | 
						|
    OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +
 | 
						|
                   BITMAP_LEN_8_BIT (
 | 
						|
                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                     );
 | 
						|
    break;
 | 
						|
  case EFI_HII_IIBT_IMAGE_24BIT:
 | 
						|
  case EFI_HII_IIBT_IMAGE_24BIT_TRANS:
 | 
						|
    OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
 | 
						|
                   BITMAP_LEN_24_BIT (
 | 
						|
                     ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),
 | 
						|
                     ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)
 | 
						|
                     );
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Create the new image block according to input image.
 | 
						|
  //
 | 
						|
  NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +
 | 
						|
                 BITMAP_LEN_24_BIT (Image->Width, Image->Height);
 | 
						|
  //
 | 
						|
  // Adjust the image package to remove the original block firstly then add the new block.
 | 
						|
  //
 | 
						|
  ImageBlocks = AllocateZeroPool (ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize);
 | 
						|
  if (ImageBlocks == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Part1Size = (UINT32) (UINTN) ((UINT8 *) CurrentImageBlock - (UINT8 *) ImagePackage->ImageBlock);
 | 
						|
  Part2Size = ImagePackage->ImageBlockSize - Part1Size - OldBlockSize;
 | 
						|
  CopyMem (ImageBlocks, ImagePackage->ImageBlock, Part1Size);
 | 
						|
 | 
						|
  //
 | 
						|
  // Set the new image block
 | 
						|
  //
 | 
						|
  NewImageBlock = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) ImageBlocks + Part1Size);
 | 
						|
  if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {
 | 
						|
    NewImageBlock->BlockType= EFI_HII_IIBT_IMAGE_24BIT_TRANS;
 | 
						|
  } else {
 | 
						|
    NewImageBlock->BlockType = EFI_HII_IIBT_IMAGE_24BIT;
 | 
						|
  }
 | 
						|
  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Width, Image->Width);
 | 
						|
  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Height, Image->Height);
 | 
						|
  CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Bitmap,
 | 
						|
                       Image->Bitmap, Image->Width * Image->Height);
 | 
						|
 | 
						|
  CopyMem ((UINT8 *) NewImageBlock + NewBlockSize, (UINT8 *) CurrentImageBlock + OldBlockSize, Part2Size);
 | 
						|
 | 
						|
  FreePool (ImagePackage->ImageBlock);
 | 
						|
  ImagePackage->ImageBlock                       = ImageBlocks;
 | 
						|
  ImagePackage->ImageBlockSize                  += NewBlockSize - OldBlockSize;
 | 
						|
  ImagePackage->ImagePkgHdr.Header.Length       += NewBlockSize - OldBlockSize;
 | 
						|
  PackageListNode->PackageListHdr.PackageLength += NewBlockSize - OldBlockSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check whether need to get the contents of HiiDataBase.
 | 
						|
  // Only after ReadyToBoot to do the export.
 | 
						|
  //
 | 
						|
  if (gExportAfterReadyToBoot) {
 | 
						|
    HiiGetDatabaseInfo(&Private->HiiDatabase);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  This function renders an image to a bitmap or the screen using the specified
 | 
						|
  color and options. It draws the image on an existing bitmap, allocates a new
 | 
						|
  bitmap or uses the screen. The images can be clipped.
 | 
						|
 | 
						|
  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
 | 
						|
  @param  Flags                  Describes how the image is to be drawn.
 | 
						|
  @param  Image                  Points to the image to be displayed.
 | 
						|
  @param  Blt                    If this points to a non-NULL on entry, this points
 | 
						|
                                 to the image, which is Width pixels wide and
 | 
						|
                                 Height pixels high.  The image will be drawn onto
 | 
						|
                                 this image and  EFI_HII_DRAW_FLAG_CLIP is implied.
 | 
						|
                                 If this points to a  NULL on entry, then a buffer
 | 
						|
                                 will be allocated to hold  the generated image and
 | 
						|
                                 the pointer updated on exit. It is the caller's
 | 
						|
                                 responsibility to free this buffer.
 | 
						|
  @param  BltX                   Specifies the offset from the left and top edge of
 | 
						|
                                 the  output image of the first pixel in the image.
 | 
						|
  @param  BltY                   Specifies the offset from the left and top edge of
 | 
						|
                                 the  output image of the first pixel in the image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The image was successfully drawn.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for Blt.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The Image or Blt was NULL.
 | 
						|
  @retval EFI_INVALID_PARAMETER  Any combination of Flags is invalid.
 | 
						|
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                          Status;
 | 
						|
  HII_DATABASE_PRIVATE_DATA           *Private;
 | 
						|
  BOOLEAN                             Transparent;
 | 
						|
  EFI_IMAGE_OUTPUT                    *ImageOut;
 | 
						|
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BltBuffer;
 | 
						|
  UINTN                               BufferLen;
 | 
						|
  UINTN                               Width;
 | 
						|
  UINTN                               Height;
 | 
						|
  UINTN                               Xpos;
 | 
						|
  UINTN                               Ypos;
 | 
						|
  UINTN                               OffsetY1;
 | 
						|
  UINTN                               OffsetY2;
 | 
						|
  EFI_FONT_DISPLAY_INFO               *FontInfo;
 | 
						|
  UINTN                               Index;
 | 
						|
 | 
						|
  if (This == NULL || Image == NULL || Blt == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Flags & EFI_HII_DRAW_FLAG_CLIP) == EFI_HII_DRAW_FLAG_CLIP && *Blt == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_TRANSPARENT) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  FontInfo = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check whether the image will be drawn transparently or opaquely.
 | 
						|
  //
 | 
						|
  Transparent = FALSE;
 | 
						|
  if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_TRANS) {
 | 
						|
    Transparent = TRUE;
 | 
						|
  } else if ((Flags & EFI_HII_DRAW_FLAG_TRANSPARENT) == EFI_HII_DRAW_FLAG_FORCE_OPAQUE){
 | 
						|
    Transparent = FALSE;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending
 | 
						|
    // on the image's transparency setting.
 | 
						|
    //
 | 
						|
    if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {
 | 
						|
      Transparent = TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Image cannot be drawn transparently if Blt points to NULL on entry.
 | 
						|
  // Currently output to Screen transparently is not supported, either.
 | 
						|
  //
 | 
						|
  if (Transparent) {
 | 
						|
    if (*Blt == NULL) {
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    } else if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
 | 
						|
 | 
						|
  //
 | 
						|
  // When Blt points to a non-NULL on entry, this image will be drawn onto
 | 
						|
  // this bitmap or screen pointed by "*Blt" and EFI_HII_DRAW_FLAG_CLIP is implied.
 | 
						|
  // Otherwise a new bitmap will be allocated to hold this image.
 | 
						|
  //
 | 
						|
  if (*Blt != NULL) {
 | 
						|
    //
 | 
						|
    // Clip the image by (Width, Height)
 | 
						|
    //
 | 
						|
 | 
						|
    Width  = Image->Width;
 | 
						|
    Height = Image->Height;
 | 
						|
 | 
						|
    if (Width > (*Blt)->Width - BltX) {
 | 
						|
      Width = (*Blt)->Width - BltX;
 | 
						|
    }
 | 
						|
    if (Height > (*Blt)->Height - BltY) {
 | 
						|
      Height = (*Blt)->Height - BltY;
 | 
						|
    }
 | 
						|
 | 
						|
    BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
 | 
						|
    BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);
 | 
						|
    if (BltBuffer == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Width == Image->Width && Height == Image->Height) {
 | 
						|
      CopyMem (BltBuffer, Image->Bitmap, BufferLen);
 | 
						|
    } else {
 | 
						|
      for (Ypos = 0; Ypos < Height; Ypos++) {
 | 
						|
        OffsetY1 = Image->Width * Ypos;
 | 
						|
        OffsetY2 = Width * Ypos;
 | 
						|
        for (Xpos = 0; Xpos < Width; Xpos++) {
 | 
						|
          BltBuffer[OffsetY2 + Xpos] = Image->Bitmap[OffsetY1 + Xpos];
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Draw the image to existing bitmap or screen depending on flag.
 | 
						|
    //
 | 
						|
    if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
 | 
						|
      //
 | 
						|
      // Caller should make sure the current UGA console is grarphic mode.
 | 
						|
      //
 | 
						|
 | 
						|
      //
 | 
						|
      // Write the image directly to the output device specified by Screen.
 | 
						|
      //
 | 
						|
      Status = (*Blt)->Image.Screen->Blt (
 | 
						|
                                       (*Blt)->Image.Screen,
 | 
						|
                                       BltBuffer,
 | 
						|
                                       EfiBltBufferToVideo,
 | 
						|
                                       0,
 | 
						|
                                       0,
 | 
						|
                                       BltX,
 | 
						|
                                       BltY,
 | 
						|
                                       Width,
 | 
						|
                                       Height,
 | 
						|
                                       0
 | 
						|
                                       );
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Draw the image onto the existing bitmap specified by Bitmap.
 | 
						|
      //
 | 
						|
      Status = ImageToBlt (
 | 
						|
                 BltBuffer,
 | 
						|
                 BltX,
 | 
						|
                 BltY,
 | 
						|
                 Width,
 | 
						|
                 Height,
 | 
						|
                 Transparent,
 | 
						|
                 Blt
 | 
						|
                 );
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    FreePool (BltBuffer);
 | 
						|
    return Status;
 | 
						|
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Allocate a new bitmap to hold the incoming image.
 | 
						|
    //
 | 
						|
    Width  = Image->Width  + BltX;
 | 
						|
    Height = Image->Height + BltY;
 | 
						|
 | 
						|
    BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
 | 
						|
    BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);
 | 
						|
    if (BltBuffer == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    ImageOut = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
 | 
						|
    if (ImageOut == NULL) {
 | 
						|
      FreePool (BltBuffer);
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
    ImageOut->Width        = (UINT16) Width;
 | 
						|
    ImageOut->Height       = (UINT16) Height;
 | 
						|
    ImageOut->Image.Bitmap = BltBuffer;
 | 
						|
 | 
						|
    //
 | 
						|
    // BUGBUG: Now all the "blank" pixels are filled with system default background
 | 
						|
    // color. Not sure if it need to be updated or not.
 | 
						|
    //
 | 
						|
    Status = GetSystemFont (Private, &FontInfo, NULL);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (BltBuffer);
 | 
						|
      FreePool (ImageOut);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
    ASSERT (FontInfo != NULL);
 | 
						|
    for (Index = 0; Index < Width * Height; Index++) {
 | 
						|
      BltBuffer[Index] = FontInfo->BackgroundColor;
 | 
						|
    }
 | 
						|
    FreePool (FontInfo);
 | 
						|
 | 
						|
    //
 | 
						|
    // Draw the incoming image to the new created image.
 | 
						|
    //
 | 
						|
    *Blt = ImageOut;
 | 
						|
    return ImageToBlt (
 | 
						|
             Image->Bitmap,
 | 
						|
             BltX,
 | 
						|
             BltY,
 | 
						|
             Image->Width,
 | 
						|
             Image->Height,
 | 
						|
             Transparent,
 | 
						|
             Blt
 | 
						|
             );
 | 
						|
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  This function renders an image to a bitmap or the screen using the specified
 | 
						|
  color and options. It draws the image on an existing bitmap, allocates a new
 | 
						|
  bitmap or uses the screen. The images can be clipped.
 | 
						|
 | 
						|
  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.
 | 
						|
  @param  Flags                  Describes how the image is to be drawn.
 | 
						|
  @param  PackageList            The package list in the HII database to search for
 | 
						|
                                 the  specified image.
 | 
						|
  @param  ImageId                The image's id, which is unique within
 | 
						|
                                 PackageList.
 | 
						|
  @param  Blt                    If this points to a non-NULL on entry, this points
 | 
						|
                                 to the image, which is Width pixels wide and
 | 
						|
                                 Height pixels high. The image will be drawn onto
 | 
						|
                                 this image and
 | 
						|
                                 EFI_HII_DRAW_FLAG_CLIP is implied. If this points
 | 
						|
                                 to a  NULL on entry, then a buffer will be
 | 
						|
                                 allocated to hold  the generated image and the
 | 
						|
                                 pointer updated on exit. It is the caller's
 | 
						|
                                 responsibility to free this buffer.
 | 
						|
  @param  BltX                   Specifies the offset from the left and top edge of
 | 
						|
                                 the  output image of the first pixel in the image.
 | 
						|
  @param  BltY                   Specifies the offset from the left and top edge of
 | 
						|
                                 the  output image of the first pixel in the image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS            The image was successfully drawn.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for Blt.
 | 
						|
  @retval EFI_INVALID_PARAMETER  The Blt was NULL.
 | 
						|
  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the database. 
 | 
						|
                           The specified PackageList is not in the database.                             
 | 
						|
 | 
						|
**/
 | 
						|
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
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                          Status;
 | 
						|
  EFI_IMAGE_INPUT                     Image;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check input parameter.
 | 
						|
  //
 | 
						|
  if (This == NULL || Blt == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the specified Image.
 | 
						|
  //
 | 
						|
  Status = HiiGetImage (This, PackageList, ImageId, &Image);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Draw this image.
 | 
						|
  //
 | 
						|
  Status = HiiDrawImage (This, Flags, &Image, Blt, BltX, BltY);
 | 
						|
  if (Image.Bitmap != NULL) {
 | 
						|
    FreePool (Image.Bitmap);
 | 
						|
  }
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 |