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