OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcAppleImageConversionLib.c
Go to the documentation of this file.
1
17#include <Library/BaseMemoryLib.h>
18#include <Library/BaseOverflowLib.h>
19#include <Library/DebugLib.h>
20#include <Library/MemoryAllocationLib.h>
22#include <Library/OcMiscLib.h>
23#include <Library/OcPngLib.h>
24#include <Library/UefiBootServicesTableLib.h>
25
26STATIC
27CONST UINT8
28 mPngHeader[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
29
30STATIC
31EFI_STATUS
32EFIAPI
34 IN VOID *ImageBuffer,
35 IN UINTN ImageSize
36 )
37{
38 if ((ImageBuffer == NULL) || (ImageSize == 0)) {
39 return EFI_INVALID_PARAMETER;
40 }
41
42 if ( (ImageSize < sizeof (mPngHeader))
43 || (CompareMem (ImageBuffer, mPngHeader, sizeof (mPngHeader)) != 0))
44 {
45 return EFI_UNSUPPORTED;
46 }
47
48 return EFI_SUCCESS;
49}
50
51STATIC
52EFI_STATUS
53EFIAPI
55 IN VOID *ImageBuffer,
56 IN UINTN ImageSize,
57 OUT UINT32 *ImageWidth,
58 OUT UINT32 *ImageHeight
59 )
60{
61 EFI_STATUS Status;
62
63 if ( (ImageBuffer == NULL)
64 || (ImageSize == 0)
65 || (ImageWidth == NULL)
66 || (ImageHeight == NULL))
67 {
68 return EFI_INVALID_PARAMETER;
69 }
70
71 Status = OcGetPngDims (ImageBuffer, ImageSize, ImageWidth, ImageHeight);
72
73 if (EFI_ERROR (Status)) {
74 DEBUG ((DEBUG_INFO, "OCIC: Failed to obtain image dimensions for image\n"));
75 }
76
77 return Status;
78}
79
80STATIC
81EFI_STATUS
82EFIAPI
84 IN VOID *ImageBuffer,
85 IN UINTN ImageSize,
86 IN OUT EFI_UGA_PIXEL **RawImageData,
87 IN OUT UINTN *RawImageDataSize
88 )
89{
90 EFI_STATUS Status;
91 UINTN Index;
92 UINTN PixelCount;
93 UINTN ByteCount;
94 VOID *RealImageData;
95 EFI_UGA_PIXEL *PixelWalker;
96 UINT32 Width;
97 UINT32 Height;
98 UINT8 TmpChannel;
99
100 STATIC_ASSERT (sizeof (EFI_UGA_PIXEL) == sizeof (UINT32), "Unsupported pixel size");
101 STATIC_ASSERT (OFFSET_OF (EFI_UGA_PIXEL, Blue) == 0, "Unsupported pixel format");
102 STATIC_ASSERT (OFFSET_OF (EFI_UGA_PIXEL, Green) == 1, "Unsupported pixel format");
103 STATIC_ASSERT (OFFSET_OF (EFI_UGA_PIXEL, Red) == 2, "Unsupported pixel format");
104 STATIC_ASSERT (OFFSET_OF (EFI_UGA_PIXEL, Reserved) == 3, "Unsupported pixel format");
105
106 if ( (ImageBuffer == NULL)
107 || (ImageSize == 0)
108 || (RawImageData == NULL)
109 || (RawImageDataSize == NULL))
110 {
111 return EFI_INVALID_PARAMETER;
112 }
113
114 Status = OcDecodePng (
115 ImageBuffer,
116 ImageSize,
117 (VOID **)&RealImageData,
118 &Width,
119 &Height,
120 NULL
121 );
122
123 if (EFI_ERROR (Status)) {
124 return EFI_UNSUPPORTED;
125 }
126
127 PixelCount = (UINTN)Width * Height;
128 ByteCount = PixelCount * sizeof (*RawImageData);
129
130 //
131 // The buffer can be callee or caller allocated.
132 // This is differentiated by passing non-null to *RawImageData.
133 // For now we always allocate our own data, since boot.efi lets caller do it anyway.
134 //
135 if (*RawImageData != NULL) {
136 if (*RawImageDataSize < ByteCount) {
137 FreePool (RealImageData);
138 *RawImageDataSize = ByteCount;
139 return EFI_BUFFER_TOO_SMALL;
140 }
141
142 CopyMem (*RawImageData, RealImageData, ByteCount);
143 FreePool (RealImageData);
144 *RawImageDataSize = ByteCount;
145 } else {
146 *RawImageData = RealImageData;
147 }
148
149 PixelWalker = *RawImageData;
150
151 for (Index = 0; Index < PixelCount; ++Index) {
152 TmpChannel = PixelWalker->Blue;
153 PixelWalker->Blue = PixelWalker->Red;
154 PixelWalker->Red = TmpChannel;
155 PixelWalker->Reserved = 0xFF - PixelWalker->Reserved;
156 ++PixelWalker;
157 }
158
159 return EFI_SUCCESS;
160}
161
162STATIC
163EFI_STATUS
164EFIAPI
166 IN VOID *Buffer,
167 IN UINTN BufferSize,
168 IN UINTN Scale,
169 OUT UINT32 *Width,
170 OUT UINT32 *Height
171 )
172{
173 if ( (Buffer == NULL)
174 || (BufferSize == 0)
175 || (Scale == 0)
176 || (Width == NULL)
177 || (Height == NULL))
178 {
179 return EFI_INVALID_PARAMETER;
180 }
181
182 if (Scale > 1) {
183 return EFI_UNSUPPORTED;
184 }
185
186 return GetImageDims (Buffer, BufferSize, Width, Height);
187}
188
189STATIC
190EFI_STATUS
191EFIAPI
193 IN VOID *Buffer,
194 IN UINTN BufferSize,
195 IN UINTN Scale,
196 IN OUT EFI_UGA_PIXEL **RawImageData,
197 IN OUT UINTN *RawImageDataSize
198 )
199{
200 if ( (Buffer == NULL)
201 || (BufferSize == 0)
202 || (Scale == 0)
203 || (RawImageData == NULL)
204 || (RawImageDataSize == NULL))
205 {
206 return EFI_INVALID_PARAMETER;
207 }
208
209 if (Scale > 1) {
210 return EFI_UNSUPPORTED;
211 }
212
213 return DecodeImageData (Buffer, BufferSize, RawImageData, RawImageDataSize);
214}
215
216//
217// Image codec protocol instance.
218//
228
231 IN BOOLEAN Reinstall
232 )
233{
234 EFI_STATUS Status;
235 APPLE_IMAGE_CONVERSION_PROTOCOL *AppleImageConversionInterface;
236 EFI_HANDLE NewHandle;
237
238 if (Reinstall) {
240 if (EFI_ERROR (Status)) {
241 DEBUG ((DEBUG_ERROR, "OCIC: Uninstall failed - %r\n", Status));
242 return NULL;
243 }
244 } else {
245 Status = gBS->LocateProtocol (
247 NULL,
248 (VOID **)&AppleImageConversionInterface
249 );
250 if (!EFI_ERROR (Status)) {
251 return AppleImageConversionInterface;
252 }
253 }
254
255 NewHandle = NULL;
256 Status = gBS->InstallMultipleProtocolInterfaces (
257 &NewHandle,
260 NULL
261 );
262
263 if (EFI_ERROR (Status)) {
264 return NULL;
265 }
266
267 return &mAppleImageConversion;
268}
UINT8 Reserved[430]
Definition Apm.h:39
EFI_GUID gAppleImageConversionProtocolGuid
#define APPLE_IMAGE_CONVERSION_PROTOCOL_ANY_EXTENSION
#define APPLE_IMAGE_CONVERSION_PROTOCOL_REVISION
STATIC EFI_STATUS EFIAPI RecognizeImageData(IN VOID *ImageBuffer, IN UINTN ImageSize)
APPLE_IMAGE_CONVERSION_PROTOCOL * OcAppleImageConversionInstallProtocol(IN BOOLEAN Reinstall)
STATIC APPLE_IMAGE_CONVERSION_PROTOCOL mAppleImageConversion
STATIC EFI_STATUS EFIAPI DecodeImageData(IN VOID *ImageBuffer, IN UINTN ImageSize, IN OUT EFI_UGA_PIXEL **RawImageData, IN OUT UINTN *RawImageDataSize)
STATIC EFI_STATUS EFIAPI GetImageDimsEx(IN VOID *Buffer, IN UINTN BufferSize, IN UINTN Scale, OUT UINT32 *Width, OUT UINT32 *Height)
STATIC CONST UINT8 mPngHeader[]
STATIC EFI_STATUS EFIAPI DecodeImageDataEx(IN VOID *Buffer, IN UINTN BufferSize, IN UINTN Scale, IN OUT EFI_UGA_PIXEL **RawImageData, IN OUT UINTN *RawImageDataSize)
STATIC EFI_STATUS EFIAPI GetImageDims(IN VOID *ImageBuffer, IN UINTN ImageSize, OUT UINT32 *ImageWidth, OUT UINT32 *ImageHeight)
STATIC_ASSERT(BYTES_PER_PIXEL==sizeof(UINT32), "Non 4-byte pixels are unsupported!")
EFI_BOOT_SERVICES * gBS
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
EFI_STATUS OcGetPngDims(IN VOID *Buffer, IN UINTN Size, OUT UINT32 *Width, OUT UINT32 *Height)
Definition OcPng.c:25
EFI_STATUS OcDecodePng(IN VOID *Buffer, IN UINTN Size, OUT VOID **RawData, OUT UINT32 *Width, OUT UINT32 *Height, OUT BOOLEAN *HasAlphaType OPTIONAL)
Definition OcPng.c:64
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)