/** @file
Implementation for EFI_HII_IMAGE_PROTOCOL.


Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HiiDatabase.h"

#define MAX_UINT24  0xFFFFFF

/**
  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 (
                   (UINT32)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 (
                   (UINT32)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_UNION  *BitMapPtr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  PaletteValue[2];
  EFI_HII_IMAGE_PALETTE_INFO           *Palette;
  UINTN                                PaletteSize;
  UINT8                                Byte;

  ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);

  BitMapPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)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].Pixel, &Palette->PaletteValue[0], 1);
  CopyRgbToGopPixel (&PaletteValue[1].Pixel, &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) {
          CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)], &PaletteValue[1], sizeof (*BitMapPtr));
        } else {
          CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 8 + (8 - Index - 1)], &PaletteValue[0], sizeof (*BitMapPtr));
        }
      }
    }

    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) {
          CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index], &PaletteValue[1], sizeof (*BitMapPtr));
        } else {
          CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 8 + Index], &PaletteValue[0], sizeof (*BitMapPtr));
        }
      }
    }
  }
}

/**
  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_UNION  *BitMapPtr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  PaletteValue[16];
  EFI_HII_IMAGE_PALETTE_INFO           *Palette;
  UINTN                                PaletteSize;
  UINT16                               PaletteNum;
  UINT8                                Byte;

  ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);

  BitMapPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)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->Pixel, Palette->PaletteValue, MIN (PaletteNum, ARRAY_SIZE (PaletteValue)));
  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);
      CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 2], &PaletteValue[Byte >> 4], sizeof (*BitMapPtr));
      CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 2 + 1], &PaletteValue[Byte & 0x0F], sizeof (*BitMapPtr));
    }

    if (Image->Width % 2 != 0) {
      //
      // Padding bits in this byte should be ignored.
      //
      Byte = *(Data + OffsetY + Xpos);
      CopyMem (&BitMapPtr[Ypos * Image->Width + Xpos * 2], &PaletteValue[Byte >> 4], sizeof (*BitMapPtr));
    }
  }
}

/**
  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_UNION  *BitMapPtr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  PaletteValue[256];
  EFI_HII_IMAGE_PALETTE_INFO           *Palette;
  UINTN                                PaletteSize;
  UINT16                               PaletteNum;
  UINT8                                Byte;

  ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);

  BitMapPtr = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)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->Pixel, Palette->PaletteValue, MIN (PaletteNum, ARRAY_SIZE (PaletteValue)));
  FreePool (Palette);

  //
  // Convert the pixel from 8 bits to corresponding color.
  //
  for (Ypos = 0; Ypos < Image->Height; Ypos++) {
    OffsetY = BITMAP_LEN_8_BIT ((UINT32)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);
      CopyMem (&BitMapPtr[OffsetY + Xpos], &PaletteValue[Byte], sizeof (*BitMapPtr));
    }
  }
}

/**
  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 ((UINT32)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_UNION  SrcPixel;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  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++) {
      CopyMem (&SrcPixel, &BltBuffer[OffsetY1 + Xpos], sizeof (SrcPixel));
      if (Transparent) {
        if (CompareMem (&SrcPixel, &ZeroPixel, 3) != 0) {
          CopyMem (&ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos], &SrcPixel, sizeof (SrcPixel));
        }
      } else {
        CopyMem (&ImageOut->Image.Bitmap[OffsetY2 + BltX + Xpos], &SrcPixel, sizeof (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;
  }

  EfiAcquireLock (&mHiiDatabaseLock);

  //
  // Calcuate the size of new image.
  // Make sure the size doesn't overflow UINT32.
  // Note: 24Bit BMP occpuies 3 bytes per pixel.
  //
  NewBlockSize = (UINT32)Image->Width * Image->Height;
  if (NewBlockSize > (MAX_UINT32 - (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL))) / 3) {
    EfiReleaseLock (&mHiiDatabaseLock);
    return EFI_OUT_OF_RESOURCES;
  }

  NewBlockSize = NewBlockSize * 3 + (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL));

  //
  // 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.
    //

    //
    // Make sure the final package length doesn't overflow.
    // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
    //
    if (NewBlockSize > MAX_UINT24 - ImagePackage->ImagePkgHdr.Header.Length) {
      EfiReleaseLock (&mHiiDatabaseLock);
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Because ImagePackage->ImageBlockSize < ImagePackage->ImagePkgHdr.Header.Length,
    // So (ImagePackage->ImageBlockSize + NewBlockSize) <= MAX_UINT24
    //
    ImageBlocks = AllocatePool (ImagePackage->ImageBlockSize + NewBlockSize);
    if (ImageBlocks == NULL) {
      EfiReleaseLock (&mHiiDatabaseLock);
      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 {
    //
    // Make sure the final package length doesn't overflow.
    // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
    //
    if (NewBlockSize > MAX_UINT24 - (sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + sizeof (EFI_HII_IIBT_END_BLOCK))) {
      EfiReleaseLock (&mHiiDatabaseLock);
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // 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) {
      EfiReleaseLock (&mHiiDatabaseLock);
      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);
      EfiReleaseLock (&mHiiDatabaseLock);
      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, (UINT32)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);
  }

  EfiReleaseLock (&mHiiDatabaseLock);

  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 = (UINTN)Iibt1bit.Bitmap.Width * Iibt1bit.Bitmap.Height;
      if (ImageLength > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
        return EFI_OUT_OF_RESOURCES;
      }

      ImageLength  *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
      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 = (UINTN)Width * Height;
      if (ImageLength > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
        return EFI_OUT_OF_RESOURCES;
      }

      ImageLength  *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
      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;
  }

  EfiAcquireLock (&mHiiDatabaseLock);

  //
  // 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 (
                       (UINT32)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 (
                       (UINT32)ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Width),
                       ReadUnaligned16 ((VOID *)&((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *)CurrentImageBlock)->Bitmap.Height)
                       );
      break;
    default:
      EfiReleaseLock (&mHiiDatabaseLock);
      return EFI_NOT_FOUND;
  }

  //
  // Create the new image block according to input image.
  //

  //
  // Make sure the final package length doesn't overflow.
  // Length of the package header is represented using 24 bits. So MAX length is MAX_UINT24.
  // 24Bit BMP occpuies 3 bytes per pixel.
  //
  NewBlockSize = (UINT32)Image->Width * Image->Height;
  if (NewBlockSize > (MAX_UINT32 - (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL))) / 3) {
    EfiReleaseLock (&mHiiDatabaseLock);
    return EFI_OUT_OF_RESOURCES;
  }

  NewBlockSize = NewBlockSize * 3 + (sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL));
  if ((NewBlockSize > OldBlockSize) &&
      (NewBlockSize - OldBlockSize > MAX_UINT24 - ImagePackage->ImagePkgHdr.Header.Length)
      )
  {
    EfiReleaseLock (&mHiiDatabaseLock);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Adjust the image package to remove the original block firstly then add the new block.
  //
  ImageBlocks = AllocateZeroPool (ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize);
  if (ImageBlocks == NULL) {
    EfiReleaseLock (&mHiiDatabaseLock);
    return EFI_OUT_OF_RESOURCES;
  }

  Part1Size = (UINT32)((UINTN)CurrentImageBlock - (UINTN)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,
    (UINT32)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);
  }

  EfiReleaseLock (&mHiiDatabaseLock);
  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;
  UINT16                         Width;
  UINT16                         Height;
  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) {
    //
    // Make sure the BltX and BltY is inside the Blt area.
    //
    if ((BltX >= (*Blt)->Width) || (BltY >= (*Blt)->Height)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Clip the image by (Width, Height)
    //

    Width  = Image->Width;
    Height = Image->Height;

    if (Width > (*Blt)->Width - (UINT16)BltX) {
      Width = (*Blt)->Width - (UINT16)BltX;
    }

    if (Height > (*Blt)->Height - (UINT16)BltY) {
      Height = (*Blt)->Height - (UINT16)BltY;
    }

    //
    // Prepare the buffer for the temporary image.
    // Make sure the buffer size doesn't overflow UINTN.
    //
    BufferLen = Width * Height;
    if (BufferLen > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
      return EFI_OUT_OF_RESOURCES;
    }

    BufferLen *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
    BltBuffer  = 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;
        CopyMem (
          &BltBuffer[OffsetY2],
          &Image->Bitmap[OffsetY1],
          Width * sizeof (*BltBuffer)
          );
      }
    }

    //
    // 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 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.
    //

    //
    // Make sure the final width and height doesn't overflow UINT16.
    //
    if ((BltX > (UINTN)MAX_UINT16 - Image->Width) || (BltY > (UINTN)MAX_UINT16 - Image->Height)) {
      return EFI_INVALID_PARAMETER;
    }

    Width  = Image->Width  + (UINT16)BltX;
    Height = Image->Height + (UINT16)BltY;

    //
    // Make sure the output image size doesn't overflow UINTN.
    //
    BufferLen = Width * Height;
    if (BufferLen > MAX_UINTN / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) {
      return EFI_OUT_OF_RESOURCES;
    }

    BufferLen *= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
    BltBuffer  = 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        = Width;
    ImageOut->Height       = 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 < (UINTN)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;
}
