--- /dev/null
+/** @file\r
+ LZMA Decompress GUIDed Section Extraction Library, which produces LZMA custom \r
+ decompression algorithm with the converter for the different arch code.\r
+ It wraps Lzma decompress interfaces to GUIDed Section Extraction interfaces\r
+ and registers them into GUIDed handler table.\r
+\r
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "LzmaDecompressLibInternal.h"\r
+#include "Sdk/C/Bra.h"\r
+\r
+/**\r
+ Examines a GUIDed section and returns the size of the decoded buffer and the\r
+ size of an scratch buffer required to actually decode the data in a GUIDed section.\r
+\r
+ Examines a GUIDed section specified by InputSection. \r
+ If GUID for InputSection does not match the GUID that this handler supports,\r
+ then RETURN_UNSUPPORTED is returned. \r
+ If the required information can not be retrieved from InputSection,\r
+ then RETURN_INVALID_PARAMETER is returned.\r
+ If the GUID of InputSection does match the GUID that this handler supports,\r
+ then the size required to hold the decoded buffer is returned in OututBufferSize,\r
+ the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field\r
+ from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.\r
+ \r
+ If InputSection is NULL, then ASSERT().\r
+ If OutputBufferSize is NULL, then ASSERT().\r
+ If ScratchBufferSize is NULL, then ASSERT().\r
+ If SectionAttribute is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.\r
+ @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required\r
+ if the buffer specified by InputSection were decoded.\r
+ @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space\r
+ if the buffer specified by InputSection were decoded.\r
+ @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes\r
+ field of EFI_GUID_DEFINED_SECTION in the PI Specification.\r
+\r
+ @retval RETURN_SUCCESS The information about InputSection was returned.\r
+ @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.\r
+ @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaArchGuidedSectionGetInfo (\r
+ IN CONST VOID *InputSection,\r
+ OUT UINT32 *OutputBufferSize,\r
+ OUT UINT32 *ScratchBufferSize,\r
+ OUT UINT16 *SectionAttribute\r
+ )\r
+{\r
+ ASSERT (InputSection != NULL);\r
+ ASSERT (OutputBufferSize != NULL);\r
+ ASSERT (ScratchBufferSize != NULL);\r
+ ASSERT (SectionAttribute != NULL);\r
+\r
+ if (IS_SECTION2 (InputSection)) {\r
+ if (!CompareGuid (\r
+ &gLzmaF86CustomDecompressGuid,\r
+ &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;\r
+\r
+ return LzmaUefiDecompressGetInfo (\r
+ (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r
+ SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r
+ OutputBufferSize,\r
+ ScratchBufferSize\r
+ );\r
+ } else {\r
+ if (!CompareGuid (\r
+ &gLzmaF86CustomDecompressGuid,\r
+ &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;\r
+\r
+ return LzmaUefiDecompressGetInfo (\r
+ (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
+ SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
+ OutputBufferSize,\r
+ ScratchBufferSize\r
+ );\r
+ }\r
+}\r
+\r
+/**\r
+ Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.\r
+ \r
+ Decodes the GUIDed section specified by InputSection. \r
+ If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned. \r
+ If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.\r
+ If the GUID of InputSection does match the GUID that this handler supports, then InputSection\r
+ is decoded into the buffer specified by OutputBuffer and the authentication status of this\r
+ decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the\r
+ data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise,\r
+ the decoded data will be placed in caller allocated buffer specified by OutputBuffer.\r
+ \r
+ If InputSection is NULL, then ASSERT().\r
+ If OutputBuffer is NULL, then ASSERT().\r
+ If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().\r
+ If AuthenticationStatus is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.\r
+ @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation. \r
+ @param[out] ScratchBuffer A caller allocated buffer that may be required by this function\r
+ as a scratch buffer to perform the decode operation. \r
+ @param[out] AuthenticationStatus \r
+ A pointer to the authentication status of the decoded output buffer.\r
+ See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI\r
+ section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must\r
+ never be set by this handler.\r
+\r
+ @retval RETURN_SUCCESS The buffer specified by InputSection was decoded.\r
+ @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.\r
+ @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaArchGuidedSectionExtraction (\r
+ IN CONST VOID *InputSection,\r
+ OUT VOID **OutputBuffer,\r
+ OUT VOID *ScratchBuffer, OPTIONAL\r
+ OUT UINT32 *AuthenticationStatus\r
+ )\r
+{\r
+ EFI_GUID *InputGuid;\r
+ VOID *Source;\r
+ UINTN SourceSize;\r
+ EFI_STATUS Status;\r
+ UINT32 X86State;\r
+ UINT32 OutputBufferSize;\r
+ UINT32 ScratchBufferSize;\r
+ \r
+ ASSERT (OutputBuffer != NULL);\r
+ ASSERT (InputSection != NULL);\r
+\r
+ if (IS_SECTION2 (InputSection)) {\r
+ InputGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);\r
+ Source = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset;\r
+ SourceSize = SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset;\r
+ } else {\r
+ InputGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);\r
+ Source = (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset;\r
+ SourceSize = SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset;\r
+ }\r
+\r
+ if (!CompareGuid (&gLzmaF86CustomDecompressGuid, InputGuid)) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Authentication is set to Zero, which may be ignored.\r
+ //\r
+ *AuthenticationStatus = 0;\r
+\r
+ Status = LzmaUefiDecompress (\r
+ Source,\r
+ SourceSize,\r
+ *OutputBuffer,\r
+ ScratchBuffer\r
+ );\r
+\r
+ //\r
+ // After decompress, the data need to be converted to the raw data. \r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = LzmaUefiDecompressGetInfo (\r
+ Source,\r
+ (UINT32) SourceSize,\r
+ &OutputBufferSize,\r
+ &ScratchBufferSize\r
+ );\r
+ \r
+ if (!EFI_ERROR (Status)) {\r
+ x86_Convert_Init(X86State);\r
+ x86_Convert(*OutputBuffer, OutputBufferSize, 0, &X86State, 0);\r
+ }\r
+ }\r
+ \r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Register LzmaArchDecompress and LzmaArchDecompressGetInfo handlers with LzmaF86CustomDecompressGuid.\r
+\r
+ @retval RETURN_SUCCESS Register successfully.\r
+ @retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LzmaArchDecompressLibConstructor (\r
+ )\r
+{\r
+ return ExtractGuidedSectionRegisterHandlers (\r
+ &gLzmaF86CustomDecompressGuid,\r
+ LzmaArchGuidedSectionGetInfo,\r
+ LzmaArchGuidedSectionExtraction\r
+ );\r
+}\r
+\r
--- /dev/null
+/** @file\r
+ LZMA Decompress GUIDed Section Extraction Library.\r
+ It wraps Lzma decompress interfaces to GUIDed Section Extraction interfaces\r
+ and registers them into GUIDed handler table.\r
+\r
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "LzmaDecompressLibInternal.h"\r
+\r
+/**\r
+ Examines a GUIDed section and returns the size of the decoded buffer and the\r
+ size of an scratch buffer required to actually decode the data in a GUIDed section.\r
+\r
+ Examines a GUIDed section specified by InputSection. \r
+ If GUID for InputSection does not match the GUID that this handler supports,\r
+ then RETURN_UNSUPPORTED is returned. \r
+ If the required information can not be retrieved from InputSection,\r
+ then RETURN_INVALID_PARAMETER is returned.\r
+ If the GUID of InputSection does match the GUID that this handler supports,\r
+ then the size required to hold the decoded buffer is returned in OututBufferSize,\r
+ the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field\r
+ from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.\r
+ \r
+ If InputSection is NULL, then ASSERT().\r
+ If OutputBufferSize is NULL, then ASSERT().\r
+ If ScratchBufferSize is NULL, then ASSERT().\r
+ If SectionAttribute is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.\r
+ @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required\r
+ if the buffer specified by InputSection were decoded.\r
+ @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space\r
+ if the buffer specified by InputSection were decoded.\r
+ @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes\r
+ field of EFI_GUID_DEFINED_SECTION in the PI Specification.\r
+\r
+ @retval RETURN_SUCCESS The information about InputSection was returned.\r
+ @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.\r
+ @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaGuidedSectionGetInfo (\r
+ IN CONST VOID *InputSection,\r
+ OUT UINT32 *OutputBufferSize,\r
+ OUT UINT32 *ScratchBufferSize,\r
+ OUT UINT16 *SectionAttribute\r
+ )\r
+{\r
+ ASSERT (InputSection != NULL);\r
+ ASSERT (OutputBufferSize != NULL);\r
+ ASSERT (ScratchBufferSize != NULL);\r
+ ASSERT (SectionAttribute != NULL);\r
+\r
+ if (IS_SECTION2 (InputSection)) {\r
+ if (!CompareGuid (\r
+ &gLzmaCustomDecompressGuid,\r
+ &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;\r
+\r
+ return LzmaUefiDecompressGetInfo (\r
+ (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r
+ SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r
+ OutputBufferSize,\r
+ ScratchBufferSize\r
+ );\r
+ } else {\r
+ if (!CompareGuid (\r
+ &gLzmaCustomDecompressGuid,\r
+ &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;\r
+\r
+ return LzmaUefiDecompressGetInfo (\r
+ (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
+ SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
+ OutputBufferSize,\r
+ ScratchBufferSize\r
+ );\r
+ }\r
+}\r
+\r
+/**\r
+ Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.\r
+ \r
+ Decodes the GUIDed section specified by InputSection. \r
+ If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned. \r
+ If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.\r
+ If the GUID of InputSection does match the GUID that this handler supports, then InputSection\r
+ is decoded into the buffer specified by OutputBuffer and the authentication status of this\r
+ decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the\r
+ data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise,\r
+ the decoded data will be placed in caller allocated buffer specified by OutputBuffer.\r
+ \r
+ If InputSection is NULL, then ASSERT().\r
+ If OutputBuffer is NULL, then ASSERT().\r
+ If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().\r
+ If AuthenticationStatus is NULL, then ASSERT().\r
+\r
+\r
+ @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file.\r
+ @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation. \r
+ @param[out] ScratchBuffer A caller allocated buffer that may be required by this function\r
+ as a scratch buffer to perform the decode operation. \r
+ @param[out] AuthenticationStatus \r
+ A pointer to the authentication status of the decoded output buffer.\r
+ See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI\r
+ section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must\r
+ never be set by this handler.\r
+\r
+ @retval RETURN_SUCCESS The buffer specified by InputSection was decoded.\r
+ @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports.\r
+ @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaGuidedSectionExtraction (\r
+ IN CONST VOID *InputSection,\r
+ OUT VOID **OutputBuffer,\r
+ OUT VOID *ScratchBuffer, OPTIONAL\r
+ OUT UINT32 *AuthenticationStatus\r
+ )\r
+{\r
+ ASSERT (OutputBuffer != NULL);\r
+ ASSERT (InputSection != NULL);\r
+\r
+ if (IS_SECTION2 (InputSection)) {\r
+ if (!CompareGuid (\r
+ &gLzmaCustomDecompressGuid,\r
+ &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Authentication is set to Zero, which may be ignored.\r
+ //\r
+ *AuthenticationStatus = 0;\r
+\r
+ return LzmaUefiDecompress (\r
+ (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r
+ SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,\r
+ *OutputBuffer,\r
+ ScratchBuffer\r
+ );\r
+ } else {\r
+ if (!CompareGuid (\r
+ &gLzmaCustomDecompressGuid,\r
+ &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Authentication is set to Zero, which may be ignored.\r
+ //\r
+ *AuthenticationStatus = 0;\r
+\r
+ return LzmaUefiDecompress (\r
+ (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
+ SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,\r
+ *OutputBuffer,\r
+ ScratchBuffer\r
+ );\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Register LzmaDecompress and LzmaDecompressGetInfo handlers with LzmaCustomerDecompressGuid.\r
+\r
+ @retval RETURN_SUCCESS Register successfully.\r
+ @retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LzmaDecompressLibConstructor (\r
+ )\r
+{\r
+ return ExtractGuidedSectionRegisterHandlers (\r
+ &gLzmaCustomDecompressGuid,\r
+ LzmaGuidedSectionGetInfo,\r
+ LzmaGuidedSectionExtraction\r
+ ); \r
+}\r
+\r
--- /dev/null
+LzmaCustomDecompressLib is based on the LZMA SDK 4.65.\r
+LZMA SDK 4.65 was placed in the public domain on\r
+2009-02-03. It was released on the\r
+http://www.7-zip.org/sdk.html website.
\ No newline at end of file
--- /dev/null
+## @file\r
+# LzmaArchCustomDecompressLib produces LZMA custom decompression algorithm with the converter for the different arch code.\r
+#\r
+# It is based on the LZMA SDK 4.65.\r
+# LZMA SDK 4.65 was placed in the public domain on 2009-02-03.\r
+# It was released on the http://www.7-zip.org/sdk.html website.\r
+#\r
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = LzmaArchDecompressLib\r
+ MODULE_UNI_FILE = LzmaArchDecompressLib.uni\r
+ FILE_GUID = A853C1D2-E003-4cc4-9DD1-8824AD79FE48\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = NULL\r
+ CONSTRUCTOR = LzmaArchDecompressLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64\r
+#\r
+\r
+[Sources]\r
+ LzmaDecompress.c\r
+ Sdk/C/Bra.h\r
+ Sdk/C/LzFind.c\r
+ Sdk/C/LzmaDec.c\r
+ Sdk/C/7zVersion.h\r
+ Sdk/C/CpuArch.h\r
+ Sdk/C/LzFind.h\r
+ Sdk/C/LzHash.h\r
+ Sdk/C/LzmaDec.h\r
+ Sdk/C/Types.h \r
+ UefiLzma.h\r
+ LzmaDecompressLibInternal.h\r
+\r
+[Sources.Ia32, Sources.X64]\r
+ Sdk/C/Bra86.c\r
+ F86GuidedSectionExtraction.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+\r
+[Guids.Ia32, Guids.X64]\r
+ gLzmaF86CustomDecompressGuid ## PRODUCES ## GUID # specifies LZMA custom decompress algorithm with converter for x86 code.\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ DebugLib\r
+ BaseMemoryLib\r
+ ExtractGuidedSectionLib\r
+\r
--- /dev/null
+## @file\r
+# LzmaCustomDecompressLib produces LZMA custom decompression algorithm.\r
+#\r
+# It is based on the LZMA SDK 4.65.\r
+# LZMA SDK 4.65 was placed in the public domain on 2009-02-03.\r
+# It was released on the http://www.7-zip.org/sdk.html website.\r
+#\r
+# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = LzmaDecompressLib\r
+ MODULE_UNI_FILE = LzmaDecompressLib.uni\r
+ FILE_GUID = 35194660-7421-44ad-9636-e44885f092d1\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = NULL\r
+ CONSTRUCTOR = LzmaDecompressLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+ LzmaDecompress.c\r
+ Sdk/C/LzFind.c\r
+ Sdk/C/LzmaDec.c\r
+ Sdk/C/7zVersion.h\r
+ Sdk/C/CpuArch.h\r
+ Sdk/C/LzFind.h\r
+ Sdk/C/LzHash.h\r
+ Sdk/C/LzmaDec.h\r
+ Sdk/C/Types.h \r
+ GuidedSectionExtraction.c\r
+ UefiLzma.h\r
+ LzmaDecompressLibInternal.h\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+\r
+[Guids]\r
+ gLzmaCustomDecompressGuid ## PRODUCES ## UNDEFINED # specifies LZMA custom decompress algorithm.\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ DebugLib\r
+ BaseMemoryLib\r
+ ExtractGuidedSectionLib\r
+\r
--- /dev/null
+/** @file\r
+ LZMA Decompress interfaces\r
+\r
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "LzmaDecompressLibInternal.h"\r
+#include "Sdk/C/Types.h"\r
+#include "Sdk/C/7zVersion.h"\r
+#include "Sdk/C/LzmaDec.h"\r
+\r
+#define SCRATCH_BUFFER_REQUEST_SIZE SIZE_64KB\r
+\r
+typedef struct\r
+{\r
+ ISzAlloc Functions;\r
+ VOID *Buffer;\r
+ UINTN BufferSize;\r
+} ISzAllocWithData;\r
+\r
+/**\r
+ Allocation routine used by LZMA decompression.\r
+\r
+ @param P Pointer to the ISzAlloc instance\r
+ @param Size The size in bytes to be allocated\r
+\r
+ @return The allocated pointer address, or NULL on failure\r
+**/\r
+VOID *\r
+SzAlloc (\r
+ VOID *P,\r
+ size_t Size\r
+ )\r
+{\r
+ VOID *Addr;\r
+ ISzAllocWithData *Private;\r
+\r
+ Private = (ISzAllocWithData*) P;\r
+\r
+ if (Private->BufferSize >= Size) {\r
+ Addr = Private->Buffer;\r
+ Private->Buffer = (VOID*) ((UINT8*)Addr + Size);\r
+ Private->BufferSize -= Size;\r
+ return Addr;\r
+ } else {\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+ }\r
+}\r
+\r
+/**\r
+ Free routine used by LZMA decompression.\r
+\r
+ @param P Pointer to the ISzAlloc instance\r
+ @param Address The address to be freed\r
+**/\r
+VOID\r
+SzFree (\r
+ VOID *P,\r
+ VOID *Address\r
+ )\r
+{\r
+ //\r
+ // We use the 'scratch buffer' for allocations, so there is no free\r
+ // operation required. The scratch buffer will be freed by the caller\r
+ // of the decompression code.\r
+ //\r
+}\r
+\r
+#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)\r
+\r
+/**\r
+ Get the size of the uncompressed buffer by parsing EncodeData header.\r
+\r
+ @param EncodedData Pointer to the compressed data.\r
+\r
+ @return The size of the uncompressed buffer.\r
+**/\r
+UINT64\r
+GetDecodedSizeOfBuf(\r
+ UINT8 *EncodedData\r
+ )\r
+{\r
+ UINT64 DecodedSize;\r
+ INTN Index;\r
+\r
+ /* Parse header */\r
+ DecodedSize = 0;\r
+ for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--)\r
+ DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index];\r
+\r
+ return DecodedSize;\r
+}\r
+\r
+//\r
+// LZMA functions and data as defined in local LzmaDecompressLibInternal.h\r
+//\r
+\r
+/**\r
+ Given a Lzma compressed source buffer, this function retrieves the size of \r
+ the uncompressed buffer and the size of the scratch buffer required \r
+ to decompress the compressed source buffer.\r
+\r
+ Retrieves the size of the uncompressed buffer and the temporary scratch buffer \r
+ required to decompress the buffer specified by Source and SourceSize.\r
+ The size of the uncompressed buffer is returned in DestinationSize, \r
+ the size of the scratch buffer is returned in ScratchSize, and RETURN_SUCCESS is returned.\r
+ This function does not have scratch buffer available to perform a thorough \r
+ checking of the validity of the source data. It just retrieves the "Original Size"\r
+ field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize.\r
+ And ScratchSize is specific to the decompression implementation.\r
+\r
+ If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT().\r
+\r
+ @param Source The source buffer containing the compressed data.\r
+ @param SourceSize The size, in bytes, of the source buffer.\r
+ @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r
+ that will be generated when the compressed buffer specified\r
+ by Source and SourceSize is decompressed.\r
+ @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r
+ is required to decompress the compressed buffer specified \r
+ by Source and SourceSize.\r
+\r
+ @retval RETURN_SUCCESS The size of the uncompressed data was returned \r
+ in DestinationSize and the size of the scratch \r
+ buffer was returned in ScratchSize.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaUefiDecompressGetInfo (\r
+ IN CONST VOID *Source,\r
+ IN UINT32 SourceSize,\r
+ OUT UINT32 *DestinationSize,\r
+ OUT UINT32 *ScratchSize\r
+ )\r
+{\r
+ UInt64 DecodedSize;\r
+\r
+ ASSERT(SourceSize >= LZMA_HEADER_SIZE);\r
+\r
+ DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);\r
+\r
+ *DestinationSize = (UINT32)DecodedSize;\r
+ *ScratchSize = SCRATCH_BUFFER_REQUEST_SIZE;\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Decompresses a Lzma compressed source buffer.\r
+\r
+ Extracts decompressed data to its original form.\r
+ If the compressed source data specified by Source is successfully decompressed \r
+ into Destination, then RETURN_SUCCESS is returned. If the compressed source data \r
+ specified by Source is not in a valid compressed data format,\r
+ then RETURN_INVALID_PARAMETER is returned.\r
+\r
+ @param Source The source buffer containing the compressed data.\r
+ @param SourceSize The size of source buffer.\r
+ @param Destination The destination buffer to store the decompressed data\r
+ @param Scratch A temporary scratch buffer that is used to perform the decompression.\r
+ This is an optional parameter that may be NULL if the \r
+ required scratch buffer size is 0.\r
+ \r
+ @retval RETURN_SUCCESS Decompression completed successfully, and \r
+ the uncompressed buffer is returned in Destination.\r
+ @retval RETURN_INVALID_PARAMETER \r
+ The source buffer specified by Source is corrupted \r
+ (not in a valid compressed format).\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaUefiDecompress (\r
+ IN CONST VOID *Source,\r
+ IN UINTN SourceSize,\r
+ IN OUT VOID *Destination,\r
+ IN OUT VOID *Scratch\r
+ )\r
+{\r
+ SRes LzmaResult;\r
+ ELzmaStatus Status;\r
+ SizeT DecodedBufSize;\r
+ SizeT EncodedDataSize;\r
+ ISzAllocWithData AllocFuncs;\r
+\r
+ AllocFuncs.Functions.Alloc = SzAlloc;\r
+ AllocFuncs.Functions.Free = SzFree;\r
+ AllocFuncs.Buffer = Scratch;\r
+ AllocFuncs.BufferSize = SCRATCH_BUFFER_REQUEST_SIZE;\r
+ \r
+ DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source);\r
+ EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE);\r
+\r
+ LzmaResult = LzmaDecode(\r
+ Destination,\r
+ &DecodedBufSize,\r
+ (Byte*)((UINT8*)Source + LZMA_HEADER_SIZE),\r
+ &EncodedDataSize,\r
+ Source,\r
+ LZMA_PROPS_SIZE,\r
+ LZMA_FINISH_END,\r
+ &Status,\r
+ &(AllocFuncs.Functions)\r
+ );\r
+\r
+ if (LzmaResult == SZ_OK) {\r
+ return RETURN_SUCCESS;\r
+ } else {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+}\r
+\r
--- /dev/null
+/** @file\r
+ LZMA Decompress Library internal header file declares Lzma decompress interfaces.\r
+\r
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __LZMADECOMPRESSLIB_INTERNAL_H__\r
+#define __LZMADECOMPRESSLIB_INTERNAL_H__\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ExtractGuidedSectionLib.h>\r
+#include <Guid/LzmaDecompress.h>\r
+\r
+/**\r
+ Given a Lzma compressed source buffer, this function retrieves the size of \r
+ the uncompressed buffer and the size of the scratch buffer required \r
+ to decompress the compressed source buffer.\r
+\r
+ Retrieves the size of the uncompressed buffer and the temporary scratch buffer \r
+ required to decompress the buffer specified by Source and SourceSize.\r
+ The size of the uncompressed buffer is returned in DestinationSize, \r
+ the size of the scratch buffer is returned in ScratchSize, and RETURN_SUCCESS is returned.\r
+ This function does not have scratch buffer available to perform a thorough \r
+ checking of the validity of the source data. It just retrieves the "Original Size"\r
+ field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize.\r
+ And ScratchSize is specific to the decompression implementation.\r
+\r
+ If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT().\r
+\r
+ @param Source The source buffer containing the compressed data.\r
+ @param SourceSize The size, in bytes, of the source buffer.\r
+ @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer\r
+ that will be generated when the compressed buffer specified\r
+ by Source and SourceSize is decompressed.\r
+ @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that\r
+ is required to decompress the compressed buffer specified \r
+ by Source and SourceSize.\r
+\r
+ @retval RETURN_SUCCESS The size of the uncompressed data was returned \r
+ in DestinationSize and the size of the scratch \r
+ buffer was returned in ScratchSize.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaUefiDecompressGetInfo (\r
+ IN CONST VOID *Source,\r
+ IN UINT32 SourceSize,\r
+ OUT UINT32 *DestinationSize,\r
+ OUT UINT32 *ScratchSize\r
+ );\r
+\r
+/**\r
+ Decompresses a Lzma compressed source buffer.\r
+\r
+ Extracts decompressed data to its original form.\r
+ If the compressed source data specified by Source is successfully decompressed \r
+ into Destination, then RETURN_SUCCESS is returned. If the compressed source data \r
+ specified by Source is not in a valid compressed data format,\r
+ then RETURN_INVALID_PARAMETER is returned.\r
+\r
+ @param Source The source buffer containing the compressed data.\r
+ @param SourceSize The size of source buffer.\r
+ @param Destination The destination buffer to store the decompressed data\r
+ @param Scratch A temporary scratch buffer that is used to perform the decompression.\r
+ This is an optional parameter that may be NULL if the \r
+ required scratch buffer size is 0.\r
+ \r
+ @retval RETURN_SUCCESS Decompression completed successfully, and \r
+ the uncompressed buffer is returned in Destination.\r
+ @retval RETURN_INVALID_PARAMETER \r
+ The source buffer specified by Source is corrupted \r
+ (not in a valid compressed format).\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaUefiDecompress (\r
+ IN CONST VOID *Source,\r
+ IN UINTN SourceSize,\r
+ IN OUT VOID *Destination,\r
+ IN OUT VOID *Scratch\r
+ );\r
+\r
+#endif\r
+\r
--- /dev/null
+#define MY_VER_MAJOR 4\r
+#define MY_VER_MINOR 65\r
+#define MY_VER_BUILD 0\r
+#define MY_VERSION "4.65"\r
+#define MY_DATE "2009-02-03"\r
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain"\r
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE\r
--- /dev/null
+/* Bra.h -- Branch converters for executables\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __BRA_H\r
+#define __BRA_H\r
+\r
+#include "Types.h"\r
+\r
+/*\r
+These functions convert relative addresses to absolute addresses\r
+in CALL instructions to increase the compression ratio.\r
+ \r
+ In:\r
+ data - data buffer\r
+ size - size of data\r
+ ip - current virtual Instruction Pinter (IP) value\r
+ state - state variable for x86 converter\r
+ encoding - 0 (for decoding), 1 (for encoding)\r
+ \r
+ Out:\r
+ state - state variable for x86 converter\r
+\r
+ Returns:\r
+ The number of processed bytes. If you call these functions with multiple calls,\r
+ you must start next call with first byte after block of processed bytes.\r
+ \r
+ Type Endian Alignment LookAhead\r
+ \r
+ x86 little 1 4\r
+ ARMT little 2 2\r
+ ARM little 4 0\r
+ PPC big 4 0\r
+ SPARC big 4 0\r
+ IA64 little 16 0\r
+\r
+ size must be >= Alignment + LookAhead, if it's not last block.\r
+ If (size < Alignment + LookAhead), converter returns 0.\r
+\r
+ Example:\r
+\r
+ UInt32 ip = 0;\r
+ for ()\r
+ {\r
+ ; size must be >= Alignment + LookAhead, if it's not last block\r
+ SizeT processed = Convert(data, size, ip, 1);\r
+ data += processed;\r
+ size -= processed;\r
+ ip += processed;\r
+ }\r
+*/\r
+\r
+#define x86_Convert_Init(state) { state = 0; }\r
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);\r
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);\r
+\r
+#endif\r
--- /dev/null
+/* Bra86.c -- Converter for x86 code (BCJ)\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#include "Bra.h"\r
+\r
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)\r
+\r
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};\r
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};\r
+\r
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)\r
+{\r
+ SizeT bufferPos = 0, prevPosT;\r
+ UInt32 prevMask = *state & 0x7;\r
+ if (size < 5)\r
+ return 0;\r
+ ip += 5;\r
+ prevPosT = (SizeT)0 - 1;\r
+\r
+ for (;;)\r
+ {\r
+ Byte *p = data + bufferPos;\r
+ Byte *limit = data + size - 4;\r
+ for (; p < limit; p++)\r
+ if ((*p & 0xFE) == 0xE8)\r
+ break;\r
+ bufferPos = (SizeT)(p - data);\r
+ if (p >= limit)\r
+ break;\r
+ prevPosT = bufferPos - prevPosT;\r
+ if (prevPosT > 3)\r
+ prevMask = 0;\r
+ else\r
+ {\r
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;\r
+ if (prevMask != 0)\r
+ {\r
+ Byte b = p[4 - kMaskToBitNumber[prevMask]];\r
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))\r
+ {\r
+ prevPosT = bufferPos;\r
+ prevMask = ((prevMask << 1) & 0x7) | 1;\r
+ bufferPos++;\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+ prevPosT = bufferPos;\r
+\r
+ if (Test86MSByte(p[4]))\r
+ {\r
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);\r
+ UInt32 dest;\r
+ for (;;)\r
+ {\r
+ Byte b;\r
+ int index;\r
+ if (encoding)\r
+ dest = (ip + (UInt32)bufferPos) + src;\r
+ else\r
+ dest = src - (ip + (UInt32)bufferPos);\r
+ if (prevMask == 0)\r
+ break;\r
+ index = kMaskToBitNumber[prevMask] * 8;\r
+ b = (Byte)(dest >> (24 - index));\r
+ if (!Test86MSByte(b))\r
+ break;\r
+ src = dest ^ ((1 << (32 - index)) - 1);\r
+ }\r
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1));\r
+ p[3] = (Byte)(dest >> 16);\r
+ p[2] = (Byte)(dest >> 8);\r
+ p[1] = (Byte)dest;\r
+ bufferPos += 5;\r
+ }\r
+ else\r
+ {\r
+ prevMask = ((prevMask << 1) & 0x7) | 1;\r
+ bufferPos++;\r
+ }\r
+ }\r
+ prevPosT = bufferPos - prevPosT;\r
+ *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));\r
+ return bufferPos;\r
+}\r
--- /dev/null
+/* CpuArch.h\r
+2008-08-05\r
+Igor Pavlov\r
+Public domain */\r
+\r
+#ifndef __CPUARCH_H\r
+#define __CPUARCH_H\r
+\r
+/*\r
+LITTLE_ENDIAN_UNALIGN means:\r
+ 1) CPU is LITTLE_ENDIAN\r
+ 2) it's allowed to make unaligned memory accesses\r
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know\r
+about these properties of platform.\r
+*/\r
+\r
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)\r
+#define LITTLE_ENDIAN_UNALIGN\r
+#endif\r
+\r
+#ifdef LITTLE_ENDIAN_UNALIGN\r
+\r
+#define GetUi16(p) (*(const UInt16 *)(p))\r
+#define GetUi32(p) (*(const UInt32 *)(p))\r
+#define GetUi64(p) (*(const UInt64 *)(p))\r
+#define SetUi32(p, d) *(UInt32 *)(p) = (d);\r
+\r
+#else\r
+\r
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))\r
+\r
+#define GetUi32(p) ( \\r
+ ((const Byte *)(p))[0] | \\r
+ ((UInt32)((const Byte *)(p))[1] << 8) | \\r
+ ((UInt32)((const Byte *)(p))[2] << 16) | \\r
+ ((UInt32)((const Byte *)(p))[3] << 24))\r
+\r
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))\r
+\r
+#define SetUi32(p, d) { UInt32 _x_ = (d); \\r
+ ((Byte *)(p))[0] = (Byte)_x_; \\r
+ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \\r
+ ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \\r
+ ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }\r
+\r
+#endif\r
+\r
+#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)\r
+\r
+#pragma intrinsic(_byteswap_ulong)\r
+#pragma intrinsic(_byteswap_uint64)\r
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))\r
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))\r
+\r
+#else\r
+\r
+#define GetBe32(p) ( \\r
+ ((UInt32)((const Byte *)(p))[0] << 24) | \\r
+ ((UInt32)((const Byte *)(p))[1] << 16) | \\r
+ ((UInt32)((const Byte *)(p))[2] << 8) | \\r
+ ((const Byte *)(p))[3] )\r
+\r
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))\r
+\r
+#endif\r
+\r
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ LzFind.c\r
+\r
+ Based on LZMA SDK 4.65:\r
+ LzFind.c -- Match finder for LZ algorithms\r
+ 2008-10-04 : Igor Pavlov : Public domain\r
+\r
+ Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef EFIAPI\r
+\r
+#include <string.h>\r
+\r
+#endif // !EFIAPI\r
+\r
+#include "LzFind.h"\r
+#include "LzHash.h"\r
+\r
+#define kEmptyHashValue 0\r
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)\r
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */\r
+#define kNormalizeMask (~(kNormalizeStepMin - 1))\r
+#define kMaxHistorySize ((UInt32)3 << 30)\r
+\r
+#define kStartMaxLen 3\r
+\r
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)\r
+{\r
+ if (!p->directInput)\r
+ {\r
+ alloc->Free(alloc, p->bufferBase);\r
+ p->bufferBase = 0;\r
+ }\r
+}\r
+\r
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */\r
+\r
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)\r
+{\r
+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;\r
+ if (p->directInput)\r
+ {\r
+ p->blockSize = blockSize;\r
+ return 1;\r
+ }\r
+ if (p->bufferBase == 0 || p->blockSize != blockSize)\r
+ {\r
+ LzInWindow_Free(p, alloc);\r
+ p->blockSize = blockSize;\r
+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);\r
+ }\r
+ return (p->bufferBase != 0);\r
+}\r
+\r
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }\r
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }\r
+\r
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }\r
+\r
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)\r
+{\r
+ p->posLimit -= subValue;\r
+ p->pos -= subValue;\r
+ p->streamPos -= subValue;\r
+}\r
+\r
+static void MatchFinder_ReadBlock(CMatchFinder *p)\r
+{\r
+ if (p->streamEndWasReached || p->result != SZ_OK)\r
+ return;\r
+ for (;;)\r
+ {\r
+ Byte *dest = p->buffer + (p->streamPos - p->pos);\r
+ size_t size = (p->bufferBase + p->blockSize - dest);\r
+ if (size == 0)\r
+ return;\r
+ p->result = p->stream->Read(p->stream, dest, &size);\r
+ if (p->result != SZ_OK)\r
+ return;\r
+ if (size == 0)\r
+ {\r
+ p->streamEndWasReached = 1;\r
+ return;\r
+ }\r
+ p->streamPos += (UInt32)size;\r
+ if (p->streamPos - p->pos > p->keepSizeAfter)\r
+ return;\r
+ }\r
+}\r
+\r
+void MatchFinder_MoveBlock(CMatchFinder *p)\r
+{\r
+ memmove(p->bufferBase,\r
+ p->buffer - p->keepSizeBefore,\r
+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));\r
+ p->buffer = p->bufferBase + p->keepSizeBefore;\r
+}\r
+\r
+int MatchFinder_NeedMove(CMatchFinder *p)\r
+{\r
+ /* if (p->streamEndWasReached) return 0; */\r
+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);\r
+}\r
+\r
+void MatchFinder_ReadIfRequired(CMatchFinder *p)\r
+{\r
+ if (p->streamEndWasReached)\r
+ return;\r
+ if (p->keepSizeAfter >= p->streamPos - p->pos)\r
+ MatchFinder_ReadBlock(p);\r
+}\r
+\r
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)\r
+{\r
+ if (MatchFinder_NeedMove(p))\r
+ MatchFinder_MoveBlock(p);\r
+ MatchFinder_ReadBlock(p);\r
+}\r
+\r
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)\r
+{\r
+ p->cutValue = 32;\r
+ p->btMode = 1;\r
+ p->numHashBytes = 4;\r
+ /* p->skipModeBits = 0; */\r
+ p->directInput = 0;\r
+ p->bigHash = 0;\r
+}\r
+\r
+#define kCrcPoly 0xEDB88320\r
+\r
+void MatchFinder_Construct(CMatchFinder *p)\r
+{\r
+ UInt32 i;\r
+ p->bufferBase = 0;\r
+ p->directInput = 0;\r
+ p->hash = 0;\r
+ MatchFinder_SetDefaultSettings(p);\r
+\r
+ for (i = 0; i < 256; i++)\r
+ {\r
+ UInt32 r = i;\r
+ int j;\r
+ for (j = 0; j < 8; j++)\r
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));\r
+ p->crc[i] = r;\r
+ }\r
+}\r
+\r
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)\r
+{\r
+ alloc->Free(alloc, p->hash);\r
+ p->hash = 0;\r
+}\r
+\r
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)\r
+{\r
+ MatchFinder_FreeThisClassMemory(p, alloc);\r
+ LzInWindow_Free(p, alloc);\r
+}\r
+\r
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)\r
+{\r
+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);\r
+ if (sizeInBytes / sizeof(CLzRef) != num)\r
+ return 0;\r
+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);\r
+}\r
+\r
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,\r
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,\r
+ ISzAlloc *alloc)\r
+{\r
+ UInt32 sizeReserv;\r
+ if (historySize > kMaxHistorySize)\r
+ {\r
+ MatchFinder_Free(p, alloc);\r
+ return 0;\r
+ }\r
+ sizeReserv = historySize >> 1;\r
+ if (historySize > ((UInt32)2 << 30))\r
+ sizeReserv = historySize >> 2;\r
+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);\r
+\r
+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;\r
+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;\r
+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */\r
+ if (LzInWindow_Create(p, sizeReserv, alloc))\r
+ {\r
+ UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;\r
+ UInt32 hs;\r
+ p->matchMaxLen = matchMaxLen;\r
+ {\r
+ p->fixedHashSize = 0;\r
+ if (p->numHashBytes == 2)\r
+ hs = (1 << 16) - 1;\r
+ else\r
+ {\r
+ hs = historySize - 1;\r
+ hs |= (hs >> 1);\r
+ hs |= (hs >> 2);\r
+ hs |= (hs >> 4);\r
+ hs |= (hs >> 8);\r
+ hs >>= 1;\r
+ /* hs >>= p->skipModeBits; */\r
+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */\r
+ if (hs > (1 << 24))\r
+ {\r
+ if (p->numHashBytes == 3)\r
+ hs = (1 << 24) - 1;\r
+ else\r
+ hs >>= 1;\r
+ }\r
+ }\r
+ p->hashMask = hs;\r
+ hs++;\r
+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;\r
+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;\r
+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;\r
+ hs += p->fixedHashSize;\r
+ }\r
+\r
+ {\r
+ UInt32 prevSize = p->hashSizeSum + p->numSons;\r
+ UInt32 newSize;\r
+ p->historySize = historySize;\r
+ p->hashSizeSum = hs;\r
+ p->cyclicBufferSize = newCyclicBufferSize;\r
+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);\r
+ newSize = p->hashSizeSum + p->numSons;\r
+ if (p->hash != 0 && prevSize == newSize)\r
+ return 1;\r
+ MatchFinder_FreeThisClassMemory(p, alloc);\r
+ p->hash = AllocRefs(newSize, alloc);\r
+ if (p->hash != 0)\r
+ {\r
+ p->son = p->hash + p->hashSizeSum;\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+ MatchFinder_Free(p, alloc);\r
+ return 0;\r
+}\r
+\r
+static void MatchFinder_SetLimits(CMatchFinder *p)\r
+{\r
+ UInt32 limit = kMaxValForNormalize - p->pos;\r
+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;\r
+ if (limit2 < limit)\r
+ limit = limit2;\r
+ limit2 = p->streamPos - p->pos;\r
+ if (limit2 <= p->keepSizeAfter)\r
+ {\r
+ if (limit2 > 0)\r
+ limit2 = 1;\r
+ }\r
+ else\r
+ limit2 -= p->keepSizeAfter;\r
+ if (limit2 < limit)\r
+ limit = limit2;\r
+ {\r
+ UInt32 lenLimit = p->streamPos - p->pos;\r
+ if (lenLimit > p->matchMaxLen)\r
+ lenLimit = p->matchMaxLen;\r
+ p->lenLimit = lenLimit;\r
+ }\r
+ p->posLimit = p->pos + limit;\r
+}\r
+\r
+void MatchFinder_Init(CMatchFinder *p)\r
+{\r
+ UInt32 i;\r
+ for (i = 0; i < p->hashSizeSum; i++)\r
+ p->hash[i] = kEmptyHashValue;\r
+ p->cyclicBufferPos = 0;\r
+ p->buffer = p->bufferBase;\r
+ p->pos = p->streamPos = p->cyclicBufferSize;\r
+ p->result = SZ_OK;\r
+ p->streamEndWasReached = 0;\r
+ MatchFinder_ReadBlock(p);\r
+ MatchFinder_SetLimits(p);\r
+}\r
+\r
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)\r
+{\r
+ return (p->pos - p->historySize - 1) & kNormalizeMask;\r
+}\r
+\r
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)\r
+{\r
+ UInt32 i;\r
+ for (i = 0; i < numItems; i++)\r
+ {\r
+ UInt32 value = items[i];\r
+ if (value <= subValue)\r
+ value = kEmptyHashValue;\r
+ else\r
+ value -= subValue;\r
+ items[i] = value;\r
+ }\r
+}\r
+\r
+static void MatchFinder_Normalize(CMatchFinder *p)\r
+{\r
+ UInt32 subValue = MatchFinder_GetSubValue(p);\r
+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);\r
+ MatchFinder_ReduceOffsets(p, subValue);\r
+}\r
+\r
+static void MatchFinder_CheckLimits(CMatchFinder *p)\r
+{\r
+ if (p->pos == kMaxValForNormalize)\r
+ MatchFinder_Normalize(p);\r
+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)\r
+ MatchFinder_CheckAndMoveAndRead(p);\r
+ if (p->cyclicBufferPos == p->cyclicBufferSize)\r
+ p->cyclicBufferPos = 0;\r
+ MatchFinder_SetLimits(p);\r
+}\r
+\r
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,\r
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,\r
+ UInt32 *distances, UInt32 maxLen)\r
+{\r
+ son[_cyclicBufferPos] = curMatch;\r
+ for (;;)\r
+ {\r
+ UInt32 delta = pos - curMatch;\r
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+ return distances;\r
+ {\r
+ const Byte *pb = cur - delta;\r
+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];\r
+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)\r
+ {\r
+ UInt32 len = 0;\r
+ while (++len != lenLimit)\r
+ if (pb[len] != cur[len])\r
+ break;\r
+ if (maxLen < len)\r
+ {\r
+ *distances++ = maxLen = len;\r
+ *distances++ = delta - 1;\r
+ if (len == lenLimit)\r
+ return distances;\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,\r
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,\r
+ UInt32 *distances, UInt32 maxLen)\r
+{\r
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;\r
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);\r
+ UInt32 len0 = 0, len1 = 0;\r
+ for (;;)\r
+ {\r
+ UInt32 delta = pos - curMatch;\r
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+ {\r
+ *ptr0 = *ptr1 = kEmptyHashValue;\r
+ return distances;\r
+ }\r
+ {\r
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);\r
+ const Byte *pb = cur - delta;\r
+ UInt32 len = (len0 < len1 ? len0 : len1);\r
+ if (pb[len] == cur[len])\r
+ {\r
+ if (++len != lenLimit && pb[len] == cur[len])\r
+ while (++len != lenLimit)\r
+ if (pb[len] != cur[len])\r
+ break;\r
+ if (maxLen < len)\r
+ {\r
+ *distances++ = maxLen = len;\r
+ *distances++ = delta - 1;\r
+ if (len == lenLimit)\r
+ {\r
+ *ptr1 = pair[0];\r
+ *ptr0 = pair[1];\r
+ return distances;\r
+ }\r
+ }\r
+ }\r
+ if (pb[len] < cur[len])\r
+ {\r
+ *ptr1 = curMatch;\r
+ ptr1 = pair + 1;\r
+ curMatch = *ptr1;\r
+ len1 = len;\r
+ }\r
+ else\r
+ {\r
+ *ptr0 = curMatch;\r
+ ptr0 = pair;\r
+ curMatch = *ptr0;\r
+ len0 = len;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,\r
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)\r
+{\r
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;\r
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);\r
+ UInt32 len0 = 0, len1 = 0;\r
+ for (;;)\r
+ {\r
+ UInt32 delta = pos - curMatch;\r
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)\r
+ {\r
+ *ptr0 = *ptr1 = kEmptyHashValue;\r
+ return;\r
+ }\r
+ {\r
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);\r
+ const Byte *pb = cur - delta;\r
+ UInt32 len = (len0 < len1 ? len0 : len1);\r
+ if (pb[len] == cur[len])\r
+ {\r
+ while (++len != lenLimit)\r
+ if (pb[len] != cur[len])\r
+ break;\r
+ {\r
+ if (len == lenLimit)\r
+ {\r
+ *ptr1 = pair[0];\r
+ *ptr0 = pair[1];\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ if (pb[len] < cur[len])\r
+ {\r
+ *ptr1 = curMatch;\r
+ ptr1 = pair + 1;\r
+ curMatch = *ptr1;\r
+ len1 = len;\r
+ }\r
+ else\r
+ {\r
+ *ptr0 = curMatch;\r
+ ptr0 = pair;\r
+ curMatch = *ptr0;\r
+ len0 = len;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+#define MOVE_POS \\r
+ ++p->cyclicBufferPos; \\r
+ p->buffer++; \\r
+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);\r
+\r
+#define MOVE_POS_RET MOVE_POS return offset;\r
+\r
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }\r
+\r
+#define GET_MATCHES_HEADER2(minLen, ret_op) \\r
+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \\r
+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \\r
+ cur = p->buffer;\r
+\r
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)\r
+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)\r
+\r
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue\r
+\r
+#define GET_MATCHES_FOOTER(offset, maxLen) \\r
+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \\r
+ distances + offset, maxLen) - distances); MOVE_POS_RET;\r
+\r
+#define SKIP_FOOTER \\r
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;\r
+\r
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+ UInt32 offset;\r
+ GET_MATCHES_HEADER(2)\r
+ HASH2_CALC;\r
+ curMatch = p->hash[hashValue];\r
+ p->hash[hashValue] = p->pos;\r
+ offset = 0;\r
+ GET_MATCHES_FOOTER(offset, 1)\r
+}\r
+\r
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+ UInt32 offset;\r
+ GET_MATCHES_HEADER(3)\r
+ HASH_ZIP_CALC;\r
+ curMatch = p->hash[hashValue];\r
+ p->hash[hashValue] = p->pos;\r
+ offset = 0;\r
+ GET_MATCHES_FOOTER(offset, 2)\r
+}\r
+\r
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+ UInt32 hash2Value, delta2, maxLen, offset;\r
+ GET_MATCHES_HEADER(3)\r
+\r
+ HASH3_CALC;\r
+\r
+ delta2 = p->pos - p->hash[hash2Value];\r
+ curMatch = p->hash[kFix3HashSize + hashValue];\r
+ \r
+ p->hash[hash2Value] =\r
+ p->hash[kFix3HashSize + hashValue] = p->pos;\r
+\r
+\r
+ maxLen = 2;\r
+ offset = 0;\r
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)\r
+ {\r
+ for (; maxLen != lenLimit; maxLen++)\r
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])\r
+ break;\r
+ distances[0] = maxLen;\r
+ distances[1] = delta2 - 1;\r
+ offset = 2;\r
+ if (maxLen == lenLimit)\r
+ {\r
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));\r
+ MOVE_POS_RET;\r
+ }\r
+ }\r
+ GET_MATCHES_FOOTER(offset, maxLen)\r
+}\r
+\r
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;\r
+ GET_MATCHES_HEADER(4)\r
+\r
+ HASH4_CALC;\r
+\r
+ delta2 = p->pos - p->hash[ hash2Value];\r
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];\r
+ curMatch = p->hash[kFix4HashSize + hashValue];\r
+ \r
+ p->hash[ hash2Value] =\r
+ p->hash[kFix3HashSize + hash3Value] =\r
+ p->hash[kFix4HashSize + hashValue] = p->pos;\r
+\r
+ maxLen = 1;\r
+ offset = 0;\r
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)\r
+ {\r
+ distances[0] = maxLen = 2;\r
+ distances[1] = delta2 - 1;\r
+ offset = 2;\r
+ }\r
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)\r
+ {\r
+ maxLen = 3;\r
+ distances[offset + 1] = delta3 - 1;\r
+ offset += 2;\r
+ delta2 = delta3;\r
+ }\r
+ if (offset != 0)\r
+ {\r
+ for (; maxLen != lenLimit; maxLen++)\r
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])\r
+ break;\r
+ distances[offset - 2] = maxLen;\r
+ if (maxLen == lenLimit)\r
+ {\r
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));\r
+ MOVE_POS_RET;\r
+ }\r
+ }\r
+ if (maxLen < 3)\r
+ maxLen = 3;\r
+ GET_MATCHES_FOOTER(offset, maxLen)\r
+}\r
+\r
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;\r
+ GET_MATCHES_HEADER(4)\r
+\r
+ HASH4_CALC;\r
+\r
+ delta2 = p->pos - p->hash[ hash2Value];\r
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];\r
+ curMatch = p->hash[kFix4HashSize + hashValue];\r
+\r
+ p->hash[ hash2Value] =\r
+ p->hash[kFix3HashSize + hash3Value] =\r
+ p->hash[kFix4HashSize + hashValue] = p->pos;\r
+\r
+ maxLen = 1;\r
+ offset = 0;\r
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)\r
+ {\r
+ distances[0] = maxLen = 2;\r
+ distances[1] = delta2 - 1;\r
+ offset = 2;\r
+ }\r
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)\r
+ {\r
+ maxLen = 3;\r
+ distances[offset + 1] = delta3 - 1;\r
+ offset += 2;\r
+ delta2 = delta3;\r
+ }\r
+ if (offset != 0)\r
+ {\r
+ for (; maxLen != lenLimit; maxLen++)\r
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])\r
+ break;\r
+ distances[offset - 2] = maxLen;\r
+ if (maxLen == lenLimit)\r
+ {\r
+ p->son[p->cyclicBufferPos] = curMatch;\r
+ MOVE_POS_RET;\r
+ }\r
+ }\r
+ if (maxLen < 3)\r
+ maxLen = 3;\r
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),\r
+ distances + offset, maxLen) - (distances));\r
+ MOVE_POS_RET\r
+}\r
+\r
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)\r
+{\r
+ UInt32 offset;\r
+ GET_MATCHES_HEADER(3)\r
+ HASH_ZIP_CALC;\r
+ curMatch = p->hash[hashValue];\r
+ p->hash[hashValue] = p->pos;\r
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),\r
+ distances, 2) - (distances));\r
+ MOVE_POS_RET\r
+}\r
+\r
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+ do\r
+ {\r
+ SKIP_HEADER(2)\r
+ HASH2_CALC;\r
+ curMatch = p->hash[hashValue];\r
+ p->hash[hashValue] = p->pos;\r
+ SKIP_FOOTER\r
+ }\r
+ while (--num != 0);\r
+}\r
+\r
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+ do\r
+ {\r
+ SKIP_HEADER(3)\r
+ HASH_ZIP_CALC;\r
+ curMatch = p->hash[hashValue];\r
+ p->hash[hashValue] = p->pos;\r
+ SKIP_FOOTER\r
+ }\r
+ while (--num != 0);\r
+}\r
+\r
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+ do\r
+ {\r
+ UInt32 hash2Value;\r
+ SKIP_HEADER(3)\r
+ HASH3_CALC;\r
+ curMatch = p->hash[kFix3HashSize + hashValue];\r
+ p->hash[hash2Value] =\r
+ p->hash[kFix3HashSize + hashValue] = p->pos;\r
+ SKIP_FOOTER\r
+ }\r
+ while (--num != 0);\r
+}\r
+\r
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+ do\r
+ {\r
+ UInt32 hash2Value, hash3Value;\r
+ SKIP_HEADER(4)\r
+ HASH4_CALC;\r
+ curMatch = p->hash[kFix4HashSize + hashValue];\r
+ p->hash[ hash2Value] =\r
+ p->hash[kFix3HashSize + hash3Value] = p->pos;\r
+ p->hash[kFix4HashSize + hashValue] = p->pos;\r
+ SKIP_FOOTER\r
+ }\r
+ while (--num != 0);\r
+}\r
+\r
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+ do\r
+ {\r
+ UInt32 hash2Value, hash3Value;\r
+ SKIP_HEADER(4)\r
+ HASH4_CALC;\r
+ curMatch = p->hash[kFix4HashSize + hashValue];\r
+ p->hash[ hash2Value] =\r
+ p->hash[kFix3HashSize + hash3Value] =\r
+ p->hash[kFix4HashSize + hashValue] = p->pos;\r
+ p->son[p->cyclicBufferPos] = curMatch;\r
+ MOVE_POS\r
+ }\r
+ while (--num != 0);\r
+}\r
+\r
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)\r
+{\r
+ do\r
+ {\r
+ SKIP_HEADER(3)\r
+ HASH_ZIP_CALC;\r
+ curMatch = p->hash[hashValue];\r
+ p->hash[hashValue] = p->pos;\r
+ p->son[p->cyclicBufferPos] = curMatch;\r
+ MOVE_POS\r
+ }\r
+ while (--num != 0);\r
+}\r
+\r
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)\r
+{\r
+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;\r
+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;\r
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;\r
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;\r
+ if (!p->btMode)\r
+ {\r
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;\r
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;\r
+ }\r
+ else if (p->numHashBytes == 2)\r
+ {\r
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;\r
+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;\r
+ }\r
+ else if (p->numHashBytes == 3)\r
+ {\r
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;\r
+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;\r
+ }\r
+ else\r
+ {\r
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;\r
+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;\r
+ }\r
+}\r
--- /dev/null
+/* LzFind.h -- Match finder for LZ algorithms\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZFIND_H\r
+#define __LZFIND_H\r
+\r
+#include "Types.h"\r
+\r
+typedef UInt32 CLzRef;\r
+\r
+typedef struct _CMatchFinder\r
+{\r
+ Byte *buffer;\r
+ UInt32 pos;\r
+ UInt32 posLimit;\r
+ UInt32 streamPos;\r
+ UInt32 lenLimit;\r
+\r
+ UInt32 cyclicBufferPos;\r
+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */\r
+\r
+ UInt32 matchMaxLen;\r
+ CLzRef *hash;\r
+ CLzRef *son;\r
+ UInt32 hashMask;\r
+ UInt32 cutValue;\r
+\r
+ Byte *bufferBase;\r
+ ISeqInStream *stream;\r
+ int streamEndWasReached;\r
+\r
+ UInt32 blockSize;\r
+ UInt32 keepSizeBefore;\r
+ UInt32 keepSizeAfter;\r
+\r
+ UInt32 numHashBytes;\r
+ int directInput;\r
+ int btMode;\r
+ /* int skipModeBits; */\r
+ int bigHash;\r
+ UInt32 historySize;\r
+ UInt32 fixedHashSize;\r
+ UInt32 hashSizeSum;\r
+ UInt32 numSons;\r
+ SRes result;\r
+ UInt32 crc[256];\r
+} CMatchFinder;\r
+\r
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)\r
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])\r
+\r
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)\r
+\r
+int MatchFinder_NeedMove(CMatchFinder *p);\r
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);\r
+void MatchFinder_MoveBlock(CMatchFinder *p);\r
+void MatchFinder_ReadIfRequired(CMatchFinder *p);\r
+\r
+void MatchFinder_Construct(CMatchFinder *p);\r
+\r
+/* Conditions:\r
+ historySize <= 3 GB\r
+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB\r
+*/\r
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,\r
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,\r
+ ISzAlloc *alloc);\r
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);\r
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);\r
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);\r
+\r
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,\r
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,\r
+ UInt32 *distances, UInt32 maxLen);\r
+\r
+/*\r
+Conditions:\r
+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.\r
+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function\r
+*/\r
+\r
+typedef void (*Mf_Init_Func)(void *object);\r
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);\r
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);\r
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);\r
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);\r
+typedef void (*Mf_Skip_Func)(void *object, UInt32);\r
+\r
+typedef struct _IMatchFinder\r
+{\r
+ Mf_Init_Func Init;\r
+ Mf_GetIndexByte_Func GetIndexByte;\r
+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;\r
+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;\r
+ Mf_GetMatches_Func GetMatches;\r
+ Mf_Skip_Func Skip;\r
+} IMatchFinder;\r
+\r
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);\r
+\r
+void MatchFinder_Init(CMatchFinder *p);\r
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);\r
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);\r
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);\r
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);\r
+\r
+#endif\r
--- /dev/null
+/* LzHash.h -- HASH functions for LZ algorithms\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZHASH_H\r
+#define __LZHASH_H\r
+\r
+#define kHash2Size (1 << 10)\r
+#define kHash3Size (1 << 16)\r
+#define kHash4Size (1 << 20)\r
+\r
+#define kFix3HashSize (kHash2Size)\r
+#define kFix4HashSize (kHash2Size + kHash3Size)\r
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)\r
+\r
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);\r
+\r
+#define HASH3_CALC { \\r
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+ hash2Value = temp & (kHash2Size - 1); \\r
+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }\r
+\r
+#define HASH4_CALC { \\r
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+ hash2Value = temp & (kHash2Size - 1); \\r
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \\r
+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }\r
+\r
+#define HASH5_CALC { \\r
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+ hash2Value = temp & (kHash2Size - 1); \\r
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \\r
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \\r
+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \\r
+ hash4Value &= (kHash4Size - 1); }\r
+\r
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */\r
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;\r
+\r
+\r
+#define MT_HASH2_CALC \\r
+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);\r
+\r
+#define MT_HASH3_CALC { \\r
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+ hash2Value = temp & (kHash2Size - 1); \\r
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }\r
+\r
+#define MT_HASH4_CALC { \\r
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \\r
+ hash2Value = temp & (kHash2Size - 1); \\r
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \\r
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ LzmaDec.c\r
+\r
+ Based on LZMA SDK 4.65:\r
+ LzmaDec.c -- LZMA Decoder\r
+ 2008-11-06 : Igor Pavlov : Public domain\r
+\r
+ Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "LzmaDec.h"\r
+\r
+#ifndef EFIAPI\r
+\r
+#include <string.h>\r
+\r
+#endif // !EFIAPI\r
+\r
+#define kNumTopBits 24\r
+#define kTopValue ((UInt32)1 << kNumTopBits)\r
+\r
+#define kNumBitModelTotalBits 11\r
+#define kBitModelTotal (1 << kNumBitModelTotalBits)\r
+#define kNumMoveBits 5\r
+\r
+#define RC_INIT_SIZE 5\r
+\r
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }\r
+\r
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));\r
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));\r
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \\r
+ { UPDATE_0(p); i = (i + i); A0; } else \\r
+ { UPDATE_1(p); i = (i + i) + 1; A1; }\r
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)\r
+\r
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }\r
+#define TREE_DECODE(probs, limit, i) \\r
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }\r
+\r
+/* #define _LZMA_SIZE_OPT */\r
+\r
+#ifdef _LZMA_SIZE_OPT\r
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)\r
+#else\r
+#define TREE_6_DECODE(probs, i) \\r
+ { i = 1; \\r
+ TREE_GET_BIT(probs, i); \\r
+ TREE_GET_BIT(probs, i); \\r
+ TREE_GET_BIT(probs, i); \\r
+ TREE_GET_BIT(probs, i); \\r
+ TREE_GET_BIT(probs, i); \\r
+ TREE_GET_BIT(probs, i); \\r
+ i -= 0x40; }\r
+#endif\r
+\r
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }\r
+\r
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)\r
+#define UPDATE_0_CHECK range = bound;\r
+#define UPDATE_1_CHECK range -= bound; code -= bound;\r
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \\r
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \\r
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }\r
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)\r
+#define TREE_DECODE_CHECK(probs, limit, i) \\r
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }\r
+\r
+\r
+#define kNumPosBitsMax 4\r
+#define kNumPosStatesMax (1 << kNumPosBitsMax)\r
+\r
+#define kLenNumLowBits 3\r
+#define kLenNumLowSymbols (1 << kLenNumLowBits)\r
+#define kLenNumMidBits 3\r
+#define kLenNumMidSymbols (1 << kLenNumMidBits)\r
+#define kLenNumHighBits 8\r
+#define kLenNumHighSymbols (1 << kLenNumHighBits)\r
+\r
+#define LenChoice 0\r
+#define LenChoice2 (LenChoice + 1)\r
+#define LenLow (LenChoice2 + 1)\r
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))\r
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))\r
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)\r
+\r
+\r
+#define kNumStates 12\r
+#define kNumLitStates 7\r
+\r
+#define kStartPosModelIndex 4\r
+#define kEndPosModelIndex 14\r
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))\r
+\r
+#define kNumPosSlotBits 6\r
+#define kNumLenToPosStates 4\r
+\r
+#define kNumAlignBits 4\r
+#define kAlignTableSize (1 << kNumAlignBits)\r
+\r
+#define kMatchMinLen 2\r
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)\r
+\r
+#define IsMatch 0\r
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))\r
+#define IsRepG0 (IsRep + kNumStates)\r
+#define IsRepG1 (IsRepG0 + kNumStates)\r
+#define IsRepG2 (IsRepG1 + kNumStates)\r
+#define IsRep0Long (IsRepG2 + kNumStates)\r
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))\r
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))\r
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)\r
+#define LenCoder (Align + kAlignTableSize)\r
+#define RepLenCoder (LenCoder + kNumLenProbs)\r
+#define Literal (RepLenCoder + kNumLenProbs)\r
+\r
+#define LZMA_BASE_SIZE 1846\r
+#define LZMA_LIT_SIZE 768\r
+\r
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))\r
+\r
+#if Literal != LZMA_BASE_SIZE\r
+StopCompilingDueBUG\r
+#endif\r
+\r
+static const Byte kLiteralNextStates[kNumStates * 2] =\r
+{\r
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,\r
+ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10\r
+};\r
+\r
+#define LZMA_DIC_MIN (1 << 12)\r
+\r
+/* First LZMA-symbol is always decoded.\r
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization\r
+Out:\r
+ Result:\r
+ SZ_OK - OK\r
+ SZ_ERROR_DATA - Error\r
+ p->remainLen:\r
+ < kMatchSpecLenStart : normal remain\r
+ = kMatchSpecLenStart : finished\r
+ = kMatchSpecLenStart + 1 : Flush marker\r
+ = kMatchSpecLenStart + 2 : State Init Marker\r
+*/\r
+\r
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
+{\r
+ CLzmaProb *probs = p->probs;\r
+\r
+ unsigned state = p->state;\r
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];\r
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;\r
+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;\r
+ unsigned lc = p->prop.lc;\r
+\r
+ Byte *dic = p->dic;\r
+ SizeT dicBufSize = p->dicBufSize;\r
+ SizeT dicPos = p->dicPos;\r
+ \r
+ UInt32 processedPos = p->processedPos;\r
+ UInt32 checkDicSize = p->checkDicSize;\r
+ unsigned len = 0;\r
+\r
+ const Byte *buf = p->buf;\r
+ UInt32 range = p->range;\r
+ UInt32 code = p->code;\r
+\r
+ do\r
+ {\r
+ CLzmaProb *prob;\r
+ UInt32 bound;\r
+ unsigned ttt;\r
+ unsigned posState = processedPos & pbMask;\r
+\r
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;\r
+ IF_BIT_0(prob)\r
+ {\r
+ unsigned symbol;\r
+ UPDATE_0(prob);\r
+ prob = probs + Literal;\r
+ if (checkDicSize != 0 || processedPos != 0)\r
+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +\r
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));\r
+\r
+ if (state < kNumLitStates)\r
+ {\r
+ symbol = 1;\r
+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);\r
+ }\r
+ else\r
+ {\r
+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+ unsigned offs = 0x100;\r
+ symbol = 1;\r
+ do\r
+ {\r
+ unsigned bit;\r
+ CLzmaProb *probLit;\r
+ matchByte <<= 1;\r
+ bit = (matchByte & offs);\r
+ probLit = prob + offs + bit + symbol;\r
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)\r
+ }\r
+ while (symbol < 0x100);\r
+ }\r
+ dic[dicPos++] = (Byte)symbol;\r
+ processedPos++;\r
+\r
+ state = kLiteralNextStates[state];\r
+ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */\r
+ continue;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(prob);\r
+ prob = probs + IsRep + state;\r
+ IF_BIT_0(prob)\r
+ {\r
+ UPDATE_0(prob);\r
+ state += kNumStates;\r
+ prob = probs + LenCoder;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(prob);\r
+ if (checkDicSize == 0 && processedPos == 0)\r
+ return SZ_ERROR_DATA;\r
+ prob = probs + IsRepG0 + state;\r
+ IF_BIT_0(prob)\r
+ {\r
+ UPDATE_0(prob);\r
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;\r
+ IF_BIT_0(prob)\r
+ {\r
+ UPDATE_0(prob);\r
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+ dicPos++;\r
+ processedPos++;\r
+ state = state < kNumLitStates ? 9 : 11;\r
+ continue;\r
+ }\r
+ UPDATE_1(prob);\r
+ }\r
+ else\r
+ {\r
+ UInt32 distance;\r
+ UPDATE_1(prob);\r
+ prob = probs + IsRepG1 + state;\r
+ IF_BIT_0(prob)\r
+ {\r
+ UPDATE_0(prob);\r
+ distance = rep1;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(prob);\r
+ prob = probs + IsRepG2 + state;\r
+ IF_BIT_0(prob)\r
+ {\r
+ UPDATE_0(prob);\r
+ distance = rep2;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(prob);\r
+ distance = rep3;\r
+ rep3 = rep2;\r
+ }\r
+ rep2 = rep1;\r
+ }\r
+ rep1 = rep0;\r
+ rep0 = distance;\r
+ }\r
+ state = state < kNumLitStates ? 8 : 11;\r
+ prob = probs + RepLenCoder;\r
+ }\r
+ {\r
+ unsigned limit2, offset;\r
+ CLzmaProb *probLen = prob + LenChoice;\r
+ IF_BIT_0(probLen)\r
+ {\r
+ UPDATE_0(probLen);\r
+ probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+ offset = 0;\r
+ limit2 = (1 << kLenNumLowBits);\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(probLen);\r
+ probLen = prob + LenChoice2;\r
+ IF_BIT_0(probLen)\r
+ {\r
+ UPDATE_0(probLen);\r
+ probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+ offset = kLenNumLowSymbols;\r
+ limit2 = (1 << kLenNumMidBits);\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1(probLen);\r
+ probLen = prob + LenHigh;\r
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
+ limit2 = (1 << kLenNumHighBits);\r
+ }\r
+ }\r
+ TREE_DECODE(probLen, limit2, len);\r
+ len += offset;\r
+ }\r
+\r
+ if (state >= kNumStates)\r
+ {\r
+ UInt32 distance;\r
+ prob = probs + PosSlot +\r
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);\r
+ TREE_6_DECODE(prob, distance);\r
+ if (distance >= kStartPosModelIndex)\r
+ {\r
+ unsigned posSlot = (unsigned)distance;\r
+ int numDirectBits = (int)(((distance >> 1) - 1));\r
+ distance = (2 | (distance & 1));\r
+ if (posSlot < kEndPosModelIndex)\r
+ {\r
+ distance <<= numDirectBits;\r
+ prob = probs + SpecPos + distance - posSlot - 1;\r
+ {\r
+ UInt32 mask = 1;\r
+ unsigned i = 1;\r
+ do\r
+ {\r
+ GET_BIT2(prob + i, i, ; , distance |= mask);\r
+ mask <<= 1;\r
+ }\r
+ while (--numDirectBits != 0);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ numDirectBits -= kNumAlignBits;\r
+ do\r
+ {\r
+ NORMALIZE\r
+ range >>= 1;\r
+ \r
+ {\r
+ UInt32 t;\r
+ code -= range;\r
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */\r
+ distance = (distance << 1) + (t + 1);\r
+ code += range & t;\r
+ }\r
+ /*\r
+ distance <<= 1;\r
+ if (code >= range)\r
+ {\r
+ code -= range;\r
+ distance |= 1;\r
+ }\r
+ */\r
+ }\r
+ while (--numDirectBits != 0);\r
+ prob = probs + Align;\r
+ distance <<= kNumAlignBits;\r
+ {\r
+ unsigned i = 1;\r
+ GET_BIT2(prob + i, i, ; , distance |= 1);\r
+ GET_BIT2(prob + i, i, ; , distance |= 2);\r
+ GET_BIT2(prob + i, i, ; , distance |= 4);\r
+ GET_BIT2(prob + i, i, ; , distance |= 8);\r
+ }\r
+ if (distance == (UInt32)0xFFFFFFFF)\r
+ {\r
+ len += kMatchSpecLenStart;\r
+ state -= kNumStates;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ rep3 = rep2;\r
+ rep2 = rep1;\r
+ rep1 = rep0;\r
+ rep0 = distance + 1;\r
+ if (checkDicSize == 0)\r
+ {\r
+ if (distance >= processedPos)\r
+ return SZ_ERROR_DATA;\r
+ }\r
+ else if (distance >= checkDicSize)\r
+ return SZ_ERROR_DATA;\r
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;\r
+ /* state = kLiteralNextStates[state]; */\r
+ }\r
+\r
+ len += kMatchMinLen;\r
+\r
+ if (limit == dicPos)\r
+ return SZ_ERROR_DATA;\r
+ {\r
+ SizeT rem = limit - dicPos;\r
+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);\r
+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);\r
+\r
+ processedPos += curLen;\r
+\r
+ len -= curLen;\r
+ if (pos + curLen <= dicBufSize)\r
+ {\r
+ Byte *dest = dic + dicPos;\r
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;\r
+ const Byte *lim = dest + curLen;\r
+ dicPos += curLen;\r
+ do\r
+ *((volatile Byte *)dest) = (Byte)*(dest + src);\r
+ while (++dest != lim);\r
+ }\r
+ else\r
+ {\r
+ do\r
+ {\r
+ dic[dicPos++] = dic[pos];\r
+ if (++pos == dicBufSize)\r
+ pos = 0;\r
+ }\r
+ while (--curLen != 0);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ while (dicPos < limit && buf < bufLimit);\r
+ NORMALIZE;\r
+ p->buf = buf;\r
+ p->range = range;\r
+ p->code = code;\r
+ p->remainLen = len;\r
+ p->dicPos = dicPos;\r
+ p->processedPos = processedPos;\r
+ p->reps[0] = rep0;\r
+ p->reps[1] = rep1;\r
+ p->reps[2] = rep2;\r
+ p->reps[3] = rep3;\r
+ p->state = state;\r
+\r
+ return SZ_OK;\r
+}\r
+\r
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)\r
+{\r
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)\r
+ {\r
+ Byte *dic = p->dic;\r
+ SizeT dicPos = p->dicPos;\r
+ SizeT dicBufSize = p->dicBufSize;\r
+ unsigned len = p->remainLen;\r
+ UInt32 rep0 = p->reps[0];\r
+ if (limit - dicPos < len)\r
+ len = (unsigned)(limit - dicPos);\r
+\r
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)\r
+ p->checkDicSize = p->prop.dicSize;\r
+\r
+ p->processedPos += len;\r
+ p->remainLen -= len;\r
+ while (len-- != 0)\r
+ {\r
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];\r
+ dicPos++;\r
+ }\r
+ p->dicPos = dicPos;\r
+ }\r
+}\r
+\r
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)\r
+{\r
+ do\r
+ {\r
+ SizeT limit2 = limit;\r
+ if (p->checkDicSize == 0)\r
+ {\r
+ UInt32 rem = p->prop.dicSize - p->processedPos;\r
+ if (limit - p->dicPos > rem)\r
+ limit2 = p->dicPos + rem;\r
+ }\r
+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));\r
+ if (p->processedPos >= p->prop.dicSize)\r
+ p->checkDicSize = p->prop.dicSize;\r
+ LzmaDec_WriteRem(p, limit);\r
+ }\r
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);\r
+\r
+ if (p->remainLen > kMatchSpecLenStart)\r
+ {\r
+ p->remainLen = kMatchSpecLenStart;\r
+ }\r
+ return 0;\r
+}\r
+\r
+typedef enum\r
+{\r
+ DUMMY_ERROR, /* unexpected end of input stream */\r
+ DUMMY_LIT,\r
+ DUMMY_MATCH,\r
+ DUMMY_REP\r
+} ELzmaDummy;\r
+\r
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)\r
+{\r
+ UInt32 range = p->range;\r
+ UInt32 code = p->code;\r
+ const Byte *bufLimit = buf + inSize;\r
+ CLzmaProb *probs = p->probs;\r
+ unsigned state = p->state;\r
+ ELzmaDummy res;\r
+\r
+ {\r
+ CLzmaProb *prob;\r
+ UInt32 bound;\r
+ unsigned ttt;\r
+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);\r
+\r
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;\r
+ IF_BIT_0_CHECK(prob)\r
+ {\r
+ UPDATE_0_CHECK\r
+\r
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */\r
+\r
+ prob = probs + Literal;\r
+ if (p->checkDicSize != 0 || p->processedPos != 0)\r
+ prob += (LZMA_LIT_SIZE *\r
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +\r
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));\r
+\r
+ if (state < kNumLitStates)\r
+ {\r
+ unsigned symbol = 1;\r
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);\r
+ }\r
+ else\r
+ {\r
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +\r
+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];\r
+ unsigned offs = 0x100;\r
+ unsigned symbol = 1;\r
+ do\r
+ {\r
+ unsigned bit;\r
+ CLzmaProb *probLit;\r
+ matchByte <<= 1;\r
+ bit = (matchByte & offs);\r
+ probLit = prob + offs + bit + symbol;\r
+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)\r
+ }\r
+ while (symbol < 0x100);\r
+ }\r
+ res = DUMMY_LIT;\r
+ }\r
+ else\r
+ {\r
+ unsigned len;\r
+ UPDATE_1_CHECK;\r
+\r
+ prob = probs + IsRep + state;\r
+ IF_BIT_0_CHECK(prob)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ state = 0;\r
+ prob = probs + LenCoder;\r
+ res = DUMMY_MATCH;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ res = DUMMY_REP;\r
+ prob = probs + IsRepG0 + state;\r
+ IF_BIT_0_CHECK(prob)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;\r
+ IF_BIT_0_CHECK(prob)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ NORMALIZE_CHECK;\r
+ return DUMMY_REP;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ prob = probs + IsRepG1 + state;\r
+ IF_BIT_0_CHECK(prob)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ prob = probs + IsRepG2 + state;\r
+ IF_BIT_0_CHECK(prob)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ }\r
+ }\r
+ }\r
+ state = kNumStates;\r
+ prob = probs + RepLenCoder;\r
+ }\r
+ {\r
+ unsigned limit, offset;\r
+ CLzmaProb *probLen = prob + LenChoice;\r
+ IF_BIT_0_CHECK(probLen)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ probLen = prob + LenLow + (posState << kLenNumLowBits);\r
+ offset = 0;\r
+ limit = 1 << kLenNumLowBits;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ probLen = prob + LenChoice2;\r
+ IF_BIT_0_CHECK(probLen)\r
+ {\r
+ UPDATE_0_CHECK;\r
+ probLen = prob + LenMid + (posState << kLenNumMidBits);\r
+ offset = kLenNumLowSymbols;\r
+ limit = 1 << kLenNumMidBits;\r
+ }\r
+ else\r
+ {\r
+ UPDATE_1_CHECK;\r
+ probLen = prob + LenHigh;\r
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;\r
+ limit = 1 << kLenNumHighBits;\r
+ }\r
+ }\r
+ TREE_DECODE_CHECK(probLen, limit, len);\r
+ len += offset;\r
+ }\r
+\r
+ if (state < 4)\r
+ {\r
+ unsigned posSlot;\r
+ prob = probs + PosSlot +\r
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<\r
+ kNumPosSlotBits);\r
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);\r
+ if (posSlot >= kStartPosModelIndex)\r
+ {\r
+ int numDirectBits = ((posSlot >> 1) - 1);\r
+\r
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */\r
+\r
+ if (posSlot < kEndPosModelIndex)\r
+ {\r
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;\r
+ }\r
+ else\r
+ {\r
+ numDirectBits -= kNumAlignBits;\r
+ do\r
+ {\r
+ NORMALIZE_CHECK\r
+ range >>= 1;\r
+ code -= range & (((code - range) >> 31) - 1);\r
+ /* if (code >= range) code -= range; */\r
+ }\r
+ while (--numDirectBits != 0);\r
+ prob = probs + Align;\r
+ numDirectBits = kNumAlignBits;\r
+ }\r
+ {\r
+ unsigned i = 1;\r
+ do\r
+ {\r
+ GET_BIT_CHECK(prob + i, i);\r
+ }\r
+ while (--numDirectBits != 0);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ NORMALIZE_CHECK;\r
+ return res;\r
+}\r
+\r
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)\r
+{\r
+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);\r
+ p->range = 0xFFFFFFFF;\r
+ p->needFlush = 0;\r
+}\r
+\r
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)\r
+{\r
+ p->needFlush = 1;\r
+ p->remainLen = 0;\r
+ p->tempBufSize = 0;\r
+\r
+ if (initDic)\r
+ {\r
+ p->processedPos = 0;\r
+ p->checkDicSize = 0;\r
+ p->needInitState = 1;\r
+ }\r
+ if (initState)\r
+ p->needInitState = 1;\r
+}\r
+\r
+void LzmaDec_Init(CLzmaDec *p)\r
+{\r
+ p->dicPos = 0;\r
+ LzmaDec_InitDicAndState(p, True, True);\r
+}\r
+\r
+static void LzmaDec_InitStateReal(CLzmaDec *p)\r
+{\r
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));\r
+ UInt32 i;\r
+ CLzmaProb *probs = p->probs;\r
+ for (i = 0; i < numProbs; i++)\r
+ probs[i] = kBitModelTotal >> 1;\r
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;\r
+ p->state = 0;\r
+ p->needInitState = 0;\r
+}\r
+\r
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,\r
+ ELzmaFinishMode finishMode, ELzmaStatus *status)\r
+{\r
+ SizeT inSize = *srcLen;\r
+ (*srcLen) = 0;\r
+ LzmaDec_WriteRem(p, dicLimit);\r
+ \r
+ *status = LZMA_STATUS_NOT_SPECIFIED;\r
+\r
+ while (p->remainLen != kMatchSpecLenStart)\r
+ {\r
+ int checkEndMarkNow;\r
+\r
+ if (p->needFlush != 0)\r
+ {\r
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)\r
+ p->tempBuf[p->tempBufSize++] = *src++;\r
+ if (p->tempBufSize < RC_INIT_SIZE)\r
+ {\r
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+ return SZ_OK;\r
+ }\r
+ if (p->tempBuf[0] != 0)\r
+ return SZ_ERROR_DATA;\r
+\r
+ LzmaDec_InitRc(p, p->tempBuf);\r
+ p->tempBufSize = 0;\r
+ }\r
+\r
+ checkEndMarkNow = 0;\r
+ if (p->dicPos >= dicLimit)\r
+ {\r
+ if (p->remainLen == 0 && p->code == 0)\r
+ {\r
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;\r
+ return SZ_OK;\r
+ }\r
+ if (finishMode == LZMA_FINISH_ANY)\r
+ {\r
+ *status = LZMA_STATUS_NOT_FINISHED;\r
+ return SZ_OK;\r
+ }\r
+ if (p->remainLen != 0)\r
+ {\r
+ *status = LZMA_STATUS_NOT_FINISHED;\r
+ return SZ_ERROR_DATA;\r
+ }\r
+ checkEndMarkNow = 1;\r
+ }\r
+\r
+ if (p->needInitState)\r
+ LzmaDec_InitStateReal(p);\r
+ \r
+ if (p->tempBufSize == 0)\r
+ {\r
+ SizeT processed;\r
+ const Byte *bufLimit;\r
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)\r
+ {\r
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);\r
+ if (dummyRes == DUMMY_ERROR)\r
+ {\r
+ memcpy(p->tempBuf, src, inSize);\r
+ p->tempBufSize = (unsigned)inSize;\r
+ (*srcLen) += inSize;\r
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+ return SZ_OK;\r
+ }\r
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)\r
+ {\r
+ *status = LZMA_STATUS_NOT_FINISHED;\r
+ return SZ_ERROR_DATA;\r
+ }\r
+ bufLimit = src;\r
+ }\r
+ else\r
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;\r
+ p->buf = src;\r
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)\r
+ return SZ_ERROR_DATA;\r
+ processed = (SizeT)(p->buf - src);\r
+ (*srcLen) += processed;\r
+ src += processed;\r
+ inSize -= processed;\r
+ }\r
+ else\r
+ {\r
+ unsigned rem = p->tempBufSize, lookAhead = 0;\r
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)\r
+ p->tempBuf[rem++] = src[lookAhead++];\r
+ p->tempBufSize = rem;\r
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)\r
+ {\r
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);\r
+ if (dummyRes == DUMMY_ERROR)\r
+ {\r
+ (*srcLen) += lookAhead;\r
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;\r
+ return SZ_OK;\r
+ }\r
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)\r
+ {\r
+ *status = LZMA_STATUS_NOT_FINISHED;\r
+ return SZ_ERROR_DATA;\r
+ }\r
+ }\r
+ p->buf = p->tempBuf;\r
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)\r
+ return SZ_ERROR_DATA;\r
+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));\r
+ (*srcLen) += lookAhead;\r
+ src += lookAhead;\r
+ inSize -= lookAhead;\r
+ p->tempBufSize = 0;\r
+ }\r
+ }\r
+ if (p->code == 0)\r
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;\r
+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;\r
+}\r
+\r
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)\r
+{\r
+ SizeT outSize = *destLen;\r
+ SizeT inSize = *srcLen;\r
+ *srcLen = *destLen = 0;\r
+ for (;;)\r
+ {\r
+ SizeT inSizeCur = inSize, outSizeCur, dicPos;\r
+ ELzmaFinishMode curFinishMode;\r
+ SRes res;\r
+ if (p->dicPos == p->dicBufSize)\r
+ p->dicPos = 0;\r
+ dicPos = p->dicPos;\r
+ if (outSize > p->dicBufSize - dicPos)\r
+ {\r
+ outSizeCur = p->dicBufSize;\r
+ curFinishMode = LZMA_FINISH_ANY;\r
+ }\r
+ else\r
+ {\r
+ outSizeCur = dicPos + outSize;\r
+ curFinishMode = finishMode;\r
+ }\r
+\r
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);\r
+ src += inSizeCur;\r
+ inSize -= inSizeCur;\r
+ *srcLen += inSizeCur;\r
+ outSizeCur = p->dicPos - dicPos;\r
+ memcpy(dest, p->dic + dicPos, outSizeCur);\r
+ dest += outSizeCur;\r
+ outSize -= outSizeCur;\r
+ *destLen += outSizeCur;\r
+ if (res != 0)\r
+ return res;\r
+ if (outSizeCur == 0 || outSize == 0)\r
+ return SZ_OK;\r
+ }\r
+}\r
+\r
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)\r
+{\r
+ alloc->Free(alloc, p->probs);\r
+ p->probs = 0;\r
+}\r
+\r
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)\r
+{\r
+ alloc->Free(alloc, p->dic);\r
+ p->dic = 0;\r
+}\r
+\r
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)\r
+{\r
+ LzmaDec_FreeProbs(p, alloc);\r
+ LzmaDec_FreeDict(p, alloc);\r
+}\r
+\r
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)\r
+{\r
+ UInt32 dicSize;\r
+ Byte d;\r
+ \r
+ if (size < LZMA_PROPS_SIZE)\r
+ return SZ_ERROR_UNSUPPORTED;\r
+ else\r
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);\r
+ \r
+ if (dicSize < LZMA_DIC_MIN)\r
+ dicSize = LZMA_DIC_MIN;\r
+ p->dicSize = dicSize;\r
+\r
+ d = data[0];\r
+ if (d >= (9 * 5 * 5))\r
+ return SZ_ERROR_UNSUPPORTED;\r
+\r
+ p->lc = d % 9;\r
+ d /= 9;\r
+ p->pb = d / 5;\r
+ p->lp = d % 5;\r
+\r
+ return SZ_OK;\r
+}\r
+\r
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)\r
+{\r
+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);\r
+ if (p->probs == 0 || numProbs != p->numProbs)\r
+ {\r
+ LzmaDec_FreeProbs(p, alloc);\r
+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));\r
+ p->numProbs = numProbs;\r
+ if (p->probs == 0)\r
+ return SZ_ERROR_MEM;\r
+ }\r
+ return SZ_OK;\r
+}\r
+\r
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)\r
+{\r
+ CLzmaProps propNew;\r
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
+ p->prop = propNew;\r
+ return SZ_OK;\r
+}\r
+\r
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)\r
+{\r
+ CLzmaProps propNew;\r
+ SizeT dicBufSize;\r
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));\r
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));\r
+ dicBufSize = propNew.dicSize;\r
+ if (p->dic == 0 || dicBufSize != p->dicBufSize)\r
+ {\r
+ LzmaDec_FreeDict(p, alloc);\r
+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);\r
+ if (p->dic == 0)\r
+ {\r
+ LzmaDec_FreeProbs(p, alloc);\r
+ return SZ_ERROR_MEM;\r
+ }\r
+ }\r
+ p->dicBufSize = dicBufSize;\r
+ p->prop = propNew;\r
+ return SZ_OK;\r
+}\r
+\r
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,\r
+ ELzmaStatus *status, ISzAlloc *alloc)\r
+{\r
+ CLzmaDec p;\r
+ SRes res;\r
+ SizeT inSize = *srcLen;\r
+ SizeT outSize = *destLen;\r
+ *srcLen = *destLen = 0;\r
+ if (inSize < RC_INIT_SIZE)\r
+ return SZ_ERROR_INPUT_EOF;\r
+\r
+ LzmaDec_Construct(&p);\r
+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);\r
+ if (res != 0)\r
+ return res;\r
+ p.dic = dest;\r
+ p.dicBufSize = outSize;\r
+\r
+ LzmaDec_Init(&p);\r
+ \r
+ *srcLen = inSize;\r
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);\r
+\r
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)\r
+ res = SZ_ERROR_INPUT_EOF;\r
+\r
+ (*destLen) = p.dicPos;\r
+ LzmaDec_FreeProbs(&p, alloc);\r
+ return res;\r
+}\r
+\r
--- /dev/null
+/* LzmaDec.h -- LZMA Decoder\r
+2008-10-04 : Igor Pavlov : Public domain */\r
+\r
+#ifndef __LZMADEC_H\r
+#define __LZMADEC_H\r
+\r
+#include "Types.h"\r
+\r
+/* #define _LZMA_PROB32 */\r
+/* _LZMA_PROB32 can increase the speed on some CPUs,\r
+ but memory usage for CLzmaDec::probs will be doubled in that case */\r
+\r
+#ifdef _LZMA_PROB32\r
+#define CLzmaProb UInt32\r
+#else\r
+#define CLzmaProb UInt16\r
+#endif\r
+\r
+\r
+/* ---------- LZMA Properties ---------- */\r
+\r
+#define LZMA_PROPS_SIZE 5\r
+\r
+typedef struct _CLzmaProps\r
+{\r
+ unsigned lc, lp, pb;\r
+ UInt32 dicSize;\r
+} CLzmaProps;\r
+\r
+/* LzmaProps_Decode - decodes properties\r
+Returns:\r
+ SZ_OK\r
+ SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+*/\r
+\r
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);\r
+\r
+\r
+/* ---------- LZMA Decoder state ---------- */\r
+\r
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.\r
+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */\r
+\r
+#define LZMA_REQUIRED_INPUT_MAX 20\r
+\r
+typedef struct\r
+{\r
+ CLzmaProps prop;\r
+ CLzmaProb *probs;\r
+ Byte *dic;\r
+ const Byte *buf;\r
+ UInt32 range, code;\r
+ SizeT dicPos;\r
+ SizeT dicBufSize;\r
+ UInt32 processedPos;\r
+ UInt32 checkDicSize;\r
+ unsigned state;\r
+ UInt32 reps[4];\r
+ unsigned remainLen;\r
+ int needFlush;\r
+ int needInitState;\r
+ UInt32 numProbs;\r
+ unsigned tempBufSize;\r
+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];\r
+} CLzmaDec;\r
+\r
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }\r
+\r
+void LzmaDec_Init(CLzmaDec *p);\r
+\r
+/* There are two types of LZMA streams:\r
+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.\r
+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */\r
+\r
+typedef enum\r
+{\r
+ LZMA_FINISH_ANY, /* finish at any point */\r
+ LZMA_FINISH_END /* block must be finished at the end */\r
+} ELzmaFinishMode;\r
+\r
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!\r
+\r
+ You must use LZMA_FINISH_END, when you know that current output buffer\r
+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.\r
+\r
+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,\r
+ and output value of destLen will be less than output buffer size limit.\r
+ You can check status result also.\r
+\r
+ You can use multiple checks to test data integrity after full decompression:\r
+ 1) Check Result and "status" variable.\r
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.\r
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.\r
+ You must use correct finish mode in that case. */\r
+\r
+typedef enum\r
+{\r
+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */\r
+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */\r
+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */\r
+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */\r
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */\r
+} ELzmaStatus;\r
+\r
+/* ELzmaStatus is used only as output value for function call */\r
+\r
+\r
+/* ---------- Interfaces ---------- */\r
+\r
+/* There are 3 levels of interfaces:\r
+ 1) Dictionary Interface\r
+ 2) Buffer Interface\r
+ 3) One Call Interface\r
+ You can select any of these interfaces, but don't mix functions from different\r
+ groups for same object. */\r
+\r
+\r
+/* There are two variants to allocate state for Dictionary Interface:\r
+ 1) LzmaDec_Allocate / LzmaDec_Free\r
+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs\r
+ You can use variant 2, if you set dictionary buffer manually.\r
+ For Buffer Interface you must always use variant 1.\r
+\r
+LzmaDec_Allocate* can return:\r
+ SZ_OK\r
+ SZ_ERROR_MEM - Memory allocation error\r
+ SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+*/\r
+ \r
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);\r
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);\r
+\r
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);\r
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);\r
+\r
+/* ---------- Dictionary Interface ---------- */\r
+\r
+/* You can use it, if you want to eliminate the overhead for data copying from\r
+ dictionary to some other external buffer.\r
+ You must work with CLzmaDec variables directly in this interface.\r
+\r
+ STEPS:\r
+ LzmaDec_Constr()\r
+ LzmaDec_Allocate()\r
+ for (each new stream)\r
+ {\r
+ LzmaDec_Init()\r
+ while (it needs more decompression)\r
+ {\r
+ LzmaDec_DecodeToDic()\r
+ use data from CLzmaDec::dic and update CLzmaDec::dicPos\r
+ }\r
+ }\r
+ LzmaDec_Free()\r
+*/\r
+\r
+/* LzmaDec_DecodeToDic\r
+ \r
+ The decoding to internal dictionary buffer (CLzmaDec::dic).\r
+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!\r
+\r
+finishMode:\r
+ It has meaning only if the decoding reaches output limit (dicLimit).\r
+ LZMA_FINISH_ANY - Decode just dicLimit bytes.\r
+ LZMA_FINISH_END - Stream must be finished after dicLimit.\r
+\r
+Returns:\r
+ SZ_OK\r
+ status:\r
+ LZMA_STATUS_FINISHED_WITH_MARK\r
+ LZMA_STATUS_NOT_FINISHED\r
+ LZMA_STATUS_NEEDS_MORE_INPUT\r
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK\r
+ SZ_ERROR_DATA - Data error\r
+*/\r
+\r
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,\r
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);\r
+\r
+\r
+/* ---------- Buffer Interface ---------- */\r
+\r
+/* It's zlib-like interface.\r
+ See LzmaDec_DecodeToDic description for information about STEPS and return results,\r
+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need\r
+ to work with CLzmaDec variables manually.\r
+\r
+finishMode:\r
+ It has meaning only if the decoding reaches output limit (*destLen).\r
+ LZMA_FINISH_ANY - Decode just destLen bytes.\r
+ LZMA_FINISH_END - Stream must be finished after (*destLen).\r
+*/\r
+\r
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,\r
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);\r
+\r
+\r
+/* ---------- One Call Interface ---------- */\r
+\r
+/* LzmaDecode\r
+\r
+finishMode:\r
+ It has meaning only if the decoding reaches output limit (*destLen).\r
+ LZMA_FINISH_ANY - Decode just destLen bytes.\r
+ LZMA_FINISH_END - Stream must be finished after (*destLen).\r
+\r
+Returns:\r
+ SZ_OK\r
+ status:\r
+ LZMA_STATUS_FINISHED_WITH_MARK\r
+ LZMA_STATUS_NOT_FINISHED\r
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK\r
+ SZ_ERROR_DATA - Data error\r
+ SZ_ERROR_MEM - Memory allocation error\r
+ SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).\r
+*/\r
+\r
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,\r
+ ELzmaStatus *status, ISzAlloc *alloc);\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Types.h\r
+\r
+ Based on LZMA SDK 4.65:\r
+ Types.h -- Basic types\r
+ 2008-11-23 : Igor Pavlov : Public domain\r
+\r
+ Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __7Z_TYPES_H\r
+#define __7Z_TYPES_H\r
+\r
+#ifdef EFIAPI\r
+\r
+#include "UefiLzma.h"\r
+\r
+#else\r
+\r
+#include <stddef.h>\r
+\r
+#ifdef _WIN32\r
+#include <windows.h>\r
+#endif\r
+\r
+#endif\r
+\r
+#define SZ_OK 0\r
+\r
+#define SZ_ERROR_DATA 1\r
+#define SZ_ERROR_MEM 2\r
+#define SZ_ERROR_CRC 3\r
+#define SZ_ERROR_UNSUPPORTED 4\r
+#define SZ_ERROR_PARAM 5\r
+#define SZ_ERROR_INPUT_EOF 6\r
+#define SZ_ERROR_OUTPUT_EOF 7\r
+#define SZ_ERROR_READ 8\r
+#define SZ_ERROR_WRITE 9\r
+#define SZ_ERROR_PROGRESS 10\r
+#define SZ_ERROR_FAIL 11\r
+#define SZ_ERROR_THREAD 12\r
+\r
+#define SZ_ERROR_ARCHIVE 16\r
+#define SZ_ERROR_NO_ARCHIVE 17\r
+\r
+typedef int SRes;\r
+\r
+#ifdef _WIN32\r
+typedef DWORD WRes;\r
+#else\r
+typedef int WRes;\r
+#endif\r
+\r
+#ifndef RINOK\r
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }\r
+#endif\r
+\r
+typedef unsigned char Byte;\r
+typedef short Int16;\r
+typedef unsigned short UInt16;\r
+\r
+#ifdef _LZMA_UINT32_IS_ULONG\r
+typedef long Int32;\r
+typedef unsigned long UInt32;\r
+#else\r
+typedef int Int32;\r
+typedef unsigned int UInt32;\r
+#endif\r
+\r
+#ifdef _SZ_NO_INT_64\r
+\r
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.\r
+ NOTES: Some code will work incorrectly in that case! */\r
+\r
+typedef long Int64;\r
+typedef unsigned long UInt64;\r
+\r
+#else\r
+\r
+#if defined(_MSC_VER) || defined(__BORLANDC__)\r
+typedef __int64 Int64;\r
+typedef unsigned __int64 UInt64;\r
+#else\r
+typedef long long int Int64;\r
+typedef unsigned long long int UInt64;\r
+#endif\r
+\r
+#endif\r
+\r
+#ifdef _LZMA_NO_SYSTEM_SIZE_T\r
+typedef UInt32 SizeT;\r
+#else\r
+typedef size_t SizeT;\r
+#endif\r
+\r
+typedef int Bool;\r
+#define True 1\r
+#define False 0\r
+\r
+\r
+#ifdef _MSC_VER\r
+\r
+#if _MSC_VER >= 1300\r
+#define MY_NO_INLINE __declspec(noinline)\r
+#else\r
+#define MY_NO_INLINE\r
+#endif\r
+\r
+#define MY_CDECL __cdecl\r
+#define MY_STD_CALL __stdcall\r
+#define MY_FAST_CALL MY_NO_INLINE __fastcall\r
+\r
+#else\r
+\r
+#define MY_CDECL\r
+#define MY_STD_CALL\r
+#define MY_FAST_CALL\r
+\r
+#endif\r
+\r
+\r
+/* The following interfaces use first parameter as pointer to structure */\r
+\r
+typedef struct\r
+{\r
+ SRes (*Read)(void *p, void *buf, size_t *size);\r
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.\r
+ (output(*size) < input(*size)) is allowed */\r
+} ISeqInStream;\r
+\r
+/* it can return SZ_ERROR_INPUT_EOF */\r
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);\r
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);\r
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);\r
+\r
+typedef struct\r
+{\r
+ size_t (*Write)(void *p, const void *buf, size_t size);\r
+ /* Returns: result - the number of actually written bytes.\r
+ (result < size) means error */\r
+} ISeqOutStream;\r
+\r
+typedef enum\r
+{\r
+ SZ_SEEK_SET = 0,\r
+ SZ_SEEK_CUR = 1,\r
+ SZ_SEEK_END = 2\r
+} ESzSeek;\r
+\r
+typedef struct\r
+{\r
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */\r
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);\r
+} ISeekInStream;\r
+\r
+typedef struct\r
+{\r
+ SRes (*Look)(void *p, void **buf, size_t *size);\r
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.\r
+ (output(*size) > input(*size)) is not allowed\r
+ (output(*size) < input(*size)) is allowed */\r
+ SRes (*Skip)(void *p, size_t offset);\r
+ /* offset must be <= output(*size) of Look */\r
+\r
+ SRes (*Read)(void *p, void *buf, size_t *size);\r
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */\r
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);\r
+} ILookInStream;\r
+\r
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);\r
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);\r
+\r
+/* reads via ILookInStream::Read */\r
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);\r
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);\r
+\r
+#define LookToRead_BUF_SIZE (1 << 14)\r
+\r
+typedef struct\r
+{\r
+ ILookInStream s;\r
+ ISeekInStream *realStream;\r
+ size_t pos;\r
+ size_t size;\r
+ Byte buf[LookToRead_BUF_SIZE];\r
+} CLookToRead;\r
+\r
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);\r
+void LookToRead_Init(CLookToRead *p);\r
+\r
+typedef struct\r
+{\r
+ ISeqInStream s;\r
+ ILookInStream *realStream;\r
+} CSecToLook;\r
+\r
+void SecToLook_CreateVTable(CSecToLook *p);\r
+\r
+typedef struct\r
+{\r
+ ISeqInStream s;\r
+ ILookInStream *realStream;\r
+} CSecToRead;\r
+\r
+void SecToRead_CreateVTable(CSecToRead *p);\r
+\r
+typedef struct\r
+{\r
+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);\r
+ /* Returns: result. (result != SZ_OK) means break.\r
+ Value (UInt64)(Int64)-1 for size means unknown value. */\r
+} ICompressProgress;\r
+\r
+typedef struct\r
+{\r
+ void *(*Alloc)(void *p, size_t size);\r
+ void (*Free)(void *p, void *address); /* address can be 0 */\r
+} ISzAlloc;\r
+\r
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)\r
+#define IAlloc_Free(p, a) (p)->Free((p), a)\r
+\r
+#endif\r
--- /dev/null
+HISTORY of the LZMA SDK\r
+-----------------------\r
+\r
+4.65 2009-02-03\r
+-------------------------\r
+- Some minor fixes\r
+\r
+\r
+4.63 2008-12-31\r
+-------------------------\r
+- Some minor fixes\r
+\r
+\r
+4.61 beta 2008-11-23\r
+-------------------------\r
+- The bug in ANSI-C LZMA Decoder was fixed:\r
+ If encoded stream was corrupted, decoder could access memory \r
+ outside of allocated range.\r
+- Some changes in ANSI-C 7z Decoder interfaces.\r
+- LZMA SDK is placed in the public domain.\r
+\r
+\r
+4.60 beta 2008-08-19\r
+-------------------------\r
+- Some minor fixes.\r
+\r
+\r
+4.59 beta 2008-08-13\r
+-------------------------\r
+- The bug was fixed:\r
+ LZMA Encoder in fast compression mode could access memory outside of \r
+ allocated range in some rare cases.\r
+\r
+\r
+4.58 beta 2008-05-05\r
+-------------------------\r
+- ANSI-C LZMA Decoder was rewritten for speed optimizations.\r
+- ANSI-C LZMA Encoder was included to LZMA SDK.\r
+- C++ LZMA code now is just wrapper over ANSI-C code.\r
+\r
+\r
+4.57 2007-12-12\r
+-------------------------\r
+- Speed optimizations in Ñ++ LZMA Decoder. \r
+- Small changes for more compatibility with some C/C++ compilers.\r
+\r
+\r
+4.49 beta 2007-07-05\r
+-------------------------\r
+- .7z ANSI-C Decoder:\r
+ - now it supports BCJ and BCJ2 filters\r
+ - now it supports files larger than 4 GB.\r
+ - now it supports "Last Write Time" field for files.\r
+- C++ code for .7z archives compressing/decompressing from 7-zip \r
+ was included to LZMA SDK.\r
+ \r
+\r
+4.43 2006-06-04\r
+-------------------------\r
+- Small changes for more compatibility with some C/C++ compilers.\r
+ \r
+\r
+4.42 2006-05-15\r
+-------------------------\r
+- Small changes in .h files in ANSI-C version.\r
+ \r
+\r
+4.39 beta 2006-04-14\r
+-------------------------\r
+- The bug in versions 4.33b:4.38b was fixed:\r
+ C++ version of LZMA encoder could not correctly compress \r
+ files larger than 2 GB with HC4 match finder (-mfhc4).\r
+ \r
+\r
+4.37 beta 2005-04-06\r
+-------------------------\r
+- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined. \r
+\r
+\r
+4.35 beta 2005-03-02\r
+-------------------------\r
+- The bug was fixed in C++ version of LZMA Decoder:\r
+ If encoded stream was corrupted, decoder could access memory \r
+ outside of allocated range.\r
+\r
+\r
+4.34 beta 2006-02-27\r
+-------------------------\r
+- Compressing speed and memory requirements for compressing were increased\r
+- LZMA now can use only these match finders: HC4, BT2, BT3, BT4\r
+\r
+\r
+4.32 2005-12-09\r
+-------------------------\r
+- Java version of LZMA SDK was included\r
+\r
+\r
+4.30 2005-11-20\r
+-------------------------\r
+- Compression ratio was improved in -a2 mode\r
+- Speed optimizations for compressing in -a2 mode\r
+- -fb switch now supports values up to 273\r
+- The bug in 7z_C (7zIn.c) was fixed:\r
+ It used Alloc/Free functions from different memory pools.\r
+ So if program used two memory pools, it worked incorrectly.\r
+- 7z_C: .7z format supporting was improved\r
+- LZMA# SDK (C#.NET version) was included\r
+\r
+\r
+4.27 (Updated) 2005-09-21\r
+-------------------------\r
+- Some GUIDs/interfaces in C++ were changed.\r
+ IStream.h:\r
+ ISequentialInStream::Read now works as old ReadPart\r
+ ISequentialOutStream::Write now works as old WritePart\r
+\r
+\r
+4.27 2005-08-07\r
+-------------------------\r
+- The bug in LzmaDecodeSize.c was fixed:\r
+ if _LZMA_IN_CB and _LZMA_OUT_READ were defined,\r
+ decompressing worked incorrectly.\r
+\r
+\r
+4.26 2005-08-05\r
+-------------------------\r
+- Fixes in 7z_C code and LzmaTest.c:\r
+ previous versions could work incorrectly,\r
+ if malloc(0) returns 0\r
+\r
+\r
+4.23 2005-06-29\r
+-------------------------\r
+- Small fixes in C++ code\r
+\r
+\r
+4.22 2005-06-10\r
+-------------------------\r
+- Small fixes\r
+\r
+\r
+4.21 2005-06-08\r
+-------------------------\r
+- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed\r
+- New additional version of ANSI-C LZMA Decoder with zlib-like interface:\r
+ - LzmaStateDecode.h\r
+ - LzmaStateDecode.c\r
+ - LzmaStateTest.c\r
+- ANSI-C LZMA Decoder now can decompress files larger than 4 GB\r
+\r
+\r
+4.17 2005-04-18\r
+-------------------------\r
+- New example for RAM->RAM compressing/decompressing: \r
+ LZMA + BCJ (filter for x86 code):\r
+ - LzmaRam.h\r
+ - LzmaRam.cpp\r
+ - LzmaRamDecode.h\r
+ - LzmaRamDecode.c\r
+ - -f86 switch for lzma.exe\r
+\r
+\r
+4.16 2005-03-29\r
+-------------------------\r
+- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder): \r
+ If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,\r
+ decoder could access memory outside of allocated range.\r
+- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).\r
+ Old version of LZMA Decoder now is in file LzmaDecodeSize.c. \r
+ LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c\r
+- Small speed optimization in LZMA C++ code\r
+- filter for SPARC's code was added\r
+- Simplified version of .7z ANSI-C Decoder was included\r
+\r
+\r
+4.06 2004-09-05\r
+-------------------------\r
+- The bug in v4.05 was fixed:\r
+ LZMA-Encoder didn't release output stream in some cases.\r
+\r
+\r
+4.05 2004-08-25\r
+-------------------------\r
+- Source code of filters for x86, IA-64, ARM, ARM-Thumb \r
+ and PowerPC code was included to SDK\r
+- Some internal minor changes\r
+\r
+\r
+4.04 2004-07-28\r
+-------------------------\r
+- More compatibility with some C++ compilers\r
+\r
+\r
+4.03 2004-06-18\r
+-------------------------\r
+- "Benchmark" command was added. It measures compressing \r
+ and decompressing speed and shows rating values. \r
+ Also it checks hardware errors.\r
+\r
+\r
+4.02 2004-06-10\r
+-------------------------\r
+- C++ LZMA Encoder/Decoder code now is more portable\r
+ and it can be compiled by GCC on Linux.\r
+\r
+\r
+4.01 2004-02-15\r
+-------------------------\r
+- Some detection of data corruption was enabled.\r
+ LzmaDecode.c / RangeDecoderReadByte\r
+ .....\r
+ {\r
+ rd->ExtraBytes = 1;\r
+ return 0xFF;\r
+ }\r
+\r
+\r
+4.00 2004-02-13\r
+-------------------------\r
+- Original version of LZMA SDK\r
+\r
+\r
+\r
+HISTORY of the LZMA\r
+-------------------\r
+ 2001-2008: Improvements to LZMA compressing/decompressing code, \r
+ keeping compatibility with original LZMA format\r
+ 1996-2001: Development of LZMA compression format\r
+\r
+ Some milestones:\r
+\r
+ 2001-08-30: LZMA compression was added to 7-Zip\r
+ 1999-01-02: First version of 7-Zip was released\r
+ \r
+\r
+End of document\r
--- /dev/null
+LZMA SDK 4.65\r
+-------------\r
+\r
+LZMA SDK provides the documentation, samples, header files, libraries, \r
+and tools you need to develop applications that use LZMA compression.\r
+\r
+LZMA is default and general compression method of 7z format\r
+in 7-Zip compression program (www.7-zip.org). LZMA provides high \r
+compression ratio and very fast decompression.\r
+\r
+LZMA is an improved version of famous LZ77 compression algorithm. \r
+It was improved in way of maximum increasing of compression ratio,\r
+keeping high decompression speed and low memory requirements for \r
+decompressing.\r
+\r
+\r
+\r
+LICENSE\r
+-------\r
+\r
+LZMA SDK is written and placed in the public domain by Igor Pavlov.\r
+\r
+\r
+LZMA SDK Contents\r
+-----------------\r
+\r
+LZMA SDK includes:\r
+\r
+ - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing\r
+ - Compiled file->file LZMA compressing/decompressing program for Windows system\r
+\r
+\r
+UNIX/Linux version \r
+------------------\r
+To compile C++ version of file->file LZMA encoding, go to directory\r
+C++/7zip/Compress/LZMA_Alone \r
+and call make to recompile it:\r
+ make -f makefile.gcc clean all\r
+\r
+In some UNIX/Linux versions you must compile LZMA with static libraries.\r
+To compile with static libraries, you can use \r
+LIB = -lm -static\r
+\r
+\r
+Files\r
+---------------------\r
+lzma.txt - LZMA SDK description (this file)\r
+7zFormat.txt - 7z Format description\r
+7zC.txt - 7z ANSI-C Decoder description\r
+methods.txt - Compression method IDs for .7z\r
+lzma.exe - Compiled file->file LZMA encoder/decoder for Windows\r
+history.txt - history of the LZMA SDK\r
+\r
+\r
+Source code structure\r
+---------------------\r
+\r
+C/ - C files\r
+ 7zCrc*.* - CRC code\r
+ Alloc.* - Memory allocation functions\r
+ Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code\r
+ LzFind.* - Match finder for LZ (LZMA) encoders \r
+ LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding\r
+ LzHash.h - Additional file for LZ match finder\r
+ LzmaDec.* - LZMA decoding\r
+ LzmaEnc.* - LZMA encoding\r
+ LzmaLib.* - LZMA Library for DLL calling\r
+ Types.h - Basic types for another .c files\r
+ Threads.* - The code for multithreading.\r
+\r
+ LzmaLib - LZMA Library (.DLL for Windows)\r
+ \r
+ LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).\r
+\r
+ Archive - files related to archiving\r
+ 7z - 7z ANSI-C Decoder\r
+\r
+CPP/ -- CPP files\r
+\r
+ Common - common files for C++ projects\r
+ Windows - common files for Windows related code\r
+\r
+ 7zip - files related to 7-Zip Project\r
+\r
+ Common - common files for 7-Zip\r
+\r
+ Compress - files related to compression/decompression\r
+\r
+ Copy - Copy coder\r
+ RangeCoder - Range Coder (special code of compression/decompression)\r
+ LZMA - LZMA compression/decompression on C++\r
+ LZMA_Alone - file->file LZMA compression/decompression\r
+ Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code\r
+\r
+ Archive - files related to archiving\r
+\r
+ Common - common files for archive handling\r
+ 7z - 7z C++ Encoder/Decoder\r
+\r
+ Bundles - Modules that are bundles of other modules\r
+ \r
+ Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2\r
+ Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2\r
+ Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.\r
+\r
+ UI - User Interface files\r
+ \r
+ Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll\r
+ Common - Common UI files\r
+ Console - Code for console archiver\r
+\r
+\r
+\r
+CS/ - C# files\r
+ 7zip\r
+ Common - some common files for 7-Zip\r
+ Compress - files related to compression/decompression\r
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm\r
+ LZMA - LZMA compression/decompression\r
+ LzmaAlone - file->file LZMA compression/decompression\r
+ RangeCoder - Range Coder (special code of compression/decompression)\r
+\r
+Java/ - Java files\r
+ SevenZip\r
+ Compression - files related to compression/decompression\r
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm\r
+ LZMA - LZMA compression/decompression\r
+ RangeCoder - Range Coder (special code of compression/decompression)\r
+\r
+\r
+C/C++ source code of LZMA SDK is part of 7-Zip project.\r
+7-Zip source code can be downloaded from 7-Zip's SourceForge page:\r
+\r
+ http://sourceforge.net/projects/sevenzip/\r
+\r
+\r
+\r
+LZMA features\r
+-------------\r
+ - Variable dictionary size (up to 1 GB)\r
+ - Estimated compressing speed: about 2 MB/s on 2 GHz CPU\r
+ - Estimated decompressing speed: \r
+ - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64\r
+ - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC\r
+ - Small memory requirements for decompressing (16 KB + DictionarySize)\r
+ - Small code size for decompressing: 5-8 KB\r
+\r
+LZMA decoder uses only integer operations and can be \r
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).\r
+\r
+Some critical operations that affect the speed of LZMA decompression:\r
+ 1) 32*16 bit integer multiply\r
+ 2) Misspredicted branches (penalty mostly depends from pipeline length)\r
+ 3) 32-bit shift and arithmetic operations\r
+\r
+The speed of LZMA decompressing mostly depends from CPU speed.\r
+Memory speed has no big meaning. But if your CPU has small data cache, \r
+overall weight of memory speed will slightly increase.\r
+\r
+\r
+How To Use\r
+----------\r
+\r
+Using LZMA encoder/decoder executable\r
+--------------------------------------\r
+\r
+Usage: LZMA <e|d> inputFile outputFile [<switches>...]\r
+\r
+ e: encode file\r
+\r
+ d: decode file\r
+\r
+ b: Benchmark. There are two tests: compressing and decompressing \r
+ with LZMA method. Benchmark shows rating in MIPS (million \r
+ instructions per second). Rating value is calculated from \r
+ measured speed and it is normalized with Intel's Core 2 results.\r
+ Also Benchmark checks possible hardware errors (RAM \r
+ errors in most cases). Benchmark uses these settings:\r
+ (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter. \r
+ Also you can change the number of iterations. Example for 30 iterations:\r
+ LZMA b 30\r
+ Default number of iterations is 10.\r
+\r
+<Switches>\r
+ \r
+\r
+ -a{N}: set compression mode 0 = fast, 1 = normal\r
+ default: 1 (normal)\r
+\r
+ d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)\r
+ The maximum value for dictionary size is 1 GB = 2^30 bytes.\r
+ Dictionary size is calculated as DictionarySize = 2^N bytes. \r
+ For decompressing file compressed by LZMA method with dictionary \r
+ size D = 2^N you need about D bytes of memory (RAM).\r
+\r
+ -fb{N}: set number of fast bytes - [5, 273], default: 128\r
+ Usually big number gives a little bit better compression ratio \r
+ and slower compression process.\r
+\r
+ -lc{N}: set number of literal context bits - [0, 8], default: 3\r
+ Sometimes lc=4 gives gain for big files.\r
+\r
+ -lp{N}: set number of literal pos bits - [0, 4], default: 0\r
+ lp switch is intended for periodical data when period is \r
+ equal 2^N. For example, for 32-bit (4 bytes) \r
+ periodical data you can use lp=2. Often it's better to set lc0, \r
+ if you change lp switch.\r
+\r
+ -pb{N}: set number of pos bits - [0, 4], default: 2\r
+ pb switch is intended for periodical data \r
+ when period is equal 2^N.\r
+\r
+ -mf{MF_ID}: set Match Finder. Default: bt4. \r
+ Algorithms from hc* group doesn't provide good compression \r
+ ratio, but they often works pretty fast in combination with \r
+ fast mode (-a0).\r
+\r
+ Memory requirements depend from dictionary size \r
+ (parameter "d" in table below). \r
+\r
+ MF_ID Memory Description\r
+\r
+ bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.\r
+ bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.\r
+ bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.\r
+ hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.\r
+\r
+ -eos: write End Of Stream marker. By default LZMA doesn't write \r
+ eos marker, since LZMA decoder knows uncompressed size \r
+ stored in .lzma file header.\r
+\r
+ -si: Read data from stdin (it will write End Of Stream marker).\r
+ -so: Write data to stdout\r
+\r
+\r
+Examples:\r
+\r
+1) LZMA e file.bin file.lzma -d16 -lc0 \r
+\r
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K) \r
+and 0 literal context bits. -lc0 allows to reduce memory requirements \r
+for decompression.\r
+\r
+\r
+2) LZMA e file.bin file.lzma -lc0 -lp2\r
+\r
+compresses file.bin to file.lzma with settings suitable \r
+for 32-bit periodical data (for example, ARM or MIPS code).\r
+\r
+3) LZMA d file.lzma file.bin\r
+\r
+decompresses file.lzma to file.bin.\r
+\r
+\r
+Compression ratio hints\r
+-----------------------\r
+\r
+Recommendations\r
+---------------\r
+\r
+To increase the compression ratio for LZMA compressing it's desirable \r
+to have aligned data (if it's possible) and also it's desirable to locate\r
+data in such order, where code is grouped in one place and data is \r
+grouped in other place (it's better than such mixing: code, data, code,\r
+data, ...).\r
+\r
+\r
+Filters\r
+-------\r
+You can increase the compression ratio for some data types, using\r
+special filters before compressing. For example, it's possible to \r
+increase the compression ratio on 5-10% for code for those CPU ISAs: \r
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.\r
+\r
+You can find C source code of such filters in C/Bra*.* files\r
+\r
+You can check the compression ratio gain of these filters with such \r
+7-Zip commands (example for ARM code):\r
+No filter:\r
+ 7z a a1.7z a.bin -m0=lzma\r
+\r
+With filter for little-endian ARM code:\r
+ 7z a a2.7z a.bin -m0=arm -m1=lzma \r
+\r
+It works in such manner:\r
+Compressing = Filter_encoding + LZMA_encoding\r
+Decompressing = LZMA_decoding + Filter_decoding\r
+\r
+Compressing and decompressing speed of such filters is very high,\r
+so it will not increase decompressing time too much.\r
+Moreover, it reduces decompression time for LZMA_decoding, \r
+since compression ratio with filtering is higher.\r
+\r
+These filters convert CALL (calling procedure) instructions \r
+from relative offsets to absolute addresses, so such data becomes more \r
+compressible.\r
+\r
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.\r
+\r
+\r
+LZMA compressed file format\r
+---------------------------\r
+Offset Size Description\r
+ 0 1 Special LZMA properties (lc,lp, pb in encoded form)\r
+ 1 4 Dictionary size (little endian)\r
+ 5 8 Uncompressed size (little endian). -1 means unknown size\r
+ 13 Compressed data\r
+\r
+\r
+ANSI-C LZMA Decoder\r
+~~~~~~~~~~~~~~~~~~~\r
+\r
+Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.\r
+If you want to use old interfaces you can download previous version of LZMA SDK\r
+from sourceforge.net site.\r
+\r
+To use ANSI-C LZMA Decoder you need the following files:\r
+1) LzmaDec.h + LzmaDec.c + Types.h\r
+LzmaUtil/LzmaUtil.c is example application that uses these files.\r
+\r
+\r
+Memory requirements for LZMA decoding\r
+-------------------------------------\r
+\r
+Stack usage of LZMA decoding function for local variables is not \r
+larger than 200-400 bytes.\r
+\r
+LZMA Decoder uses dictionary buffer and internal state structure.\r
+Internal state structure consumes\r
+ state_size = (4 + (1.5 << (lc + lp))) KB\r
+by default (lc=3, lp=0), state_size = 16 KB.\r
+\r
+\r
+How To decompress data\r
+----------------------\r
+\r
+LZMA Decoder (ANSI-C version) now supports 2 interfaces:\r
+1) Single-call Decompressing\r
+2) Multi-call State Decompressing (zlib-like interface)\r
+\r
+You must use external allocator:\r
+Example:\r
+void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }\r
+void SzFree(void *p, void *address) { p = p; free(address); }\r
+ISzAlloc alloc = { SzAlloc, SzFree };\r
+\r
+You can use p = p; operator to disable compiler warnings.\r
+\r
+\r
+Single-call Decompressing\r
+-------------------------\r
+When to use: RAM->RAM decompressing\r
+Compile files: LzmaDec.h + LzmaDec.c + Types.h\r
+Compile defines: no defines\r
+Memory Requirements:\r
+ - Input buffer: compressed size\r
+ - Output buffer: uncompressed size\r
+ - LZMA Internal Structures: state_size (16 KB for default settings) \r
+\r
+Interface:\r
+ int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,\r
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, \r
+ ELzmaStatus *status, ISzAlloc *alloc);\r
+ In: \r
+ dest - output data\r
+ destLen - output data size\r
+ src - input data\r
+ srcLen - input data size\r
+ propData - LZMA properties (5 bytes)\r
+ propSize - size of propData buffer (5 bytes)\r
+ finishMode - It has meaning only if the decoding reaches output limit (*destLen).\r
+ LZMA_FINISH_ANY - Decode just destLen bytes.\r
+ LZMA_FINISH_END - Stream must be finished after (*destLen).\r
+ You can use LZMA_FINISH_END, when you know that \r
+ current output buffer covers last bytes of stream. \r
+ alloc - Memory allocator.\r
+\r
+ Out: \r
+ destLen - processed output size \r
+ srcLen - processed input size \r
+\r
+ Output:\r
+ SZ_OK\r
+ status:\r
+ LZMA_STATUS_FINISHED_WITH_MARK\r
+ LZMA_STATUS_NOT_FINISHED \r
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK\r
+ SZ_ERROR_DATA - Data error\r
+ SZ_ERROR_MEM - Memory allocation error\r
+ SZ_ERROR_UNSUPPORTED - Unsupported properties\r
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).\r
+\r
+ If LZMA decoder sees end_marker before reaching output limit, it returns OK result,\r
+ and output value of destLen will be less than output buffer size limit.\r
+\r
+ You can use multiple checks to test data integrity after full decompression:\r
+ 1) Check Result and "status" variable.\r
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.\r
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. \r
+ You must use correct finish mode in that case. */ \r
+\r
+\r
+Multi-call State Decompressing (zlib-like interface)\r
+----------------------------------------------------\r
+\r
+When to use: file->file decompressing \r
+Compile files: LzmaDec.h + LzmaDec.c + Types.h\r
+\r
+Memory Requirements:\r
+ - Buffer for input stream: any size (for example, 16 KB)\r
+ - Buffer for output stream: any size (for example, 16 KB)\r
+ - LZMA Internal Structures: state_size (16 KB for default settings) \r
+ - LZMA dictionary (dictionary size is encoded in LZMA properties header)\r
+\r
+1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:\r
+ unsigned char header[LZMA_PROPS_SIZE + 8];\r
+ ReadFile(inFile, header, sizeof(header)\r
+\r
+2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties\r
+\r
+ CLzmaDec state;\r
+ LzmaDec_Constr(&state);\r
+ res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);\r
+ if (res != SZ_OK)\r
+ return res;\r
+\r
+3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop\r
+\r
+ LzmaDec_Init(&state);\r
+ for (;;)\r
+ {\r
+ ... \r
+ int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, \r
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);\r
+ ...\r
+ }\r
+\r
+\r
+4) Free all allocated structures\r
+ LzmaDec_Free(&state, &g_Alloc);\r
+\r
+For full code example, look at C/LzmaUtil/LzmaUtil.c code.\r
+\r
+\r
+How To compress data\r
+--------------------\r
+\r
+Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +\r
+LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h\r
+\r
+Memory Requirements:\r
+ - (dictSize * 11.5 + 6 MB) + state_size\r
+\r
+Lzma Encoder can use two memory allocators:\r
+1) alloc - for small arrays.\r
+2) allocBig - for big arrays.\r
+\r
+For example, you can use Large RAM Pages (2 MB) in allocBig allocator for \r
+better compression speed. Note that Windows has bad implementation for \r
+Large RAM Pages. \r
+It's OK to use same allocator for alloc and allocBig.\r
+\r
+\r
+Single-call Compression with callbacks\r
+--------------------------------------\r
+\r
+Check C/LzmaUtil/LzmaUtil.c as example, \r
+\r
+When to use: file->file decompressing \r
+\r
+1) you must implement callback structures for interfaces:\r
+ISeqInStream\r
+ISeqOutStream\r
+ICompressProgress\r
+ISzAlloc\r
+\r
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }\r
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }\r
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };\r
+\r
+ CFileSeqInStream inStream;\r
+ CFileSeqOutStream outStream;\r
+\r
+ inStream.funcTable.Read = MyRead;\r
+ inStream.file = inFile;\r
+ outStream.funcTable.Write = MyWrite;\r
+ outStream.file = outFile;\r
+\r
+\r
+2) Create CLzmaEncHandle object;\r
+\r
+ CLzmaEncHandle enc;\r
+\r
+ enc = LzmaEnc_Create(&g_Alloc);\r
+ if (enc == 0)\r
+ return SZ_ERROR_MEM;\r
+\r
+\r
+3) initialize CLzmaEncProps properties;\r
+\r
+ LzmaEncProps_Init(&props);\r
+\r
+ Then you can change some properties in that structure.\r
+\r
+4) Send LZMA properties to LZMA Encoder\r
+\r
+ res = LzmaEnc_SetProps(enc, &props);\r
+\r
+5) Write encoded properties to header\r
+\r
+ Byte header[LZMA_PROPS_SIZE + 8];\r
+ size_t headerSize = LZMA_PROPS_SIZE;\r
+ UInt64 fileSize;\r
+ int i;\r
+\r
+ res = LzmaEnc_WriteProperties(enc, header, &headerSize);\r
+ fileSize = MyGetFileLength(inFile);\r
+ for (i = 0; i < 8; i++)\r
+ header[headerSize++] = (Byte)(fileSize >> (8 * i));\r
+ MyWriteFileAndCheck(outFile, header, headerSize)\r
+\r
+6) Call encoding function:\r
+ res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, \r
+ NULL, &g_Alloc, &g_Alloc);\r
+\r
+7) Destroy LZMA Encoder Object\r
+ LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);\r
+\r
+\r
+If callback function return some error code, LzmaEnc_Encode also returns that code.\r
+\r
+\r
+Single-call RAM->RAM Compression\r
+--------------------------------\r
+\r
+Single-call RAM->RAM Compression is similar to Compression with callbacks,\r
+but you provide pointers to buffers instead of pointers to stream callbacks:\r
+\r
+HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,\r
+ CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, \r
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);\r
+\r
+Return code:\r
+ SZ_OK - OK\r
+ SZ_ERROR_MEM - Memory allocation error \r
+ SZ_ERROR_PARAM - Incorrect paramater\r
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow\r
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)\r
+\r
+\r
+\r
+LZMA Defines\r
+------------\r
+\r
+_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.\r
+\r
+_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for \r
+ some structures will be doubled in that case.\r
+\r
+_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.\r
+\r
+_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.\r
+\r
+\r
+C++ LZMA Encoder/Decoder \r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+C++ LZMA code use COM-like interfaces. So if you want to use it, \r
+you can study basics of COM/OLE.\r
+C++ LZMA code is just wrapper over ANSI-C code.\r
+\r
+\r
+C++ Notes\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),\r
+you must check that you correctly work with "new" operator.\r
+7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.\r
+So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:\r
+operator new(size_t size)\r
+{\r
+ void *p = ::malloc(size);\r
+ if (p == 0)\r
+ throw CNewException();\r
+ return p;\r
+}\r
+If you use MSCV that throws exception for "new" operator, you can compile without \r
+"NewHandler.cpp". So standard exception will be used. Actually some code of \r
+7-Zip catches any exception in internal code and converts it to HRESULT code.\r
+So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.\r
+\r
+---\r
+\r
+http://www.7-zip.org\r
+http://www.7-zip.org/sdk.html\r
+http://www.7-zip.org/support.html\r
--- /dev/null
+/** @file\r
+ LZMA UEFI header file\r
+\r
+ Allows LZMA code to build under UEFI (edk2) build environment\r
+\r
+ Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __UEFILZMA_H__\r
+#define __UEFILZMA_H__\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#ifdef _WIN32\r
+#undef _WIN32\r
+#endif\r
+\r
+#ifndef _SIZE_T_DEFINED\r
+#if !defined(_WIN64) || defined(__GNUC__)\r
+typedef unsigned int size_t;\r
+#endif\r
+#endif\r
+\r
+#ifdef _WIN64\r
+#undef _WIN64\r
+#endif\r
+\r
+#ifndef _PTRDIFF_T_DEFINED\r
+typedef int ptrdiff_t;\r
+#endif\r
+\r
+#define memcpy CopyMem\r
+#define memmove CopyMem\r
+\r
+#define _LZMA_SIZE_OPT\r
+\r
+#endif // __UEFILZMA_H__\r
+\r
--- /dev/null
+/** @file\r
+ Debug Library based on report status code library.\r
+\r
+ Note that if the debug message length is larger than the maximum allowable\r
+ record length, then the debug message will be ignored directly.\r
+\r
+ Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Guid/StatusCodeDataTypeId.h>\r
+#include <Guid/StatusCodeDataTypeDebug.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugPrintErrorLevelLib.h>\r
+\r
+/**\r
+ Prints a debug message to the debug output device if the specified error level is enabled.\r
+\r
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function \r
+ GetDebugPrintErrorLevel (), then print the message specified by Format and the \r
+ associated variable argument list to the debug output device.\r
+\r
+ If Format is NULL, then ASSERT().\r
+\r
+ If the length of the message string specificed by Format is larger than the maximum allowable\r
+ record length, then directly return and not print it.\r
+\r
+ @param ErrorLevel The error level of the debug message.\r
+ @param Format Format string for the debug message to print.\r
+ @param ... Variable argument list whose contents are accessed \r
+ based on the format string specified by Format.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugPrint (\r
+ IN UINTN ErrorLevel,\r
+ IN CONST CHAR8 *Format,\r
+ ...\r
+ )\r
+{\r
+ UINT64 Buffer[(EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)) + 1];\r
+ EFI_DEBUG_INFO *DebugInfo;\r
+ UINTN TotalSize;\r
+ VA_LIST VaListMarker;\r
+ BASE_LIST BaseListMarker;\r
+ CHAR8 *FormatString;\r
+ BOOLEAN Long;\r
+\r
+ //\r
+ // If Format is NULL, then ASSERT().\r
+ //\r
+ ASSERT (Format != NULL);\r
+\r
+ //\r
+ // Check driver Debug Level value and global debug level\r
+ //\r
+ if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Compute the total size of the record.\r
+ // Note that the passing-in format string and variable parameters will be constructed to \r
+ // the following layout:\r
+ //\r
+ // Buffer->|------------------------|\r
+ // | Padding | 4 bytes\r
+ // DebugInfo->|------------------------|\r
+ // | EFI_DEBUG_INFO | sizeof(EFI_DEBUG_INFO)\r
+ // BaseListMarker->|------------------------|\r
+ // | ... |\r
+ // | variable arguments | 12 * sizeof (UINT64)\r
+ // | ... |\r
+ // |------------------------|\r
+ // | Format String |\r
+ // |------------------------|<- (UINT8 *)Buffer + sizeof(Buffer)\r
+ //\r
+ TotalSize = 4 + sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrSize (Format);\r
+\r
+ //\r
+ // If the TotalSize is larger than the maximum record size, then return\r
+ //\r
+ if (TotalSize > sizeof (Buffer)) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Fill in EFI_DEBUG_INFO\r
+ //\r
+ // Here we skip the first 4 bytes of Buffer, because we must ensure BaseListMarker is\r
+ // 64-bit aligned, otherwise retrieving 64-bit parameter from BaseListMarker will cause\r
+ // exception on IPF. Buffer starts at 64-bit aligned address, so skipping 4 types (sizeof(EFI_DEBUG_INFO))\r
+ // just makes address of BaseListMarker, which follows DebugInfo, 64-bit aligned.\r
+ //\r
+ DebugInfo = (EFI_DEBUG_INFO *)(Buffer) + 1;\r
+ DebugInfo->ErrorLevel = (UINT32)ErrorLevel;\r
+ BaseListMarker = (BASE_LIST)(DebugInfo + 1);\r
+ FormatString = (CHAR8 *)((UINT64 *)(DebugInfo + 1) + 12);\r
+\r
+ //\r
+ // Copy the Format string into the record\r
+ //\r
+ AsciiStrCpy (FormatString, Format);\r
+\r
+ //\r
+ // The first 12 * sizeof (UINT64) bytes following EFI_DEBUG_INFO are for variable arguments\r
+ // of format in DEBUG string, which is followed by the DEBUG format string.\r
+ // Here we will process the variable arguments and pack them in this area.\r
+ //\r
+ VA_START (VaListMarker, Format);\r
+ for (; *Format != '\0'; Format++) {\r
+ //\r
+ // Only format with prefix % is processed.\r
+ //\r
+ if (*Format != '%') {\r
+ continue;\r
+ }\r
+ Long = FALSE;\r
+ //\r
+ // Parse Flags and Width\r
+ //\r
+ for (Format++; TRUE; Format++) {\r
+ if (*Format == '.' || *Format == '-' || *Format == '+' || *Format == ' ') {\r
+ //\r
+ // These characters in format field are omitted.\r
+ //\r
+ continue;\r
+ }\r
+ if (*Format >= '0' && *Format <= '9') {\r
+ //\r
+ // These characters in format field are omitted.\r
+ //\r
+ continue;\r
+ }\r
+ if (*Format == 'L' || *Format == 'l') {\r
+ //\r
+ // 'L" or "l" in format field means the number being printed is a UINT64\r
+ //\r
+ Long = TRUE;\r
+ continue;\r
+ }\r
+ if (*Format == '*') {\r
+ //\r
+ // '*' in format field means the precision of the field is specified by\r
+ // a UINTN argument in the argument list.\r
+ //\r
+ BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
+ continue;\r
+ }\r
+ if (*Format == '\0') {\r
+ //\r
+ // Make no output if Format string terminates unexpectedly when\r
+ // looking up for flag, width, precision and type. \r
+ //\r
+ Format--;\r
+ }\r
+ //\r
+ // When valid argument type detected or format string terminates unexpectedly,\r
+ // the inner loop is done.\r
+ //\r
+ break;\r
+ }\r
+ \r
+ //\r
+ // Pack variable arguments into the storage area following EFI_DEBUG_INFO.\r
+ //\r
+ if ((*Format == 'p') && (sizeof (VOID *) > 4)) {\r
+ Long = TRUE;\r
+ }\r
+ if (*Format == 'p' || *Format == 'X' || *Format == 'x' || *Format == 'd') {\r
+ if (Long) {\r
+ BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);\r
+ } else {\r
+ BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int);\r
+ }\r
+ } else if (*Format == 's' || *Format == 'S' || *Format == 'a' || *Format == 'g' || *Format == 't') {\r
+ BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *);\r
+ } else if (*Format == 'c') {\r
+ BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
+ } else if (*Format == 'r') {\r
+ BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS);\r
+ }\r
+\r
+ //\r
+ // If the converted BASE_LIST is larger than the 12 * sizeof (UINT64) allocated bytes, then ASSERT()\r
+ // This indicates that the DEBUG() macro is passing in more argument than can be handled by \r
+ // the EFI_DEBUG_INFO record\r
+ //\r
+ ASSERT ((CHAR8 *)BaseListMarker <= FormatString);\r
+\r
+ //\r
+ // If the converted BASE_LIST is larger than the 12 * sizeof (UINT64) allocated bytes, then return\r
+ //\r
+ if ((CHAR8 *)BaseListMarker > FormatString) {\r
+ VA_END (VaListMarker);\r
+ return;\r
+ }\r
+ }\r
+ VA_END (VaListMarker);\r
+\r
+ //\r
+ // Send the DebugInfo record\r
+ //\r
+ REPORT_STATUS_CODE_EX (\r
+ EFI_DEBUG_CODE,\r
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),\r
+ 0,\r
+ NULL,\r
+ &gEfiStatusCodeDataTypeDebugGuid,\r
+ DebugInfo,\r
+ TotalSize\r
+ );\r
+}\r
+\r
+/**\r
+ Prints an assert message containing a filename, line number, and description. \r
+ This may be followed by a breakpoint or a dead loop.\r
+\r
+ Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"\r
+ to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of \r
+ PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if \r
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then \r
+ CpuDeadLoop() is called. If neither of these bits are set, then this function \r
+ returns immediately after the message is printed to the debug output device.\r
+ DebugAssert() must actively prevent recursion. If DebugAssert() is called while\r
+ processing another DebugAssert(), then DebugAssert() must return immediately.\r
+\r
+ If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.\r
+ If Description is NULL, then a <Description> string of "(NULL) Description" is printed.\r
+\r
+ @param FileName Pointer to the name of the source file that generated the assert condition.\r
+ @param LineNumber The line number in the source file that generated the assert condition\r
+ @param Description Pointer to the description of the assert condition.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugAssert (\r
+ IN CONST CHAR8 *FileName,\r
+ IN UINTN LineNumber,\r
+ IN CONST CHAR8 *Description\r
+ )\r
+{\r
+ UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof(UINT64)];\r
+ EFI_DEBUG_ASSERT_DATA *AssertData;\r
+ UINTN HeaderSize;\r
+ UINTN TotalSize;\r
+ CHAR8 *Temp;\r
+ UINTN FileNameSize;\r
+ UINTN DescriptionSize;\r
+\r
+ //\r
+ // Get string size\r
+ //\r
+ HeaderSize = sizeof (EFI_DEBUG_ASSERT_DATA);\r
+ FileNameSize = AsciiStrSize (FileName);\r
+ DescriptionSize = AsciiStrSize (Description);\r
+\r
+ //\r
+ // Make sure it will all fit in the passed in buffer.\r
+ //\r
+ if (HeaderSize + FileNameSize + DescriptionSize > sizeof (Buffer)) {\r
+ //\r
+ // FileName + Description is too long to be filled into buffer. \r
+ //\r
+ if (HeaderSize + FileNameSize < sizeof (Buffer)) {\r
+ //\r
+ // Description has enough buffer to be truncated. \r
+ //\r
+ DescriptionSize = sizeof (Buffer) - HeaderSize - FileNameSize;\r
+ } else {\r
+ //\r
+ // FileName is too long to be filled into buffer.\r
+ // FileName will be truncated. Reserved one byte for Description NULL terminator.\r
+ //\r
+ DescriptionSize = 1;\r
+ FileNameSize = sizeof (Buffer) - HeaderSize - DescriptionSize;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Fill in EFI_DEBUG_ASSERT_DATA\r
+ //\r
+ AssertData = (EFI_DEBUG_ASSERT_DATA *)Buffer;\r
+ AssertData->LineNumber = (UINT32)LineNumber;\r
+ TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA);\r
+\r
+ //\r
+ // Copy Ascii FileName including NULL terminator.\r
+ //\r
+ Temp = CopyMem (AssertData + 1, FileName, FileNameSize);\r
+ Temp[FileNameSize - 1] = 0;\r
+ TotalSize += FileNameSize;\r
+\r
+ //\r
+ // Copy Ascii Description include NULL terminator.\r
+ //\r
+ Temp = CopyMem (Temp + FileNameSize, Description, DescriptionSize);\r
+ Temp[DescriptionSize - 1] = 0;\r
+ TotalSize += DescriptionSize;\r
+\r
+ REPORT_STATUS_CODE_EX (\r
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),\r
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),\r
+ 0,\r
+ NULL,\r
+ NULL,\r
+ AssertData,\r
+ TotalSize\r
+ );\r
+\r
+ //\r
+ // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings\r
+ //\r
+ if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {\r
+ CpuBreakpoint ();\r
+ } else if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {\r
+ CpuDeadLoop ();\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.\r
+\r
+ This function fills Length bytes of Buffer with the value specified by \r
+ PcdDebugClearMemoryValue, and returns Buffer.\r
+\r
+ If Buffer is NULL, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
+\r
+ @param Buffer Pointer to the target buffer to be filled with PcdDebugClearMemoryValue.\r
+ @param Length Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. \r
+\r
+ @return Buffer Pointer to the target buffer filled with PcdDebugClearMemoryValue.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DebugClearMemory (\r
+ OUT VOID *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ ASSERT (Buffer != NULL);\r
+\r
+ return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue));\r
+}\r
+\r
+\r
+/**\r
+ Returns TRUE if ASSERT() macros are enabled.\r
+\r
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of \r
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.\r
+\r
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.\r
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugAssertEnabled (\r
+ VOID\r
+ )\r
+{\r
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);\r
+}\r
+\r
+\r
+/** \r
+ Returns TRUE if DEBUG() macros are enabled.\r
+\r
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of \r
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.\r
+\r
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.\r
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugPrintEnabled (\r
+ VOID\r
+ )\r
+{\r
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);\r
+}\r
+\r
+\r
+/** \r
+ Returns TRUE if DEBUG_CODE() macros are enabled.\r
+\r
+ This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of \r
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.\r
+\r
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.\r
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugCodeEnabled (\r
+ VOID\r
+ )\r
+{\r
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);\r
+}\r
+\r
+\r
+/** \r
+ Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.\r
+\r
+ This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of \r
+ PcdDebugProperyMask is set. Otherwise FALSE is returned.\r
+\r
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.\r
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugClearMemoryEnabled (\r
+ VOID\r
+ )\r
+{\r
+ return (BOOLEAN) ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);\r
+}\r
+\r
+/**\r
+ Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.\r
+\r
+ This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.\r
+\r
+ @retval TRUE Current ErrorLevel is supported.\r
+ @retval FALSE Current ErrorLevel is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugPrintLevelEnabled (\r
+ IN CONST UINTN ErrorLevel\r
+ )\r
+{\r
+ return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);\r
+}\r
--- /dev/null
+## @file\r
+# Debug Library based on report status code library\r
+#\r
+# Debug Library for PEIMs and DXE drivers that sends debug messages to ReportStatusCode\r
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = PeiDxeDebugLibReportStatusCode\r
+ MODULE_UNI_FILE = PeiDxeDebugLibReportStatusCode.uni\r
+ FILE_GUID = bda39d3a-451b-4350-8266-81ab10fa0523\r
+ MODULE_TYPE = PEIM\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = DebugLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE PEIM SEC PEI_CORE UEFI_APPLICATION UEFI_DRIVER\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+ DebugLib.c\r
+\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ \r
+[LibraryClasses]\r
+ PcdLib\r
+ ReportStatusCodeLib\r
+ BaseMemoryLib\r
+ BaseLib\r
+ DebugPrintErrorLevelLib\r
+\r
+[Pcd]\r
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES\r
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES\r
+ gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES\r
+\r
+[Guids]\r
+ gEfiStatusCodeDataTypeDebugGuid ## SOMETIMES_CONSUMES ## GUID\r
+\r
MdeModulePkg/Library/PeiDebugPrintHobLib/PeiDebugPrintHobLib.inf\r
MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf\r
MdeModulePkg/Library/PlatformHookLibSerialPortPpi/PlatformHookLibSerialPortPpi.inf\r
+ MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf\r
+ MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf\r
\r
MdeModulePkg/Universal/CapsulePei/CapsulePei.inf\r
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf\r
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf\r
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf\r
MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf\r
+ MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaArchCustomDecompressLib.inf\r
MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf\r
MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf\r
MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf\r