From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.120; helo=mga04.intel.com; envelope-from=star.zeng@intel.com; receiver=edk2-devel@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C63EC22361E49 for ; Wed, 7 Feb 2018 21:04:41 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Feb 2018 21:10:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,476,1511856000"; d="scan'208";a="33026999" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga002.jf.intel.com with ESMTP; 07 Feb 2018 21:10:25 -0800 Received: from fmsmsx116.amr.corp.intel.com (10.18.116.20) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 7 Feb 2018 21:10:25 -0800 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx116.amr.corp.intel.com (10.18.116.20) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 7 Feb 2018 21:10:24 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.124]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.130]) with mapi id 14.03.0319.002; Thu, 8 Feb 2018 13:10:22 +0800 From: "Zeng, Star" To: "Kinney, Michael D" , "edk2-devel@lists.01.org" CC: Sean Brogan , "Yao, Jiewen" , "Dong, Eric" , "Ni, Ruiyu" , "Zeng, Star" Thread-Topic: [Patch 01/10] MdeModulePkg: Add BmpSupportLib class and instance Thread-Index: AQHToGcwRGg1QEwF2U28GUscyacLN6OZ9Jig Date: Thu, 8 Feb 2018 05:10:22 +0000 Message-ID: <0C09AFA07DD0434D9E2A0C6AEB0483103BA3D7C0@shsmsx102.ccr.corp.intel.com> References: <20180207225822.28876-1-michael.d.kinney@intel.com> <20180207225822.28876-2-michael.d.kinney@intel.com> In-Reply-To: <20180207225822.28876-2-michael.d.kinney@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [Patch 01/10] MdeModulePkg: Add BmpSupportLib class and instance X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Feb 2018 05:04:42 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Star Zeng to MdeModulePkg change with a = minor comment below. Update the comments in MdeModulePkg/Include/Library/BmpSupportLib.h and Mde= ModulePkg.dec? Provides services to convert a BMP graphics image to a GOP BLT buffer. -> Provides services to convert a BMP graphics image to a GOP BLT buffer and t= o convert a GOP BLT buffer to a BMP graphics image. Thanks, Star -----Original Message----- From: Kinney, Michael D=20 Sent: Thursday, February 8, 2018 6:58 AM To: edk2-devel@lists.01.org Cc: Sean Brogan ; Yao, Jiewen ; Zeng, Star ; Dong, Eric ; N= i, Ruiyu ; Kinney, Michael D Subject: [Patch 01/10] MdeModulePkg: Add BmpSupportLib class and instance https://bugzilla.tianocore.org/show_bug.cgi?id=3D800 Based on content from the following branch/commits: https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport https://github.com/Microsoft/MS_UEFI/commit/33bab4031a417d7d5a7d356c15a14c2= e60302b2d https://github.com/Microsoft/MS_UEFI/commit/ca516b1a61315c2d823f453e12d2135= 098f53d61 https://github.com/Microsoft/MS_UEFI/commit/2b9f111f2e74a4c2ef4c4e32379e111= f016dbd9b Add BmpSupportLib class and instances that provides services to convert a B= MP graphics image to a GOP BLT buffer and to convert a GOP BLT buffer to a = BMP graphics image. Cc: Sean Brogan Cc: Jiewen Yao Cc: Star Zeng Cc: Eric Dong Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney --- MdeModulePkg/Include/Library/BmpSupportLib.h | 105 ++++ .../BaseBmpSupportLib/BaseBmpSupportLib.inf | 49 ++ .../BaseBmpSupportLib/BaseBmpSupportLib.uni | 20 + .../Library/BaseBmpSupportLib/BmpSupportLib.c | 583 +++++++++++++++++= ++++ MdeModulePkg/MdeModulePkg.dec | 6 +- MdeModulePkg/MdeModulePkg.dsc | 1 + 6 files changed, 763 insertions(+), 1 deletion(-) create mode 100644 MdeM= odulePkg/Include/Library/BmpSupportLib.h create mode 100644 MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLi= b.inf create mode 100644 MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLi= b.uni create mode 100644 MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c diff --git a/MdeModulePkg/Include/Library/BmpSupportLib.h b/MdeModulePkg/In= clude/Library/BmpSupportLib.h new file mode 100644 index 0000000000..3406aa3fca --- /dev/null +++ b/MdeModulePkg/Include/Library/BmpSupportLib.h @@ -0,0 +1,105 @@ +/** @file + +Provides services to convert a BMP graphics image to a GOP BLT buffer. + +Copyright (c) 2016, Microsoft Corporation Copyright (c) 2018, Intel=20 +Corporation. All rights reserved.
+ +All rights reserved. +Redistribution and use in source and binary forms, with or without=20 +modification, are permitted provided that the following conditions are met= : +1. Redistributions of source code must retain the above copyright=20 +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright=20 +notice, this list of conditions and the following disclaimer in the=20 +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS=20 +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED=20 +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR= PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR=20 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL=20 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS=20 +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)=20 +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,=20 +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING=20 +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBI= LITY OF SUCH DAMAGE. + +**/ + +#ifndef __BMP_SUPPORT_LIB_H__ +#define __BMP_SUPPORT_LIB_H__ + +#include + +/** + Translate a *.BMP graphics image to a GOP blt buffer. If a NULL Blt=20 +buffer + is passed in a GopBlt buffer will be allocated by this routine using + EFI_BOOT_SERVICES.AllocatePool(). If a GopBlt buffer is passed in it=20 +will be + used if it is big enough. + + @param [in] BmpImage Pointer to BMP file. + @param [in] BmpImageSize Number of bytes in BmpImage. + @param [in, out] GopBlt Buffer containing GOP version of BmpImage= . + @param [in, out] GopBltSize Size of GopBlt in bytes. + @param [out] PixelHeight Height of GopBlt/BmpImage in pixels. + @param [out] PixelWidth Width of GopBlt/BmpImage in pixels. + + @retval RETURN_SUCCESS GopBlt and GopBltSize are returned. + @retval RETURN_INVALID_PARAMETER BmpImage is NULL. + @retval RETURN_INVALID_PARAMETER GopBlt is NULL. + @retval RETURN_INVALID_PARAMETER GopBltSize is NULL. + @retval RETURN_INVALID_PARAMETER PixelHeight is NULL. + @retval RETURN_INVALID_PARAMETER PixelWidth is NULL. + @retval RETURN_UNSUPPORTED BmpImage is not a valid *.BMP image. + @retval RETURN_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big + enough. The required size is returned= in + GopBltSize. + @retval RETURN_OUT_OF_RESOURCES The GopBlt buffer could not be allocat= ed. + +**/ +RETURN_STATUS +EFIAPI +TranslateBmpToGopBlt ( + IN VOID *BmpImage, + IN UINTN BmpImageSize, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **GopBlt, + IN OUT UINTN *GopBltSize, + OUT UINTN *PixelHeight, + OUT UINTN *PixelWidth + ); + +/** + Translate a GOP blt buffer to an uncompressed 24-bit per pixel BMP=20 +graphics + image. If a NULL BmpImage is passed in a BmpImage buffer will be=20 +allocated by + this routine using EFI_BOOT_SERVICES.AllocatePool(). If a BmpImage=20 +buffer is + passed in it will be used if it is big enough. + + @param [in] GopBlt Pointer to GOP blt buffer. + @param [in] PixelHeight Height of GopBlt/BmpImage in pixels. + @param [in] PixelWidth Width of GopBlt/BmpImage in pixels. + @param [in, out] BmpImage Buffer containing BMP version of GopBlt. + @param [in, out] BmpImageSize Size of BmpImage in bytes. + + @retval RETURN_SUCCESS BmpImage and BmpImageSize are returned= . + @retval RETURN_INVALID_PARAMETER GopBlt is NULL. + @retval RETURN_INVALID_PARAMETER BmpImage is NULL. + @retval RETURN_INVALID_PARAMETER BmpImageSize is NULL. + @retval RETURN_UNSUPPORTED GopBlt cannot be converted to a *.BMP = image. + @retval RETURN_BUFFER_TOO_SMALL The passed in BmpImage buffer is not b= ig + enough. The required size is returned= in + BmpImageSize. + @retval RETURN_OUT_OF_RESOURCES The BmpImage buffer could not be alloc= ated. + +**/ +RETURN_STATUS +EFIAPI +TranslateGopBltToBmp ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GopBlt, + IN UINT32 PixelHeight, + IN UINT32 PixelWidth, + IN OUT VOID **BmpImage, + IN OUT UINT32 *BmpImageSize + ); + +#endif diff --git a/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf b= /MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf new file mode 100644 index 0000000000..02c3fae0b4 --- /dev/null +++ b/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf @@ -0,0 +1,49 @@ +## @file +# +# Provides services to convert a BMP graphics image to a GOP BLT buffer=20 +and # from a GOP BLT buffer to a BMP graphics image. +# +# Copyright (c) 2017, Microsoft Corporation # # All rights reserved. +# Redistribution and use in source and binary forms, with or without #=20 +modification, are permitted provided that the following conditions are met= : +# 1. Redistributions of source code must retain the above copyright=20 +notice, # this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright=20 +notice, # this list of conditions and the following disclaimer in the=20 +documentation # and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS=20 +"AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT=20 +LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A = PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR=20 +ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR=20 +CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF=20 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR=20 +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY,=20 +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE #=20 +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF = # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D BaseBmpSupportLib + MODULE_UNI_FILE =3D BaseBmpSupportLib.uni + FILE_GUID =3D CF5F650B-C208-409A-B889-0755172E2B0C + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D BASE + LIBRARY_CLASS =3D BmpSupportLib + +[LibraryClasses] + DebugLib + BaseMemoryLib + MemoryAllocationLib + SafeIntLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Sources] + BmpSupportLib.c diff --git a/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.uni b= /MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.uni new file mode 100644 index 0000000000..f24e2d246f --- /dev/null +++ b/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.uni @@ -0,0 +1,20 @@ +// /** @file +// +// Provides services to convert a BMP graphics image to a GOP BLT=20 +buffer and // from a GOP BLT buffer to a BMP graphics image. +// +// Copyright (c) 2018, Intel Corporation. All rights reserved.
//=20 +// This program and the accompanying materials // are licensed and made=20 +available under the terms and conditions of the BSD License // which=20 +accompanies this distribution. The full text of the license may be=20 +found at // http://opensource.org/licenses/bsd-license.php +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"=20 +BASIS, // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRES= S OR IMPLIED. +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "BmpSupportLib ins= tance" + +#string STR_MODULE_DESCRIPTION #language en-US "BmpSupportLib ins= tance." + diff --git a/MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c b/MdeMo= dulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c new file mode 100644 index 0000000000..2c95e91ecc --- /dev/null +++ b/MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c @@ -0,0 +1,583 @@ +/** @file + + Provides services to convert a BMP graphics image to a GOP BLT buffer=20 + and from a GOP BLT buffer to a BMP graphics image. + + Caution: This module requires additional review when modified. + This module processes external input - BMP image. + This external input must be validated carefully to avoid security=20 + issue such as buffer overflow, integer overflow. + + TranslateBmpToGopBlt() receives untrusted input and performs basic valid= ation. + + Copyright (c) 2016-2017, Microsoft Corporation Copyright (c) 2018,=20 + Intel Corporation. All rights reserved.
+ + All rights reserved. + Redistribution and use in source and binary forms, with or without =20 + modification, are permitted provided that the following conditions are me= t: + 1. Redistributions of source code must retain the above copyright=20 + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright=20 + notice, this list of conditions and the following disclaimer in the=20 + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS=20 + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT=20 + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A = PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR=20 + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR=20 + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF=20 + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR=20 + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,=20 + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE =20 + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF= ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +**/ + +#include +#include +#include +#include #include=20 + #include + +#include + +// +// BMP Image header for an uncompressed 24-bit per pixel BMP image. +// +const BMP_IMAGE_HEADER mBmpImageHeaderTemplate =3D { + 'B', // CharB + 'M', // CharM + 0, // Size will be updated at runtime + {0, 0}, // Reserved + sizeof (BMP_IMAGE_HEADER), // ImageOffset + sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IMAGE_HEADER, HeaderSize), //= HeaderSize + 0, // PixelWidth will be updated at runtime + 0, // PixelHeight will be updated at runtime + 1, // Planes + 24, // BitPerPixel + 0, // CompressionType + 0, // ImageSize will be updated at runtime + 0, // XPixelsPerMeter + 0, // YPixelsPerMeter + 0, // NumberOfColors + 0 // ImportantColors +}; + +/** + Translate a *.BMP graphics image to a GOP blt buffer. If a NULL Blt=20 +buffer + is passed in a GopBlt buffer will be allocated by this routine using + EFI_BOOT_SERVICES.AllocatePool(). If a GopBlt buffer is passed in it=20 +will be + used if it is big enough. + + @param[in] BmpImage Pointer to BMP file. + @param[in] BmpImageSize Number of bytes in BmpImage. + @param[in, out] GopBlt Buffer containing GOP version of BmpImage= . + @param[in, out] GopBltSize Size of GopBlt in bytes. + @param[out] PixelHeight Height of GopBlt/BmpImage in pixels. + @param[out] PixelWidth Width of GopBlt/BmpImage in pixels. + + @retval RETURN_SUCCESS GopBlt and GopBltSize are returned. + @retval RETURN_INVALID_PARAMETER BmpImage is NULL. + @retval RETURN_INVALID_PARAMETER GopBlt is NULL. + @retval RETURN_INVALID_PARAMETER GopBltSize is NULL. + @retval RETURN_INVALID_PARAMETER PixelHeight is NULL. + @retval RETURN_INVALID_PARAMETER PixelWidth is NULL. + @retval RETURN_UNSUPPORTED BmpImage is not a valid *.BMP image. + @retval RETURN_BUFFER_TOO_SMALL The passed in GopBlt buffer is not bi= g + enough. The required size is returne= d in + GopBltSize. + @retval RETURN_OUT_OF_RESOURCES The GopBlt buffer could not be alloca= ted. + +**/ +RETURN_STATUS +EFIAPI +TranslateBmpToGopBlt ( + IN VOID *BmpImage, + IN UINTN BmpImageSize, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **GopBlt, + IN OUT UINTN *GopBltSize, + OUT UINTN *PixelHeight, + OUT UINTN *PixelWidth + ) +{ + UINT8 *Image; + UINT8 *ImageHeader; + BMP_IMAGE_HEADER *BmpHeader; + BMP_COLOR_MAP *BmpColorMap; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINT32 BltBufferSize; + UINTN Index; + UINTN Height; + UINTN Width; + UINTN ImageIndex; + UINT32 DataSizePerLine; + BOOLEAN IsAllocated; + UINT32 ColorMapNum; + RETURN_STATUS Status; + UINT32 DataSize; + UINT32 Temp; + + if (BmpImage =3D=3D NULL || GopBlt =3D=3D NULL || GopBltSize =3D=3D NULL= ) { + return RETURN_INVALID_PARAMETER; + } + if (PixelHeight =3D=3D NULL || PixelWidth =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (BmpImageSize < sizeof (BMP_IMAGE_HEADER)) { + DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: BmpImageSize too small\n")= ); + return RETURN_UNSUPPORTED; + } + + BmpHeader =3D (BMP_IMAGE_HEADER *)BmpImage; + + if (BmpHeader->CharB !=3D 'B' || BmpHeader->CharM !=3D 'M') { + DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: BmpHeader->Char fields inc= orrect\n")); + return RETURN_UNSUPPORTED; + } + + // + // Doesn't support compress. + // + if (BmpHeader->CompressionType !=3D 0) { + DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: Compression Type unsupport= ed.\n")); + return RETURN_UNSUPPORTED; + } + + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER =3D BMP_IMAGE_HEADER // if=20 + (BmpHeader->HeaderSize !=3D sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IM= AGE_HEADER, HeaderSize)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: BmpHeader->Headership is not as expected. He= adersize is 0x%x\n", + BmpHeader->HeaderSize + )); + return RETURN_UNSUPPORTED; + } + + // + // The data size in each line must be 4 byte alignment. + // + Status =3D SafeUint32Mult ( + BmpHeader->PixelWidth, + BmpHeader->BitPerPixel, + &DataSizePerLine + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: invalid BmpImage... PixelWidth:0x%x BitPerPix= el:0x%x\n", + BmpHeader->PixelWidth, + BmpHeader->BitPerPixel + )); + return RETURN_UNSUPPORTED; + } + + Status =3D SafeUint32Add (DataSizePerLine, 31, &DataSizePerLine); if=20 + (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: invalid BmpImage... DataSizePerLine:0x%x\n", + DataSizePerLine + )); + + return RETURN_UNSUPPORTED; + } + + DataSizePerLine =3D (DataSizePerLine >> 3) &(~0x3); Status =3D=20 + SafeUint32Mult ( + DataSizePerLine, + BmpHeader->PixelHeight, + &BltBufferSize + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: invalid BmpImage... DataSizePerLine:0x%x Pixe= lHeight:0x%x\n", + DataSizePerLine, BmpHeader->PixelHeight + )); + + return RETURN_UNSUPPORTED; + } + + Status =3D SafeUint32Mult ( + BmpHeader->PixelHeight, + DataSizePerLine, + &DataSize + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: invalid BmpImage... PixelHeight:0x%x DataSize= PerLine:0x%x\n", + BmpHeader->PixelHeight, DataSizePerLine + )); + + return RETURN_UNSUPPORTED; + } + + if ((BmpHeader->Size !=3D BmpImageSize) || + (BmpHeader->Size < BmpHeader->ImageOffset) || + (BmpHeader->Size - BmpHeader->ImageOffset !=3D DataSize)) { + + DEBUG ((DEBUG_ERROR, "TranslateBmpToGopBlt: invalid BmpImage... \n")); + DEBUG ((DEBUG_ERROR, " BmpHeader->Size: 0x%x\n", BmpHeader->Size)); + DEBUG ((DEBUG_ERROR, " BmpHeader->ImageOffset: 0x%x\n", BmpHeader->I= mageOffset)); + DEBUG ((DEBUG_ERROR, " BmpImageSize: 0x%lx\n", (UINTN)BmpImageSize))= ; + DEBUG ((DEBUG_ERROR, " DataSize: 0x%lx\n", (UINTN)DataSize)); + + return RETURN_UNSUPPORTED; + } + + // + // Calculate Color Map offset in the image. + // + Image =3D BmpImage; + BmpColorMap =3D (BMP_COLOR_MAP *)(Image + sizeof (BMP_IMAGE_HEADER)); =20 + if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) { + return RETURN_UNSUPPORTED; + } + + if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) { + switch (BmpHeader->BitPerPixel) { + case 1: + ColorMapNum =3D 2; + break; + case 4: + ColorMapNum =3D 16; + break; + case 8: + ColorMapNum =3D 256; + break; + default: + ColorMapNum =3D 0; + break; + } + // + // BMP file may has padding data between the bmp header section and th= e + // bmp data section. + // + if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_C= OLOR_MAP) * ColorMapNum) { + return RETURN_UNSUPPORTED; + } + } + + // + // Calculate graphics image data address in the image // Image =3D=20 + ((UINT8 *)BmpImage) + BmpHeader->ImageOffset; ImageHeader =3D Image; + + // + // Calculate the BltBuffer needed size. + // + Status =3D SafeUint32Mult ( + BmpHeader->PixelWidth, + BmpHeader->PixelHeight, + &BltBufferSize + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: invalid BltBuffer needed size... PixelWidth:0= x%x PixelHeight:0x%x\n", + BltBufferSize + )); + + return RETURN_UNSUPPORTED; + } + + Temp =3D BltBufferSize; + Status =3D SafeUint32Mult ( + BltBufferSize, + sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), + &BltBufferSize + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateBmpToGopBlt: invalid BltBuffer needed size... BltBufferSiz= e:0x%lx struct size:0x%x\n", + Temp, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + )); + + return RETURN_UNSUPPORTED; + } + + IsAllocated =3D FALSE; + if (*GopBlt =3D=3D NULL) { + // + // GopBlt is not allocated by caller. + // + DEBUG ((DEBUG_INFO, "Bmp Support: Allocating 0x%X bytes of memory\n", = BltBufferSize)); + *GopBltSize =3D (UINTN)BltBufferSize; + *GopBlt =3D AllocatePool (*GopBltSize); + IsAllocated =3D TRUE; + if (*GopBlt =3D=3D NULL) { + return RETURN_OUT_OF_RESOURCES; + } + } else { + // + // GopBlt has been allocated by caller. + // + if (*GopBltSize < (UINTN)BltBufferSize) { + *GopBltSize =3D (UINTN)BltBufferSize; + return RETURN_BUFFER_TOO_SMALL; + } + } + + *PixelWidth =3D BmpHeader->PixelWidth; *PixelHeight =3D=20 + BmpHeader->PixelHeight; DEBUG ((DEBUG_INFO, "BmpHeader->ImageOffset=20 + 0x%X\n", BmpHeader->ImageOffset)); DEBUG ((DEBUG_INFO,=20 + "BmpHeader->PixelWidth 0x%X\n", BmpHeader->PixelWidth)); DEBUG=20 + ((DEBUG_INFO, "BmpHeader->PixelHeight 0x%X\n",=20 + BmpHeader->PixelHeight)); DEBUG ((DEBUG_INFO, "BmpHeader->BitPerPixel=20 + 0x%X\n", BmpHeader->BitPerPixel)); DEBUG ((DEBUG_INFO,=20 + "BmpHeader->ImageSize 0x%X\n", BmpHeader->ImageSize)); DEBUG=20 + ((DEBUG_INFO, "BmpHeader->HeaderSize 0x%X\n", BmpHeader->HeaderSize)); =20 + DEBUG ((DEBUG_INFO, "BmpHeader->Size 0x%X\n", BmpHeader->Size)); + + // + // Translate image from BMP to Blt buffer format // BltBuffer =3D=20 + *GopBlt; for (Height =3D 0; Height < BmpHeader->PixelHeight; Height++)=20 + { + Blt =3D &BltBuffer[ (BmpHeader->PixelHeight - Height - 1) * BmpHeader-= >PixelWidth]; + for (Width =3D 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt= ++) { + switch (BmpHeader->BitPerPixel) { + case 1: + // + // Translate 1-bit (2 colors) BMP to 24-bit color + // + for (Index =3D 0; Index < 8 && Width < BmpHeader->PixelWidth; Inde= x++) { + Blt->Red =3D BmpColorMap[ ((*Image) >> (7 - Index)) & 0x1].Red= ; + Blt->Green =3D BmpColorMap[ ((*Image) >> (7 - Index)) & 0x1].Gre= en; + Blt->Blue =3D BmpColorMap[ ((*Image) >> (7 - Index)) & 0x1].Blu= e; + Blt++; + Width++; + } + + Blt--; + Width--; + break; + + case 4: + // + // Translate 4-bit (16 colors) BMP Palette to 24-bit color + // + Index =3D (*Image) >> 4; + Blt->Red =3D BmpColorMap[Index].Red; + Blt->Green =3D BmpColorMap[Index].Green; + Blt->Blue =3D BmpColorMap[Index].Blue; + if (Width < (BmpHeader->PixelWidth - 1)) { + Blt++; + Width++; + Index =3D (*Image) & 0x0f; + Blt->Red =3D BmpColorMap[Index].Red; + Blt->Green =3D BmpColorMap[Index].Green; + Blt->Blue =3D BmpColorMap[Index].Blue; + } + break; + + case 8: + // + // Translate 8-bit (256 colors) BMP Palette to 24-bit color + // + Blt->Red =3D BmpColorMap[*Image].Red; + Blt->Green =3D BmpColorMap[*Image].Green; + Blt->Blue =3D BmpColorMap[*Image].Blue; + break; + + case 24: + // + // It is 24-bit BMP. + // + Blt->Blue =3D *Image++; + Blt->Green =3D *Image++; + Blt->Red =3D *Image; + break; + + case 32: + // + //Conver 32 bit to 24bit bmp - just ignore the final byte of each = pixel + Blt->Blue =3D *Image++; + Blt->Green =3D *Image++; + Blt->Red =3D *Image++; + break; + + default: + // + // Other bit format BMP is not supported. + // + if (IsAllocated) { + FreePool (*GopBlt); + *GopBlt =3D NULL; + } + DEBUG ((DEBUG_ERROR, "Bmp Bit format not supported. 0x%X\n", BmpH= eader->BitPerPixel)); + return RETURN_UNSUPPORTED; + break; + }; + + } + + ImageIndex =3D (UINTN)(Image - ImageHeader); + if ((ImageIndex % 4) !=3D 0) { + // + // Bmp Image starts each row on a 32-bit boundary! + // + Image =3D Image + (4 - (ImageIndex % 4)); + } + } + + return RETURN_SUCCESS; +} + +/** + Translate a GOP blt buffer to an uncompressed 24-bit per pixel BMP=20 +graphics + image. If a NULL BmpImage is passed in a BmpImage buffer will be=20 +allocated by + this routine using EFI_BOOT_SERVICES.AllocatePool(). If a BmpImage=20 +buffer is + passed in it will be used if it is big enough. + + @param [in] GopBlt Pointer to GOP blt buffer. + @param [in] PixelHeight Height of GopBlt/BmpImage in pixels. + @param [in] PixelWidth Width of GopBlt/BmpImage in pixels. + @param [in, out] BmpImage Buffer containing BMP version of GopBlt. + @param [in, out] BmpImageSize Size of BmpImage in bytes. + + @retval RETURN_SUCCESS BmpImage and BmpImageSize are returned= . + @retval RETURN_INVALID_PARAMETER GopBlt is NULL. + @retval RETURN_INVALID_PARAMETER BmpImage is NULL. + @retval RETURN_INVALID_PARAMETER BmpImageSize is NULL. + @retval RETURN_UNSUPPORTED GopBlt cannot be converted to a *.BMP = image. + @retval RETURN_BUFFER_TOO_SMALL The passed in BmpImage buffer is not b= ig + enough. The required size is returned= in + BmpImageSize. + @retval RETURN_OUT_OF_RESOURCES The BmpImage buffer could not be alloc= ated. + +**/ +RETURN_STATUS +EFIAPI +TranslateGopBltToBmp ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GopBlt, + IN UINT32 PixelHeight, + IN UINT32 PixelWidth, + IN OUT VOID **BmpImage, + IN OUT UINT32 *BmpImageSize + ) +{ + RETURN_STATUS Status; + UINT32 PaddingSize; + UINT32 BmpSize; + BMP_IMAGE_HEADER *BmpImageHeader; + UINT8 *Image; + UINTN Col; + UINTN Row; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel; + + if (GopBlt =3D=3D NULL || BmpImage =3D=3D NULL || BmpImageSize =3D=3D NU= LL) { + return RETURN_INVALID_PARAMETER; + } + + // + // Allocate memory for BMP file. + // + PaddingSize =3D PixelWidth & 0x3; + + // + // First check PixelWidth * 3 + PaddingSize doesn't overflow // =20 + Status =3D SafeUint32Mult (PixelWidth, 3, &BmpSize); if (EFI_ERROR=20 + (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWi= dth:0x%x\n", + PixelHeight, + PixelWidth + )); + return RETURN_UNSUPPORTED; + } + Status =3D SafeUint32Add (BmpSize, PaddingSize, &BmpSize); if=20 + (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWi= dth:0x%x\n", + PixelHeight, + PixelWidth + )); + return RETURN_UNSUPPORTED; + } + + // + // Second check (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof=20 + (BMP_IMAGE_HEADER) doesn't overflow // Status =3D SafeUint32Mult=20 + (BmpSize, PixelHeight, &BmpSize); if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWi= dth:0x%x\n", + PixelHeight, + PixelWidth + )); + return RETURN_UNSUPPORTED; + } + Status =3D SafeUint32Add (BmpSize, sizeof (BMP_IMAGE_HEADER),=20 + &BmpSize); if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "TranslateGopBltToBmp: GopBlt is too large. PixelHeight:0x%x PixelWi= dth:0x%x\n", + PixelHeight, + PixelWidth + )); + return RETURN_UNSUPPORTED; + } + + // + // The image should be stored in EfiBootServicesData, allowing the=20 + system to // reclaim the memory // if (*BmpImage =3D=3D NULL) { + *BmpImage =3D AllocateZeroPool (BmpSize); + if (*BmpImage =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + *BmpImageSize =3D BmpSize; + } else if (*BmpImageSize < BmpSize) { + *BmpImageSize =3D BmpSize; + return RETURN_BUFFER_TOO_SMALL; + } + + BmpImageHeader =3D (BMP_IMAGE_HEADER *)*BmpImage; CopyMem=20 + (BmpImageHeader, &mBmpImageHeaderTemplate, sizeof (BMP_IMAGE_HEADER)); + BmpImageHeader->Size =3D *BmpImageSize; + BmpImageHeader->ImageSize =3D *BmpImageSize - sizeof (BMP_IMAGE_HEADER= ); + BmpImageHeader->PixelWidth =3D PixelWidth; =20 + BmpImageHeader->PixelHeight =3D PixelHeight; + + // + // Convert BLT buffer to BMP file. + // + Image =3D (UINT8 *)BmpImageHeader + sizeof (BMP_IMAGE_HEADER); for=20 + (Row =3D 0; Row < PixelHeight; Row++) { + BltPixel =3D &GopBlt[(PixelHeight - Row - 1) * PixelWidth]; + + for (Col =3D 0; Col < PixelWidth; Col++) { + *Image++ =3D BltPixel->Blue; + *Image++ =3D BltPixel->Green; + *Image++ =3D BltPixel->Red; + BltPixel++; + } + + // + // Padding for 4 byte alignment. + // + Image +=3D PaddingSize; + } + + return RETURN_SUCCESS; +} diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec = index 61d034fba8..e3f87a4d28 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -7,7 +7,7 @@ # Copyright (c) 2016, Linaro Ltd. All rights reserved.
# (C) Copyrigh= t 2016 Hewlett Packard Enterprise Development LP
# Copyright (c) 2017,= AMD Incorporated. All rights reserved.
-# +# Copyright (c) 2016, Microsoft Corporation
# This program and the accompanying materials are licensed and made availa= ble under # the terms and conditions of the BSD License that accompanies t= his distribution. # The full text of the license may be found at @@ -167,6 +167,10 @@ ## NonDiscoverableDeviceRegistrationLib|Include/Library/NonDiscoverableDevi= ceRegistrationLib.h =20 + ## @libraryclass Provides services to convert a BMP graphics image to a= GOP BLT buffer. + # + BmpSupportLib|Include/Library/BmpSupportLib.h + [Guids] ## MdeModule package token space guid # Include/Guid/MdeModulePkgTokenSpace.h diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc = index 1c0085aee6..efd33f4b82 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -321,6 +321,7 @@ MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol= .inf MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverabl= eDeviceRegistrationLib.inf + MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf =20 MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf -- 2.14.2.windows.3