]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
MdeModulePkg: Refine type cast for pointer subtraction
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Image.c
index e570913c6ffdd2fba54fa10e7cb35c552097203f..e2fa16e6e02bad5abee3cc8c79b68d2adee89930 100644 (file)
@@ -2,8 +2,8 @@
 Implementation for EFI_HII_IMAGE_PROTOCOL.\r
 \r
 \r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -24,51 +24,44 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
   This is a internal function.\r
 \r
-  @param ImageBlock      Points to the beginning of a series of image blocks stored in order.\r
+  @param ImageBlocks     Points to the beginning of a series of image blocks stored in order.\r
   @param ImageId         If input ImageId is 0, output the image id of the EFI_HII_IIBT_END_BLOCK;\r
                          else use this id to find its corresponding image block address.\r
 \r
   @return The image block address when input ImageId is not zero; otherwise return NULL.\r
 \r
 **/\r
-UINT8*\r
+EFI_HII_IMAGE_BLOCK *\r
 GetImageIdOrAddress (\r
-  IN  UINT8           *ImageBlock,\r
-  IN OUT EFI_IMAGE_ID *ImageId\r
+  IN EFI_HII_IMAGE_BLOCK *ImageBlocks,\r
+  IN OUT EFI_IMAGE_ID    *ImageId\r
   )\r
 {\r
   EFI_IMAGE_ID                   ImageIdCurrent;\r
-  UINT8                          *ImageBlockHdr;\r
-  UINT8                          Length8;\r
-  UINT16                         Length16;\r
-  UINT32                         Length32;\r
-  EFI_HII_IIBT_IMAGE_1BIT_BLOCK  Iibt1bit;\r
-  EFI_HII_IIBT_IMAGE_4BIT_BLOCK  Iibt4bit;\r
-  EFI_HII_IIBT_IMAGE_8BIT_BLOCK  Iibt8bit;\r
-  UINT16                         Width;\r
-  UINT16                         Height;\r
-\r
-  ASSERT (ImageBlock != NULL && ImageId != NULL);\r
-\r
-  ImageBlockHdr  = ImageBlock;\r
-  ImageIdCurrent = 1;\r
-\r
-  while (((EFI_HII_IMAGE_BLOCK *) ImageBlock)->BlockType != EFI_HII_IIBT_END) {\r
-    if (*ImageId > 0) {\r
+  EFI_HII_IMAGE_BLOCK            *CurrentImageBlock;\r
+  UINTN                          Length;\r
+\r
+  ASSERT (ImageBlocks != NULL && ImageId != NULL);\r
+  CurrentImageBlock = ImageBlocks;\r
+  ImageIdCurrent    = 1;\r
+\r
+  while (CurrentImageBlock->BlockType != EFI_HII_IIBT_END) {\r
+    if (*ImageId != 0) {\r
       if (*ImageId == ImageIdCurrent) {\r
         //\r
         // If the found image block is a duplicate block, update the ImageId to\r
         // find the previous defined image block.\r
         //\r
-        if (((EFI_HII_IMAGE_BLOCK *) ImageBlock)->BlockType == EFI_HII_IIBT_DUPLICATE) {\r
-          CopyMem (ImageId, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (EFI_IMAGE_ID));\r
+        if (CurrentImageBlock->BlockType == EFI_HII_IIBT_DUPLICATE) {\r
+          *ImageId = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_DUPLICATE_BLOCK *) CurrentImageBlock)->ImageId);\r
           ASSERT (*ImageId != ImageIdCurrent);\r
-          ImageBlock = ImageBlockHdr;\r
+          ASSERT (*ImageId != 0);\r
+          CurrentImageBlock = ImageBlocks;\r
           ImageIdCurrent = 1;\r
           continue;\r
         }\r
 \r
-        return ImageBlock;\r
+        return CurrentImageBlock;\r
       }\r
       if (*ImageId < ImageIdCurrent) {\r
         //\r
@@ -77,89 +70,80 @@ GetImageIdOrAddress (
         return NULL;\r
       }\r
     }\r
-    switch (((EFI_HII_IMAGE_BLOCK *) ImageBlock)->BlockType) {\r
+    switch (CurrentImageBlock->BlockType) {\r
     case EFI_HII_IIBT_EXT1:\r
-      Length8 = *(ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8));\r
-      ImageBlock += Length8;\r
-      ImageIdCurrent++;\r
+      Length = ((EFI_HII_IIBT_EXT1_BLOCK *) CurrentImageBlock)->Length;\r
       break;\r
     case EFI_HII_IIBT_EXT2:\r
-      CopyMem (\r
-        &Length16,\r
-        ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8),\r
-        sizeof (UINT16)\r
-        );\r
-      ImageBlock += Length16;\r
-      ImageIdCurrent++;\r
+      Length = ReadUnaligned16 (&((EFI_HII_IIBT_EXT2_BLOCK *) CurrentImageBlock)->Length);\r
       break;\r
     case EFI_HII_IIBT_EXT4:\r
-      CopyMem (\r
-        &Length32,\r
-        ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8),\r
-        sizeof (UINT32)\r
-        );\r
-      ImageBlock += Length32;\r
-      ImageIdCurrent++;\r
+      Length = ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_EXT4_BLOCK *) CurrentImageBlock)->Length);\r
       break;\r
 \r
     case EFI_HII_IIBT_IMAGE_1BIT:\r
     case EFI_HII_IIBT_IMAGE_1BIT_TRANS:\r
-      CopyMem (&Iibt1bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));\r
-      ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +\r
-                    BITMAP_LEN_1_BIT (Iibt1bit.Bitmap.Width, Iibt1bit.Bitmap.Height);\r
+      Length = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +\r
+               BITMAP_LEN_1_BIT (\r
+                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                 );\r
       ImageIdCurrent++;\r
       break;\r
 \r
     case EFI_HII_IIBT_IMAGE_4BIT:\r
     case EFI_HII_IIBT_IMAGE_4BIT_TRANS:\r
-      CopyMem (&Iibt4bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK));\r
-      ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +\r
-                    BITMAP_LEN_4_BIT (Iibt4bit.Bitmap.Width, Iibt4bit.Bitmap.Height);\r
+      Length = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +\r
+               BITMAP_LEN_4_BIT (\r
+                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                 );\r
       ImageIdCurrent++;\r
       break;\r
 \r
     case EFI_HII_IIBT_IMAGE_8BIT:\r
     case EFI_HII_IIBT_IMAGE_8BIT_TRANS:\r
-      CopyMem (&Iibt8bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK));\r
-      ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +\r
-                    BITMAP_LEN_8_BIT (Iibt8bit.Bitmap.Width, Iibt8bit.Bitmap.Height);\r
+      Length = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +\r
+               BITMAP_LEN_8_BIT (\r
+                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                 ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                 );\r
       ImageIdCurrent++;\r
       break;\r
 \r
     case EFI_HII_IIBT_IMAGE_24BIT:\r
     case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
-      CopyMem (&Width, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));\r
-      CopyMem (\r
-        &Height,\r
-        ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT16),\r
-        sizeof (UINT16)\r
-        );\r
-      ImageBlock += sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
-                    BITMAP_LEN_24_BIT (Width, Height);\r
+      Length = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
+               BITMAP_LEN_24_BIT (\r
+                 ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                 ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                 );\r
       ImageIdCurrent++;\r
       break;\r
 \r
     case EFI_HII_IIBT_DUPLICATE:\r
-      ImageBlock += sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK);\r
+      Length = sizeof (EFI_HII_IIBT_DUPLICATE_BLOCK);\r
       ImageIdCurrent++;\r
       break;\r
 \r
     case EFI_HII_IIBT_IMAGE_JPEG:\r
-      CopyMem (&Length32, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT32));\r
-      ImageBlock += Length32;\r
+      Length = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size);\r
+      ImageIdCurrent++;\r
+      break;\r
+\r
+    case EFI_HII_IIBT_IMAGE_PNG:\r
+      Length = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size);\r
       ImageIdCurrent++;\r
       break;\r
 \r
     case EFI_HII_IIBT_SKIP1:\r
-      Length8 = *(ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK));\r
-      ImageBlock += sizeof (EFI_HII_IIBT_SKIP1_BLOCK);\r
-      ImageIdCurrent = (UINT16) (ImageIdCurrent + Length8);\r
+      Length = sizeof (EFI_HII_IIBT_SKIP1_BLOCK);\r
+      ImageIdCurrent += ((EFI_HII_IIBT_SKIP1_BLOCK *) CurrentImageBlock)->SkipCount;\r
       break;\r
 \r
     case EFI_HII_IIBT_SKIP2:\r
-      CopyMem (&Length16, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));\r
-      ImageBlock += sizeof (EFI_HII_IIBT_SKIP2_BLOCK);\r
-      ImageIdCurrent = (UINT16) (ImageIdCurrent + Length16);\r
+      Length = sizeof (EFI_HII_IIBT_SKIP2_BLOCK);\r
+      ImageIdCurrent += ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_SKIP2_BLOCK *) CurrentImageBlock)->SkipCount);\r
       break;\r
 \r
     default:\r
@@ -167,7 +151,12 @@ GetImageIdOrAddress (
       // Unknown image blocks can not be skipped, processing halts.\r
       //\r
       ASSERT (FALSE);\r
+      Length = 0;\r
+      break;\r
     }\r
+\r
+    CurrentImageBlock = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) CurrentImageBlock + Length);\r
+\r
   }\r
 \r
   //\r
@@ -175,7 +164,7 @@ GetImageIdOrAddress (
   //\r
   if (*ImageId == 0) {\r
     *ImageId = ImageIdCurrent;\r
-    return ImageBlock;\r
+    return CurrentImageBlock;\r
   }\r
 \r
   return NULL;\r
@@ -269,7 +258,7 @@ Output1bitPixel (
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      PaletteValue[2];\r
   EFI_HII_IMAGE_PALETTE_INFO         *Palette;\r
-  UINT16                             PaletteSize;\r
+  UINT                             PaletteSize;\r
   UINT8                              Byte;\r
 \r
   ASSERT (Image != NULL && Data != NULL && PaletteInfo != NULL);\r
@@ -279,16 +268,20 @@ Output1bitPixel (
   //\r
   // First entry corresponds to color 0 and second entry corresponds to color 1.\r
   //\r
+  PaletteSize = 0;\r
   CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
   PaletteSize += sizeof (UINT16);\r
   Palette = AllocateZeroPool (PaletteSize);\r
   ASSERT (Palette != NULL);\r
+  if (Palette == NULL) {\r
+    return;\r
+  }\r
   CopyMem (Palette, PaletteInfo, PaletteSize);\r
 \r
   ZeroMem (PaletteValue, sizeof (PaletteValue));\r
   CopyRgbToGopPixel (&PaletteValue[0], &Palette->PaletteValue[0], 1);\r
   CopyRgbToGopPixel (&PaletteValue[1], &Palette->PaletteValue[1], 1);\r
-  SafeFreePool (Palette);\r
+  FreePool (Palette);\r
 \r
   //\r
   // Convert the pixel from one bit to corresponding color.\r
@@ -353,7 +346,7 @@ Output4bitPixel (
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      PaletteValue[16];\r
   EFI_HII_IMAGE_PALETTE_INFO         *Palette;\r
-  UINT16                             PaletteSize;\r
+  UINT                             PaletteSize;\r
   UINT16                             PaletteNum;\r
   UINT8                              Byte;\r
 \r
@@ -364,16 +357,20 @@ Output4bitPixel (
   //\r
   // The bitmap should allocate each color index starting from 0.\r
   //\r
+  PaletteSize = 0;\r
   CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
   PaletteSize += sizeof (UINT16);\r
   Palette = AllocateZeroPool (PaletteSize);\r
   ASSERT (Palette != NULL);\r
+  if (Palette == NULL) {\r
+    return;\r
+  }\r
   CopyMem (Palette, PaletteInfo, PaletteSize);\r
   PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));\r
 \r
   ZeroMem (PaletteValue, sizeof (PaletteValue));\r
   CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);\r
-  SafeFreePool (Palette);\r
+  FreePool (Palette);\r
 \r
   //\r
   // Convert the pixel from 4 bit to corresponding color.\r
@@ -427,7 +424,7 @@ Output8bitPixel (
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BitMapPtr;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      PaletteValue[256];\r
   EFI_HII_IMAGE_PALETTE_INFO         *Palette;\r
-  UINT16                             PaletteSize;\r
+  UINT                             PaletteSize;\r
   UINT16                             PaletteNum;\r
   UINT8                              Byte;\r
 \r
@@ -438,15 +435,19 @@ Output8bitPixel (
   //\r
   // The bitmap should allocate each color index starting from 0.\r
   //\r
+  PaletteSize = 0;\r
   CopyMem (&PaletteSize, PaletteInfo, sizeof (UINT16));\r
   PaletteSize += sizeof (UINT16);\r
   Palette = AllocateZeroPool (PaletteSize);\r
   ASSERT (Palette != NULL);\r
+  if (Palette == NULL) {\r
+    return;\r
+  }\r
   CopyMem (Palette, PaletteInfo, PaletteSize);\r
   PaletteNum = (UINT16)(Palette->PaletteSize / sizeof (EFI_HII_RGB_PIXEL));\r
   ZeroMem (PaletteValue, sizeof (PaletteValue));\r
   CopyRgbToGopPixel (PaletteValue, Palette->PaletteValue, PaletteNum);\r
-  SafeFreePool (Palette);\r
+  FreePool (Palette);\r
 \r
   //\r
   // Convert the pixel from 8 bits to corresponding color.\r
@@ -573,6 +574,37 @@ ImageToBlt (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Return the HII package list identified by PackageList HII handle.\r
+\r
+  @param Database    Pointer to HII database list header.\r
+  @param PackageList HII handle of the package list to locate.\r
+\r
+  @retval The HII package list instance.\r
+**/\r
+HII_DATABASE_PACKAGE_LIST_INSTANCE *\r
+LocatePackageList (\r
+  IN  LIST_ENTRY                     *Database,\r
+  IN  EFI_HII_HANDLE                 PackageList\r
+  )\r
+{\r
+  LIST_ENTRY                         *Link;\r
+  HII_DATABASE_RECORD                *Record;\r
+\r
+  //\r
+  // Get the specified package list and image package.\r
+  //\r
+  for (Link = GetFirstNode (Database);\r
+       !IsNull (Database, Link);\r
+       Link = GetNextNode (Database, Link)\r
+      ) {\r
+    Record = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
+    if (Record->Handle == PackageList) {\r
+      return Record->PackageList;\r
+    }\r
+  }\r
+  return NULL;\r
+}\r
 \r
 /**\r
   This function adds the image Image to the group of images owned by PackageList, and returns\r
@@ -602,52 +634,23 @@ HiiNewImage (
   )\r
 {\r
   HII_DATABASE_PRIVATE_DATA           *Private;\r
-  LIST_ENTRY                          *Link;\r
-  HII_DATABASE_RECORD                 *DatabaseRecord;\r
   HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;\r
   HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;\r
-  UINT8                               *ImageBlock;\r
-  UINTN                               BlockSize;\r
-  UINT8                               *NewBlock;\r
-  UINT8                               *NewBlockPtr;\r
-  UINTN                               NewBlockSize;\r
-  EFI_IMAGE_INPUT                     *ImageIn;\r
+  EFI_HII_IMAGE_BLOCK                 *ImageBlocks;\r
+  UINT32                              NewBlockSize;\r
 \r
   if (This == NULL || ImageId == NULL || Image == NULL || Image->Bitmap == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!IsHiiHandleValid (PackageList)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
   Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  //\r
-  // Get the specified package list\r
-  //\r
-\r
-  PackageListNode = NULL;\r
-\r
-  for (Link = Private->DatabaseList.ForwardLink;\r
-       Link != &Private->DatabaseList;\r
-       Link = Link->ForwardLink\r
-      ) {\r
-    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
-    if (DatabaseRecord->Handle == PackageList) {\r
-      PackageListNode = DatabaseRecord->PackageList;\r
-      break;\r
-    }\r
-  }\r
-\r
+  PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
   if (PackageListNode == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  ImageIn = (EFI_IMAGE_INPUT *) Image;\r
-\r
   NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
-                 BITMAP_LEN_24_BIT (ImageIn->Width, ImageIn->Height);\r
+                 BITMAP_LEN_24_BIT (Image->Width, Image->Height);\r
 \r
   //\r
   // Get the image package in the package list,\r
@@ -666,39 +669,33 @@ HiiNewImage (
     //\r
     // Update the package's image block by appending the new block to the end.\r
     //\r
-    BlockSize  = ImagePackage->ImageBlockSize + NewBlockSize;\r
-    ImageBlock = (UINT8 *) AllocateZeroPool (BlockSize);\r
-    if (ImageBlock == NULL) {\r
+    ImageBlocks = AllocatePool (ImagePackage->ImageBlockSize + NewBlockSize);\r
+    if (ImageBlocks == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
     // Copy the original content.\r
     //\r
     CopyMem (\r
-      ImageBlock,\r
+      ImageBlocks,\r
       ImagePackage->ImageBlock,\r
       ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)\r
       );\r
-    SafeFreePool (ImagePackage->ImageBlock);\r
-    ImagePackage->ImageBlock = ImageBlock;\r
-    ImageBlock += ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK);\r
+    FreePool (ImagePackage->ImageBlock);\r
+    ImagePackage->ImageBlock = ImageBlocks;\r
+\r
     //\r
-    // Temp memory to store new block.\r
+    // Point to the very last block.\r
     //\r
-    NewBlock = AllocateZeroPool (NewBlockSize);\r
-    if (NewBlock == NULL) {\r
-      SafeFreePool (ImagePackage->ImageBlock);\r
-      ImagePackage->ImageBlock = NULL;\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    NewBlockPtr = NewBlock;\r
-\r
+    ImageBlocks = (EFI_HII_IMAGE_BLOCK *) (\r
+                    (UINT8 *) ImageBlocks + ImagePackage->ImageBlockSize - sizeof (EFI_HII_IIBT_END_BLOCK)\r
+                    );\r
     //\r
     // Update the length record.\r
     //\r
-    ImagePackage->ImageBlockSize = (UINT32) BlockSize;\r
-    ImagePackage->ImagePkgHdr.Header.Length += (UINT32) NewBlockSize;\r
-    PackageListNode->PackageListHdr.PackageLength += (UINT32) NewBlockSize;\r
+    ImagePackage->ImageBlockSize                  += NewBlockSize;\r
+    ImagePackage->ImagePkgHdr.Header.Length       += NewBlockSize;\r
+    PackageListNode->PackageListHdr.PackageLength += NewBlockSize;\r
 \r
   } else {\r
     //\r
@@ -714,11 +711,10 @@ HiiNewImage (
     // first image block so that id is initially to one.\r
     //\r
     *ImageId = 1;\r
-    BlockSize    = sizeof (EFI_HII_IIBT_END_BLOCK) + NewBlockSize;\r
     //\r
     // Fill in image package header.\r
     //\r
-    ImagePackage->ImagePkgHdr.Header.Length     = (UINT32) BlockSize + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
+    ImagePackage->ImagePkgHdr.Header.Length     = sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);\r
     ImagePackage->ImagePkgHdr.Header.Type       = EFI_HII_PACKAGE_IMAGES;\r
     ImagePackage->ImagePkgHdr.ImageInfoOffset   = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);\r
     ImagePackage->ImagePkgHdr.PaletteInfoOffset = 0;\r
@@ -732,24 +728,13 @@ HiiNewImage (
     //\r
     // Fill in image blocks.\r
     //\r
-    ImagePackage->ImageBlockSize = (UINT32) BlockSize;\r
-    ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (BlockSize);\r
+    ImagePackage->ImageBlockSize = NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK);\r
+    ImagePackage->ImageBlock = AllocateZeroPool (NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK));\r
     if (ImagePackage->ImageBlock == NULL) {\r
-      SafeFreePool (ImagePackage);\r
+      FreePool (ImagePackage);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    ImageBlock = ImagePackage->ImageBlock;\r
-\r
-    //\r
-    // Temp memory to store new block.\r
-    //\r
-    NewBlock = AllocateZeroPool (NewBlockSize);\r
-    if (NewBlock == NULL) {\r
-      SafeFreePool (ImagePackage->ImageBlock);\r
-      SafeFreePool (ImagePackage);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    NewBlockPtr = NewBlock;\r
+    ImageBlocks = ImagePackage->ImageBlock;\r
 \r
     //\r
     // Insert this image package.\r
@@ -761,26 +746,28 @@ HiiNewImage (
   //\r
   // Append the new block here\r
   //\r
-  if (ImageIn->Flags == EFI_IMAGE_TRANSPARENT) {\r
-    *NewBlock = EFI_HII_IIBT_IMAGE_24BIT_TRANS;\r
+  if (Image->Flags == EFI_IMAGE_TRANSPARENT) {\r
+    ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT_TRANS;\r
   } else {\r
-    *NewBlock = EFI_HII_IIBT_IMAGE_24BIT;\r
+    ImageBlocks->BlockType = EFI_HII_IIBT_IMAGE_24BIT;\r
   }\r
-  NewBlock++;\r
-  CopyMem (NewBlock, &ImageIn->Width, sizeof (UINT16));\r
-  NewBlock += sizeof (UINT16);\r
-  CopyMem (NewBlock, &ImageIn->Height, sizeof (UINT16));\r
-  NewBlock += sizeof (UINT16);\r
-  CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL *) NewBlock, ImageIn->Bitmap, ImageIn->Width * ImageIn->Height);\r
-\r
-  CopyMem (ImageBlock, NewBlockPtr, NewBlockSize);\r
-  SafeFreePool (NewBlockPtr);\r
+  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Width, Image->Width);\r
+  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Height, Image->Height);\r
+  CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) ImageBlocks)->Bitmap.Bitmap, Image->Bitmap, Image->Width * Image->Height);\r
 \r
   //\r
   // Append the block end\r
   //\r
-  ImageBlock += NewBlockSize;\r
-  ((EFI_HII_IIBT_END_BLOCK *) (ImageBlock))->Header.BlockType = EFI_HII_IIBT_END;\r
+  ImageBlocks = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) ImageBlocks + NewBlockSize);\r
+  ImageBlocks->BlockType = EFI_HII_IIBT_END;\r
+\r
+  //\r
+  // Check whether need to get the contents of HiiDataBase.\r
+  // Only after ReadyToBoot to do the export.\r
+  //\r
+  if (gExportAfterReadyToBoot) {\r
+    HiiGetDatabaseInfo(&Private->HiiDatabase);\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -790,73 +777,52 @@ HiiNewImage (
   This function retrieves the image specified by ImageId which is associated with\r
   the specified PackageList and copies it into the buffer specified by Image.\r
 \r
-  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
+  @param  Database               A pointer to the database list header.\r
   @param  PackageList            Handle of the package list where this image will\r
                                  be searched.\r
   @param  ImageId                The image's id,, which is unique within\r
                                  PackageList.\r
   @param  Image                  Points to the image.\r
+  @param  BitmapOnly             TRUE to only return the bitmap type image.\r
+                                 FALSE to locate image decoder instance to decode image.\r
 \r
   @retval EFI_SUCCESS            The new image was returned successfully.\r
-  @retval EFI_NOT_FOUND           The image specified by ImageId is not in the\r
-                                                database. The specified PackageList is not in the database.\r
+  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the\r
+                                 database. The specified PackageList is not in the database.\r
   @retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small to\r
                                  hold the image.\r
   @retval EFI_INVALID_PARAMETER  The Image or ImageSize was NULL.\r
   @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there was not\r
-                                                     enough memory.\r
-\r
+                                 enough memory.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-HiiGetImage (\r
-  IN  CONST EFI_HII_IMAGE_PROTOCOL   *This,\r
+IGetImage (\r
+  IN  LIST_ENTRY                     *Database,\r
   IN  EFI_HII_HANDLE                 PackageList,\r
   IN  EFI_IMAGE_ID                   ImageId,\r
-  OUT EFI_IMAGE_INPUT                *Image\r
+  OUT EFI_IMAGE_INPUT                *Image,\r
+  IN  BOOLEAN                        BitmapOnly\r
   )\r
 {\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  LIST_ENTRY                          *Link;\r
-  HII_DATABASE_RECORD                 *DatabaseRecord;\r
+  EFI_STATUS                          Status;\r
   HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;\r
   HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;\r
-  UINT8                               *ImageBlock;\r
-  EFI_IMAGE_ID                        LocalImageId;\r
-  UINT8                               BlockType;\r
+  EFI_HII_IMAGE_BLOCK                 *CurrentImageBlock;\r
   EFI_HII_IIBT_IMAGE_1BIT_BLOCK       Iibt1bit;\r
   UINT16                              Width;\r
   UINT16                              Height;\r
   UINTN                               ImageLength;\r
-  BOOLEAN                             Flag;\r
   UINT8                               *PaletteInfo;\r
   UINT8                               PaletteIndex;\r
   UINT16                              PaletteSize;\r
+  EFI_HII_IMAGE_DECODER_PROTOCOL      *Decoder;\r
+  EFI_IMAGE_OUTPUT                    *ImageOut;\r
 \r
-  if (This == NULL || Image == NULL || ImageId < 1) {\r
+  if (Image == NULL || ImageId == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!IsHiiHandleValid (PackageList)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  //\r
-  // Get the specified package list and image package.\r
-  //\r
-  PackageListNode = NULL;\r
-  for (Link = Private->DatabaseList.ForwardLink;\r
-       Link != &Private->DatabaseList;\r
-       Link = Link->ForwardLink\r
-      ) {\r
-    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
-    if (DatabaseRecord->Handle == PackageList) {\r
-      PackageListNode = DatabaseRecord->PackageList;\r
-      break;\r
-    }\r
-  }\r
+  PackageListNode = LocatePackageList (Database, PackageList);\r
   if (PackageListNode == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -868,27 +834,57 @@ HiiGetImage (
   //\r
   // Find the image block specified by ImageId\r
   //\r
-  LocalImageId = ImageId;\r
-  ImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &LocalImageId);\r
-  if (ImageBlock == NULL) {\r
+  CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);\r
+  if (CurrentImageBlock == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  Flag      = FALSE;\r
-  BlockType = *ImageBlock;\r
-\r
-  switch (BlockType) {\r
+  Image->Flags = 0;\r
+  switch (CurrentImageBlock->BlockType) {\r
   case EFI_HII_IIBT_IMAGE_JPEG:\r
+  case EFI_HII_IIBT_IMAGE_PNG:\r
+    if (BitmapOnly) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    ImageOut = NULL;\r
+    Decoder = LocateHiiImageDecoder (CurrentImageBlock->BlockType);\r
+    if (Decoder == NULL) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
     //\r
-    // BUGBUG: need to be supported as soon as image tool is designed.\r
+    // Use the common block code since the definition of two structures is the same.\r
     //\r
-    return EFI_UNSUPPORTED;\r
-    break;\r
+    ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data));\r
+    ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data) ==\r
+            sizeof (((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Data));\r
+    ASSERT (OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Size) == OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Size));\r
+    ASSERT (sizeof (((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size) ==\r
+            sizeof (((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size));\r
+    Status = Decoder->DecodeImage (\r
+      Decoder,\r
+      ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data,\r
+      ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size,\r
+      &ImageOut,\r
+      FALSE\r
+    );\r
+\r
+    //\r
+    // Spec requires to use the first capable image decoder instance.\r
+    // The first image decoder instance may fail to decode the image.\r
+    //\r
+    if (!EFI_ERROR (Status)) {\r
+      Image->Bitmap = ImageOut->Image.Bitmap;\r
+      Image->Height = ImageOut->Height;\r
+      Image->Width = ImageOut->Width;\r
+      FreePool (ImageOut);\r
+    }\r
+    return Status;\r
 \r
   case EFI_HII_IIBT_IMAGE_1BIT_TRANS:\r
   case EFI_HII_IIBT_IMAGE_4BIT_TRANS:\r
   case EFI_HII_IIBT_IMAGE_8BIT_TRANS:\r
-    Flag = TRUE;\r
+    Image->Flags = EFI_IMAGE_TRANSPARENT;\r
     //\r
     // fall through\r
     //\r
@@ -898,17 +894,14 @@ HiiGetImage (
     //\r
     // Use the common block code since the definition of these structures is the same.\r
     //\r
-    CopyMem (&Iibt1bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));\r
+    CopyMem (&Iibt1bit, CurrentImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));\r
     ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) *\r
                   (Iibt1bit.Bitmap.Width * Iibt1bit.Bitmap.Height);\r
-    Image->Bitmap = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (ImageLength);\r
+    Image->Bitmap = AllocateZeroPool (ImageLength);\r
     if (Image->Bitmap == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    if (Flag) {\r
-      Image->Flags = EFI_IMAGE_TRANSPARENT;\r
-    }\r
     Image->Width  = Iibt1bit.Bitmap.Width;\r
     Image->Height = Iibt1bit.Bitmap.Height;\r
 \r
@@ -922,69 +915,96 @@ HiiGetImage (
     //\r
     // Output bitmap data\r
     //\r
-    if (BlockType == EFI_HII_IIBT_IMAGE_1BIT || BlockType == EFI_HII_IIBT_IMAGE_1BIT_TRANS) {\r
+    if (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT ||\r
+        CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_1BIT_TRANS) {\r
       Output1bitPixel (\r
         Image,\r
-        (UINT8 *) (ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8)),\r
+        ((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,\r
         (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo\r
         );\r
-    } else if (BlockType == EFI_HII_IIBT_IMAGE_4BIT || BlockType == EFI_HII_IIBT_IMAGE_4BIT_TRANS) {\r
+    } else if (CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT ||\r
+               CurrentImageBlock->BlockType == EFI_HII_IIBT_IMAGE_4BIT_TRANS) {\r
       Output4bitPixel (\r
         Image,\r
-        (UINT8 *) (ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8)),\r
+        ((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,\r
         (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo\r
         );\r
     } else {\r
       Output8bitPixel (\r
         Image,\r
-        (UINT8 *) (ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8)),\r
+        ((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Data,\r
         (EFI_HII_IMAGE_PALETTE_INFO *) PaletteInfo\r
         );\r
     }\r
 \r
     return EFI_SUCCESS;\r
-    break;\r
 \r
   case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
-    Flag = TRUE;\r
+    Image->Flags = EFI_IMAGE_TRANSPARENT;\r
     //\r
     // fall through\r
     //\r
   case EFI_HII_IIBT_IMAGE_24BIT:\r
-    CopyMem (&Width, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));\r
-    CopyMem (\r
-      &Height,\r
-      ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT16),\r
-      sizeof (UINT16)\r
-      );\r
+    Width = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width);\r
+    Height = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height);\r
     ImageLength = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * (Width * Height);\r
-    Image->Bitmap = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (ImageLength);\r
+    Image->Bitmap = AllocateZeroPool (ImageLength);\r
     if (Image->Bitmap == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    if (Flag) {\r
-      Image->Flags = EFI_IMAGE_TRANSPARENT;\r
-    }\r
     Image->Width  = Width;\r
     Image->Height = Height;\r
 \r
     //\r
-    // Output the bimap data directly.\r
+    // Output the bitmap data directly.\r
     //\r
     Output24bitPixel (\r
       Image,\r
-      (EFI_HII_RGB_PIXEL *) (ImageBlock + sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL))\r
+      ((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Bitmap\r
       );\r
     return EFI_SUCCESS;\r
-    break;\r
 \r
   default:\r
     return EFI_NOT_FOUND;\r
-    break;\r
   }\r
 }\r
 \r
+/**\r
+  This function retrieves the image specified by ImageId which is associated with\r
+  the specified PackageList and copies it into the buffer specified by Image.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_PROTOCOL instance.\r
+  @param  PackageList            Handle of the package list where this image will\r
+                                 be searched.\r
+  @param  ImageId                The image's id,, which is unique within\r
+                                 PackageList.\r
+  @param  Image                  Points to the image.\r
+\r
+  @retval EFI_SUCCESS            The new image was returned successfully.\r
+  @retval EFI_NOT_FOUND           The image specified by ImageId is not in the\r
+                                                database. The specified PackageList is not in the database.\r
+  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small to\r
+                                 hold the image.\r
+  @retval EFI_INVALID_PARAMETER  The Image or ImageSize was NULL.\r
+  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there was not\r
+                                 enough memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetImage (\r
+  IN  CONST EFI_HII_IMAGE_PROTOCOL   *This,\r
+  IN  EFI_HII_HANDLE                 PackageList,\r
+  IN  EFI_IMAGE_ID                   ImageId,\r
+  OUT EFI_IMAGE_INPUT                *Image\r
+  )\r
+{\r
+  HII_DATABASE_PRIVATE_DATA           *Private;\r
+  Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  return IGetImage (&Private->DatabaseList, PackageList, ImageId, Image, TRUE);\r
+}\r
+\r
 \r
 /**\r
   This function updates the image specified by ImageId in the specified PackageListHandle to\r
@@ -1012,53 +1032,22 @@ HiiSetImage (
   )\r
 {\r
   HII_DATABASE_PRIVATE_DATA           *Private;\r
-  LIST_ENTRY                          *Link;\r
-  HII_DATABASE_RECORD                 *DatabaseRecord;\r
   HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;\r
   HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;\r
-  UINT8                               *ImageBlock;\r
-  EFI_IMAGE_ID                        LocalImageId;\r
-  UINT8                               BlockType;\r
-  EFI_HII_IIBT_IMAGE_1BIT_BLOCK       Iibt1bit;\r
-  EFI_HII_IIBT_IMAGE_4BIT_BLOCK       Iibt4bit;\r
-  EFI_HII_IIBT_IMAGE_8BIT_BLOCK       Iibt8bit;\r
-  UINT16                              Width;\r
-  UINT16                              Height;\r
-  UINT32                              BlockSize;\r
+  EFI_HII_IMAGE_BLOCK                 *CurrentImageBlock;\r
+  EFI_HII_IMAGE_BLOCK                 *ImageBlocks;\r
+  EFI_HII_IMAGE_BLOCK                 *NewImageBlock;\r
   UINT32                              NewBlockSize;\r
   UINT32                              OldBlockSize;\r
-  EFI_IMAGE_INPUT                     *ImageIn;\r
-  UINT8                               *NewBlock;\r
-  UINT8                               *NewBlockPtr;\r
-  UINT8                               *Block;\r
-  UINT8                               *BlockPtr;\r
   UINT32                               Part1Size;\r
   UINT32                               Part2Size;\r
 \r
-  if (This == NULL || Image == NULL || ImageId < 1 || Image->Bitmap == NULL) {\r
+  if (This == NULL || Image == NULL || ImageId == 0 || Image->Bitmap == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!IsHiiHandleValid (PackageList)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
   Private = HII_IMAGE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  //\r
-  // Get the specified package list and image package.\r
-  //\r
-  PackageListNode = NULL;\r
-  for (Link = Private->DatabaseList.ForwardLink;\r
-       Link != &Private->DatabaseList;\r
-       Link = Link->ForwardLink\r
-      ) {\r
-    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
-    if (DatabaseRecord->Handle == PackageList) {\r
-      PackageListNode = DatabaseRecord->PackageList;\r
-      break;\r
-    }\r
-  }\r
+  PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
   if (PackageListNode == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -1070,112 +1059,105 @@ HiiSetImage (
   //\r
   // Find the image block specified by ImageId\r
   //\r
-  LocalImageId = ImageId;\r
-  ImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &LocalImageId);\r
-  if (ImageBlock == NULL) {\r
+  CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);\r
+  if (CurrentImageBlock == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  BlockType = *ImageBlock;\r
-\r
   //\r
   // Get the size of original image block. Use some common block code here\r
   // since the definition of some structures is the same.\r
   //\r
-  switch (BlockType) {\r
+  switch (CurrentImageBlock->BlockType) {\r
   case EFI_HII_IIBT_IMAGE_JPEG:\r
-    //\r
-    // BUGBUG: need to be supported as soon as image tool is designed.\r
-    //\r
-    return EFI_UNSUPPORTED;\r
+    OldBlockSize = OFFSET_OF (EFI_HII_IIBT_JPEG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size);\r
+    break;\r
+  case EFI_HII_IIBT_IMAGE_PNG:\r
+    OldBlockSize = OFFSET_OF (EFI_HII_IIBT_PNG_BLOCK, Data) + ReadUnaligned32 ((VOID *) &((EFI_HII_IIBT_PNG_BLOCK *) CurrentImageBlock)->Size);\r
     break;\r
-\r
   case EFI_HII_IIBT_IMAGE_1BIT:\r
   case EFI_HII_IIBT_IMAGE_1BIT_TRANS:\r
-    CopyMem (&Iibt1bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK));\r
     OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_1BIT_BLOCK) - sizeof (UINT8) +\r
-                   BITMAP_LEN_1_BIT (Iibt1bit.Bitmap.Width, Iibt1bit.Bitmap.Height);\r
+                   BITMAP_LEN_1_BIT (\r
+                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                     );\r
     break;\r
   case EFI_HII_IIBT_IMAGE_4BIT:\r
   case EFI_HII_IIBT_IMAGE_4BIT_TRANS:\r
-    CopyMem (&Iibt4bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK));\r
     OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_4BIT_BLOCK) - sizeof (UINT8) +\r
-                   BITMAP_LEN_4_BIT (Iibt4bit.Bitmap.Width, Iibt4bit.Bitmap.Height);\r
+                   BITMAP_LEN_4_BIT (\r
+                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_4BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                     );\r
     break;\r
   case EFI_HII_IIBT_IMAGE_8BIT:\r
   case EFI_HII_IIBT_IMAGE_8BIT_TRANS:\r
-    CopyMem (&Iibt8bit, ImageBlock, sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK));\r
     OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_8BIT_BLOCK) - sizeof (UINT8) +\r
-                   BITMAP_LEN_8_BIT (Iibt8bit.Bitmap.Width, Iibt8bit.Bitmap.Height);\r
+                   BITMAP_LEN_8_BIT (\r
+                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                     ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_8BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                     );\r
     break;\r
   case EFI_HII_IIBT_IMAGE_24BIT:\r
   case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
-    CopyMem (&Width, ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK), sizeof (UINT16));\r
-    CopyMem (\r
-      &Height,\r
-      ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT16),\r
-      sizeof (UINT16)\r
-      );\r
     OldBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
-                   BITMAP_LEN_24_BIT (Width , Height);\r
+                   BITMAP_LEN_24_BIT (\r
+                     ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width),\r
+                     ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height)\r
+                     );\r
     break;\r
   default:\r
     return EFI_NOT_FOUND;\r
-    break;\r
   }\r
 \r
   //\r
   // Create the new image block according to input image.\r
   //\r
-  ImageIn = (EFI_IMAGE_INPUT *) Image;\r
   NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
-                 BITMAP_LEN_24_BIT (ImageIn->Width, ImageIn->Height);\r
-  NewBlock = (UINT8 *) AllocateZeroPool (NewBlockSize);\r
-  if (NewBlock == NULL) {\r
+                 BITMAP_LEN_24_BIT (Image->Width, Image->Height);\r
+  //\r
+  // Adjust the image package to remove the original block firstly then add the new block.\r
+  //\r
+  ImageBlocks = AllocateZeroPool (ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize);\r
+  if (ImageBlocks == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  NewBlockPtr = NewBlock;\r
-  if ((ImageIn->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {\r
-    *NewBlockPtr = EFI_HII_IIBT_IMAGE_24BIT_TRANS;\r
+  Part1Size = (UINT32) ((UINTN) CurrentImageBlock - (UINTN) ImagePackage->ImageBlock);\r
+  Part2Size = ImagePackage->ImageBlockSize - Part1Size - OldBlockSize;\r
+  CopyMem (ImageBlocks, ImagePackage->ImageBlock, Part1Size);\r
+\r
+  //\r
+  // Set the new image block\r
+  //\r
+  NewImageBlock = (EFI_HII_IMAGE_BLOCK *) ((UINT8 *) ImageBlocks + Part1Size);\r
+  if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {\r
+    NewImageBlock->BlockType= EFI_HII_IIBT_IMAGE_24BIT_TRANS;\r
   } else {\r
-    *NewBlockPtr = EFI_HII_IIBT_IMAGE_24BIT;\r
+    NewImageBlock->BlockType = EFI_HII_IIBT_IMAGE_24BIT;\r
   }\r
-  NewBlockPtr++;\r
+  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Width, Image->Width);\r
+  WriteUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Height, Image->Height);\r
+  CopyGopToRgbPixel (((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) NewImageBlock)->Bitmap.Bitmap,\r
+                       Image->Bitmap, Image->Width * Image->Height);\r
 \r
-  CopyMem (NewBlockPtr, &ImageIn->Width, sizeof (UINT16));\r
-  NewBlockPtr += sizeof (UINT16);\r
-  CopyMem (NewBlockPtr, &ImageIn->Height, sizeof (UINT16));\r
-  NewBlockPtr += sizeof (UINT16);\r
+  CopyMem ((UINT8 *) NewImageBlock + NewBlockSize, (UINT8 *) CurrentImageBlock + OldBlockSize, Part2Size);\r
 \r
-  CopyGopToRgbPixel ((EFI_HII_RGB_PIXEL *) NewBlockPtr, ImageIn->Bitmap, ImageIn->Width * ImageIn->Height);\r
+  FreePool (ImagePackage->ImageBlock);\r
+  ImagePackage->ImageBlock                       = ImageBlocks;\r
+  ImagePackage->ImageBlockSize                  += NewBlockSize - OldBlockSize;\r
+  ImagePackage->ImagePkgHdr.Header.Length       += NewBlockSize - OldBlockSize;\r
+  PackageListNode->PackageListHdr.PackageLength += NewBlockSize - OldBlockSize;\r
 \r
   //\r
-  // Adjust the image package to remove the original block firstly then add the new block.\r
+  // Check whether need to get the contents of HiiDataBase.\r
+  // Only after ReadyToBoot to do the export.\r
   //\r
-  BlockSize = ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize;\r
-  Block = (UINT8 *) AllocateZeroPool (BlockSize);\r
-  if (Block == NULL) {\r
-    SafeFreePool (NewBlock);\r
-    return EFI_OUT_OF_RESOURCES;\r
+  if (gExportAfterReadyToBoot) {\r
+    HiiGetDatabaseInfo(&Private->HiiDatabase);\r
   }\r
 \r
-  BlockPtr  = Block;\r
-  Part1Size = (UINT32) (ImageBlock - ImagePackage->ImageBlock);\r
-  Part2Size = ImagePackage->ImageBlockSize - Part1Size - OldBlockSize;\r
-  CopyMem (BlockPtr, ImagePackage->ImageBlock, Part1Size);\r
-  BlockPtr += Part1Size;\r
-  CopyMem (BlockPtr, NewBlock, NewBlockSize);\r
-  BlockPtr += NewBlockSize;\r
-  CopyMem (BlockPtr, ImageBlock + OldBlockSize, Part2Size);\r
-\r
-  SafeFreePool (ImagePackage->ImageBlock);\r
-  SafeFreePool (NewBlock);\r
-  ImagePackage->ImageBlock     = Block;\r
-  ImagePackage->ImageBlockSize = BlockSize;\r
-  ImagePackage->ImagePkgHdr.Header.Length += NewBlockSize - OldBlockSize;\r
-  PackageListNode->PackageListHdr.PackageLength += NewBlockSize - OldBlockSize;\r
-\r
   return EFI_SUCCESS;\r
 \r
 }\r
@@ -1222,7 +1204,6 @@ HiiDrawImage (
   EFI_STATUS                          Status;\r
   HII_DATABASE_PRIVATE_DATA           *Private;\r
   BOOLEAN                             Transparent;\r
-  EFI_IMAGE_INPUT                     *ImageIn;\r
   EFI_IMAGE_OUTPUT                    *ImageOut;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BltBuffer;\r
   UINTN                               BufferLen;\r
@@ -1234,7 +1215,6 @@ HiiDrawImage (
   UINTN                               OffsetY2;\r
   EFI_FONT_DISPLAY_INFO               *FontInfo;\r
   UINTN                               Index;\r
-  EFI_CONSOLE_CONTROL_PROTOCOL        *Console;\r
 \r
   if (This == NULL || Image == NULL || Blt == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1248,7 +1228,7 @@ HiiDrawImage (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  ImageIn = (EFI_IMAGE_INPUT *) Image;\r
+  FontInfo = NULL;\r
 \r
   //\r
   // Check whether the image will be drawn transparently or opaquely.\r
@@ -1263,7 +1243,7 @@ HiiDrawImage (
     // Now EFI_HII_DRAW_FLAG_DEFAULT is set, whether image will be drawn depending\r
     // on the image's transparency setting.\r
     //\r
-    if ((ImageIn->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {\r
+    if ((Image->Flags & EFI_IMAGE_TRANSPARENT) == EFI_IMAGE_TRANSPARENT) {\r
       Transparent = TRUE;\r
     }\r
   }\r
@@ -1292,8 +1272,8 @@ HiiDrawImage (
     // Clip the image by (Width, Height)\r
     //\r
 \r
-    Width  = ImageIn->Width;\r
-    Height = ImageIn->Height;\r
+    Width  = Image->Width;\r
+    Height = Image->Height;\r
 \r
     if (Width > (*Blt)->Width - BltX) {\r
       Width = (*Blt)->Width - BltX;\r
@@ -1308,14 +1288,14 @@ HiiDrawImage (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    if (Width == ImageIn->Width && Height == ImageIn->Height) {\r
-      CopyMem (BltBuffer, ImageIn->Bitmap, BufferLen);\r
+    if (Width == Image->Width && Height == Image->Height) {\r
+      CopyMem (BltBuffer, Image->Bitmap, BufferLen);\r
     } else {\r
       for (Ypos = 0; Ypos < Height; Ypos++) {\r
-        OffsetY1 = ImageIn->Width * Ypos;\r
+        OffsetY1 = Image->Width * Ypos;\r
         OffsetY2 = Width * Ypos;\r
         for (Xpos = 0; Xpos < Width; Xpos++) {\r
-          BltBuffer[OffsetY2 + Xpos] = ImageIn->Bitmap[OffsetY1 + Xpos];\r
+          BltBuffer[OffsetY2 + Xpos] = Image->Bitmap[OffsetY1 + Xpos];\r
         }\r
       }\r
     }\r
@@ -1324,17 +1304,10 @@ HiiDrawImage (
     // Draw the image to existing bitmap or screen depending on flag.\r
     //\r
     if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
-      Status = gBS->LocateProtocol (\r
-                      &gEfiConsoleControlProtocolGuid,\r
-                      NULL,\r
-                      (VOID **) &Console\r
-                      );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
+      //\r
+      // Caller should make sure the current UGA console is grarphic mode.\r
+      //\r
 \r
-      Console->SetMode (Console, EfiConsoleControlScreenGraphics);\r
       //\r
       // Write the image directly to the output device specified by Screen.\r
       //\r
@@ -1366,15 +1339,15 @@ HiiDrawImage (
 \r
     }\r
 \r
-    SafeFreePool (BltBuffer);\r
+    FreePool (BltBuffer);\r
     return Status;\r
 \r
   } else {\r
     //\r
     // Allocate a new bitmap to hold the incoming image.\r
     //\r
-    Width  = ImageIn->Width  + BltX;\r
-    Height = ImageIn->Height + BltY;\r
+    Width  = Image->Width  + BltX;\r
+    Height = Image->Height + BltY;\r
 \r
     BufferLen = Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
     BltBuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocateZeroPool (BufferLen);\r
@@ -1384,7 +1357,7 @@ HiiDrawImage (
 \r
     ImageOut = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
     if (ImageOut == NULL) {\r
-      SafeFreePool (BltBuffer);\r
+      FreePool (BltBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     ImageOut->Width        = (UINT16) Width;\r
@@ -1397,25 +1370,26 @@ HiiDrawImage (
     //\r
     Status = GetSystemFont (Private, &FontInfo, NULL);\r
     if (EFI_ERROR (Status)) {\r
-      SafeFreePool (BltBuffer);\r
-      SafeFreePool (ImageOut);\r
+      FreePool (BltBuffer);\r
+      FreePool (ImageOut);\r
       return Status;\r
     }\r
+    ASSERT (FontInfo != NULL);\r
     for (Index = 0; Index < Width * Height; Index++) {\r
       BltBuffer[Index] = FontInfo->BackgroundColor;\r
     }\r
-    SafeFreePool (FontInfo);\r
+    FreePool (FontInfo);\r
 \r
     //\r
     // Draw the incoming image to the new created image.\r
     //\r
     *Blt = ImageOut;\r
     return ImageToBlt (\r
-             ImageIn->Bitmap,\r
+             Image->Bitmap,\r
              BltX,\r
              BltY,\r
-             ImageIn->Width,\r
-             ImageIn->Height,\r
+             Image->Width,\r
+             Image->Height,\r
              Transparent,\r
              Blt\r
              );\r
@@ -1478,10 +1452,6 @@ HiiDrawImageId (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!IsHiiHandleValid (PackageList)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
   //\r
   // Get the specified Image.\r
   //\r
@@ -1494,7 +1464,9 @@ HiiDrawImageId (
   // Draw this image.\r
   //\r
   Status = HiiDrawImage (This, Flags, &Image, Blt, BltX, BltY);\r
-  SafeFreePool (Image.Bitmap);\r
+  if (Image.Bitmap != NULL) {\r
+    FreePool (Image.Bitmap);\r
+  }\r
   return Status;\r
 }\r
 \r