MdeModulePkg: Add BmpImageDecoderLib to provide BMP decoding capability
authorRuiyu Ni <ruiyu.ni@intel.com>
Thu, 12 Nov 2015 05:22:21 +0000 (05:22 +0000)
committerniruiyu <niruiyu@Edk2>
Thu, 12 Nov 2015 05:22:21 +0000 (05:22 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18771 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c [new file with mode: 0644]
MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dsc

diff --git a/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c b/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c
new file mode 100644 (file)
index 0000000..86dcc91
--- /dev/null
@@ -0,0 +1,272 @@
+/** @file\r
+  This library provides BMP image decoding capability.\r
+\r
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<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
+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
+#include <Uefi.h>\r
+#include <IndustryStandard/Bmp.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ImageDecoderLib.h>\r
+\r
+/**\r
+  Convert a *.BMP graphics image to a callee allocated GOP blt buffer.\r
+\r
+  @param  ImageFormat   Format of the image file.\r
+  @param  BmpImage      Pointer to BMP file\r
+  @param  BmpImageSize  Number of bytes in BmpImage\r
+  @param  GopBlt        Buffer containing GOP version of BmpImage.\r
+  @param  GopBltSize    Size of GopBlt in bytes.\r
+  @param  PixelHeight   Height of GopBlt/BmpImage in pixels\r
+  @param  PixelWidth    Width of GopBlt/BmpImage in pixels\r
+\r
+  @retval EFI_SUCCESS           GopBlt and GopBltSize are returned.\r
+  @retval EFI_INVALID_PARAMETER GopBlt or GopBltSize is NULL.\r
+  @retval EFI_UNSUPPORTED       BmpImage is not a valid *.BMP image\r
+  @retval EFI_OUT_OF_RESOURCES  No enough buffer to allocate.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BmpImageDecoderLibConvertBmpToGopBlt (\r
+  IN  IMAGE_FORMAT                  ImageFormat,\r
+  IN  UINT8                         *BmpImage,\r
+  IN  UINTN                         BmpImageSize,\r
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **GopBlt,\r
+  OUT UINTN                         *GopBltSize,\r
+  OUT UINTN                         *PixelWidth,\r
+  OUT UINTN                         *PixelHeight\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
+  UINT64                        BltBufferSize;\r
+  UINTN                         Index;\r
+  UINTN                         Height;\r
+  UINTN                         Width;\r
+  UINTN                         ImageIndex;\r
+  UINT32                        DataSizePerLine;\r
+  UINT32                        ColorMapNum;\r
+\r
+  ASSERT ((GopBlt != NULL) && (GopBltSize != NULL));\r
+\r
+  if (ImageFormat != ImageFormatBmp) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
+\r
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Doesn't support compress.\r
+  //\r
+  if (BmpHeader->CompressionType != 0) {\r
+    return EFI_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
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // The data size in each line must be 4 byte alignment.\r
+  //\r
+  DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);\r
+  BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);\r
+  if (BltBufferSize > (UINT32) ~0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((BmpHeader->Size != BmpImageSize) || \r
+      (BmpHeader->Size < BmpHeader->ImageOffset) ||\r
+      (BmpHeader->Size - BmpHeader->ImageOffset !=  BmpHeader->PixelHeight * DataSizePerLine)) {\r
+    return EFI_INVALID_PARAMETER;\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 EFI_INVALID_PARAMETER;\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 bmp data section.\r
+    //\r
+    if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {\r
+      return EFI_INVALID_PARAMETER;\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
+  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
+  //\r
+  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
+  //\r
+  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+\r
+  *GopBltSize = (UINTN) BltBufferSize;\r
+  *GopBlt     = AllocatePool (*GopBltSize);\r
+  if (*GopBlt == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *PixelWidth   = BmpHeader->PixelWidth;\r
+  *PixelHeight  = BmpHeader->PixelHeight;\r
+\r
+  //\r
+  // Convert 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
+        // Convert 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
+        // Convert 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
+        // Convert 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
+      default:\r
+        //\r
+        // Other bit format BMP is not supported.\r
+        //\r
+        return EFI_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 EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Initialize BmpImageDecoderLib library.\r
+\r
+  @param ImageHandle     The image handle.\r
+  @param SystemTable     The system table.\r
+\r
+  @retval EFI_SUCCESS    The BmpImageDecoderLib library is initialized correctly.\r
+  @return Other value if failed to initialize the BmpImageDecoderLib library.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BmpImageDecoderLibConstructor (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+)\r
+{\r
+  RegisterImageDecoder (BmpImageDecoderLibConvertBmpToGopBlt);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf b/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf
new file mode 100644 (file)
index 0000000..2d1c160
--- /dev/null
@@ -0,0 +1,42 @@
+## @file\r
+#  This library provides BMP image decoding capability.\r
+#  \r
+#  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<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
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BmpImageDecoderLib\r
+  FILE_GUID                      = DF414223-F17C-4022-A1F4-4062612AB00D\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION\r
+  CONSTRUCTOR                    = BmpImageDecoderLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  BmpImageDecoderLib.c\r
+  \r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  ImageDecoderLib
\ No newline at end of file
index 20af2d442ca1b484ad2e06f25c4f838023c162c3..5e3d8767d78e7e2db27d0a5a5e552680fe63a969 100644 (file)
   MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf\r
   MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf\r
   MdeModulePkg/Library/ImageDecoderLib/ImageDecoderLib.inf\r
   MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf\r
   MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf\r
   MdeModulePkg/Library/ImageDecoderLib/ImageDecoderLib.inf\r
+  MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf\r
   MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
   MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf\r
   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf\r
   MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
   MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf\r
   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf\r