]>
Commit | Line | Data |
---|---|---|
841b2590 SB |
1 | /** @file\r |
2 | Brotli Decompress interfaces\r | |
3 | \r | |
792ace0a | 4 | Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r |
9d510e61 | 5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
841b2590 SB |
6 | \r |
7 | **/\r | |
8 | #include <BrotliDecompressLibInternal.h>\r | |
9 | \r | |
841b2590 SB |
10 | /**\r |
11 | Allocation routine used by BROTLI decompression.\r | |
12 | \r | |
13 | @param Ptr Pointer to the BROTLI_BUFF instance.\r | |
14 | @param Size The size in bytes to be allocated.\r | |
15 | \r | |
16 | @return The allocated pointer address, or NULL on failure\r | |
17 | **/\r | |
18 | VOID *\r | |
19 | BrAlloc (\r | |
1436aea4 MK |
20 | IN VOID *Ptr,\r |
21 | IN size_t Size\r | |
841b2590 SB |
22 | )\r |
23 | {\r | |
1436aea4 MK |
24 | VOID *Addr;\r |
25 | BROTLI_BUFF *Private;\r | |
841b2590 SB |
26 | \r |
27 | Private = (BROTLI_BUFF *)Ptr;\r | |
28 | \r | |
29 | if (Private->BuffSize >= Size) {\r | |
1436aea4 MK |
30 | Addr = Private->Buff;\r |
31 | Private->Buff = (VOID *)((UINT8 *)Addr + Size);\r | |
841b2590 SB |
32 | Private->BuffSize -= Size;\r |
33 | return Addr;\r | |
34 | } else {\r | |
35 | ASSERT (FALSE);\r | |
36 | return NULL;\r | |
37 | }\r | |
38 | }\r | |
39 | \r | |
40 | /**\r | |
41 | Free routine used by BROTLI decompression.\r | |
42 | \r | |
43 | @param Ptr Pointer to the BROTLI_BUFF instance\r | |
44 | @param Address The address to be freed\r | |
45 | **/\r | |
46 | VOID\r | |
47 | BrFree (\r | |
1436aea4 MK |
48 | IN VOID *Ptr,\r |
49 | IN VOID *Address\r | |
841b2590 SB |
50 | )\r |
51 | {\r | |
52 | //\r | |
53 | // We use the 'scratch buffer' for allocations, so there is no free\r | |
54 | // operation required. The scratch buffer will be freed by the caller\r | |
55 | // of the decompression code.\r | |
56 | //\r | |
57 | }\r | |
58 | \r | |
59 | /**\r | |
60 | Decompresses a Brotli compressed source buffer.\r | |
61 | \r | |
62 | Extracts decompressed data to its original form.\r | |
63 | If the compressed source data specified by Source is successfully decompressed\r | |
64 | into Destination, then EFI_SUCCESS is returned. If the compressed source data\r | |
65 | specified by Source is not in a valid compressed data format,\r | |
66 | then EFI_INVALID_PARAMETER is returned.\r | |
67 | \r | |
68 | @param Source The source buffer containing the compressed data.\r | |
69 | @param SourceSize The size of source buffer.\r | |
70 | @param Destination The destination buffer to store the decompressed data.\r | |
71 | @param DestSize The destination buffer size.\r | |
72 | @param BuffInfo The pointer to the BROTLI_BUFF instance.\r | |
73 | \r | |
74 | @retval EFI_SUCCESS Decompression completed successfully, and\r | |
75 | the uncompressed buffer is returned in Destination.\r | |
76 | @retval EFI_INVALID_PARAMETER\r | |
77 | The source buffer specified by Source is corrupted\r | |
78 | (not in a valid compressed format).\r | |
79 | **/\r | |
80 | EFI_STATUS\r | |
81 | BrotliDecompress (\r | |
1436aea4 MK |
82 | IN CONST VOID *Source,\r |
83 | IN UINTN SourceSize,\r | |
84 | IN OUT VOID *Destination,\r | |
85 | IN OUT UINTN DestSize,\r | |
86 | IN VOID *BuffInfo\r | |
841b2590 SB |
87 | )\r |
88 | {\r | |
1436aea4 MK |
89 | UINT8 *Input;\r |
90 | UINT8 *Output;\r | |
91 | const UINT8 *NextIn;\r | |
92 | UINT8 *NextOut;\r | |
93 | size_t TotalOut;\r | |
94 | size_t AvailableIn;\r | |
95 | size_t AvailableOut;\r | |
96 | VOID *Temp;\r | |
97 | BrotliDecoderResult Result;\r | |
98 | BrotliDecoderState *BroState;\r | |
99 | \r | |
100 | TotalOut = 0;\r | |
841b2590 | 101 | AvailableOut = FILE_BUFFER_SIZE;\r |
1436aea4 MK |
102 | Result = BROTLI_DECODER_RESULT_ERROR;\r |
103 | BroState = BrotliDecoderCreateInstance (BrAlloc, BrFree, BuffInfo);\r | |
104 | Temp = Destination;\r | |
841b2590 SB |
105 | \r |
106 | if (BroState == NULL) {\r | |
107 | return EFI_INVALID_PARAMETER;\r | |
108 | }\r | |
1436aea4 MK |
109 | \r |
110 | Input = (UINT8 *)BrAlloc (BuffInfo, FILE_BUFFER_SIZE);\r | |
111 | Output = (UINT8 *)BrAlloc (BuffInfo, FILE_BUFFER_SIZE);\r | |
112 | if ((Input == NULL) || (Output == NULL)) {\r | |
113 | BrFree (BuffInfo, Input);\r | |
114 | BrFree (BuffInfo, Output);\r | |
115 | BrotliDecoderDestroyInstance (BroState);\r | |
841b2590 SB |
116 | return EFI_INVALID_PARAMETER;\r |
117 | }\r | |
1436aea4 | 118 | \r |
841b2590 | 119 | NextOut = Output;\r |
1436aea4 | 120 | Result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;\r |
841b2590 | 121 | while (1) {\r |
2730470f | 122 | if (Result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {\r |
841b2590 SB |
123 | if (SourceSize == 0) {\r |
124 | break;\r | |
125 | }\r | |
1436aea4 | 126 | \r |
841b2590 SB |
127 | if (SourceSize >= FILE_BUFFER_SIZE) {\r |
128 | AvailableIn = FILE_BUFFER_SIZE;\r | |
1436aea4 | 129 | } else {\r |
841b2590 SB |
130 | AvailableIn = SourceSize;\r |
131 | }\r | |
1436aea4 MK |
132 | \r |
133 | CopyMem (Input, Source, AvailableIn);\r | |
134 | Source = (VOID *)((UINT8 *)Source + AvailableIn);\r | |
841b2590 | 135 | SourceSize -= AvailableIn;\r |
1436aea4 | 136 | NextIn = Input;\r |
2730470f | 137 | } else if (Result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {\r |
1436aea4 | 138 | CopyMem (Temp, Output, FILE_BUFFER_SIZE);\r |
841b2590 | 139 | AvailableOut = FILE_BUFFER_SIZE;\r |
1436aea4 MK |
140 | Temp = (VOID *)((UINT8 *)Temp +FILE_BUFFER_SIZE);\r |
141 | NextOut = Output;\r | |
841b2590 SB |
142 | } else {\r |
143 | break; /* Error or success. */\r | |
144 | }\r | |
1436aea4 MK |
145 | \r |
146 | Result = BrotliDecoderDecompressStream (\r | |
147 | BroState,\r | |
148 | &AvailableIn,\r | |
149 | &NextIn,\r | |
150 | &AvailableOut,\r | |
151 | &NextOut,\r | |
152 | &TotalOut\r | |
153 | );\r | |
841b2590 | 154 | }\r |
1436aea4 | 155 | \r |
841b2590 | 156 | if (NextOut != Output) {\r |
1436aea4 | 157 | CopyMem (Temp, Output, (size_t)(NextOut - Output));\r |
841b2590 SB |
158 | }\r |
159 | \r | |
160 | DestSize = TotalOut;\r | |
161 | \r | |
1436aea4 MK |
162 | BrFree (BuffInfo, Input);\r |
163 | BrFree (BuffInfo, Output);\r | |
164 | BrotliDecoderDestroyInstance (BroState);\r | |
2730470f | 165 | return (Result == BROTLI_DECODER_RESULT_SUCCESS) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;\r |
841b2590 SB |
166 | }\r |
167 | \r | |
168 | /**\r | |
169 | Get the size of the uncompressed buffer by parsing EncodeData header.\r | |
170 | \r | |
171 | @param EncodedData Pointer to the compressed data.\r | |
172 | @param StartOffset Start offset of the compressed data.\r | |
173 | @param EndOffset End offset of the compressed data.\r | |
174 | \r | |
175 | @return The size of the uncompressed buffer.\r | |
176 | **/\r | |
177 | UINT64\r | |
1436aea4 MK |
178 | BrGetDecodedSizeOfBuf (\r |
179 | IN UINT8 *EncodedData,\r | |
180 | IN UINT8 StartOffset,\r | |
181 | IN UINT8 EndOffset\r | |
841b2590 SB |
182 | )\r |
183 | {\r | |
1436aea4 MK |
184 | UINT64 DecodedSize;\r |
185 | INTN Index;\r | |
841b2590 SB |
186 | \r |
187 | /* Parse header */\r | |
188 | DecodedSize = 0;\r | |
1436aea4 MK |
189 | for (Index = EndOffset - 1; Index >= StartOffset; Index--) {\r |
190 | DecodedSize = LShiftU64 (DecodedSize, 8) + EncodedData[Index];\r | |
191 | }\r | |
841b2590 SB |
192 | \r |
193 | return DecodedSize;\r | |
194 | }\r | |
195 | \r | |
196 | /**\r | |
197 | Given a Brotli compressed source buffer, this function retrieves the size of\r | |
198 | the uncompressed buffer and the size of the scratch buffer required\r | |
199 | to decompress the compressed source buffer.\r | |
200 | \r | |
201 | Retrieves the size of the uncompressed buffer and the temporary scratch buffer\r | |
202 | required to decompress the buffer specified by Source and SourceSize.\r | |
203 | The size of the uncompressed buffer is returned in DestinationSize,\r | |
204 | the size of the scratch buffer is returned in ScratchSize, and EFI_SUCCESS is returned.\r | |
205 | This function does not have scratch buffer available to perform a thorough\r | |
206 | checking of the validity of the source data. It just retrieves the "Original Size"\r | |
207 | field from the BROTLI_SCRATCH_MAX beginning bytes of the source data and output it as DestinationSize.\r | |
208 | And ScratchSize is specific to the decompression implementation.\r | |
209 | \r | |
210 | If SourceSize is less than BROTLI_SCRATCH_MAX, then ASSERT().\r | |
211 | \r | |
212 | @param Source The source buffer containing the compressed data.\r | |
213 | @param SourceSize The size, in bytes, of the source buffer.\r | |
214 | @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r | |
215 | that will be generated when the compressed buffer specified\r | |
216 | by Source and SourceSize is decompressed.\r | |
217 | @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r | |
218 | is required to decompress the compressed buffer specified\r | |
219 | by Source and SourceSize.\r | |
220 | \r | |
221 | @retval EFI_SUCCESS The size of the uncompressed data was returned\r | |
222 | in DestinationSize and the size of the scratch\r | |
223 | buffer was returned in ScratchSize.\r | |
224 | **/\r | |
225 | EFI_STATUS\r | |
226 | EFIAPI\r | |
227 | BrotliUefiDecompressGetInfo (\r | |
1436aea4 MK |
228 | IN CONST VOID *Source,\r |
229 | IN UINT32 SourceSize,\r | |
230 | OUT UINT32 *DestinationSize,\r | |
231 | OUT UINT32 *ScratchSize\r | |
841b2590 SB |
232 | )\r |
233 | {\r | |
234 | UINT64 GetSize;\r | |
235 | UINT8 MaxOffset;\r | |
236 | \r | |
1436aea4 | 237 | ASSERT (SourceSize >= BROTLI_SCRATCH_MAX);\r |
841b2590 | 238 | \r |
1436aea4 MK |
239 | MaxOffset = BROTLI_DECODE_MAX;\r |
240 | GetSize = BrGetDecodedSizeOfBuf ((UINT8 *)Source, MaxOffset - BROTLI_INFO_SIZE, MaxOffset);\r | |
841b2590 | 241 | *DestinationSize = (UINT32)GetSize;\r |
1436aea4 MK |
242 | MaxOffset = BROTLI_SCRATCH_MAX;\r |
243 | GetSize = BrGetDecodedSizeOfBuf ((UINT8 *)Source, MaxOffset - BROTLI_INFO_SIZE, MaxOffset);\r | |
244 | *ScratchSize = (UINT32)GetSize;\r | |
841b2590 SB |
245 | return EFI_SUCCESS;\r |
246 | }\r | |
247 | \r | |
248 | /**\r | |
249 | Decompresses a Brotli compressed source buffer.\r | |
250 | \r | |
251 | Extracts decompressed data to its original form.\r | |
252 | If the compressed source data specified by Source is successfully decompressed\r | |
253 | into Destination, then RETURN_SUCCESS is returned. If the compressed source data\r | |
254 | specified by Source is not in a valid compressed data format,\r | |
255 | then RETURN_INVALID_PARAMETER is returned.\r | |
256 | \r | |
257 | @param Source The source buffer containing the compressed data.\r | |
258 | @param SourceSize The size of source buffer.\r | |
259 | @param Destination The destination buffer to store the decompressed data\r | |
260 | @param Scratch A temporary scratch buffer that is used to perform the decompression.\r | |
261 | This is an optional parameter that may be NULL if the\r | |
262 | required scratch buffer size is 0.\r | |
263 | \r | |
264 | @retval EFI_SUCCESS Decompression completed successfully, and\r | |
265 | the uncompressed buffer is returned in Destination.\r | |
266 | @retval EFI_INVALID_PARAMETER\r | |
267 | The source buffer specified by Source is corrupted\r | |
268 | (not in a valid compressed format).\r | |
269 | **/\r | |
270 | EFI_STATUS\r | |
271 | EFIAPI\r | |
272 | BrotliUefiDecompress (\r | |
1436aea4 MK |
273 | IN CONST VOID *Source,\r |
274 | IN UINTN SourceSize,\r | |
275 | IN OUT VOID *Destination,\r | |
276 | IN OUT VOID *Scratch\r | |
841b2590 SB |
277 | )\r |
278 | {\r | |
1436aea4 MK |
279 | UINTN DestSize = 0;\r |
280 | EFI_STATUS Status;\r | |
281 | BROTLI_BUFF BroBuff;\r | |
282 | UINT64 GetSize;\r | |
283 | UINT8 MaxOffset;\r | |
841b2590 SB |
284 | \r |
285 | MaxOffset = BROTLI_SCRATCH_MAX;\r | |
1436aea4 | 286 | GetSize = BrGetDecodedSizeOfBuf ((UINT8 *)Source, MaxOffset - BROTLI_INFO_SIZE, MaxOffset);\r |
841b2590 SB |
287 | \r |
288 | BroBuff.Buff = Scratch;\r | |
289 | BroBuff.BuffSize = (UINTN)GetSize;\r | |
290 | \r | |
1436aea4 MK |
291 | Status = BrotliDecompress (\r |
292 | (VOID *)((UINT8 *)Source + BROTLI_SCRATCH_MAX),\r | |
293 | SourceSize - BROTLI_SCRATCH_MAX,\r | |
294 | Destination,\r | |
295 | DestSize,\r | |
296 | (VOID *)(&BroBuff)\r | |
297 | );\r | |
841b2590 SB |
298 | \r |
299 | return Status;\r | |
300 | }\r |