]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c
5c89d9870f0a8bd3a429207aa6bab883c20a191a
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / LzmaCustomDecompressLib / LzmaDecompress.c
1 /** @file
2 LZMA Decompress interfaces
3
4 Copyright (c) 2009, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "LzmaDecompressLibInternal.h"
16 #include "Sdk/C/Types.h"
17 #include "Sdk/C/7zVersion.h"
18 #include "Sdk/C/LzmaDec.h"
19
20 #define SCRATCH_BUFFER_REQUEST_SIZE SIZE_64KB
21
22 typedef struct
23 {
24 ISzAlloc Functions;
25 VOID *Buffer;
26 UINTN BufferSize;
27 } ISzAllocWithData;
28
29 /**
30 Allocation routine used by LZMA decompression.
31
32 @param P Pointer to the ISzAlloc instance
33 @param Size The size in bytes to be allocated
34
35 @return The allocated pointer address, or NULL on failure
36 **/
37 VOID *
38 SzAlloc (
39 VOID *P,
40 size_t Size
41 )
42 {
43 VOID *Addr;
44 ISzAllocWithData *Private = (ISzAllocWithData*) P;
45
46 if (Private->BufferSize >= Size) {
47 Addr = Private->Buffer;
48 Private->Buffer = (VOID*) ((UINT8*)Addr + Size);
49 Private->BufferSize -= Size;
50 return Addr;
51 } else {
52 ASSERT (FALSE);
53 return NULL;
54 }
55 }
56
57 /**
58 Free routine used by LZMA decompression.
59
60 @param P Pointer to the ISzAlloc instance
61 @param Address The address to be freed
62 **/
63 VOID
64 SzFree (
65 VOID *P,
66 VOID *Address
67 )
68 {
69 //
70 // We use the 'scratch buffer' for allocations, so there is no free
71 // operation required. The scratch buffer will be freed by the caller
72 // of the decompression code.
73 //
74 }
75
76 #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
77
78 /**
79 Get the size of the uncompressed buffer by parsing EncodeData header.
80
81 @param EncodedData Pointer to the compressed data.
82
83 @return The size of the uncompressed buffer.
84 **/
85 UINT64
86 GetDecodedSizeOfBuf(
87 UINT8 *EncodedData
88 )
89 {
90 UINT64 DecodedSize;
91 INTN Index;
92
93 /* Parse header */
94 DecodedSize = 0;
95 for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--)
96 DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index];
97
98 return DecodedSize;
99 }
100
101 //
102 // LZMA functions and data as defined in local LzmaDecompressLibInternal.h
103 //
104
105 /**
106 Given a Lzma compressed source buffer, this function retrieves the size of
107 the uncompressed buffer and the size of the scratch buffer required
108 to decompress the compressed source buffer.
109
110 Retrieves the size of the uncompressed buffer and the temporary scratch buffer
111 required to decompress the buffer specified by Source and SourceSize.
112 The size of the uncompressed buffer is returned in DestinationSize,
113 the size of the scratch buffer is returned in ScratchSize, and RETURN_SUCCESS is returned.
114 This function does not have scratch buffer available to perform a thorough
115 checking of the validity of the source data. It just retrieves the "Original Size"
116 field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize.
117 And ScratchSize is specific to the decompression implementation.
118
119 If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT().
120
121 @param Source The source buffer containing the compressed data.
122 @param SourceSize The size, in bytes, of the source buffer.
123 @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer
124 that will be generated when the compressed buffer specified
125 by Source and SourceSize is decompressed.
126 @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that
127 is required to decompress the compressed buffer specified
128 by Source and SourceSize.
129
130 @retval RETURN_SUCCESS The size of the uncompressed data was returned
131 in DestinationSize and the size of the scratch
132 buffer was returned in ScratchSize.
133
134 **/
135 RETURN_STATUS
136 EFIAPI
137 LzmaUefiDecompressGetInfo (
138 IN CONST VOID *Source,
139 IN UINT32 SourceSize,
140 OUT UINT32 *DestinationSize,
141 OUT UINT32 *ScratchSize
142 )
143 {
144 UInt64 DecodedSize;
145
146 ASSERT(SourceSize >= LZMA_HEADER_SIZE);
147
148 DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
149
150 *DestinationSize = (UINT32)DecodedSize;
151 *ScratchSize = SCRATCH_BUFFER_REQUEST_SIZE;
152 return RETURN_SUCCESS;
153 }
154
155 /**
156 Decompresses a Lzma compressed source buffer.
157
158 Extracts decompressed data to its original form.
159 If the compressed source data specified by Source is successfully decompressed
160 into Destination, then RETURN_SUCCESS is returned. If the compressed source data
161 specified by Source is not in a valid compressed data format,
162 then RETURN_INVALID_PARAMETER is returned.
163
164 @param Source The source buffer containing the compressed data.
165 @param Destination The destination buffer to store the decompressed data
166 @param Scratch A temporary scratch buffer that is used to perform the decompression.
167 This is an optional parameter that may be NULL if the
168 required scratch buffer size is 0.
169
170 @retval RETURN_SUCCESS Decompression completed successfully, and
171 the uncompressed buffer is returned in Destination.
172 @retval RETURN_INVALID_PARAMETER
173 The source buffer specified by Source is corrupted
174 (not in a valid compressed format).
175 **/
176 RETURN_STATUS
177 EFIAPI
178 LzmaUefiDecompress (
179 IN CONST VOID *Source,
180 IN UINTN SourceSize,
181 IN OUT VOID *Destination,
182 IN OUT VOID *Scratch
183 )
184 {
185 SRes LzmaResult;
186 ELzmaStatus Status;
187 SizeT DecodedBufSize;
188 SizeT EncodedDataSize;
189 ISzAllocWithData AllocFuncs;
190
191 AllocFuncs.Functions.Alloc = SzAlloc;
192 AllocFuncs.Functions.Free = SzFree;
193 AllocFuncs.Buffer = Scratch;
194 AllocFuncs.BufferSize = SCRATCH_BUFFER_REQUEST_SIZE;
195
196 DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source);
197 EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE);
198
199 LzmaResult = LzmaDecode(
200 Destination,
201 &DecodedBufSize,
202 (Byte*)((UINT8*)Source + LZMA_HEADER_SIZE),
203 &EncodedDataSize,
204 Source,
205 LZMA_PROPS_SIZE,
206 LZMA_FINISH_END,
207 &Status,
208 &(AllocFuncs.Functions)
209 );
210
211 if (LzmaResult == SZ_OK) {
212 return RETURN_SUCCESS;
213 } else {
214 return RETURN_INVALID_PARAMETER;
215 }
216 }
217