summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c
new file mode 100644
index 00000000..9908a1bb
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c
@@ -0,0 +1,293 @@
+/** @file
+ Brotli Decompress interfaces
+
+ Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <BrotliDecompressLibInternal.h>
+
+/**
+ Allocation routine used by BROTLI decompression.
+
+ @param Ptr Pointer to the BROTLI_BUFF instance.
+ @param Size The size in bytes to be allocated.
+
+ @return The allocated pointer address, or NULL on failure
+**/
+VOID *
+BrAlloc (
+ IN VOID * Ptr,
+ IN size_t Size
+ )
+{
+ VOID *Addr;
+ BROTLI_BUFF *Private;
+
+ Private = (BROTLI_BUFF *)Ptr;
+
+ if (Private->BuffSize >= Size) {
+ Addr = Private->Buff;
+ Private->Buff = (VOID *) ((UINT8 *)Addr + Size);
+ Private->BuffSize -= Size;
+ return Addr;
+ } else {
+ ASSERT (FALSE);
+ return NULL;
+ }
+}
+
+/**
+ Free routine used by BROTLI decompression.
+
+ @param Ptr Pointer to the BROTLI_BUFF instance
+ @param Address The address to be freed
+**/
+VOID
+BrFree (
+ IN VOID * Ptr,
+ IN 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.
+ //
+}
+
+/**
+ Decompresses a Brotli compressed source buffer.
+
+ Extracts decompressed data to its original form.
+ If the compressed source data specified by Source is successfully decompressed
+ into Destination, then EFI_SUCCESS is returned. If the compressed source data
+ specified by Source is not in a valid compressed data format,
+ then EFI_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 DestSize The destination buffer size.
+ @param BuffInfo The pointer to the BROTLI_BUFF instance.
+
+ @retval EFI_SUCCESS Decompression completed successfully, and
+ the uncompressed buffer is returned in Destination.
+ @retval EFI_INVALID_PARAMETER
+ The source buffer specified by Source is corrupted
+ (not in a valid compressed format).
+**/
+EFI_STATUS
+BrotliDecompress (
+ IN CONST VOID* Source,
+ IN UINTN SourceSize,
+ IN OUT VOID* Destination,
+ IN OUT UINTN DestSize,
+ IN VOID * BuffInfo
+ )
+{
+ UINT8 * Input;
+ UINT8 * Output;
+ const UINT8 * NextIn;
+ UINT8 * NextOut;
+ size_t TotalOut;
+ size_t AvailableIn;
+ size_t AvailableOut;
+ VOID * Temp;
+ BrotliDecoderResult Result;
+ BrotliDecoderState * BroState;
+
+ TotalOut = 0;
+ AvailableOut = FILE_BUFFER_SIZE;
+ Result = BROTLI_DECODER_RESULT_ERROR;
+ BroState = BrotliDecoderCreateInstance(BrAlloc, BrFree, BuffInfo);
+ Temp = Destination;
+
+ if (BroState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Input = (UINT8 *)BrAlloc(BuffInfo, FILE_BUFFER_SIZE);
+ Output = (UINT8 *)BrAlloc(BuffInfo, FILE_BUFFER_SIZE);
+ if ((Input==NULL) || (Output==NULL)) {
+ BrFree(BuffInfo, Input);
+ BrFree(BuffInfo, Output);
+ BrotliDecoderDestroyInstance(BroState);
+ return EFI_INVALID_PARAMETER;
+ }
+ NextOut = Output;
+ Result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
+ while (1) {
+ if (Result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
+ if (SourceSize == 0) {
+ break;
+ }
+ if (SourceSize >= FILE_BUFFER_SIZE) {
+ AvailableIn = FILE_BUFFER_SIZE;
+ }else{
+ AvailableIn = SourceSize;
+ }
+ CopyMem(Input, Source, AvailableIn);
+ Source = (VOID *)((UINT8 *)Source + AvailableIn);
+ SourceSize -= AvailableIn;
+ NextIn = Input;
+ } else if (Result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
+ CopyMem(Temp, Output, FILE_BUFFER_SIZE);
+ AvailableOut = FILE_BUFFER_SIZE;
+ Temp = (VOID *)((UINT8 *)Temp +FILE_BUFFER_SIZE);
+ NextOut = Output;
+ } else {
+ break; /* Error or success. */
+ }
+ Result = BrotliDecoderDecompressStream(
+ BroState,
+ &AvailableIn,
+ &NextIn,
+ &AvailableOut,
+ &NextOut,
+ &TotalOut
+ );
+ }
+ if (NextOut != Output) {
+ CopyMem(Temp, Output, (size_t)(NextOut - Output));
+ }
+
+ DestSize = TotalOut;
+
+ BrFree(BuffInfo, Input);
+ BrFree(BuffInfo, Output);
+ BrotliDecoderDestroyInstance(BroState);
+ return (Result == BROTLI_DECODER_RESULT_SUCCESS) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+}
+
+/**
+ Get the size of the uncompressed buffer by parsing EncodeData header.
+
+ @param EncodedData Pointer to the compressed data.
+ @param StartOffset Start offset of the compressed data.
+ @param EndOffset End offset of the compressed data.
+
+ @return The size of the uncompressed buffer.
+**/
+UINT64
+BrGetDecodedSizeOfBuf(
+ IN UINT8 * EncodedData,
+ IN UINT8 StartOffset,
+ IN UINT8 EndOffset
+ )
+{
+ UINT64 DecodedSize;
+ INTN Index;
+
+ /* Parse header */
+ DecodedSize = 0;
+ for (Index = EndOffset - 1; Index >= StartOffset; Index--)
+ DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index];
+
+ return DecodedSize;
+}
+
+/**
+ Given a Brotli 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 EFI_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 BROTLI_SCRATCH_MAX beginning bytes of the source data and output it as DestinationSize.
+ And ScratchSize is specific to the decompression implementation.
+
+ If SourceSize is less than BROTLI_SCRATCH_MAX, 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 EFI_SUCCESS The size of the uncompressed data was returned
+ in DestinationSize and the size of the scratch
+ buffer was returned in ScratchSize.
+**/
+EFI_STATUS
+EFIAPI
+BrotliUefiDecompressGetInfo (
+ IN CONST VOID * Source,
+ IN UINT32 SourceSize,
+ OUT UINT32 * DestinationSize,
+ OUT UINT32 * ScratchSize
+ )
+{
+ UINT64 GetSize;
+ UINT8 MaxOffset;
+
+ ASSERT(SourceSize >= BROTLI_SCRATCH_MAX);
+
+ MaxOffset = BROTLI_DECODE_MAX;
+ GetSize = BrGetDecodedSizeOfBuf((UINT8 *)Source, MaxOffset - BROTLI_INFO_SIZE, MaxOffset);
+ *DestinationSize = (UINT32)GetSize;
+ MaxOffset = BROTLI_SCRATCH_MAX;
+ GetSize = BrGetDecodedSizeOfBuf((UINT8 *)Source, MaxOffset - BROTLI_INFO_SIZE, MaxOffset);
+ *ScratchSize = (UINT32)GetSize;
+ return EFI_SUCCESS;
+}
+
+/**
+ Decompresses a Brotli 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 EFI_SUCCESS Decompression completed successfully, and
+ the uncompressed buffer is returned in Destination.
+ @retval EFI_INVALID_PARAMETER
+ The source buffer specified by Source is corrupted
+ (not in a valid compressed format).
+**/
+EFI_STATUS
+EFIAPI
+BrotliUefiDecompress (
+ IN CONST VOID * Source,
+ IN UINTN SourceSize,
+ IN OUT VOID * Destination,
+ IN OUT VOID * Scratch
+ )
+{
+ UINTN DestSize = 0;
+ EFI_STATUS Status;
+ BROTLI_BUFF BroBuff;
+ UINT64 GetSize;
+ UINT8 MaxOffset;
+
+ MaxOffset = BROTLI_SCRATCH_MAX;
+ GetSize = BrGetDecodedSizeOfBuf((UINT8 *)Source, MaxOffset - BROTLI_INFO_SIZE, MaxOffset);
+
+ BroBuff.Buff = Scratch;
+ BroBuff.BuffSize = (UINTN)GetSize;
+
+ Status = BrotliDecompress(
+ (VOID *)((UINT8 *)Source + BROTLI_SCRATCH_MAX),
+ SourceSize - BROTLI_SCRATCH_MAX,
+ Destination,
+ DestSize,
+ (VOID *)(&BroBuff)
+ );
+
+ return Status;
+}