X-Git-Url: https://code.delx.au/refind/blobdiff_plain/e8d44d7578a450f6289abf45f841c65514a6d443..e71f070b28bf167ea4c236aa271c21ea7b2f5128:/libeg/load_bmp.c diff --git a/libeg/load_bmp.c b/libeg/load_bmp.c index a836e6e..24fec9f 100644 --- a/libeg/load_bmp.c +++ b/libeg/load_bmp.c @@ -51,20 +51,20 @@ typedef struct { 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; - UINT32 YPixelsPerMeter; - UINT32 NumberOfColors; - UINT32 ImportantColors; + INT32 Size; + INT16 Reserved[2]; + INT32 ImageOffset; + INT32 HeaderSize; + INT32 PixelWidth; + INT32 PixelHeight; + INT16 Planes; // Must be 1 + INT16 BitPerPixel; // 1, 4, 8, or 24 + INT32 CompressionType; + INT32 ImageSize; // Compressed image size in bytes + INT32 XPixelsPerMeter; + INT32 YPixelsPerMeter; + INT32 NumberOfColors; + INT32 ImportantColors; } BMP_IMAGE_HEADER; #pragma pack() @@ -82,8 +82,9 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico UINTN x, y; UINT8 *ImagePtr; UINT8 *ImagePtrBase; - UINTN ImageLineOffset; + UINTN PixelWidth, PixelHeight, ImageLineOffset; UINT8 ImageValue = 0, AlphaValue; + BOOLEAN UpsideDown; EG_PIXEL *PixelPtr; UINTN Index, BitIndex; @@ -98,9 +99,19 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico if (BmpHeader->BitPerPixel != 1 && BmpHeader->BitPerPixel != 4 && BmpHeader->BitPerPixel != 8 && BmpHeader->BitPerPixel != 24) return NULL; + if (BmpHeader->PixelWidth < 1 || BmpHeader->PixelWidth > 4096 || + BmpHeader->PixelHeight < -4096 || BmpHeader->PixelHeight == 0 || + BmpHeader->PixelHeight > 4096) + return NULL; // calculate parameters - ImageLineOffset = BmpHeader->PixelWidth; + PixelWidth = BmpHeader->PixelWidth; + UpsideDown = BmpHeader->PixelHeight >= 0; + if (BmpHeader->PixelHeight < 0) + PixelHeight = -BmpHeader->PixelHeight; + else + PixelHeight = BmpHeader->PixelHeight; + ImageLineOffset = PixelWidth; if (BmpHeader->BitPerPixel == 24) ImageLineOffset *= 3; else if (BmpHeader->BitPerPixel == 1) @@ -110,11 +121,11 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico if ((ImageLineOffset % 4) != 0) ImageLineOffset = ImageLineOffset + (4 - (ImageLineOffset % 4)); // check bounds - if (BmpHeader->ImageOffset + ImageLineOffset * BmpHeader->PixelHeight > FileDataLength) + if (BmpHeader->ImageOffset + ImageLineOffset * PixelHeight > FileDataLength) return NULL; // allocate image structure and buffer - NewImage = egCreateImage(BmpHeader->PixelWidth, BmpHeader->PixelHeight, WantAlpha); + NewImage = egCreateImage(PixelWidth, PixelHeight, WantAlpha); if (NewImage == NULL) return NULL; AlphaValue = WantAlpha ? 255 : 0; @@ -122,15 +133,18 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico // convert image BmpColorMap = (BMP_COLOR_MAP *)(FileData + sizeof(BMP_IMAGE_HEADER)); ImagePtrBase = FileData + BmpHeader->ImageOffset; - for (y = 0; y < BmpHeader->PixelHeight; y++) { + for (y = 0; y < PixelHeight; y++) { ImagePtr = ImagePtrBase; ImagePtrBase += ImageLineOffset; - PixelPtr = NewImage->PixelData + (BmpHeader->PixelHeight - 1 - y) * BmpHeader->PixelWidth; + if (UpsideDown) + PixelPtr = NewImage->PixelData + (PixelHeight - 1 - y) * PixelWidth; + else + PixelPtr = NewImage->PixelData + y * PixelWidth; switch (BmpHeader->BitPerPixel) { case 1: - for (x = 0; x < BmpHeader->PixelWidth; x++) { + for (x = 0; x < PixelWidth; x++) { BitIndex = x & 0x07; if (BitIndex == 0) ImageValue = *ImagePtr++; @@ -145,7 +159,7 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico break; case 4: - for (x = 0; x <= BmpHeader->PixelWidth - 2; x += 2) { + for (x = 0; x <= PixelWidth - 2; x += 2) { ImageValue = *ImagePtr++; Index = ImageValue >> 4; @@ -162,7 +176,7 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico PixelPtr->a = AlphaValue; PixelPtr++; } - if (x < BmpHeader->PixelWidth) { + if (x < PixelWidth) { ImageValue = *ImagePtr++; Index = ImageValue >> 4; @@ -175,7 +189,7 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico break; case 8: - for (x = 0; x < BmpHeader->PixelWidth; x++) { + for (x = 0; x < PixelWidth; x++) { Index = *ImagePtr++; PixelPtr->b = BmpColorMap[Index].Blue; PixelPtr->g = BmpColorMap[Index].Green; @@ -186,7 +200,7 @@ EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ico break; case 24: - for (x = 0; x < BmpHeader->PixelWidth; x++) { + for (x = 0; x < PixelWidth; x++) { PixelPtr->b = *ImagePtr++; PixelPtr->g = *ImagePtr++; PixelPtr->r = *ImagePtr++; @@ -234,11 +248,11 @@ VOID egEncodeBMP(IN EG_IMAGE *Image, OUT UINT8 **FileDataReturn, OUT UINTN *File BmpHeader = (BMP_IMAGE_HEADER *)FileData; BmpHeader->CharB = 'B'; BmpHeader->CharM = 'M'; - BmpHeader->Size = FileDataLength; + BmpHeader->Size = (INT32)FileDataLength; BmpHeader->ImageOffset = sizeof(BMP_IMAGE_HEADER); BmpHeader->HeaderSize = 40; - BmpHeader->PixelWidth = Image->Width; - BmpHeader->PixelHeight = Image->Height; + BmpHeader->PixelWidth = (INT32)Image->Width; + BmpHeader->PixelHeight = (INT32)Image->Height; BmpHeader->Planes = 1; BmpHeader->BitPerPixel = 24; BmpHeader->CompressionType = 0;