VOID egDrawImageArea(IN EG_IMAGE *Image, IN UINTN AreaPosX, IN UINTN AreaPosY, IN UINTN AreaWidth, IN UINTN AreaHeight, IN UINTN ScreenPosX, IN UINTN ScreenPosY) { if (!egHasGraphics) return; egRestrictImageArea(Image, AreaPosX, AreaPosY, &AreaWidth, &AreaHeight); if (AreaWidth == 0) return; if (Image->HasAlpha) { Image->HasAlpha = FALSE; egSetPlane(PLPTR(Image, a), 0, Image->Width * Image->Height); } if (GraphicsOutput != NULL) { GraphicsOutput->Blt(GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData, EfiBltBufferToVideo, AreaPosX, AreaPosY, ScreenPosX, ScreenPosY, AreaWidth, AreaHeight, Image->Width * 4); } else if (UgaDraw != NULL) { UgaDraw->Blt(UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaBltBufferToVideo, AreaPosX, AreaPosY, ScreenPosX, ScreenPosY, AreaWidth, AreaHeight, Image->Width * 4); } }
VOID egDrawImage(IN EG_IMAGE *Image, IN UINTN ScreenPosX, IN UINTN ScreenPosY) { if (!egHasGraphics) return; if (Image->HasAlpha) { Image->HasAlpha = FALSE; egSetPlane(PLPTR(Image, a), 0, Image->Width * Image->Height); } if (GraphicsOutput != NULL) { refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData, EfiBltBufferToVideo, 0, 0, ScreenPosX, ScreenPosY, Image->Width, Image->Height, 0); } else if (UgaDraw != NULL) { refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaBltBufferToVideo, 0, 0, ScreenPosX, ScreenPosY, Image->Width, Image->Height, 0); } }
EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN IconSize, IN BOOLEAN WantAlpha) { EG_IMAGE *NewImage; UINT8 *Ptr, *BufferEnd, *DataPtr, *MaskPtr; UINT32 BlockLen, DataLen, MaskLen; UINTN FetchPixelSize, PixelCount, i; UINT8 *CompData; UINTN CompLen; UINT8 *SrcPtr; EG_PIXEL *DestPtr; if (FileDataLength < 8 || FileData == NULL || FileData[0] != 'i' || FileData[1] != 'c' || FileData[2] != 'n' || FileData[3] != 's') { // not an icns file... return NULL; } FetchPixelSize = IconSize; for (;;) { DataPtr = NULL; DataLen = 0; MaskPtr = NULL; MaskLen = 0; Ptr = FileData + 8; BufferEnd = FileData + FileDataLength; // iterate over tagged blocks in the file while (Ptr + 8 <= BufferEnd) { BlockLen = ((UINT32)Ptr[4] << 24) + ((UINT32)Ptr[5] << 16) + ((UINT32)Ptr[6] << 8) + (UINT32)Ptr[7]; if (Ptr + BlockLen > BufferEnd) // block continues beyond end of file break; // extract the appropriate blocks for each pixel size if (FetchPixelSize == 128) { if (Ptr[0] == 'i' && Ptr[1] == 't' && Ptr[2] == '3' && Ptr[3] == '2') { if (Ptr[8] == 0 && Ptr[9] == 0 && Ptr[10] == 0 && Ptr[11] == 0) { DataPtr = Ptr + 12; DataLen = BlockLen - 12; } } else if (Ptr[0] == 't' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { MaskPtr = Ptr + 8; MaskLen = BlockLen - 8; } } else if (FetchPixelSize == 48) { if (Ptr[0] == 'i' && Ptr[1] == 'h' && Ptr[2] == '3' && Ptr[3] == '2') { DataPtr = Ptr + 8; DataLen = BlockLen - 8; } else if (Ptr[0] == 'h' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { MaskPtr = Ptr + 8; MaskLen = BlockLen - 8; } } else if (FetchPixelSize == 32) { if (Ptr[0] == 'i' && Ptr[1] == 'l' && Ptr[2] == '3' && Ptr[3] == '2') { DataPtr = Ptr + 8; DataLen = BlockLen - 8; } else if (Ptr[0] == 'l' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { MaskPtr = Ptr + 8; MaskLen = BlockLen - 8; } } else if (FetchPixelSize == 16) { if (Ptr[0] == 'i' && Ptr[1] == 's' && Ptr[2] == '3' && Ptr[3] == '2') { DataPtr = Ptr + 8; DataLen = BlockLen - 8; } else if (Ptr[0] == 's' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { MaskPtr = Ptr + 8; MaskLen = BlockLen - 8; } } Ptr += BlockLen; } //TODO - take different larger size if not found /* FUTURE: try to load a different size and scale it later if (DataPtr == NULL && FetchPixelSize == 32) { FetchPixelSize = 128; continue; } */ break; } if (DataPtr == NULL) return NULL; // no image found // allocate image structure and buffer NewImage = egCreateImage(FetchPixelSize, FetchPixelSize, WantAlpha); if (NewImage == NULL) return NULL; PixelCount = FetchPixelSize * FetchPixelSize; if (DataLen < PixelCount * 3) { // pixel data is compressed, RGB planar CompData = DataPtr; CompLen = DataLen; egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, r), PixelCount); egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, g), PixelCount); egDecompressIcnsRLE(&CompData, &CompLen, PLPTR(NewImage, b), PixelCount); // possible assertion: CompLen == 0 if (CompLen > 0) { Print(L" egLoadICNSIcon: %d bytes of compressed data left\n", CompLen); } } else { // pixel data is uncompressed, RGB interleaved SrcPtr = DataPtr; DestPtr = NewImage->PixelData; for (i = 0; i < PixelCount; i++, DestPtr++) { DestPtr->r = *SrcPtr++; DestPtr->g = *SrcPtr++; DestPtr->b = *SrcPtr++; } } // add/set alpha plane if (MaskPtr != NULL && MaskLen >= PixelCount && WantAlpha) egInsertPlane(MaskPtr, PLPTR(NewImage, a), PixelCount); else egSetPlane(PLPTR(NewImage, a), WantAlpha ? 255 : 0, PixelCount); // FUTURE: scale to originally requested size if we had to load another size return NewImage; }