diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
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.c | 293 |
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; +} |