| /** @file | |
| LZMA Decompress interfaces | |
| Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "LzmaDecompressLibInternal.h" | |
| #include "Sdk/C/Types.h" | |
| #include "Sdk/C/7zVersion.h" | |
| #include "Sdk/C/LzmaDec.h" | |
| #define SCRATCH_BUFFER_REQUEST_SIZE SIZE_64KB | |
| typedef struct | |
| { | |
| ISzAlloc Functions; | |
| VOID *Buffer; | |
| UINTN BufferSize; | |
| } ISzAllocWithData; | |
| /** | |
| Allocation routine used by LZMA decompression. | |
| @param P Pointer to the ISzAlloc instance | |
| @param Size The size in bytes to be allocated | |
| @return The allocated pointer address, or NULL on failure | |
| **/ | |
| VOID * | |
| SzAlloc ( | |
| VOID *P, | |
| size_t Size | |
| ) | |
| { | |
| VOID *Addr; | |
| ISzAllocWithData *Private; | |
| Private = (ISzAllocWithData*) P; | |
| if (Private->BufferSize >= Size) { | |
| Addr = Private->Buffer; | |
| Private->Buffer = (VOID*) ((UINT8*)Addr + Size); | |
| Private->BufferSize -= Size; | |
| return Addr; | |
| } else { | |
| ASSERT (FALSE); | |
| return NULL; | |
| } | |
| } | |
| /** | |
| Free routine used by LZMA decompression. | |
| @param P Pointer to the ISzAlloc instance | |
| @param Address The address to be freed | |
| **/ | |
| VOID | |
| SzFree ( | |
| VOID *P, | |
| VOID *Address | |
| ) | |
| { | |
| // | |
| // We use the 'scratch buffer' for allocations, so there is no free | |
| // operation required. The scratch buffer will be freed by the caller | |
| // of the decompression code. | |
| // | |
| } | |
| #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) | |
| /** | |
| Get the size of the uncompressed buffer by parsing EncodeData header. | |
| @param EncodedData Pointer to the compressed data. | |
| @return The size of the uncompressed buffer. | |
| **/ | |
| UINT64 | |
| GetDecodedSizeOfBuf( | |
| UINT8 *EncodedData | |
| ) | |
| { | |
| UINT64 DecodedSize; | |
| INTN Index; | |
| /* Parse header */ | |
| DecodedSize = 0; | |
| for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--) | |
| DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index]; | |
| return DecodedSize; | |
| } | |
| // | |
| // LZMA functions and data as defined in local LzmaDecompressLibInternal.h | |
| // | |
| /** | |
| Given a Lzma compressed source buffer, this function retrieves the size of | |
| the uncompressed buffer and the size of the scratch buffer required | |
| to decompress the compressed source buffer. | |
| Retrieves the size of the uncompressed buffer and the temporary scratch buffer | |
| required to decompress the buffer specified by Source and SourceSize. | |
| The size of the uncompressed buffer is returned in DestinationSize, | |
| the size of the scratch buffer is returned in ScratchSize, and RETURN_SUCCESS is returned. | |
| This function does not have scratch buffer available to perform a thorough | |
| checking of the validity of the source data. It just retrieves the "Original Size" | |
| field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize. | |
| And ScratchSize is specific to the decompression implementation. | |
| If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT(). | |
| @param Source The source buffer containing the compressed data. | |
| @param SourceSize The size, in bytes, of the source buffer. | |
| @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer | |
| that will be generated when the compressed buffer specified | |
| by Source and SourceSize is decompressed. | |
| @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that | |
| is required to decompress the compressed buffer specified | |
| by Source and SourceSize. | |
| @retval RETURN_SUCCESS The size of the uncompressed data was returned | |
| in DestinationSize and the size of the scratch | |
| buffer was returned in ScratchSize. | |
| **/ | |
| RETURN_STATUS | |
| EFIAPI | |
| LzmaUefiDecompressGetInfo ( | |
| IN CONST VOID *Source, | |
| IN UINT32 SourceSize, | |
| OUT UINT32 *DestinationSize, | |
| OUT UINT32 *ScratchSize | |
| ) | |
| { | |
| UInt64 DecodedSize; | |
| ASSERT(SourceSize >= LZMA_HEADER_SIZE); | |
| DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); | |
| *DestinationSize = (UINT32)DecodedSize; | |
| *ScratchSize = SCRATCH_BUFFER_REQUEST_SIZE; | |
| return RETURN_SUCCESS; | |
| } | |
| /** | |
| Decompresses a Lzma compressed source buffer. | |
| Extracts decompressed data to its original form. | |
| If the compressed source data specified by Source is successfully decompressed | |
| into Destination, then RETURN_SUCCESS is returned. If the compressed source data | |
| specified by Source is not in a valid compressed data format, | |
| then RETURN_INVALID_PARAMETER is returned. | |
| @param Source The source buffer containing the compressed data. | |
| @param SourceSize The size of source buffer. | |
| @param Destination The destination buffer to store the decompressed data | |
| @param Scratch A temporary scratch buffer that is used to perform the decompression. | |
| This is an optional parameter that may be NULL if the | |
| required scratch buffer size is 0. | |
| @retval RETURN_SUCCESS Decompression completed successfully, and | |
| the uncompressed buffer is returned in Destination. | |
| @retval RETURN_INVALID_PARAMETER | |
| The source buffer specified by Source is corrupted | |
| (not in a valid compressed format). | |
| **/ | |
| RETURN_STATUS | |
| EFIAPI | |
| LzmaUefiDecompress ( | |
| IN CONST VOID *Source, | |
| IN UINTN SourceSize, | |
| IN OUT VOID *Destination, | |
| IN OUT VOID *Scratch | |
| ) | |
| { | |
| SRes LzmaResult; | |
| ELzmaStatus Status; | |
| SizeT DecodedBufSize; | |
| SizeT EncodedDataSize; | |
| ISzAllocWithData AllocFuncs; | |
| AllocFuncs.Functions.Alloc = SzAlloc; | |
| AllocFuncs.Functions.Free = SzFree; | |
| AllocFuncs.Buffer = Scratch; | |
| AllocFuncs.BufferSize = SCRATCH_BUFFER_REQUEST_SIZE; | |
| DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source); | |
| EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE); | |
| LzmaResult = LzmaDecode( | |
| Destination, | |
| &DecodedBufSize, | |
| (Byte*)((UINT8*)Source + LZMA_HEADER_SIZE), | |
| &EncodedDataSize, | |
| Source, | |
| LZMA_PROPS_SIZE, | |
| LZMA_FINISH_END, | |
| &Status, | |
| &(AllocFuncs.Functions) | |
| ); | |
| if (LzmaResult == SZ_OK) { | |
| return RETURN_SUCCESS; | |
| } else { | |
| return RETURN_INVALID_PARAMETER; | |
| } | |
| } | |