]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add BmpSupportLib class and instance
authorKinney, Michael D <michael.d.kinney@intel.com>
Fri, 22 Dec 2017 19:24:38 +0000 (11:24 -0800)
committerMichael D Kinney <michael.d.kinney@intel.com>
Mon, 12 Feb 2018 00:04:54 +0000 (16:04 -0800)
https://bugzilla.tianocore.org/show_bug.cgi?id=800

Based on content from the following branch/commits:
https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
https://github.com/Microsoft/MS_UEFI/commit/33bab4031a417d7d5a7d356c15a14c2e60302b2d
https://github.com/Microsoft/MS_UEFI/commit/ca516b1a61315c2d823f453e12d2135098f53d61
https://github.com/Microsoft/MS_UEFI/commit/2b9f111f2e74a4c2ef4c4e32379e111f016dbd9b

Add BmpSupportLib class and instances that provides services to
convert a BMP graphics image to a GOP BLT buffer and to convert
a GOP BLT buffer to a BMP graphics image.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
MdeModulePkg/Include/Library/BmpSupportLib.h [new file with mode: 0644]
MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf [new file with mode: 0644]
MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.uni [new file with mode: 0644]
MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc

diff --git a/MdeModulePkg/Include/Library/BmpSupportLib.h b/MdeModulePkg/Include/Library/BmpSupportLib.h
new file mode 100644 (file)
index 0000000..69b993f
--- /dev/null
@@ -0,0 +1,106 @@
+/** @file\r
+\r
+Provides services to convert a BMP graphics image to a GOP BLT buffer\r
+and to convert a GOP BLT buffer to a BMP graphics image.\r
+\r
+Copyright (c) 2016, Microsoft Corporation\r
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+\r
+All rights reserved.\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+1. Redistributions of source code must retain the above copyright notice,\r
+this list of conditions and the following disclaimer.\r
+2. Redistributions in binary form must reproduce the above copyright notice,\r
+this list of conditions and the following disclaimer in the documentation\r
+ and/or other materials provided with the distribution.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+**/\r
+\r
+#ifndef __BMP_SUPPORT_LIB_H__\r
+#define __BMP_SUPPORT_LIB_H__\r
+\r
+#include <Protocol/GraphicsOutput.h>\r
+\r
+/**\r
+  Translate a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
+  is passed in a GopBlt buffer will be allocated by this routine using\r
+  EFI_BOOT_SERVICES.AllocatePool(). If a GopBlt buffer is passed in it will be\r
+  used if it is big enough.\r
+\r
+  @param [in]      BmpImage      Pointer to BMP file.\r
+  @param [in]      BmpImageSize  Number of bytes in BmpImage.\r
+  @param [in, out] GopBlt        Buffer containing GOP version of BmpImage.\r
+  @param [in, out] GopBltSize    Size of GopBlt in bytes.\r
+  @param [out]     PixelHeight   Height of GopBlt/BmpImage in pixels.\r
+  @param [out]     PixelWidth    Width of GopBlt/BmpImage in pixels.\r
+\r
+  @retval RETURN_SUCCESS            GopBlt and GopBltSize are returned.\r
+  @retval RETURN_INVALID_PARAMETER  BmpImage is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  GopBlt is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  GopBltSize is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  PixelHeight is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  PixelWidth is NULL.\r
+  @retval RETURN_UNSUPPORTED        BmpImage is not a valid *.BMP image.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The passed in GopBlt buffer is not big\r
+                                    enough.  The required size is returned in\r
+                                    GopBltSize.\r
+  @retval RETURN_OUT_OF_RESOURCES   The GopBlt buffer could not be allocated.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+TranslateBmpToGopBlt (\r
+  IN     VOID                           *BmpImage,\r
+  IN     UINTN                          BmpImageSize,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **GopBlt,\r
+  IN OUT UINTN                          *GopBltSize,\r
+  OUT    UINTN                          *PixelHeight,\r
+  OUT    UINTN                          *PixelWidth\r
+  );\r
+\r
+/**\r
+  Translate a GOP blt buffer to an uncompressed 24-bit per pixel BMP graphics\r
+  image. If a NULL BmpImage is passed in a BmpImage buffer will be allocated by\r
+  this routine using EFI_BOOT_SERVICES.AllocatePool(). If a BmpImage buffer is\r
+  passed in it will be used if it is big enough.\r
+\r
+  @param [in]      GopBlt        Pointer to GOP blt buffer.\r
+  @param [in]      PixelHeight   Height of GopBlt/BmpImage in pixels.\r
+  @param [in]      PixelWidth    Width of GopBlt/BmpImage in pixels.\r
+  @param [in, out] BmpImage      Buffer containing BMP version of GopBlt.\r
+  @param [in, out] BmpImageSize  Size of BmpImage in bytes.\r
+\r
+  @retval RETURN_SUCCESS            BmpImage and BmpImageSize are returned.\r
+  @retval RETURN_INVALID_PARAMETER  GopBlt is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  BmpImage is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  BmpImageSize is NULL.\r
+  @retval RETURN_UNSUPPORTED        GopBlt cannot be converted to a *.BMP image.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The passed in BmpImage buffer is not big\r
+                                    enough.  The required size is returned in\r
+                                    BmpImageSize.\r
+  @retval RETURN_OUT_OF_RESOURCES   The BmpImage buffer could not be allocated.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+TranslateGopBltToBmp (\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *GopBlt,\r
+  IN     UINT32                         PixelHeight,\r
+  IN     UINT32                         PixelWidth,\r
+  IN OUT VOID                           **BmpImage,\r
+  IN OUT UINT32                         *BmpImageSize\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf b/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
new file mode 100644 (file)
index 0000000..02c3fae
--- /dev/null
@@ -0,0 +1,49 @@
+## @file\r
+#\r
+# Provides services to convert a BMP graphics image to a GOP BLT buffer and\r
+# from a GOP BLT buffer to a BMP graphics image.\r
+#\r
+# Copyright (c) 2017, Microsoft Corporation\r
+#\r
+# All rights reserved.\r
+# Redistribution and use in source and binary forms, with or without\r
+# modification, are permitted provided that the following conditions are met:\r
+# 1. Redistributions of source code must retain the above copyright notice,\r
+# this list of conditions and the following disclaimer.\r
+# 2. Redistributions in binary form must reproduce the above copyright notice,\r
+# this list of conditions and the following disclaimer in the documentation\r
+# and/or other materials provided with the distribution.\r
+#\r
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION     = 0x00010017\r
+  BASE_NAME       = BaseBmpSupportLib\r
+  MODULE_UNI_FILE = BaseBmpSupportLib.uni\r
+  FILE_GUID       = CF5F650B-C208-409A-B889-0755172E2B0C\r
+  VERSION_STRING  = 1.0\r
+  MODULE_TYPE     = BASE\r
+  LIBRARY_CLASS   = BmpSupportLib\r
+\r
+[LibraryClasses]\r
+  DebugLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  SafeIntLib\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[Sources]\r
+  BmpSupportLib.c\r
diff --git a/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.uni b/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.uni
new file mode 100644 (file)
index 0000000..f24e2d2
--- /dev/null
@@ -0,0 +1,20 @@
+// /** @file\r
+//\r
+// Provides services to convert a BMP graphics image to a GOP BLT buffer and\r
+// from a GOP BLT buffer to a BMP graphics image.\r
+//\r
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+//\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
+// 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
+#string STR_MODULE_ABSTRACT             #language en-US "BmpSupportLib instance"\r
+\r
+#string STR_MODULE_DESCRIPTION          #language en-US "BmpSupportLib instance."\r
+\r
diff --git a/MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c b/MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c
new file mode 100644 (file)
index 0000000..2c95e91
--- /dev/null
@@ -0,0 +1,583 @@
+/** @file\r
+\r
+  Provides services to convert a BMP graphics image to a GOP BLT buffer and\r
+  from a GOP BLT buffer to a BMP graphics image.\r
+\r
+  Caution: This module requires additional review when modified.\r
+  This module processes external input - BMP image.\r
+  This external input must be validated carefully to avoid security issue such\r
+  as buffer overflow, integer overflow.\r
+\r
+  TranslateBmpToGopBlt() receives untrusted input and performs basic validation.\r
+\r
+  Copyright (c) 2016-2017, Microsoft Corporation\r
+  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+\r
+  All rights reserved.\r
+  Redistribution and use in source and binary forms, with or without\r
+  modification, are permitted provided that the following conditions are met:\r
+  1. Redistributions of source code must retain the above copyright notice,\r
+  this list of conditions and the following disclaimer.\r
+  2. Redistributions in binary form must reproduce the above copyright notice,\r
+  this list of conditions and the following disclaimer in the documentation\r
+  and/or other materials provided with the distribution.\r
+\r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/SafeIntLib.h>\r
+#include <IndustryStandard/Bmp.h>\r
+\r
+#include <Library/BmpSupportLib.h>\r
+\r
+//\r
+// BMP Image header for an uncompressed 24-bit per pixel BMP image.\r
+//\r
+const BMP_IMAGE_HEADER  mBmpImageHeaderTemplate = {\r
+  'B',    // CharB\r
+  'M',    // CharM\r
+  0,      // Size will be updated at runtime\r
+  {0, 0}, // Reserved\r
+  sizeof (BMP_IMAGE_HEADER), // ImageOffset\r
+  sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IMAGE_HEADER, HeaderSize), // HeaderSize\r
+  0,      // PixelWidth will be updated at runtime\r
+  0,      // PixelHeight will be updated at runtime\r
+  1,      // Planes\r
+  24,     // BitPerPixel\r
+  0,      // CompressionType\r
+  0,      // ImageSize will be updated at runtime\r
+  0,      // XPixelsPerMeter\r
+  0,      // YPixelsPerMeter\r
+  0,      // NumberOfColors\r
+  0       // ImportantColors\r
+};\r
+\r
+/**\r
+  Translate a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
+  is passed in a GopBlt buffer will be allocated by this routine using\r
+  EFI_BOOT_SERVICES.AllocatePool(). If a GopBlt buffer is passed in it will be\r
+  used if it is big enough.\r
+\r
+  @param[in]       BmpImage      Pointer to BMP file.\r
+  @param[in]       BmpImageSize  Number of bytes in BmpImage.\r
+  @param[in, out]  GopBlt        Buffer containing GOP version of BmpImage.\r
+  @param[in, out]  GopBltSize    Size of GopBlt in bytes.\r
+  @param[out]      PixelHeight   Height of GopBlt/BmpImage in pixels.\r
+  @param[out]      PixelWidth    Width of GopBlt/BmpImage in pixels.\r
+\r
+  @retval  RETURN_SUCCESS            GopBlt and GopBltSize are returned.\r
+  @retval  RETURN_INVALID_PARAMETER  BmpImage is NULL.\r
+  @retval  RETURN_INVALID_PARAMETER  GopBlt is NULL.\r
+  @retval  RETURN_INVALID_PARAMETER  GopBltSize is NULL.\r
+  @retval  RETURN_INVALID_PARAMETER  PixelHeight is NULL.\r
+  @retval  RETURN_INVALID_PARAMETER  PixelWidth is NULL.\r
+  @retval  RETURN_UNSUPPORTED        BmpImage is not a valid *.BMP image.\r
+  @retval  RETURN_BUFFER_TOO_SMALL   The passed in GopBlt buffer is not big\r
+                                     enough.  The required size is returned in\r
+                                     GopBltSize.\r
+  @retval  RETURN_OUT_OF_RESOURCES   The GopBlt buffer could not be allocated.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+TranslateBmpToGopBlt (\r
+  IN     VOID                           *BmpImage,\r
+  IN     UINTN                          BmpImageSize,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **GopBlt,\r
+  IN OUT UINTN                          *GopBltSize,\r
+  OUT    UINTN                          *PixelHeight,\r
+  OUT    UINTN                          *PixelWidth\r
+  )\r
+{\r
+  UINT8                          *Image;\r
+  UINT8                          *ImageHeader;\r
+  BMP_IMAGE_HEADER               *BmpHeader;\r
+  BMP_COLOR_MAP                  *BmpColorMap;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Blt;\r
+  UINT32                         BltBufferSize;\r
+  UINTN                          Index;\r
+  UINTN                          Height;\r
+  UINTN                          Width;\r
+  UINTN                          ImageIndex;\r
+  UINT32                         DataSizePerLine;\r
+  BOOLEAN                        IsAllocated;\r
+  UINT32                         ColorMapNum;\r
+  RETURN_STATUS                  Status;\r
+  UINT32                         DataSize;\r
+  UINT32                         Temp;\r
+\r
+  if (BmpImage == NULL || GopBlt == NULL || GopBltSize == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+  if (PixelHeight == NULL || PixelWidth == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BmpImageSize < sizeof (BMP_IMAGE_HEADER)) {\r
+    DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: BmpImageSize too small\n"));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  BmpHeader = (BMP_IMAGE_HEADER *)BmpImage;\r
+\r
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
+    DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: BmpHeader->Char fields incorrect\n"));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Doesn't support compress.\r
+  //\r
+  if (BmpHeader->CompressionType != 0) {\r
+    DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: Compression Type unsupported.\n"));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Only support BITMAPINFOHEADER format.\r
+  // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER\r
+  //\r
+  if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IMAGE_HEADER, HeaderSize)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: BmpHeader->Headership is not as expected.  Headersize is 0x%x\n",\r
+      BmpHeader->HeaderSize\r
+      ));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // The data size in each line must be 4 byte alignment.\r
+  //\r
+  Status = SafeUint32Mult (\r
+             BmpHeader->PixelWidth,\r
+             BmpHeader->BitPerPixel,\r
+             &DataSizePerLine\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: invalid BmpImage... PixelWidth:0x%x BitPerPixel:0x%x\n",\r
+      BmpHeader->PixelWidth,\r
+      BmpHeader->BitPerPixel\r
+      ));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  Status = SafeUint32Add (DataSizePerLine, 31, &DataSizePerLine);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: invalid BmpImage... DataSizePerLine:0x%x\n",\r
+      DataSizePerLine\r
+      ));\r
+\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  DataSizePerLine = (DataSizePerLine >> 3) &(~0x3);\r
+  Status = SafeUint32Mult (\r
+             DataSizePerLine,\r
+             BmpHeader->PixelHeight,\r
+             &BltBufferSize\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: invalid BmpImage... DataSizePerLine:0x%x PixelHeight:0x%x\n",\r
+      DataSizePerLine, BmpHeader->PixelHeight\r
+      ));\r
+\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  Status = SafeUint32Mult (\r
+             BmpHeader->PixelHeight,\r
+             DataSizePerLine,\r
+             &DataSize\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: invalid BmpImage... PixelHeight:0x%x DataSizePerLine:0x%x\n",\r
+      BmpHeader->PixelHeight, DataSizePerLine\r
+      ));\r
+\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  if ((BmpHeader->Size != BmpImageSize) ||\r
+      (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
+      (BmpHeader->Size - BmpHeader->ImageOffset != DataSize)) {\r
+\r
+    DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: invalid BmpImage... \n"));\r
+    DEBUG ((DEBUG_ERROR, "   BmpHeader->Size: 0x%x\n", BmpHeader->Size));\r
+    DEBUG ((DEBUG_ERROR, "   BmpHeader->ImageOffset: 0x%x\n", BmpHeader->ImageOffset));\r
+    DEBUG ((DEBUG_ERROR, "   BmpImageSize: 0x%lx\n", (UINTN)BmpImageSize));\r
+    DEBUG ((DEBUG_ERROR, "   DataSize: 0x%lx\n", (UINTN)DataSize));\r
+\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Calculate Color Map offset in the image.\r
+  //\r
+  Image = BmpImage;\r
+  BmpColorMap = (BMP_COLOR_MAP *)(Image + sizeof (BMP_IMAGE_HEADER));\r
+  if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {\r
+    switch (BmpHeader->BitPerPixel) {\r
+    case 1:\r
+      ColorMapNum = 2;\r
+      break;\r
+    case 4:\r
+      ColorMapNum = 16;\r
+      break;\r
+    case 8:\r
+      ColorMapNum = 256;\r
+      break;\r
+    default:\r
+      ColorMapNum = 0;\r
+      break;\r
+    }\r
+    //\r
+    // BMP file may has padding data between the bmp header section and the\r
+    // bmp data section.\r
+    //\r
+    if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Calculate graphics image data address in the image\r
+  //\r
+  Image = ((UINT8 *)BmpImage) + BmpHeader->ImageOffset;\r
+  ImageHeader = Image;\r
+\r
+  //\r
+  // Calculate the BltBuffer needed size.\r
+  //\r
+  Status = SafeUint32Mult (\r
+             BmpHeader->PixelWidth,\r
+             BmpHeader->PixelHeight,\r
+             &BltBufferSize\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: invalid BltBuffer needed size... PixelWidth:0x%x PixelHeight:0x%x\n",\r
+      BltBufferSize\r
+      ));\r
+\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  Temp = BltBufferSize;\r
+  Status = SafeUint32Mult (\r
+             BltBufferSize,\r
+             sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
+             &BltBufferSize\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateBmpToGopBlt: invalid BltBuffer needed size... BltBufferSize:0x%lx struct size:0x%x\n",\r
+      Temp, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+      ));\r
+\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  IsAllocated = FALSE;\r
+  if (*GopBlt == NULL) {\r
+    //\r
+    // GopBlt is not allocated by caller.\r
+    //\r
+    DEBUG ((DEBUG_INFO, "Bmp Support: Allocating 0x%X bytes of memory\n", BltBufferSize));\r
+    *GopBltSize = (UINTN)BltBufferSize;\r
+    *GopBlt = AllocatePool (*GopBltSize);\r
+    IsAllocated = TRUE;\r
+    if (*GopBlt == NULL) {\r
+      return RETURN_OUT_OF_RESOURCES;\r
+    }\r
+  } else {\r
+    //\r
+    // GopBlt has been allocated by caller.\r
+    //\r
+    if (*GopBltSize < (UINTN)BltBufferSize) {\r
+      *GopBltSize = (UINTN)BltBufferSize;\r
+      return RETURN_BUFFER_TOO_SMALL;\r
+    }\r
+  }\r
+\r
+  *PixelWidth  = BmpHeader->PixelWidth;\r
+  *PixelHeight = BmpHeader->PixelHeight;\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->ImageOffset 0x%X\n", BmpHeader->ImageOffset));\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->PixelWidth 0x%X\n", BmpHeader->PixelWidth));\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->PixelHeight 0x%X\n", BmpHeader->PixelHeight));\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->BitPerPixel 0x%X\n", BmpHeader->BitPerPixel));\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->ImageSize 0x%X\n", BmpHeader->ImageSize));\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->HeaderSize 0x%X\n", BmpHeader->HeaderSize));\r
+  DEBUG ((DEBUG_INFO, "BmpHeader->Size 0x%X\n", BmpHeader->Size));\r
+\r
+  //\r
+  // Translate image from BMP to Blt buffer format\r
+  //\r
+  BltBuffer = *GopBlt;\r
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
+    Blt = &BltBuffer[ (BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
+      switch (BmpHeader->BitPerPixel) {\r
+      case 1:\r
+        //\r
+        // Translate 1-bit (2 colors) BMP to 24-bit color\r
+        //\r
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
+          Blt->Red   = BmpColorMap[ ((*Image) >> (7 - Index)) & 0x1].Red;\r
+          Blt->Green = BmpColorMap[ ((*Image) >> (7 - Index)) & 0x1].Green;\r
+          Blt->Blue  = BmpColorMap[ ((*Image) >> (7 - Index)) & 0x1].Blue;\r
+          Blt++;\r
+          Width++;\r
+        }\r
+\r
+        Blt--;\r
+        Width--;\r
+        break;\r
+\r
+      case 4:\r
+        //\r
+        // Translate 4-bit (16 colors) BMP Palette to 24-bit color\r
+        //\r
+        Index = (*Image) >> 4;\r
+        Blt->Red   = BmpColorMap[Index].Red;\r
+        Blt->Green = BmpColorMap[Index].Green;\r
+        Blt->Blue  = BmpColorMap[Index].Blue;\r
+        if (Width < (BmpHeader->PixelWidth - 1)) {\r
+          Blt++;\r
+          Width++;\r
+          Index = (*Image) & 0x0f;\r
+          Blt->Red   = BmpColorMap[Index].Red;\r
+          Blt->Green = BmpColorMap[Index].Green;\r
+          Blt->Blue  = BmpColorMap[Index].Blue;\r
+        }\r
+        break;\r
+\r
+      case 8:\r
+        //\r
+        // Translate 8-bit (256 colors) BMP Palette to 24-bit color\r
+        //\r
+        Blt->Red   = BmpColorMap[*Image].Red;\r
+        Blt->Green = BmpColorMap[*Image].Green;\r
+        Blt->Blue  = BmpColorMap[*Image].Blue;\r
+        break;\r
+\r
+      case 24:\r
+        //\r
+        // It is 24-bit BMP.\r
+        //\r
+        Blt->Blue  = *Image++;\r
+        Blt->Green = *Image++;\r
+        Blt->Red   = *Image;\r
+        break;\r
+\r
+      case 32:\r
+        //\r
+        //Conver 32 bit to 24bit bmp - just ignore the final byte of each pixel\r
+        Blt->Blue  = *Image++;\r
+        Blt->Green = *Image++;\r
+        Blt->Red   = *Image++;\r
+        break;\r
+\r
+      default:\r
+        //\r
+        // Other bit format BMP is not supported.\r
+        //\r
+        if (IsAllocated) {\r
+          FreePool (*GopBlt);\r
+          *GopBlt = NULL;\r
+        }\r
+        DEBUG ((DEBUG_ERROR, "Bmp Bit format not supported.  0x%X\n", BmpHeader->BitPerPixel));\r
+        return RETURN_UNSUPPORTED;\r
+        break;\r
+      };\r
+\r
+    }\r
+\r
+    ImageIndex = (UINTN)(Image - ImageHeader);\r
+    if ((ImageIndex % 4) != 0) {\r
+      //\r
+      // Bmp Image starts each row on a 32-bit boundary!\r
+      //\r
+      Image = Image + (4 - (ImageIndex % 4));\r
+    }\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Translate a GOP blt buffer to an uncompressed 24-bit per pixel BMP graphics\r
+  image. If a NULL BmpImage is passed in a BmpImage buffer will be allocated by\r
+  this routine using EFI_BOOT_SERVICES.AllocatePool(). If a BmpImage buffer is\r
+  passed in it will be used if it is big enough.\r
+\r
+  @param [in]      GopBlt        Pointer to GOP blt buffer.\r
+  @param [in]      PixelHeight   Height of GopBlt/BmpImage in pixels.\r
+  @param [in]      PixelWidth    Width of GopBlt/BmpImage in pixels.\r
+  @param [in, out] BmpImage      Buffer containing BMP version of GopBlt.\r
+  @param [in, out] BmpImageSize  Size of BmpImage in bytes.\r
+\r
+  @retval RETURN_SUCCESS            BmpImage and BmpImageSize are returned.\r
+  @retval RETURN_INVALID_PARAMETER  GopBlt is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  BmpImage is NULL.\r
+  @retval RETURN_INVALID_PARAMETER  BmpImageSize is NULL.\r
+  @retval RETURN_UNSUPPORTED        GopBlt cannot be converted to a *.BMP image.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The passed in BmpImage buffer is not big\r
+                                    enough.  The required size is returned in\r
+                                    BmpImageSize.\r
+  @retval RETURN_OUT_OF_RESOURCES   The BmpImage buffer could not be allocated.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+TranslateGopBltToBmp (\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *GopBlt,\r
+  IN     UINT32                         PixelHeight,\r
+  IN     UINT32                         PixelWidth,\r
+  IN OUT VOID                           **BmpImage,\r
+  IN OUT UINT32                         *BmpImageSize\r
+  )\r
+{\r
+  RETURN_STATUS                  Status;\r
+  UINT32                         PaddingSize;\r
+  UINT32                         BmpSize;\r
+  BMP_IMAGE_HEADER               *BmpImageHeader;\r
+  UINT8                          *Image;\r
+  UINTN                          Col;\r
+  UINTN                          Row;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltPixel;\r
+\r
+  if (GopBlt == NULL || BmpImage == NULL || BmpImageSize == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Allocate memory for BMP file.\r
+  //\r
+  PaddingSize = PixelWidth & 0x3;\r
+\r
+  //\r
+  // First check PixelWidth * 3 + PaddingSize doesn't overflow\r
+  //\r
+  Status = SafeUint32Mult (PixelWidth, 3, &BmpSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWidth:0x%x\n",\r
+      PixelHeight,\r
+      PixelWidth\r
+      ));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  Status = SafeUint32Add (BmpSize, PaddingSize, &BmpSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWidth:0x%x\n",\r
+      PixelHeight,\r
+      PixelWidth\r
+      ));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Second check (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER) doesn't overflow\r
+  //\r
+  Status = SafeUint32Mult (BmpSize, PixelHeight, &BmpSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWidth:0x%x\n",\r
+      PixelHeight,\r
+      PixelWidth\r
+      ));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  Status = SafeUint32Add (BmpSize, sizeof (BMP_IMAGE_HEADER), &BmpSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWidth:0x%x\n",\r
+      PixelHeight,\r
+      PixelWidth\r
+      ));\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // The image should be stored in EfiBootServicesData, allowing the system to\r
+  // reclaim the memory\r
+  //\r
+  if (*BmpImage == NULL) {\r
+    *BmpImage = AllocateZeroPool (BmpSize);\r
+    if (*BmpImage == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    *BmpImageSize = BmpSize;\r
+  } else if (*BmpImageSize < BmpSize) {\r
+    *BmpImageSize = BmpSize;\r
+    return RETURN_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  BmpImageHeader = (BMP_IMAGE_HEADER *)*BmpImage;\r
+  CopyMem (BmpImageHeader, &mBmpImageHeaderTemplate, sizeof (BMP_IMAGE_HEADER));\r
+  BmpImageHeader->Size        = *BmpImageSize;\r
+  BmpImageHeader->ImageSize   = *BmpImageSize - sizeof (BMP_IMAGE_HEADER);\r
+  BmpImageHeader->PixelWidth  = PixelWidth;\r
+  BmpImageHeader->PixelHeight = PixelHeight;\r
+\r
+  //\r
+  // Convert BLT buffer to BMP file.\r
+  //\r
+  Image = (UINT8 *)BmpImageHeader + sizeof (BMP_IMAGE_HEADER);\r
+  for (Row = 0; Row < PixelHeight; Row++) {\r
+    BltPixel = &GopBlt[(PixelHeight - Row - 1) * PixelWidth];\r
+\r
+    for (Col = 0; Col < PixelWidth; Col++) {\r
+      *Image++ = BltPixel->Blue;\r
+      *Image++ = BltPixel->Green;\r
+      *Image++ = BltPixel->Red;\r
+      BltPixel++;\r
+    }\r
+\r
+    //\r
+    // Padding for 4 byte alignment.\r
+    //\r
+    Image += PaddingSize;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
index 0f3d8546ff67252c898f17100d9add80a15a87f4..455979386e3f7c05f7d20345ad106f89dc526d9e 100644 (file)
@@ -7,7 +7,7 @@
 # Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 # Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 # Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 # Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
-#\r
+# Copyright (c) 2016, Microsoft Corporation<BR>\r
 # This program and the accompanying materials are licensed and made available under\r
 # the terms and conditions of the BSD License that accompanies this distribution.\r
 # The full text of the license may be found at\r
 # This program and the accompanying materials are licensed and made available under\r
 # the terms and conditions of the BSD License that accompanies this distribution.\r
 # The full text of the license may be found at\r
   ##\r
   NonDiscoverableDeviceRegistrationLib|Include/Library/NonDiscoverableDeviceRegistrationLib.h\r
 \r
   ##\r
   NonDiscoverableDeviceRegistrationLib|Include/Library/NonDiscoverableDeviceRegistrationLib.h\r
 \r
+  ## @libraryclass  Provides services to convert a BMP graphics image to a GOP BLT buffer\r
+  #  and to convert a GOP BLT buffer to a BMP graphics image.\r
+  #\r
+  BmpSupportLib|Include/Library/BmpSupportLib.h\r
+\r
 [Guids]\r
   ## MdeModule package token space guid\r
   # Include/Guid/MdeModulePkgTokenSpace.h\r
 [Guids]\r
   ## MdeModule package token space guid\r
   # Include/Guid/MdeModulePkgTokenSpace.h\r
index 96b85ea4e305cd427148621b19595198b22b16b0..acefd70e2959a469bf602572b0155ca7d544fa54 100644 (file)
   MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf\r
   MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
   MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf\r
   MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf\r
   MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
   MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf\r
+  MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf\r
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r
 \r
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf\r