]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/HiiDatabase: Add HiiImageEx implementation.
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 21 Sep 2016 09:48:13 +0000 (17:48 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Wed, 28 Sep 2016 08:22:04 +0000 (16:22 +0800)
According to UEFI spec, NewImageEx()/SetImageEx()/DrawImageEx()
implicitly call the non-Ex version interface
of HiiImage protocol.
GetImageEx()/DrawImageIdEx() are the enhanced version of
GetImage()/DrawImageId(), which can support decoding JPEG/PNG
through the help of HiiImageDecoder protocol.

Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Liming Gao <liming.gao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseEntry.c
MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
MdeModulePkg/Universal/HiiDatabaseDxe/ImageEx.c [new file with mode: 0644]

index 0ca2fba5ecefe34f29e7eb17b830d9d085a9cefc..ee4936466adf5aaa9c28120c8149d801b1e3b522 100644 (file)
@@ -20,6 +20,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/HiiFont.h>\r
 #include <Protocol/HiiImage.h>\r
+#include <Protocol/HiiImageEx.h>\r
+#include <Protocol/HiiImageDecoder.h>\r
 #include <Protocol/HiiString.h>\r
 #include <Protocol/HiiDatabase.h>\r
 #include <Protocol/HiiConfigRouting.h>\r
@@ -301,6 +303,7 @@ typedef struct _HII_DATABASE_PRIVATE_DATA {
   LIST_ENTRY                            DatabaseNotifyList;\r
   EFI_HII_FONT_PROTOCOL                 HiiFont;\r
   EFI_HII_IMAGE_PROTOCOL                HiiImage;\r
+  EFI_HII_IMAGE_EX_PROTOCOL             HiiImageEx;\r
   EFI_HII_STRING_PROTOCOL               HiiString;\r
   EFI_HII_DATABASE_PROTOCOL             HiiDatabase;\r
   EFI_HII_CONFIG_ROUTING_PROTOCOL       ConfigRouting;\r
@@ -327,6 +330,13 @@ typedef struct _HII_DATABASE_PRIVATE_DATA {
       HII_DATABASE_PRIVATE_DATA_SIGNATURE \\r
       )\r
 \r
+#define HII_IMAGE_EX_DATABASE_PRIVATE_DATA_FROM_THIS(a) \\r
+  CR (a, \\r
+      HII_DATABASE_PRIVATE_DATA, \\r
+      HiiImageEx, \\r
+      HII_DATABASE_PRIVATE_DATA_SIGNATURE \\r
+      )\r
+\r
 #define HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS(a) \\r
   CR (a, \\r
       HII_DATABASE_PRIVATE_DATA, \\r
@@ -813,6 +823,82 @@ HiiGetFontInfo (
 // EFI_HII_IMAGE_PROTOCOL interfaces\r
 //\r
 \r
+/**\r
+  Get the image id of last image block: EFI_HII_IIBT_END_BLOCK when input\r
+  ImageId is zero, otherwise return the address of the\r
+  corresponding image block with identifier specified by ImageId.\r
+\r
+  This is a internal function.\r
+\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
+EFI_HII_IMAGE_BLOCK *\r
+GetImageIdOrAddress (\r
+  IN EFI_HII_IMAGE_BLOCK *ImageBlocks,\r
+  IN OUT EFI_IMAGE_ID    *ImageId\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
+/**\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  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_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
+EFI_STATUS\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
+  IN  BOOLEAN                        BitmapOnly\r
+  );\r
+\r
+/**\r
+  Return the first HII image decoder instance which supports the DecoderName.\r
+\r
+  @param BlockType  The image block type.\r
+\r
+  @retval Pointer to the HII image decoder instance.\r
+**/\r
+EFI_HII_IMAGE_DECODER_PROTOCOL *\r
+LocateHiiImageDecoder (\r
+  UINT8                          BlockType\r
+  );\r
 \r
 /**\r
   This function adds the image Image to the group of images owned by PackageList, and returns\r
@@ -984,10 +1070,213 @@ HiiDrawImageId (
   IN OUT EFI_IMAGE_OUTPUT            **Blt,\r
   IN UINTN                           BltX,\r
   IN UINTN                           BltY\r
-  )\r
+  );\r
 \r
-;\r
+/**\r
+  The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.NewImage().\r
+  This protocol invokes EFI_HII_IMAGE_PROTOCOL.NewImage() implicitly.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  PackageList            Handle of the package list where this image will\r
+                                 be added.\r
+  @param  ImageId                On return, contains the new image id, which is\r
+                                 unique within PackageList.\r
+  @param  Image                  Points to the image.\r
+\r
+  @retval EFI_SUCCESS            The new image was added successfully.\r
+  @retval EFI_NOT_FOUND          The PackageList could not be found.\r
+  @retval EFI_OUT_OF_RESOURCES   Could not add the image due to lack of resources.\r
+  @retval EFI_INVALID_PARAMETER  Image is NULL or ImageId is NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiNewImageEx (\r
+  IN  CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN  EFI_HII_HANDLE                  PackageList,\r
+  OUT EFI_IMAGE_ID                    *ImageId,\r
+  IN  CONST EFI_IMAGE_INPUT           *Image\r
+  );\r
 \r
+/**\r
+  Return the information about the image, associated with the package list.\r
+  The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.GetImage().\r
+\r
+  This function is similar to EFI_HII_IMAGE_PROTOCOL.GetImage(). The difference is that\r
+  this function will locate all EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the\r
+  system if the decoder of the certain image type is not supported by the\r
+  EFI_HII_IMAGE_EX_PROTOCOL. The function will attempt to decode the image to the\r
+  EFI_IMAGE_INPUT using the first EFI_HII_IMAGE_DECODER_PROTOCOL instance that\r
+  supports the requested image type.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  PackageList            The package list in the HII database to search for the\r
+                                 specified image.\r
+  @param  ImageId                The image's id, which is unique within 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 available. The specified\r
+                                 PackageList is not in the Database.\r
+  @retval EFI_INVALID_PARAMETER  Image was NULL or ImageId was 0.\r
+  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there\r
+                                 was not enough memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetImageEx (\r
+  IN  CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN  EFI_HII_HANDLE                  PackageList,\r
+  IN  EFI_IMAGE_ID                    ImageId,\r
+  OUT EFI_IMAGE_INPUT                 *Image\r
+  );\r
+\r
+/**\r
+  Change the information about the image.\r
+\r
+  Same with EFI_HII_IMAGE_PROTOCOL.SetImage(), this protocol invokes\r
+  EFI_HII_IMAGE_PROTOCOL.SetImage()implicitly.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  PackageList            The package list containing the images.\r
+  @param  ImageId                The image's id, which is unique within PackageList.\r
+  @param  Image                  Points to the image.\r
+\r
+  @retval EFI_SUCCESS            The new image was successfully updated.\r
+  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the\r
+                                 database. The specified PackageList is not in\r
+                                 the database.\r
+  @retval EFI_INVALID_PARAMETER  The Image was NULL, the ImageId was 0 or\r
+                                 the Image->Bitmap was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiSetImageEx (\r
+  IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN EFI_HII_HANDLE                  PackageList,\r
+  IN EFI_IMAGE_ID                    ImageId,\r
+  IN CONST EFI_IMAGE_INPUT           *Image\r
+  );\r
+\r
+/**\r
+  Renders an image to a bitmap or to the display.\r
+\r
+  The prototype of this extension function is the same with\r
+  EFI_HII_IMAGE_PROTOCOL.DrawImage(). This protocol invokes\r
+  EFI_HII_IMAGE_PROTOCOL.DrawImage() implicitly.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  Flags                  Describes how the image is to be drawn.\r
+  @param  Image                  Points to the image to be displayed.\r
+  @param  Blt                    If this points to a non-NULL on entry, this points\r
+                                 to the image, which is Width pixels wide and\r
+                                 Height pixels high.  The image will be drawn onto\r
+                                 this image and  EFI_HII_DRAW_FLAG_CLIP is implied.\r
+                                 If this points to a NULL on entry, then a buffer\r
+                                 will be allocated to hold the generated image and\r
+                                 the pointer updated on exit. It is the caller's\r
+                                 responsibility to free this buffer.\r
+  @param  BltX                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+  @param  BltY                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+\r
+  @retval EFI_SUCCESS            The image was successfully drawn.\r
+  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for Blt.\r
+  @retval EFI_INVALID_PARAMETER  The Image or Blt was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiDrawImageEx (\r
+  IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN EFI_HII_DRAW_FLAGS              Flags,\r
+  IN CONST EFI_IMAGE_INPUT           *Image,\r
+  IN OUT EFI_IMAGE_OUTPUT            **Blt,\r
+  IN UINTN                           BltX,\r
+  IN UINTN                           BltY\r
+  );\r
+\r
+/**\r
+  Renders an image to a bitmap or the screen containing the contents of the specified\r
+  image.\r
+\r
+  This function is similar to EFI_HII_IMAGE_PROTOCOL.DrawImageId(). The difference is that\r
+  this function will locate all EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the\r
+  system if the decoder of the certain image type is not supported by the\r
+  EFI_HII_IMAGE_EX_PROTOCOL. The function will attempt to decode the image to the\r
+  EFI_IMAGE_INPUT using the first EFI_HII_IMAGE_DECODER_PROTOCOL instance that\r
+  supports the requested image type.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  Flags                  Describes how the image is to be drawn.\r
+  @param  PackageList            The package list in the HII database to search for\r
+                                 the  specified image.\r
+  @param  ImageId                The image's id, which is unique within PackageList.\r
+  @param  Blt                    If this points to a non-NULL on entry, this points\r
+                                 to the image, which is Width pixels wide and\r
+                                 Height pixels high. The image will be drawn onto\r
+                                 this image and EFI_HII_DRAW_FLAG_CLIP is implied.\r
+                                 If this points to a NULL on entry, then a buffer\r
+                                 will be allocated to hold  the generated image\r
+                                 and the pointer updated on exit. It is the caller's\r
+                                 responsibility to free this buffer.\r
+  @param  BltX                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+  @param  BltY                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+\r
+  @retval EFI_SUCCESS            The image was successfully drawn.\r
+  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for Blt.\r
+  @retval EFI_INVALID_PARAMETER  The Blt was NULL or ImageId was 0.\r
+  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the database.\r
+                                 The specified PackageList is not in the database.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiDrawImageIdEx (\r
+  IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN EFI_HII_DRAW_FLAGS              Flags,\r
+  IN EFI_HII_HANDLE                  PackageList,\r
+  IN EFI_IMAGE_ID                    ImageId,\r
+  IN OUT EFI_IMAGE_OUTPUT            **Blt,\r
+  IN UINTN                           BltX,\r
+  IN UINTN                           BltY\r
+  );\r
+\r
+/**\r
+  This function returns the image information to EFI_IMAGE_OUTPUT. Only the width\r
+  and height are returned to the EFI_IMAGE_OUTPUT instead of decoding the image\r
+  to the buffer. This function is used to get the geometry of the image. This function\r
+  will try to locate all of the EFI_HII_IMAGE_DECODER_PROTOCOL installed on the\r
+  system if the decoder of image type is not supported by the EFI_HII_IMAGE_EX_PROTOCOL.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_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 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 was NULL or the ImageId was 0.\r
+  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there\r
+                                 was not enough memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetImageInfo (\r
+  IN CONST  EFI_HII_IMAGE_EX_PROTOCOL       *This,\r
+  IN        EFI_HII_HANDLE                  PackageList,\r
+  IN        EFI_IMAGE_ID                    ImageId,\r
+  OUT       EFI_IMAGE_OUTPUT                *Image\r
+  );\r
 //\r
 // EFI_HII_STRING_PROTOCOL\r
 //\r
index 2fb619e05a8b70b25bbf312013f4f470659526df..f82a1f48fe05ab69db7568df54ea5f76826b9a43 100644 (file)
@@ -35,6 +35,7 @@
 [Sources]\r
   HiiDatabaseEntry.c\r
   Image.c\r
+  ImageEx.c\r
   HiiDatabase.h\r
   ConfigRouting.c\r
   String.c\r
@@ -63,7 +64,9 @@
 [Protocols]\r
   gEfiDevicePathProtocolGuid                                            ## SOMETIMES_CONSUMES\r
   gEfiHiiStringProtocolGuid                                             ## PRODUCES\r
-  gEfiHiiImageProtocolGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol  ## SOMETIMES_PRODUCES\r
+  gEfiHiiImageProtocolGuid        |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol  ## SOMETIMES_PRODUCES\r
+  gEfiHiiImageExProtocolGuid      |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol  ## SOMETIMES_PRODUCES\r
+  gEfiHiiImageDecoderProtocolGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol  ## SOMETIMES_CONSUMES\r
   gEfiHiiConfigRoutingProtocolGuid                                      ## PRODUCES\r
   gEfiHiiDatabaseProtocolGuid                                           ## PRODUCES\r
   gEfiHiiFontProtocolGuid                                               ## PRODUCES\r
@@ -85,6 +88,8 @@
   ## CONSUMES  ## Event\r
   ## PRODUCES  ## Event\r
   gEfiHiiKeyBoardLayoutGuid\r
+  gEfiHiiImageDecoderNameJpegGuid |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol  ## SOMETIMES_CONSUMES\r
+  gEfiHiiImageDecoderNamePngGuid  |gEfiMdeModulePkgTokenSpaceGuid.PcdSupportHiiImageProtocol  ## SOMETIMES_CONSUMES\r
 \r
 [Depex]\r
   TRUE\r
index b48254f670444889ecfe5783ee6160a889d7ab0c..9d09c60b23512cd4d567f55c8656603a35f0f071 100644 (file)
@@ -39,11 +39,19 @@ HII_DATABASE_PRIVATE_DATA mPrivate = {
     HiiGetFontInfo\r
   },\r
   {\r
-    NULL,\r
-    NULL,\r
-    NULL,\r
-    NULL,\r
-    NULL\r
+    HiiNewImage,\r
+    HiiGetImage,\r
+    HiiSetImage,\r
+    HiiDrawImage,\r
+    HiiDrawImageId\r
+  },\r
+  {\r
+    HiiNewImageEx,\r
+    HiiGetImageEx,\r
+    HiiSetImageEx,\r
+    HiiDrawImageEx,\r
+    HiiDrawImageIdEx,\r
+    HiiGetImageInfo\r
   },\r
   {\r
     HiiNewString,\r
@@ -96,14 +104,6 @@ HII_DATABASE_PRIVATE_DATA mPrivate = {
   NULL\r
 };\r
 \r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_HII_IMAGE_PROTOCOL mImageProtocol = {\r
-  HiiNewImage,\r
-  HiiGetImage,\r
-  HiiSetImage,\r
-  HiiDrawImage,\r
-  HiiDrawImageId\r
-};\r
-\r
 /**\r
   The default event handler for gHiiKeyboardLayoutChanged\r
   event group.\r
@@ -230,12 +230,10 @@ InitializeHiiDatabase (
   }\r
 \r
   if (FeaturePcdGet (PcdSupportHiiImageProtocol)) {\r
-    CopyMem (&mPrivate.HiiImage, &mImageProtocol, sizeof (mImageProtocol));\r
-\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &Handle,\r
-                    &gEfiHiiImageProtocolGuid,\r
-                    &mPrivate.HiiImage,\r
+                    &gEfiHiiImageProtocolGuid, &mPrivate.HiiImage,\r
+                    &gEfiHiiImageExProtocolGuid, &mPrivate.HiiImageEx,\r
                     NULL\r
                     );\r
 \r
index c8e9258ba67c217c39ab3bfee4010810b53620e3..1668828486a73a22f5634d97c39bb1adfe869fca 100644 (file)
@@ -643,10 +643,6 @@ HiiNewImage (
     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
   PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
   if (PackageListNode == NULL) {\r
@@ -781,33 +777,34 @@ 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
+  EFI_STATUS                          Status;\r
   HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;\r
   HII_IMAGE_PACKAGE_INSTANCE          *ImagePackage;\r
   EFI_HII_IMAGE_BLOCK                 *CurrentImageBlock;\r
@@ -818,17 +815,14 @@ HiiGetImage (
   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 == 0) {\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
-  PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
+  PackageListNode = LocatePackageList (Database, PackageList);\r
   if (PackageListNode == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -845,14 +839,47 @@ HiiGetImage (
     return EFI_NOT_FOUND;\r
   }\r
 \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
-    // HiiImage protocol doesn't support return JPEG/PNG.\r
-    // Use HiiImageEx instead.\r
+    // Use the common block code since the definition of two structures is the same.\r
     //\r
-    return EFI_UNSUPPORTED;\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
@@ -870,7 +897,7 @@ HiiGetImage (
     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
@@ -943,6 +970,41 @@ HiiGetImage (
   }\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
@@ -984,10 +1046,6 @@ HiiSetImage (
     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
   PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
   if (PackageListNode == NULL) {\r
@@ -1394,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
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ImageEx.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ImageEx.c
new file mode 100644 (file)
index 0000000..1e3f3bd
--- /dev/null
@@ -0,0 +1,423 @@
+/** @file\r
+Implementation for EFI_HII_IMAGE_EX_PROTOCOL.\r
+\r
+\r
+Copyright (c) 2016, 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
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include "HiiDatabase.h"\r
+\r
+/**\r
+  The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.NewImage().\r
+  This protocol invokes EFI_HII_IMAGE_PROTOCOL.NewImage() implicitly.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  PackageList            Handle of the package list where this image will\r
+                                 be added.\r
+  @param  ImageId                On return, contains the new image id, which is\r
+                                 unique within PackageList.\r
+  @param  Image                  Points to the image.\r
+\r
+  @retval EFI_SUCCESS            The new image was added successfully.\r
+  @retval EFI_NOT_FOUND          The PackageList could not be found.\r
+  @retval EFI_OUT_OF_RESOURCES   Could not add the image due to lack of resources.\r
+  @retval EFI_INVALID_PARAMETER  Image is NULL or ImageId is NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiNewImageEx (\r
+  IN  CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN  EFI_HII_HANDLE                  PackageList,\r
+  OUT EFI_IMAGE_ID                    *ImageId,\r
+  IN  CONST EFI_IMAGE_INPUT           *Image\r
+  )\r
+{\r
+  HII_DATABASE_PRIVATE_DATA           *Private;\r
+\r
+  Private = HII_IMAGE_EX_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  return HiiNewImage (&Private->HiiImage, PackageList, ImageId, Image);\r
+}\r
+\r
+/**\r
+  Return the information about the image, associated with the package list.\r
+  The prototype of this extension function is the same with EFI_HII_IMAGE_PROTOCOL.GetImage().\r
+\r
+  This function is similar to EFI_HII_IMAGE_PROTOCOL.GetImage().The difference is that\r
+  this function will locate all EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the\r
+  system if the decoder of the certain image type is not supported by the\r
+  EFI_HII_IMAGE_EX_PROTOCOL. The function will attempt to decode the image to the\r
+  EFI_IMAGE_INPUT using the first EFI_HII_IMAGE_DECODER_PROTOCOL instance that\r
+  supports the requested image type.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  PackageList            The package list in the HII database to search for the\r
+                                 specified image.\r
+  @param  ImageId                The image's id, which is unique within 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 available. The specified\r
+                                 PackageList is not in the Database.\r
+  @retval EFI_INVALID_PARAMETER  Image was NULL or ImageId was 0.\r
+  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there\r
+                                 was not enough memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetImageEx (\r
+  IN  CONST EFI_HII_IMAGE_EX_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
+\r
+  Private = HII_IMAGE_EX_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  return IGetImage (&Private->DatabaseList, PackageList, ImageId, Image, FALSE);\r
+}\r
+\r
+\r
+/**\r
+  Change the information about the image.\r
+\r
+  Same with EFI_HII_IMAGE_PROTOCOL.SetImage(),this protocol invokes\r
+  EFI_HII_IMAGE_PROTOCOL.SetImage()implicitly.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  PackageList            The package list containing the images.\r
+  @param  ImageId                The image's id, which is unique within PackageList.\r
+  @param  Image                  Points to the image.\r
+\r
+  @retval EFI_SUCCESS            The new image was successfully updated.\r
+  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the\r
+                                 database. The specified PackageList is not in\r
+                                 the database.\r
+  @retval EFI_INVALID_PARAMETER  The Image was NULL, the ImageId was 0 or\r
+                                 the Image->Bitmap was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiSetImageEx (\r
+  IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN EFI_HII_HANDLE                  PackageList,\r
+  IN EFI_IMAGE_ID                    ImageId,\r
+  IN CONST EFI_IMAGE_INPUT           *Image\r
+  )\r
+{\r
+  HII_DATABASE_PRIVATE_DATA           *Private;\r
+  Private = HII_IMAGE_EX_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  return HiiSetImage (&Private->HiiImage, PackageList, ImageId, Image);\r
+}\r
+\r
+\r
+/**\r
+  Renders an image to a bitmap or to the display.\r
+\r
+  The prototype of this extension function is the same with\r
+  EFI_HII_IMAGE_PROTOCOL.DrawImage(). This protocol invokes\r
+  EFI_HII_IMAGE_PROTOCOL.DrawImage() implicitly.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  Flags                  Describes how the image is to be drawn.\r
+  @param  Image                  Points to the image to be displayed.\r
+  @param  Blt                    If this points to a non-NULL on entry, this points\r
+                                 to the image, which is Width pixels wide and\r
+                                 Height pixels high.  The image will be drawn onto\r
+                                 this image and  EFI_HII_DRAW_FLAG_CLIP is implied.\r
+                                 If this points to a NULL on entry, then a buffer\r
+                                 will be allocated to hold the generated image and\r
+                                 the pointer updated on exit. It is the caller's\r
+                                 responsibility to free this buffer.\r
+  @param  BltX                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+  @param  BltY                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+\r
+  @retval EFI_SUCCESS            The image was successfully drawn.\r
+  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for Blt.\r
+  @retval EFI_INVALID_PARAMETER  The Image or Blt was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiDrawImageEx (\r
+  IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN EFI_HII_DRAW_FLAGS              Flags,\r
+  IN CONST EFI_IMAGE_INPUT           *Image,\r
+  IN OUT EFI_IMAGE_OUTPUT            **Blt,\r
+  IN UINTN                           BltX,\r
+  IN UINTN                           BltY\r
+  )\r
+{\r
+  HII_DATABASE_PRIVATE_DATA           *Private;\r
+  Private = HII_IMAGE_EX_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  return HiiDrawImage (&Private->HiiImage, Flags, Image, Blt, BltX, BltY);\r
+}\r
+\r
+\r
+/**\r
+  Renders an image to a bitmap or the screen containing the contents of the specified\r
+  image.\r
+\r
+  This function is similar to EFI_HII_IMAGE_PROTOCOL.DrawImageId(). The difference is that\r
+  this function will locate all EFI_HII_IMAGE_DECODER_PROTOCOL instances installed in the\r
+  system if the decoder of the certain image type is not supported by the\r
+  EFI_HII_IMAGE_EX_PROTOCOL. The function will attempt to decode the image to the\r
+  EFI_IMAGE_INPUT using the first EFI_HII_IMAGE_DECODER_PROTOCOL instance that\r
+  supports the requested image type.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_PROTOCOL instance.\r
+  @param  Flags                  Describes how the image is to be drawn.\r
+  @param  PackageList            The package list in the HII database to search for\r
+                                 the  specified image.\r
+  @param  ImageId                The image's id, which is unique within PackageList.\r
+  @param  Blt                    If this points to a non-NULL on entry, this points\r
+                                 to the image, which is Width pixels wide and\r
+                                 Height pixels high. The image will be drawn onto\r
+                                 this image and EFI_HII_DRAW_FLAG_CLIP is implied.\r
+                                 If this points to a NULL on entry, then a buffer\r
+                                 will be allocated to hold  the generated image\r
+                                 and the pointer updated on exit. It is the caller's\r
+                                 responsibility to free this buffer.\r
+  @param  BltX                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+  @param  BltY                   Specifies the offset from the left and top edge of\r
+                                 the output image of the first pixel in the image.\r
+\r
+  @retval EFI_SUCCESS            The image was successfully drawn.\r
+  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for Blt.\r
+  @retval EFI_INVALID_PARAMETER  The Blt was NULL or ImageId was 0.\r
+  @retval EFI_NOT_FOUND          The image specified by ImageId is not in the database.\r
+                                 The specified PackageList is not in the database.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiDrawImageIdEx (\r
+  IN CONST EFI_HII_IMAGE_EX_PROTOCOL *This,\r
+  IN EFI_HII_DRAW_FLAGS              Flags,\r
+  IN EFI_HII_HANDLE                  PackageList,\r
+  IN EFI_IMAGE_ID                    ImageId,\r
+  IN OUT EFI_IMAGE_OUTPUT            **Blt,\r
+  IN UINTN                           BltX,\r
+  IN UINTN                           BltY\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_IMAGE_INPUT                     Image;\r
+\r
+  //\r
+  // Check input parameter.\r
+  //\r
+  if (This == NULL || Blt == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Get the specified Image.\r
+  //\r
+  Status = HiiGetImageEx (This, PackageList, ImageId, &Image);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Draw this image.\r
+  //\r
+  Status = HiiDrawImageEx (This, Flags, &Image, Blt, BltX, BltY);\r
+  if (Image.Bitmap != NULL) {\r
+    FreePool (Image.Bitmap);\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Return the first HII image decoder instance which supports the DecoderName.\r
+\r
+  @param BlockType  The image block type.\r
+\r
+  @retval Pointer to the HII image decoder instance.\r
+**/\r
+EFI_HII_IMAGE_DECODER_PROTOCOL *\r
+LocateHiiImageDecoder (\r
+  UINT8                          BlockType\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_HII_IMAGE_DECODER_PROTOCOL *Decoder;\r
+  EFI_HANDLE                     *Handles;\r
+  UINTN                          HandleNum;\r
+  UINTN                          Index;\r
+  EFI_GUID                       *DecoderNames;\r
+  UINT16                         NumberOfDecoderName;\r
+  UINT16                         DecoderNameIndex;\r
+  EFI_GUID                       *DecoderName;\r
+\r
+  switch (BlockType) {\r
+  case EFI_HII_IIBT_IMAGE_JPEG:\r
+    DecoderName = &gEfiHiiImageDecoderNameJpegGuid;\r
+    break;\r
+\r
+  case EFI_HII_IIBT_IMAGE_PNG:\r
+    DecoderName = &gEfiHiiImageDecoderNamePngGuid;\r
+    break;\r
+\r
+  default:\r
+    ASSERT (FALSE);\r
+    return NULL;\r
+  }\r
+\r
+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiHiiImageDecoderProtocolGuid, NULL, &HandleNum, &Handles);\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+  for (Index = 0; Index < HandleNum; Index++) {\r
+    Status = gBS->HandleProtocol (Handles[Index], &gEfiHiiImageDecoderProtocolGuid, (VOID **) &Decoder);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    Status = Decoder->GetImageDecoderName (Decoder, &DecoderNames, &NumberOfDecoderName);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+    for (DecoderNameIndex = 0; DecoderNameIndex < NumberOfDecoderName; DecoderNameIndex++) {\r
+      if (CompareGuid (DecoderName, &DecoderNames[DecoderNameIndex])) {\r
+        return Decoder;\r
+      }\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  This function returns the image information to EFI_IMAGE_OUTPUT. Only the width\r
+  and height are returned to the EFI_IMAGE_OUTPUT instead of decoding the image\r
+  to the buffer. This function is used to get the geometry of the image. This function\r
+  will try to locate all of the EFI_HII_IMAGE_DECODER_PROTOCOL installed on the\r
+  system if the decoder of image type is not supported by the EFI_HII_IMAGE_EX_PROTOCOL.\r
+\r
+  @param  This                   A pointer to the EFI_HII_IMAGE_EX_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 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 was NULL or the ImageId was 0.\r
+  @retval EFI_OUT_OF_RESOURCES   The bitmap could not be retrieved because there\r
+                                 was not enough memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetImageInfo (\r
+  IN CONST  EFI_HII_IMAGE_EX_PROTOCOL       *This,\r
+  IN        EFI_HII_HANDLE                  PackageList,\r
+  IN        EFI_IMAGE_ID                    ImageId,\r
+  OUT       EFI_IMAGE_OUTPUT                *Image\r
+  )\r
+{\r
+  EFI_STATUS                              Status;\r
+  HII_DATABASE_PRIVATE_DATA               *Private;\r
+  HII_DATABASE_PACKAGE_LIST_INSTANCE      *PackageListNode;\r
+  HII_IMAGE_PACKAGE_INSTANCE              *ImagePackage;\r
+  EFI_HII_IMAGE_BLOCK                     *CurrentImageBlock;\r
+  EFI_HII_IMAGE_DECODER_PROTOCOL          *Decoder;\r
+  EFI_HII_IMAGE_DECODER_IMAGE_INFO_HEADER *ImageInfo;\r
+\r
+  if (Image == NULL || ImageId == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = HII_IMAGE_EX_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  PackageListNode = LocatePackageList (&Private->DatabaseList, PackageList);\r
+  if (PackageListNode == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  ImagePackage = PackageListNode->ImagePkg;\r
+  if (ImagePackage == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Find the image block specified by ImageId\r
+  //\r
+  CurrentImageBlock = GetImageIdOrAddress (ImagePackage->ImageBlock, &ImageId);\r
+  switch (CurrentImageBlock->BlockType) {\r
+  case EFI_HII_IIBT_IMAGE_JPEG:\r
+  case EFI_HII_IIBT_IMAGE_PNG:\r
+    Decoder = LocateHiiImageDecoder (CurrentImageBlock->BlockType);\r
+    if (Decoder == NULL) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    //\r
+    // Use the common block code since the definition of two structures is the same.\r
+    //\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->GetImageInfo (\r
+      Decoder,\r
+      ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Data,\r
+      ((EFI_HII_IIBT_JPEG_BLOCK *) CurrentImageBlock)->Size,\r
+      &ImageInfo\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->Height = ImageInfo->ImageHeight;\r
+      Image->Width = ImageInfo->ImageWidth;\r
+      Image->Image.Bitmap = NULL;\r
+      FreePool (ImageInfo);\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
+  case EFI_HII_IIBT_IMAGE_1BIT:\r
+  case EFI_HII_IIBT_IMAGE_4BIT:\r
+  case EFI_HII_IIBT_IMAGE_8BIT:\r
+    //\r
+    // Use the common block code since the definition of these structures is the same.\r
+    //\r
+    Image->Width = ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width);\r
+    Image->Height = ReadUnaligned16 (&((EFI_HII_IIBT_IMAGE_1BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height);\r
+    Image->Image.Bitmap = NULL;\r
+    return EFI_SUCCESS;\r
+\r
+  case EFI_HII_IIBT_IMAGE_24BIT_TRANS:\r
+  case EFI_HII_IIBT_IMAGE_24BIT:\r
+    Image->Width = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Width);\r
+    Image->Height = ReadUnaligned16 ((VOID *) &((EFI_HII_IIBT_IMAGE_24BIT_BLOCK *) CurrentImageBlock)->Bitmap.Height);\r
+    Image->Image.Bitmap = NULL;\r
+    return EFI_SUCCESS;\r
+\r
+  default:\r
+    return EFI_NOT_FOUND;\r
+  }\r
+}\r