diff --git a/MdePkg/Include/IndustryStandard/Bmp.h b/MdePkg/Include/IndustryStandard/Bmp.h index dd8c26d07..356869582 100644 --- a/MdePkg/Include/IndustryStandard/Bmp.h +++ b/MdePkg/Include/IndustryStandard/Bmp.h @@ -19,19 +19,19 @@ typedef struct { } BMP_COLOR_MAP; typedef struct { - CHAR8 CharB; - CHAR8 CharM; - UINT32 Size; - UINT16 Reserved[2]; - UINT32 ImageOffset; - UINT32 HeaderSize; - UINT32 PixelWidth; - UINT32 PixelHeight; - UINT16 Planes; ///< Must be 1 - UINT16 BitPerPixel; ///< 1, 4, 8, or 24 - UINT32 CompressionType; - UINT32 ImageSize; ///< Compressed image size in bytes - UINT32 XPixelsPerMeter; + CHAR8 CharB; //B + CHAR8 CharM; //M + UINT32 Size; // 8A 44 01 00 + UINT16 Reserved[2]; // 00 00 00 00 + UINT32 ImageOffset; // 8A 00 00 00 + UINT32 HeaderSize; // 7C 00 00 00 + INT32 PixelWidth; // 90 00 00 00 + INT32 PixelHeight; // 70 FF FF FF + UINT16 Planes; // 01 00 //< Must be 1 + UINT16 BitPerPixel; // 20 00 //< 1, 4, 8, or 24 + UINT32 CompressionType; // 03 00 0000 + UINT32 ImageSize; // 00 44 01 00 //< Compressed image size in bytes + UINT32 XPixelsPerMeter; // UINT32 YPixelsPerMeter; UINT32 NumberOfColors; UINT32 ImportantColors; diff --git a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp index 11cd43e4c..c773578e8 100644 --- a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp +++ b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp @@ -690,6 +690,30 @@ EFI_STATUS REFIT_MENU_SCREEN::WaitForInputEventPoll(UINTN TimeoutDefault) return Status; } +void testBMP() +{ + EFI_STATUS Status; + UINT8 *FileData = NULL; + UINTN FileDataLength = 0; + INTN Width = 256, Height = 256; + + // load file + Status = egLoadFile(&self.getSelfVolumeRootDir(), L"Sample.bmp", &FileData, &FileDataLength); + + if (!EFI_ERROR(Status)) { + DBG("read file size=%llu\n", FileDataLength); + XImage NewImage(Width, Height); + NewImage.FromBMP(FileData, FileDataLength); + Width = NewImage.GetWidth(); + Height = NewImage.GetHeight(); + DBG("new image sizes w=%llu h=%llu\n", Width, Height); + NewImage.Draw((UGAWidth - Width) / 2, (UGAHeight - Height) / 2); + FreePool(FileData); + FileData = NULL; + } + +} + UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN OUT INTN *DefaultEntryIndex, OUT REFIT_ABSTRACT_MENU_ENTRY **ChosenEntry) { @@ -975,7 +999,8 @@ UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN OUT INTN *DefaultEntryIndex, OUT REFI break; case SCAN_F8: - testSVG(); + // testSVG(); + testBMP(); // SaveHdaDumpBin(); // SaveHdaDumpTxt(); break; @@ -1014,6 +1039,9 @@ UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN OUT INTN *DefaultEntryIndex, OUT REFI MenuExit = MENU_EXIT_ENTER; } break; + case 'B': + testBMP(); + break; case ' ': //CHAR_SPACE if ((Entries[ScrollState.CurrentSelection].getREFIT_INPUT_DIALOG()) || (Entries[ScrollState.CurrentSelection].getREFIT_MENU_CHECKBIT())) { diff --git a/rEFIt_UEFI/libeg/XImage.cpp b/rEFIt_UEFI/libeg/XImage.cpp index 53e3bd9bd..b8ac256a2 100644 --- a/rEFIt_UEFI/libeg/XImage.cpp +++ b/rEFIt_UEFI/libeg/XImage.cpp @@ -579,8 +579,10 @@ void XImage::Draw(INTN x, INTN y, float scale) const void XImage::Draw(INTN x, INTN y, float scale, XBool Opaque) const { + DBG("draw at %lld %lld\n", x, y); //prepare images if (isEmpty()) { + DBG("emptyimage\n"); return; } diff --git a/rEFIt_UEFI/libeg/load_bmp.cpp b/rEFIt_UEFI/libeg/load_bmp.cpp index f8d747538..dca621fe7 100644 --- a/rEFIt_UEFI/libeg/load_bmp.cpp +++ b/rEFIt_UEFI/libeg/load_bmp.cpp @@ -34,11 +34,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libegint.h" +#include "../Platform/Utils.h" #include "XImage.h" #include //#include "picopng.h" +//#define DBG(...) DebugLog(1, __VA_ARGS__) #define DBG(...) // BMP structures @@ -83,7 +85,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) // EG_IMAGE *NewImage; BMP_IMAGE_HEADER *BmpHeader; BMP_COLOR_MAP *BmpColorMap; - UINT32 RealPixelHeight, RealPixelWidth; + INT32 RealPixelHeight, RealPixelWidth; UINT8 *ImagePtr; UINT8 *ImagePtrBase; UINTN ImageLineOffset; @@ -95,18 +97,25 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) // read and check header if (FileDataLength < sizeof(BMP_IMAGE_HEADER) || FileData == NULL) { setEmpty(); // to be 100% sure + DBG("1\n"); return EFI_NOT_FOUND; } BmpHeader = (BMP_IMAGE_HEADER *) FileData; - if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') + if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { + DBG("2\n"); return EFI_NOT_FOUND; + } if (BmpHeader->BitPerPixel != 1 && BmpHeader->BitPerPixel != 4 && BmpHeader->BitPerPixel != 8 && BmpHeader->BitPerPixel != 24 && - BmpHeader->BitPerPixel != 32) + BmpHeader->BitPerPixel != 32) { + DBG("3\n"); return EFI_NOT_FOUND; + } // 32-bit images are always stored uncompressed - if (BmpHeader->CompressionType > 0 && BmpHeader->BitPerPixel != 32) + if (BmpHeader->CompressionType > 0 && BmpHeader->BitPerPixel != 32) { + DBG("4\n"); return EFI_NOT_FOUND; + } // calculate parameters ImageLineOffset = BmpHeader->PixelWidth; @@ -121,11 +130,16 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) if ((ImageLineOffset % 4) != 0) ImageLineOffset = ImageLineOffset + (4 - (ImageLineOffset % 4)); + DBG("ImageOffset=%d ImageLineOffset=%lld FileDataLength=%lld\n", + BmpHeader->ImageOffset, ImageLineOffset, FileDataLength); + // check bounds - RealPixelHeight = BmpHeader->PixelHeight > 0 ? BmpHeader->PixelHeight : -BmpHeader->PixelHeight; - RealPixelWidth = BmpHeader->PixelWidth > 0 ? BmpHeader->PixelWidth : -BmpHeader->PixelWidth; - if (BmpHeader->ImageOffset + ImageLineOffset * RealPixelHeight > FileDataLength) + RealPixelHeight = (BmpHeader->PixelHeight > 0 ? BmpHeader->PixelHeight : -BmpHeader->PixelHeight); + RealPixelWidth = (BmpHeader->PixelWidth > 0 ? BmpHeader->PixelWidth : -BmpHeader->PixelWidth); + if (BmpHeader->ImageOffset + ImageLineOffset * RealPixelHeight > FileDataLength) { + DBG("5 H=%d W=%d\n", RealPixelHeight, RealPixelWidth); return EFI_NOT_FOUND; + } // allocate image structure and buffer // NewImage = egCreateImage(RealPixelWidth, RealPixelHeight, WantAlpha); @@ -135,12 +149,13 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) AlphaValue = 255; setSizeInPixels(RealPixelWidth, RealPixelHeight); + DBG("set sizes %u,%u\n", RealPixelWidth, RealPixelHeight); // PixelCount = RealPixelWidth * RealPixelHeight; // convert image BmpColorMap = (BMP_COLOR_MAP *)(FileData + sizeof(BMP_IMAGE_HEADER)); ImagePtrBase = FileData + BmpHeader->ImageOffset; - for (UINT32 y = 0; y < RealPixelHeight; y++) { + for (INT32 y = 0; y < RealPixelHeight; y++) { ImagePtr = ImagePtrBase; ImagePtrBase += ImageLineOffset; // vertically mirror @@ -150,11 +165,11 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) } else { PixelPtr = GetPixelPtr(0,0) + (RealPixelHeight - 1 - y) * RealPixelWidth; } - + DBG("6 BitPerPixel=%d\n", BmpHeader->BitPerPixel); switch (BmpHeader->BitPerPixel) { case 1: - for (UINT32 x = 0; x < RealPixelWidth; x++) { + for (INT32 x = 0; x < RealPixelWidth; x++) { BitIndex = x & 0x07; if (BitIndex == 0) ImageValue = *ImagePtr++; @@ -170,8 +185,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) case 4: { - UINT32 x; - for (x = 0; x <= RealPixelWidth - 2; x += 2) { + for (INT32 x = 0; x <= RealPixelWidth - 2; x += 2) { ImageValue = *ImagePtr++; Index = ImageValue >> 4; @@ -188,7 +202,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) PixelPtr->Reserved = AlphaValue; PixelPtr++; } - if (x < RealPixelWidth) { + if ((RealPixelWidth & 1) == 1) { // для нечетных ImageValue = *ImagePtr++; Index = ImageValue >> 4; @@ -201,7 +215,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) break; } case 8: - for (UINT32 x = 0; x < RealPixelWidth; x++) { + for (INT32 x = 0; x < RealPixelWidth; x++) { Index = *ImagePtr++; PixelPtr->Blue = BmpColorMap[Index].Blue; PixelPtr->Green = BmpColorMap[Index].Green; @@ -212,7 +226,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) break; case 24: - for (UINT32 x = 0; x < RealPixelWidth; x++) { + for (INT32 x = 0; x < RealPixelWidth; x++) { PixelPtr->Blue = *ImagePtr++; PixelPtr->Green = *ImagePtr++; PixelPtr->Red = *ImagePtr++; @@ -221,7 +235,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) } break; case 32: - for (UINT32 x = 0; x < RealPixelWidth; x++) { + for (INT32 x = 0; x < RealPixelWidth; x++) { PixelPtr->Blue = *ImagePtr++; PixelPtr->Green = *ImagePtr++; PixelPtr->Red = *ImagePtr++; @@ -233,6 +247,7 @@ EFI_STATUS XImage::FromBMP(UINT8 *FileData, IN UINTN FileDataLength) } } + DBG("sucсess\n"); return EFI_SUCCESS; } @@ -263,7 +278,7 @@ EFI_STATUS XImage::ToBMP(UINT8** FileDataReturn, UINTN& FileDataLengthReturn) FileDataLength = sizeof(BMP_IMAGE_HEADER) + MultU64x64(Height, ImageLineOffset); FileData = (UINT8*)AllocateZeroPool((UINTN)FileDataLength); if (FileData == NULL) { - DBG("Error allocate %d bytes\n", FileDataLength); + DBG("Error allocate %lld bytes\n", FileDataLength); *FileDataReturn = NULL; FileDataLengthReturn = 0; return EFI_NOT_FOUND;