The same functions have been defined in BrotliDecUefiSupport.c. Signed-off-by: Liming Gao <gaoliming@byosoft.com.cn> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
		
			
				
	
	
		
			294 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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;
 | |
| }
 |