Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu...@intel.com>
Cc: Feng Tian <feng.t...@intel.com>
---
 .../BmpImageDecoderLib/BmpImageDecoderLib.c        | 272 +++++++++++++++++++++
 .../BmpImageDecoderLib/BmpImageDecoderLib.inf      |  42 ++++
 MdeModulePkg/MdeModulePkg.dsc                      |   1 +
 3 files changed, 315 insertions(+)
 create mode 100644 MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c
 create mode 100644 
MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf

diff --git a/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c 
b/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c
new file mode 100644
index 0000000..86dcc91
--- /dev/null
+++ b/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.c
@@ -0,0 +1,272 @@
+/** @file
+  This library provides BMP image decoding capability.
+
+Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available 
under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <IndustryStandard/Bmp.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ImageDecoderLib.h>
+
+/**
+  Convert a *.BMP graphics image to a callee allocated GOP blt buffer.
+
+  @param  ImageFormat   Format of the image file.
+  @param  BmpImage      Pointer to BMP file
+  @param  BmpImageSize  Number of bytes in BmpImage
+  @param  GopBlt        Buffer containing GOP version of BmpImage.
+  @param  GopBltSize    Size of GopBlt in bytes.
+  @param  PixelHeight   Height of GopBlt/BmpImage in pixels
+  @param  PixelWidth    Width of GopBlt/BmpImage in pixels
+
+  @retval EFI_SUCCESS           GopBlt and GopBltSize are returned.
+  @retval EFI_INVALID_PARAMETER GopBlt or GopBltSize is NULL.
+  @retval EFI_UNSUPPORTED       BmpImage is not a valid *.BMP image
+  @retval EFI_OUT_OF_RESOURCES  No enough buffer to allocate.
+
+**/
+EFI_STATUS
+EFIAPI
+BmpImageDecoderLibConvertBmpToGopBlt (
+  IN  IMAGE_FORMAT                  ImageFormat,
+  IN  UINT8                         *BmpImage,
+  IN  UINTN                         BmpImageSize,
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **GopBlt,
+  OUT UINTN                         *GopBltSize,
+  OUT UINTN                         *PixelWidth,
+  OUT UINTN                         *PixelHeight
+  )
+{
+  UINT8                         *Image;
+  UINT8                         *ImageHeader;
+  BMP_IMAGE_HEADER              *BmpHeader;
+  BMP_COLOR_MAP                 *BmpColorMap;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+  UINT64                        BltBufferSize;
+  UINTN                         Index;
+  UINTN                         Height;
+  UINTN                         Width;
+  UINTN                         ImageIndex;
+  UINT32                        DataSizePerLine;
+  UINT32                        ColorMapNum;
+
+  ASSERT ((GopBlt != NULL) && (GopBltSize != NULL));
+
+  if (ImageFormat != ImageFormatBmp) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
+    return EFI_UNSUPPORTED;
+  }
+
+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
+
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Doesn't support compress.
+  //
+  if (BmpHeader->CompressionType != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Only support BITMAPINFOHEADER format.
+  // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+  //
+  if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - 
OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // The data size in each line must be 4 byte alignment.
+  //
+  DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 
3) & (~0x3);
+  BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+  if (BltBufferSize > (UINT32) ~0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((BmpHeader->Size != BmpImageSize) || 
+      (BmpHeader->Size < BmpHeader->ImageOffset) ||
+      (BmpHeader->Size - BmpHeader->ImageOffset !=  BmpHeader->PixelHeight * 
DataSizePerLine)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Calculate Color Map offset in the image.
+  //
+  Image       = BmpImage;
+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+  if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+    switch (BmpHeader->BitPerPixel) {
+      case 1:
+        ColorMapNum = 2;
+        break;
+      case 4:
+        ColorMapNum = 16;
+        break;
+      case 8:
+        ColorMapNum = 256;
+        break;
+      default:
+        ColorMapNum = 0;
+        break;
+      }
+    //
+    // BMP file may has padding data between the bmp header section and the 
bmp data section.
+    //
+    if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof 
(BMP_COLOR_MAP) * ColorMapNum) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Calculate graphics image data address in the image
+  //
+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+  ImageHeader   = Image;
+
+  //
+  // Calculate the BltBuffer needed size.
+  //
+  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, 
BmpHeader->PixelHeight);
+  //
+  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't 
overflow
+  //
+  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof 
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    return EFI_UNSUPPORTED;
+  }
+  BltBufferSize = MultU64x32 (BltBufferSize, sizeof 
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+  *GopBltSize = (UINTN) BltBufferSize;
+  *GopBlt     = AllocatePool (*GopBltSize);
+  if (*GopBlt == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *PixelWidth   = BmpHeader->PixelWidth;
+  *PixelHeight  = BmpHeader->PixelHeight;
+
+  //
+  // Convert image from BMP to Blt buffer format
+  //
+  BltBuffer = *GopBlt;
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * 
BmpHeader->PixelWidth];
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+      switch (BmpHeader->BitPerPixel) {
+      case 1:
+        //
+        // Convert 1-bit (2 colors) BMP to 24-bit color
+        //
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+          Blt++;
+          Width++;
+        }
+
+        Blt--;
+        Width--;
+        break;
+
+      case 4:
+        //
+        // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+        //
+        Index       = (*Image) >> 4;
+        Blt->Red    = BmpColorMap[Index].Red;
+        Blt->Green  = BmpColorMap[Index].Green;
+        Blt->Blue   = BmpColorMap[Index].Blue;
+        if (Width < (BmpHeader->PixelWidth - 1)) {
+          Blt++;
+          Width++;
+          Index       = (*Image) & 0x0f;
+          Blt->Red    = BmpColorMap[Index].Red;
+          Blt->Green  = BmpColorMap[Index].Green;
+          Blt->Blue   = BmpColorMap[Index].Blue;
+        }
+        break;
+
+      case 8:
+        //
+        // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+        //
+        Blt->Red    = BmpColorMap[*Image].Red;
+        Blt->Green  = BmpColorMap[*Image].Green;
+        Blt->Blue   = BmpColorMap[*Image].Blue;
+        break;
+
+      case 24:
+        //
+        // It is 24-bit BMP.
+        //
+        Blt->Blue   = *Image++;
+        Blt->Green  = *Image++;
+        Blt->Red    = *Image;
+        break;
+
+      default:
+        //
+        // Other bit format BMP is not supported.
+        //
+        return EFI_UNSUPPORTED;
+        break;
+      };
+
+    }
+
+    ImageIndex = (UINTN) (Image - ImageHeader);
+    if ((ImageIndex % 4) != 0) {
+      //
+      // Bmp Image starts each row on a 32-bit boundary!
+      //
+      Image = Image + (4 - (ImageIndex % 4));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize BmpImageDecoderLib library.
+
+  @param ImageHandle     The image handle.
+  @param SystemTable     The system table.
+
+  @retval EFI_SUCCESS    The BmpImageDecoderLib library is initialized 
correctly.
+  @return Other value if failed to initialize the BmpImageDecoderLib library.
+**/
+EFI_STATUS
+EFIAPI
+BmpImageDecoderLibConstructor (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+)
+{
+  RegisterImageDecoder (BmpImageDecoderLibConvertBmpToGopBlt);
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf 
b/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf
new file mode 100644
index 0000000..2d1c160
--- /dev/null
+++ b/MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf
@@ -0,0 +1,42 @@
+## @file
+#  This library provides BMP image decoding capability.
+#  
+#  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+#  This program and the accompanying materials are licensed and made available 
under
+#  the terms and conditions of the BSD License that accompanies this 
distribution.
+#  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php.
+#  
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+#  
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BmpImageDecoderLib
+  FILE_GUID                      = DF414223-F17C-4022-A1F4-4062612AB00D
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION
+  CONSTRUCTOR                    = BmpImageDecoderLibConstructor
+
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  BmpImageDecoderLib.c
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  DebugLib
+  ImageDecoderLib
\ No newline at end of file
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 20af2d4..5e3d876 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -278,6 +278,7 @@
   MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
   
MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf
   MdeModulePkg/Library/ImageDecoderLib/ImageDecoderLib.inf
+  MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf
   MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
   MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to