| 76 | // |
| 77 | |
| 78 | EG_IMAGE * egDecodeBMP(IN UINT8 *FileData, IN UINTN FileDataLength, IN BOOLEAN WantAlpha) |
| 79 | { |
| 80 | EG_IMAGE *NewImage; |
| 81 | BMP_IMAGE_HEADER *BmpHeader; |
| 82 | BMP_COLOR_MAP *BmpColorMap; |
| 83 | INT32 x, y; |
| 84 | INT32 RealPixelHeight, RealPixelWidth; |
| 85 | UINT8 *ImagePtr; |
| 86 | UINT8 *ImagePtrBase; |
| 87 | UINTN ImageLineOffset; |
| 88 | UINT8 ImageValue = 0; |
| 89 | UINT8 AlphaValue; |
| 90 | EFI_UGA_PIXEL *PixelPtr; |
| 91 | UINTN Index, BitIndex; |
| 92 | |
| 93 | // read and check header |
| 94 | if (FileDataLength < sizeof(BMP_IMAGE_HEADER) || FileData == NULL) |
| 95 | return NULL; |
| 96 | BmpHeader = (BMP_IMAGE_HEADER *) FileData; |
| 97 | if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') |
| 98 | return NULL; |
| 99 | if (BmpHeader->BitPerPixel != 1 && BmpHeader->BitPerPixel != 4 && |
| 100 | BmpHeader->BitPerPixel != 8 && BmpHeader->BitPerPixel != 24 && |
| 101 | BmpHeader->BitPerPixel != 32) |
| 102 | return NULL; |
| 103 | // 32-bit images are always stored uncompressed |
| 104 | if (BmpHeader->CompressionType > 0 && BmpHeader->BitPerPixel != 32) |
| 105 | return NULL; |
| 106 | |
| 107 | // calculate parameters |
| 108 | ImageLineOffset = BmpHeader->PixelWidth; |
| 109 | if (BmpHeader->BitPerPixel == 32) |
| 110 | ImageLineOffset *= 4; |
| 111 | else if (BmpHeader->BitPerPixel == 24) |
| 112 | ImageLineOffset *= 3; |
| 113 | else if (BmpHeader->BitPerPixel == 1) |
| 114 | ImageLineOffset = (ImageLineOffset + 7) >> 3; |
| 115 | else if (BmpHeader->BitPerPixel == 4) |
| 116 | ImageLineOffset = (ImageLineOffset + 1) >> 1; |
| 117 | if ((ImageLineOffset % 4) != 0) |
| 118 | ImageLineOffset = ImageLineOffset + (4 - (ImageLineOffset % 4)); |
| 119 | |
| 120 | // check bounds |
| 121 | RealPixelHeight = BmpHeader->PixelHeight > 0 ? BmpHeader->PixelHeight : -BmpHeader->PixelHeight; |
| 122 | RealPixelWidth = BmpHeader->PixelWidth > 0 ? BmpHeader->PixelWidth : -BmpHeader->PixelWidth; |
| 123 | if (BmpHeader->ImageOffset + ImageLineOffset * RealPixelHeight > FileDataLength) |
| 124 | return NULL; |
| 125 | |
| 126 | // allocate image structure and buffer |
| 127 | NewImage = egCreateImage(RealPixelWidth, RealPixelHeight, WantAlpha); |
| 128 | if (NewImage == NULL) |
| 129 | return NULL; |
| 130 | AlphaValue = WantAlpha ? 255 : 0; |
| 131 | |
| 132 | // convert image |
| 133 | BmpColorMap = (BMP_COLOR_MAP *)(FileData + sizeof(BMP_IMAGE_HEADER)); |
| 134 | ImagePtrBase = FileData + BmpHeader->ImageOffset; |
| 135 | for (y = 0; y < RealPixelHeight; y++) { |
no test coverage detected