MdeModulePkg: Add BmpImageDecoderLib to provide BMP decoding capability

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
This commit is contained in:
Ruiyu Ni 2015-11-12 05:22:21 +00:00 committed by niruiyu
parent 345c2b0713
commit 328de7ae41
3 changed files with 315 additions and 0 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -278,6 +278,7 @@
MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf
MdeModulePkg/Library/ImageDecoderLib/ImageDecoderLib.inf MdeModulePkg/Library/ImageDecoderLib/ImageDecoderLib.inf
MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf
MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf