diff --git a/.gitignore b/.gitignore index 06290d093..924116736 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # OS X temporary files that should never be committed .vs .DS_Store +.project +.cproject +.settings *.swp *.lock *.bak @@ -57,4 +60,4 @@ RELEASE_*/ *copy [0-9]* #work in progress -*_wip \ No newline at end of file +*_wip diff --git a/Clover.dsc b/Clover.dsc index f71b6c5ed..35d99046e 100644 --- a/Clover.dsc +++ b/Clover.dsc @@ -772,7 +772,7 @@ Protocols/MsgLog/MsgLog.inf #Protocols/SMCHelper/SMCHelper.inf #Protocols/FirmwareVolume/FirmwareVolume.inf - Protocols/AppleImageCodec/AppleImageCodec.inf + #Protocols/AppleImageCodec/AppleImageCodec.inf #Protocols/AppleUITheme/AppleUITheme.inf Protocols/HashServiceFix/HashServiceFix.inf Protocols/AppleKeyAggregator/AppleKeyAggregator.inf diff --git a/OpenCorePkg b/OpenCorePkg index ac03fdb31..c3b81619a 160000 --- a/OpenCorePkg +++ b/OpenCorePkg @@ -1 +1 @@ -Subproject commit ac03fdb3174877a17da5b3834104bd5034eea0c8 +Subproject commit c3b81619a9dd9e1cfcf7b85f2f3107c6517840ea diff --git a/Protocols/AppleImageCodec/AppleImageCodec.c b/Protocols/AppleImageCodec/AppleImageCodec.c index d5d3ca569..9eb099d2f 100644 --- a/Protocols/AppleImageCodec/AppleImageCodec.c +++ b/Protocols/AppleImageCodec/AppleImageCodec.c @@ -16,7 +16,10 @@ #include #include +//#include "XImage.h" + #include "picopng.h" +//#include "lodepng.h" //#define DBG(...) AsciiPrint(__VA_ARGS__); #define DBG(...) diff --git a/rEFIt_UEFI/Platform/DataHubCpu.cpp b/rEFIt_UEFI/Platform/DataHubCpu.cpp index cf8d65aae..f0238bef1 100644 --- a/rEFIt_UEFI/Platform/DataHubCpu.cpp +++ b/rEFIt_UEFI/Platform/DataHubCpu.cpp @@ -48,6 +48,7 @@ #include #include +#include #define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100 @@ -71,6 +72,7 @@ constexpr const EFI_GUID gDataHubPlatformGuid = { extern APPLE_SMC_IO_PROTOCOL *gAppleSmc; extern UINT32 mCurrentColor; +extern APPLE_IMAGE_CODEC_PROTOCOL gAppleImageCodec; typedef union { diff --git a/rEFIt_UEFI/Platform/Injectors.cpp b/rEFIt_UEFI/Platform/Injectors.cpp index 846bb4ee0..0599d6527 100644 --- a/rEFIt_UEFI/Platform/Injectors.cpp +++ b/rEFIt_UEFI/Platform/Injectors.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef DEBUG_ALL #define DEBUG_PRO 1 @@ -56,6 +57,7 @@ UINT16 KeyboardProduct = 0x021d; //iMac aluminium extern UINT32 mCurrentColor; extern EFI_GUID gAppleUserInterfaceThemeProtocolGuid; extern EFI_GUID gAppleSystemInfoProtocolGuid; +extern APPLE_IMAGE_CODEC_PROTOCOL gAppleImageCodec; typedef struct _APPLE_GETVAR_PROTOCOL APPLE_GETVAR_PROTOCOL; @@ -410,13 +412,27 @@ SetPrivateVarProto(void) &mAppleUserInterfaceThemeProtocol, &gEfiFirmwareVolumeProtocolGuid, &FirmwareVolume, - &gAppleSMCProtocolGuid, - &SMCHelperProtocol, - &gAppleSMCStateProtocolGuid, - &SMCStateProtocol, - NULL - ); -// Status = SMCHelperInstall(&gImageHandle); + &gAppleSMCProtocolGuid, + &SMCHelperProtocol, + &gAppleSMCStateProtocolGuid, + &SMCStateProtocol, + NULL + ); + if (EFI_ERROR(Status)) { + DBG("Error installing multiple protocol, Status = %s\n", efiStrError(Status)); + } + + + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gAppleImageCodecProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID *)&gAppleImageCodec + ); + + if (EFI_ERROR(Status)) { + DBG("AppleImageCodec: error installing protocol, Status = %s\n", efiStrError(Status)); + } //obligatory protocol Status = gBS->InstallProtocolInterface (&gImageHandle, @@ -424,6 +440,10 @@ SetPrivateVarProto(void) EFI_NATIVE_INTERFACE, &mDeviceProperties ); + if (EFI_ERROR(Status)) { + DBG("DevicePathPropertyDatabase: error installing protocol, Status = %s\n", efiStrError(Status)); + } + return Status; } diff --git a/rEFIt_UEFI/libeg/AppleImageCodec.cpp b/rEFIt_UEFI/libeg/AppleImageCodec.cpp new file mode 100644 index 000000000..851e6ee47 --- /dev/null +++ b/rEFIt_UEFI/libeg/AppleImageCodec.cpp @@ -0,0 +1,234 @@ +/** @file + + Driver with Apple image decode protocol implementation + for PNG. + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "XImage.h" + +//#include "picopng.h" +#include "lodepng.h" + +//#define DBG(...) AsciiPrint(__VA_ARGS__); +#define DBG(...) + +struct EFI_RES_ENTRY { + CHAR8 Name[64]; + UINT32 DataOffset; + UINT32 DataLength; +}; + +struct EFI_RES { + UINT16 Magic; // 0x200 (BigEndian) or 0x02 (LE) + UINT16 Num; // LE + struct EFI_RES_ENTRY Entries[1]; //NUM - dynamic array +}; + +//Fool Proof +/* + 02 00 14 00 61 76 61 74 61 72 2E 70 6E 67 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 EC 05 00 00 AF 2D 00 00 + + 61 76 61 74 61 72 40 32 78 2E 70 6E 67 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 9B 33 00 00 32 84 00 00 + + Num=20 + 1. avatar.png Offset=0x05EC (LittleEndian) Size=0x2DAF Offset+Size=0x339B + 2. avatar@2x.png Offset=0x339C (!) Aligned Size=0x8432 End=0xB7CE + 3. Offset=0xB7CD = 0x339B+0x8432 Not alinged(!!!) File=0xB7CE Aligned + */ + +XImage egDecodeAny(IN UINT8 *FileData, IN UINTN FileDataLength) +{ + XImage NewXImage; + NewXImage.FromPNG(FileData, FileDataLength); + + + if (NewXImage.isEmpty()) { + DBG(" ..png is wrong try to decode icns\n"); + NewXImage.FromICNS(FileData, FileDataLength, 128); + } + + return NewXImage; +} + + +// +// PNG Image codec protocol instance implementation +// + +EFI_STATUS +EFIAPI +RecognizeImageData (//IN APPLE_IMAGE_CODEC_PROTOCOL* This, + VOID *ImageBuffer, + UINTN ImageSize, + OUT VOID **OutBuffer + ) +{ + XImage Image; + + if (!ImageBuffer) { + return EFI_INVALID_PARAMETER; + } + if (*(UINT16*)ImageBuffer == 0x02) { + return EFI_SUCCESS; //this is efires image + } + + DBG("AppleImageCodec RecognizeImageData: Status = "); + Image = egDecodeAny((UINT8*)ImageBuffer, ImageSize); + if (Image.isEmpty()) { + DBG("EFI_UNSUPPORTED\n"); + return EFI_UNSUPPORTED; + } + + DBG("EFI_SUCCESS\n"); + DBG(" ImageSize=%d\n", ImageSize); +// DBG("Decoded: W=%d, H=%d\n", Image.GetWidth(), Image.GetHeight()); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +GetImageDims (//IN APPLE_IMAGE_CODEC_PROTOCOL* This, + VOID *ImageBuffer, + UINTN ImageSize, + UINT32 *ImageWidth, + UINT32 *ImageHeight + ) +{ + XImage Image; + + DBG("AppleImageCodec GetImageDims: Status = "); + Image = egDecodeAny((UINT8*)ImageBuffer, ImageSize); + if (Image.isEmpty()) { + DBG("EFI_UNSUPPORTED\n"); + return EFI_UNSUPPORTED; + } + + *ImageWidth = (UINT32)Image.GetWidth(); + *ImageHeight = (UINT32)Image.GetHeight(); + + DBG("EFI_SUCCESS, Width=%d, Height=%d\n", *ImageWidth, *ImageHeight); + DBG("ImageSize=%d\n", ImageSize); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +DecodeImageData (//IN APPLE_IMAGE_CODEC_PROTOCOL* This, + VOID *ImageBuffer, + UINTN ImageSize, + EFI_UGA_PIXEL **RawImageData, + UINT32 *RawImageDataSize + ) +{ + EFI_STATUS Status; + XImage Image; + + //automatic choose format + if (!RawImageData || !RawImageDataSize) { + return EFI_INVALID_PARAMETER; + } + + DBG("AppleImageCodec DecodeImageData: Status = "); + Image = egDecodeAny((UINT8*)ImageBuffer, ImageSize); + if (Image.isEmpty()) { + DBG("EFI_UNSUPPORTED\n"); + return EFI_UNSUPPORTED; + } + + *RawImageDataSize = (UINT32)(Image.GetWidth() * Image.GetHeight() * sizeof(EFI_UGA_PIXEL)); + Status = gBS->AllocatePool(EfiBootServicesData, *RawImageDataSize, (VOID **)RawImageData); + if (!EFI_ERROR(Status)) { + CopyMem(*RawImageData, (VOID*)Image.GetPixelPtr(0,0), *RawImageDataSize); + } + + DBG("EFI_SUCCESS, RawImageDataSize=%d\n", *RawImageDataSize); +// DBG("ImageBuffer=%p, ImageSize=%d\n", ImageBuffer, ImageSize); +// DBG("Decoded: W=%d, H=%d\n", Image->Width, Image->Height); +// for (int Index=0; Index<10; Index++) { +// DBG("P%d: r,g,b,a= %x, %x, %x, %x\n", Index, (*RawImageData)[Index].Red, (*RawImageData)[Index].Green, (*RawImageData)[Index].Blue, (*RawImageData)[Index].Reserved); +// } +// egFreeImage(Image); + return EFI_SUCCESS; +} + +//more explanations are in OC but the functions are useless +EFI_STATUS +EFIAPI +Unknown1 (VOID* ImageBuffer, UINTN Param1, UINTN Param2, UINTN Param3) +{ + DBG("AppleImageCodec unk1 called\n"); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Unknown2 (VOID* ImageBuffer, UINTN Param1, UINTN Param2, UINTN Param3) +{ + DBG("AppleImageCodec unk2 called\n"); + return EFI_SUCCESS; +} + +/** Image codec protocol instance. */ +APPLE_IMAGE_CODEC_PROTOCOL gAppleImageCodec = { + // Version + 1, + // FileExt + 0, + + RecognizeImageData, + GetImageDims, + DecodeImageData, + + Unknown1, + Unknown2, +}; + +/** Driver's entry point. Installs our StartImage to detect boot loader start. */ +EFI_STATUS +EFIAPI +AppleImageCodecEntrypoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; +// EFI_HANDLE NewHandle; + + // + // Install instance of Apple image codec protocol for + // PNG files + // +// NewHandle = NULL; // install to a new handle +// Status = gBS->InstallMultipleProtocolInterfaces(&NewHandle, &gAppleImageCodecProtocolGuid, &gAppleImageCodec, NULL); + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gAppleImageCodecProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID *)&gAppleImageCodec + ); + + if (EFI_ERROR(Status)) { + DBG("AppleImageCodec: error installing protocol, Status = %s\n", efiStrError(Status)); + } + return Status; +} diff --git a/rEFIt_UEFI/refit.inf b/rEFIt_UEFI/refit.inf index 205e5a297..6877c84f3 100644 --- a/rEFIt_UEFI/refit.inf +++ b/rEFIt_UEFI/refit.inf @@ -160,6 +160,7 @@ include/syslinux_mbr.h include/TagTypes.h include/VolumeTypes.h + libeg/AppleImageCodec.cpp libeg/BmLib.cpp libeg/BmLib.h libeg/egemb_font.cpp