Add LzmaCustomDecompressLib based on the LZMA SDK 4.65 which was
placed in the public domain on 2009-02-03. The LZMA SDK 4.65 was released at the http://www.7-zip.org/sdk.html website. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8227 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
33d487d463
commit
306bf4e22a
30
IntelFrameworkModulePkg/Include/Guid/LzmaDecompress.h
Normal file
30
IntelFrameworkModulePkg/Include/Guid/LzmaDecompress.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2007, Intel Corporation
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
LzmaDecompress.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Lzma Custom decompress algorithm Guid definitions
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef __LZMA_DECOMPRESS_GUID_H__
|
||||||
|
#define __LZMA_DECOMPRESS_GUID_H__
|
||||||
|
|
||||||
|
#define LZMA_CUSTOM_DECOMPRESS_GUID \
|
||||||
|
{ 0xEE4E5898, 0x3914, 0x4259, { 0x9D, 0x6E, 0xDC, 0x7B, 0xD7, 0x94, 0x03, 0xCF } }
|
||||||
|
|
||||||
|
extern GUID gLzmaCustomDecompressGuid;
|
||||||
|
|
||||||
|
#endif
|
@ -51,6 +51,9 @@
|
|||||||
## Include/Guid/CustomDecompress.h
|
## Include/Guid/CustomDecompress.h
|
||||||
gTianoCustomDecompressGuid = { 0xA31280AD, 0x481E, 0x41B6, { 0x95, 0xE8, 0x12, 0x7F, 0x4C, 0x98, 0x47, 0x79 }}
|
gTianoCustomDecompressGuid = { 0xA31280AD, 0x481E, 0x41B6, { 0x95, 0xE8, 0x12, 0x7F, 0x4C, 0x98, 0x47, 0x79 }}
|
||||||
|
|
||||||
|
## Include/Guid/LzmaDecompress.h
|
||||||
|
gLzmaCustomDecompressGuid = { 0xEE4E5898, 0x3914, 0x4259, { 0x9D, 0x6E, 0xDC, 0x7B, 0xD7, 0x94, 0x03, 0xCF }}
|
||||||
|
|
||||||
## Guid specify the default BMP logo file.
|
## Guid specify the default BMP logo file.
|
||||||
## Include/Guid/Logo.h
|
## Include/Guid/Logo.h
|
||||||
gEfiDefaultBmpLogoGuid = { 0x7BB28B99, 0x61BB, 0x11D5, { 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
gEfiDefaultBmpLogoGuid = { 0x7BB28B99, 0x61BB, 0x11D5, { 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
||||||
|
@ -201,6 +201,8 @@
|
|||||||
|
|
||||||
[Components.common]
|
[Components.common]
|
||||||
IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
|
IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
|
||||||
|
IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/Pei/LzmaCustomDecompressLib.inf
|
||||||
|
IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/Dxe/LzmaCustomDecompressLib.inf
|
||||||
IntelFrameworkModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
|
IntelFrameworkModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
|
||||||
IntelFrameworkModulePkg/Library/PciIncompatibleDeviceSupportLib/PciIncompatibleDeviceSupportLib.inf
|
IntelFrameworkModulePkg/Library/PciIncompatibleDeviceSupportLib/PciIncompatibleDeviceSupportLib.inf
|
||||||
IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
|
IntelFrameworkModulePkg/Library/PeiS3Lib/PeiS3Lib.inf
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
#/** @file
|
||||||
|
# LZMA GUIDed Section Extraction Protocol Library
|
||||||
|
#
|
||||||
|
# Uefi Decompression library instance
|
||||||
|
# Copyright (c) 2006, 2009, Intel Corporation.
|
||||||
|
#
|
||||||
|
# All rights reserved. This program and the accompanying materials
|
||||||
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
# http://opensource.org/licenses/bsd-license.php
|
||||||
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = LzmaDxeDecompressLib
|
||||||
|
FILE_GUID = 35194660-7421-44ad-9636-e44885f092d1
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = BASE
|
||||||
|
EDK_RELEASE_VERSION = 0x00020000
|
||||||
|
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||||
|
|
||||||
|
CONSTRUCTOR = LzmaDecompressLibConstructor
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
LzmaDxeMemory.c
|
||||||
|
../LzmaDecompress.c
|
||||||
|
../Sdk/C/LzFind.c
|
||||||
|
../Sdk/C/LzmaDec.c
|
||||||
|
../GuidedSectionExtraction.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gLzmaCustomDecompressGuid
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
DebugLib
|
||||||
|
BaseMemoryLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
ExtractGuidedSectionLib
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
/** @file
|
||||||
|
LZMA Memory Allocation for DXE
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include "Sdk/C/Types.h"
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID *
|
||||||
|
SzAlloc(
|
||||||
|
void *p,
|
||||||
|
size_t size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
void *np;
|
||||||
|
p = p;
|
||||||
|
np = AllocatePool(size);
|
||||||
|
return np;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SzFree(
|
||||||
|
void *p,
|
||||||
|
void *address
|
||||||
|
)
|
||||||
|
{
|
||||||
|
p = p;
|
||||||
|
if (address != NULL) {
|
||||||
|
FreePool(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
@ -0,0 +1,177 @@
|
|||||||
|
/** @file
|
||||||
|
LZMA Decompress GUIDed Section Extraction Library
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/ExtractGuidedSectionLib.h>
|
||||||
|
#include <Pi/PiFirmwareFile.h>
|
||||||
|
#include <Guid/LzmaDecompress.h>
|
||||||
|
|
||||||
|
#include "LzmaDecompress.h"
|
||||||
|
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaGuidedSectionGetCompressedLocation (
|
||||||
|
IN CONST VOID *InputSection,
|
||||||
|
OUT VOID **LmzaCompressedData,
|
||||||
|
OUT UINT32 *LmzaCompressedDataSize OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!CompareGuid (
|
||||||
|
&gLzmaCustomDecompressGuid,
|
||||||
|
&(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
|
||||||
|
return RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve the size and attribute of the input section data.
|
||||||
|
//
|
||||||
|
*LmzaCompressedData =
|
||||||
|
(VOID*) (
|
||||||
|
(UINT8 *) InputSection +
|
||||||
|
((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset
|
||||||
|
);
|
||||||
|
if (LmzaCompressedDataSize != NULL) {
|
||||||
|
*LmzaCompressedDataSize =
|
||||||
|
(UINT32)(
|
||||||
|
(
|
||||||
|
(*(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size)) &
|
||||||
|
0x00ffffff
|
||||||
|
) -
|
||||||
|
((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
The implementation of 'GetInfo' for Guided Section
|
||||||
|
Extraction of LZMA compression.
|
||||||
|
|
||||||
|
@param InputSection Buffer containing the input GUIDed section to be processed.
|
||||||
|
@param OutputBufferSize The size of OutputBuffer.
|
||||||
|
@param ScratchBufferSize The size of ScratchBuffer.
|
||||||
|
@param SectionAttribute The attribute of the input guided section.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS The size of destination buffer and the size of scratch buffer are successull retrieved.
|
||||||
|
@retval RETURN_INVALID_PARAMETER The source data is corrupted, or
|
||||||
|
The GUID in InputSection does not match this instance guid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaGuidedSectionGetInfo (
|
||||||
|
IN CONST VOID *InputSection,
|
||||||
|
OUT UINT32 *OutputBufferSize,
|
||||||
|
OUT UINT32 *ScratchBufferSize,
|
||||||
|
OUT UINT16 *SectionAttribute
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
VOID *LzmaInput;
|
||||||
|
UINT32 LzmaInputSize;
|
||||||
|
|
||||||
|
Status = LzmaGuidedSectionGetCompressedLocation(
|
||||||
|
InputSection,
|
||||||
|
&LzmaInput,
|
||||||
|
&LzmaInputSize
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;
|
||||||
|
|
||||||
|
return LzmaUefiDecompressGetInfo (
|
||||||
|
LzmaInput,
|
||||||
|
LzmaInputSize,
|
||||||
|
OutputBufferSize,
|
||||||
|
ScratchBufferSize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
The implementation of Guided Section Extraction
|
||||||
|
for LZMA compression.
|
||||||
|
|
||||||
|
@param InputSection Buffer containing the input GUIDed section to be processed.
|
||||||
|
@param OutputBuffer OutputBuffer to point to the start of the section's contents.
|
||||||
|
if guided data is not prcessed. Otherwise,
|
||||||
|
OutputBuffer to contain the output data, which is allocated by the caller.
|
||||||
|
@param ScratchBuffer A pointer to a caller-allocated buffer for function internal use.
|
||||||
|
@param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the
|
||||||
|
authentication status of the output buffer.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS Decompression is successfull
|
||||||
|
@retval RETURN_INVALID_PARAMETER The source data is corrupted, or
|
||||||
|
The GUID in InputSection does not match this instance guid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaGuidedSectionExtraction (
|
||||||
|
IN CONST VOID *InputSection,
|
||||||
|
OUT VOID **OutputBuffer,
|
||||||
|
IN VOID *ScratchBuffer, OPTIONAL
|
||||||
|
OUT UINT32 *AuthenticationStatus
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
VOID *LzmaInput;
|
||||||
|
|
||||||
|
Status = LzmaGuidedSectionGetCompressedLocation(
|
||||||
|
InputSection,
|
||||||
|
&LzmaInput,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Authentication is set to Zero, which may be ignored.
|
||||||
|
//
|
||||||
|
*AuthenticationStatus = 0;
|
||||||
|
|
||||||
|
return LzmaUefiDecompress (
|
||||||
|
LzmaInput,
|
||||||
|
*OutputBuffer,
|
||||||
|
ScratchBuffer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Register LzmaDecompress handler.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS Register successfully.
|
||||||
|
@retval RETURN_OUT_OF_RESOURCES No enough memory to store this handler.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaDecompressLibConstructor (
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ExtractGuidedSectionRegisterHandlers (
|
||||||
|
&gLzmaCustomDecompressGuid,
|
||||||
|
LzmaGuidedSectionGetInfo,
|
||||||
|
LzmaGuidedSectionExtraction
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
LzmaCustomDecompressLib is based on the LZMA SDK 4.65.
|
||||||
|
LZMA SDK 4.65 was placed in the public domain on
|
||||||
|
2009-02-03. It was released on the
|
||||||
|
http://www.7-zip.org/sdk.html website.
|
@ -0,0 +1,144 @@
|
|||||||
|
/** @file
|
||||||
|
LZMA Decompress routines for edk2
|
||||||
|
|
||||||
|
Portions based on LZMA SDK 4.65:
|
||||||
|
LzmaUtil.c -- Test application for LZMA compression
|
||||||
|
2008-11-23 : Igor Pavlov : Public domain
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/UefiDecompressLib.h>
|
||||||
|
#include <Library/ExtractGuidedSectionLib.h>
|
||||||
|
#include <Guid/LzmaDecompress.h>
|
||||||
|
|
||||||
|
#include "Sdk/C/Types.h"
|
||||||
|
#include "Sdk/C/7zVersion.h"
|
||||||
|
#include "Sdk/C/LzmaDec.h"
|
||||||
|
|
||||||
|
extern ISzAlloc g_Alloc;
|
||||||
|
|
||||||
|
#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
UINT64
|
||||||
|
GetDecodedSizeOfBuf(
|
||||||
|
UINT8 *encodedData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 DecodedSize;
|
||||||
|
INTN Index;
|
||||||
|
|
||||||
|
/* Parse header */
|
||||||
|
DecodedSize = 0;
|
||||||
|
for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--)
|
||||||
|
DecodedSize = LShiftU64(DecodedSize, 8) + encodedData[Index];
|
||||||
|
|
||||||
|
return DecodedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LZMA functions and data as defined in local LzmaDecompress.h
|
||||||
|
//
|
||||||
|
|
||||||
|
STATIC CONST VOID *mSourceLastUsedWithGetInfo;
|
||||||
|
STATIC UINT32 mSizeOfLastSource;
|
||||||
|
STATIC UINT32 mDecompressedSizeForLastSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
|
||||||
|
|
||||||
|
@param Source The source buffer containing the compressed data.
|
||||||
|
@param SourceSize The size of source buffer
|
||||||
|
@param DestinationSize The size of destination buffer.
|
||||||
|
@param ScratchSize The size of scratch buffer.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
|
||||||
|
@retval RETURN_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaUefiDecompressGetInfo (
|
||||||
|
IN CONST VOID *Source,
|
||||||
|
IN UINT32 SourceSize,
|
||||||
|
OUT UINT32 *DestinationSize,
|
||||||
|
OUT UINT32 *ScratchSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UInt64 DecodedSize;
|
||||||
|
|
||||||
|
ASSERT(SourceSize >= LZMA_HEADER_SIZE);
|
||||||
|
|
||||||
|
DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
|
||||||
|
|
||||||
|
mSourceLastUsedWithGetInfo = Source;
|
||||||
|
mSizeOfLastSource = SourceSize;
|
||||||
|
mDecompressedSizeForLastSource = (UInt32)DecodedSize;
|
||||||
|
*DestinationSize = mDecompressedSizeForLastSource;
|
||||||
|
*ScratchSize = 0x10;
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
|
||||||
|
|
||||||
|
@param Source - The source buffer containing the compressed data.
|
||||||
|
@param Destination - The destination buffer to store the decompressed data
|
||||||
|
@param Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS - Decompression is successfull
|
||||||
|
@retval RETURN_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaUefiDecompress (
|
||||||
|
IN CONST VOID *Source,
|
||||||
|
IN OUT VOID *Destination,
|
||||||
|
IN OUT VOID *Scratch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SRes lzmaResult;
|
||||||
|
ELzmaStatus status;
|
||||||
|
SizeT decodedBufSize;
|
||||||
|
SizeT encodedDataSize;
|
||||||
|
|
||||||
|
if (Source != mSourceLastUsedWithGetInfo) {
|
||||||
|
return RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedBufSize = (SizeT)mDecompressedSizeForLastSource;
|
||||||
|
encodedDataSize = (SizeT)(mSizeOfLastSource - LZMA_HEADER_SIZE);
|
||||||
|
|
||||||
|
lzmaResult = LzmaDecode(
|
||||||
|
Destination,
|
||||||
|
&decodedBufSize,
|
||||||
|
(Byte*)((UINT8*)Source + LZMA_HEADER_SIZE),
|
||||||
|
&encodedDataSize,
|
||||||
|
Source,
|
||||||
|
LZMA_PROPS_SIZE,
|
||||||
|
LZMA_FINISH_END,
|
||||||
|
&status,
|
||||||
|
&g_Alloc
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lzmaResult == SZ_OK) {
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
/** @file
|
||||||
|
LZMA Decompress Library header file
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __LZMADECOMPRESS_H__
|
||||||
|
#define __LZMADECOMPRESS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
|
||||||
|
|
||||||
|
@param Source The source buffer containing the compressed data.
|
||||||
|
@param SourceSize The size of source buffer
|
||||||
|
@param DestinationSize The size of destination buffer.
|
||||||
|
@param ScratchSize The size of scratch buffer.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
|
||||||
|
@retval RETURN_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaUefiDecompressGetInfo (
|
||||||
|
IN CONST VOID *Source,
|
||||||
|
IN UINT32 SourceSize,
|
||||||
|
OUT UINT32 *DestinationSize,
|
||||||
|
OUT UINT32 *ScratchSize
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
|
||||||
|
|
||||||
|
@param Source - The source buffer containing the compressed data.
|
||||||
|
@param Destination - The destination buffer to store the decompressed data
|
||||||
|
@param Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||||
|
|
||||||
|
@retval RETURN_SUCCESS - Decompression is successfull
|
||||||
|
@retval RETURN_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
**/
|
||||||
|
RETURN_STATUS
|
||||||
|
EFIAPI
|
||||||
|
LzmaUefiDecompress (
|
||||||
|
IN CONST VOID *Source,
|
||||||
|
IN OUT VOID *Destination,
|
||||||
|
IN OUT VOID *Scratch
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // __LZMADECOMPRESS_H__
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
#/** @file
|
||||||
|
# LZMA GUIDed Section Extraction Protocol Library
|
||||||
|
#
|
||||||
|
# Uefi Decompression library instance
|
||||||
|
# Copyright (c) 2006, 2009, Intel Corporation.
|
||||||
|
#
|
||||||
|
# All rights reserved. This program and the accompanying materials
|
||||||
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
# http://opensource.org/licenses/bsd-license.php
|
||||||
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = LzmaPeiDecompressLib
|
||||||
|
FILE_GUID = 6725ae86-6ed1-43bd-aeec-0517c0749d70
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = BASE
|
||||||
|
EDK_RELEASE_VERSION = 0x00020000
|
||||||
|
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||||
|
|
||||||
|
CONSTRUCTOR = LzmaDecompressLibConstructor
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
LzmaPeiMemory.c
|
||||||
|
../LzmaDecompress.c
|
||||||
|
../Sdk/C/LzFind.c
|
||||||
|
../Sdk/C/LzmaDec.c
|
||||||
|
../GuidedSectionExtraction.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gLzmaCustomDecompressGuid
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseLib
|
||||||
|
DebugLib
|
||||||
|
BaseMemoryLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
ExtractGuidedSectionLib
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
/** @file
|
||||||
|
LZMA Memory Allocation for PEI
|
||||||
|
|
||||||
|
AllocatePool does not work for large blocks during PEI, so we must
|
||||||
|
use AllocatePages.
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include "Sdk/C/Types.h"
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID *
|
||||||
|
SzAlloc(
|
||||||
|
void *p,
|
||||||
|
size_t size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
void *np;
|
||||||
|
p = p;
|
||||||
|
if (size > EFI_PAGE_SIZE) {
|
||||||
|
np = AllocatePages(EFI_SIZE_TO_PAGES(size));
|
||||||
|
} else {
|
||||||
|
np = AllocatePool(size);
|
||||||
|
}
|
||||||
|
return np;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SzFree(
|
||||||
|
void *p,
|
||||||
|
void *address
|
||||||
|
)
|
||||||
|
{
|
||||||
|
p = p;
|
||||||
|
if (address != NULL) {
|
||||||
|
FreePool(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
#define MY_VER_MAJOR 4
|
||||||
|
#define MY_VER_MINOR 65
|
||||||
|
#define MY_VER_BUILD 0
|
||||||
|
#define MY_VERSION "4.65"
|
||||||
|
#define MY_DATE "2009-02-03"
|
||||||
|
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||||
|
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
@ -0,0 +1,69 @@
|
|||||||
|
/* CpuArch.h
|
||||||
|
2008-08-05
|
||||||
|
Igor Pavlov
|
||||||
|
Public domain */
|
||||||
|
|
||||||
|
#ifndef __CPUARCH_H
|
||||||
|
#define __CPUARCH_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
LITTLE_ENDIAN_UNALIGN means:
|
||||||
|
1) CPU is LITTLE_ENDIAN
|
||||||
|
2) it's allowed to make unaligned memory accesses
|
||||||
|
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
||||||
|
about these properties of platform.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
|
||||||
|
#define LITTLE_ENDIAN_UNALIGN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LITTLE_ENDIAN_UNALIGN
|
||||||
|
|
||||||
|
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||||
|
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||||
|
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||||
|
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||||
|
|
||||||
|
#define GetUi32(p) ( \
|
||||||
|
((const Byte *)(p))[0] | \
|
||||||
|
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||||
|
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[3] << 24))
|
||||||
|
|
||||||
|
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||||
|
|
||||||
|
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||||
|
((Byte *)(p))[0] = (Byte)_x_; \
|
||||||
|
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||||
|
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||||
|
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||||
|
|
||||||
|
#pragma intrinsic(_byteswap_ulong)
|
||||||
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GetBe32(p) ( \
|
||||||
|
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||||
|
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||||
|
((const Byte *)(p))[3] )
|
||||||
|
|
||||||
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,770 @@
|
|||||||
|
/** @file
|
||||||
|
LzFind.c
|
||||||
|
|
||||||
|
Based on LZMA SDK 4.65:
|
||||||
|
LzFind.c -- Match finder for LZ algorithms
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain
|
||||||
|
|
||||||
|
Copyright (c) 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef EFIAPI
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#endif // !EFIAPI
|
||||||
|
|
||||||
|
#include "LzFind.h"
|
||||||
|
#include "LzHash.h"
|
||||||
|
|
||||||
|
#define kEmptyHashValue 0
|
||||||
|
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||||
|
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||||
|
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||||
|
#define kMaxHistorySize ((UInt32)3 << 30)
|
||||||
|
|
||||||
|
#define kStartMaxLen 3
|
||||||
|
|
||||||
|
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
if (!p->directInput)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->bufferBase);
|
||||||
|
p->bufferBase = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
||||||
|
|
||||||
|
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
||||||
|
if (p->directInput)
|
||||||
|
{
|
||||||
|
p->blockSize = blockSize;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
||||||
|
{
|
||||||
|
LzInWindow_Free(p, alloc);
|
||||||
|
p->blockSize = blockSize;
|
||||||
|
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
||||||
|
}
|
||||||
|
return (p->bufferBase != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||||
|
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||||
|
|
||||||
|
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||||
|
|
||||||
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||||
|
{
|
||||||
|
p->posLimit -= subValue;
|
||||||
|
p->pos -= subValue;
|
||||||
|
p->streamPos -= subValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||||
|
return;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||||
|
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
p->result = p->stream->Read(p->stream, dest, &size);
|
||||||
|
if (p->result != SZ_OK)
|
||||||
|
return;
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
p->streamEndWasReached = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p->streamPos += (UInt32)size;
|
||||||
|
if (p->streamPos - p->pos > p->keepSizeAfter)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
memmove(p->bufferBase,
|
||||||
|
p->buffer - p->keepSizeBefore,
|
||||||
|
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
||||||
|
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
/* if (p->streamEndWasReached) return 0; */
|
||||||
|
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->streamEndWasReached)
|
||||||
|
return;
|
||||||
|
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (MatchFinder_NeedMove(p))
|
||||||
|
MatchFinder_MoveBlock(p);
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
p->cutValue = 32;
|
||||||
|
p->btMode = 1;
|
||||||
|
p->numHashBytes = 4;
|
||||||
|
/* p->skipModeBits = 0; */
|
||||||
|
p->directInput = 0;
|
||||||
|
p->bigHash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define kCrcPoly 0xEDB88320
|
||||||
|
|
||||||
|
void MatchFinder_Construct(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
p->bufferBase = 0;
|
||||||
|
p->directInput = 0;
|
||||||
|
p->hash = 0;
|
||||||
|
MatchFinder_SetDefaultSettings(p);
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
UInt32 r = i;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
|
p->crc[i] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
alloc->Free(alloc, p->hash);
|
||||||
|
p->hash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
|
LzInWindow_Free(p, alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||||
|
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||||
|
return 0;
|
||||||
|
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
|
ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
UInt32 sizeReserv;
|
||||||
|
if (historySize > kMaxHistorySize)
|
||||||
|
{
|
||||||
|
MatchFinder_Free(p, alloc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sizeReserv = historySize >> 1;
|
||||||
|
if (historySize > ((UInt32)2 << 30))
|
||||||
|
sizeReserv = historySize >> 2;
|
||||||
|
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||||
|
|
||||||
|
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||||
|
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||||
|
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||||
|
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||||
|
{
|
||||||
|
UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
|
||||||
|
UInt32 hs;
|
||||||
|
p->matchMaxLen = matchMaxLen;
|
||||||
|
{
|
||||||
|
p->fixedHashSize = 0;
|
||||||
|
if (p->numHashBytes == 2)
|
||||||
|
hs = (1 << 16) - 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hs = historySize - 1;
|
||||||
|
hs |= (hs >> 1);
|
||||||
|
hs |= (hs >> 2);
|
||||||
|
hs |= (hs >> 4);
|
||||||
|
hs |= (hs >> 8);
|
||||||
|
hs >>= 1;
|
||||||
|
/* hs >>= p->skipModeBits; */
|
||||||
|
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||||
|
if (hs > (1 << 24))
|
||||||
|
{
|
||||||
|
if (p->numHashBytes == 3)
|
||||||
|
hs = (1 << 24) - 1;
|
||||||
|
else
|
||||||
|
hs >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->hashMask = hs;
|
||||||
|
hs++;
|
||||||
|
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
|
||||||
|
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
|
||||||
|
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
|
||||||
|
hs += p->fixedHashSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
||||||
|
UInt32 newSize;
|
||||||
|
p->historySize = historySize;
|
||||||
|
p->hashSizeSum = hs;
|
||||||
|
p->cyclicBufferSize = newCyclicBufferSize;
|
||||||
|
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
||||||
|
newSize = p->hashSizeSum + p->numSons;
|
||||||
|
if (p->hash != 0 && prevSize == newSize)
|
||||||
|
return 1;
|
||||||
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
|
p->hash = AllocRefs(newSize, alloc);
|
||||||
|
if (p->hash != 0)
|
||||||
|
{
|
||||||
|
p->son = p->hash + p->hashSizeSum;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MatchFinder_Free(p, alloc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||||
|
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||||
|
if (limit2 < limit)
|
||||||
|
limit = limit2;
|
||||||
|
limit2 = p->streamPos - p->pos;
|
||||||
|
if (limit2 <= p->keepSizeAfter)
|
||||||
|
{
|
||||||
|
if (limit2 > 0)
|
||||||
|
limit2 = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
limit2 -= p->keepSizeAfter;
|
||||||
|
if (limit2 < limit)
|
||||||
|
limit = limit2;
|
||||||
|
{
|
||||||
|
UInt32 lenLimit = p->streamPos - p->pos;
|
||||||
|
if (lenLimit > p->matchMaxLen)
|
||||||
|
lenLimit = p->matchMaxLen;
|
||||||
|
p->lenLimit = lenLimit;
|
||||||
|
}
|
||||||
|
p->posLimit = p->pos + limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Init(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < p->hashSizeSum; i++)
|
||||||
|
p->hash[i] = kEmptyHashValue;
|
||||||
|
p->cyclicBufferPos = 0;
|
||||||
|
p->buffer = p->bufferBase;
|
||||||
|
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||||
|
p->result = SZ_OK;
|
||||||
|
p->streamEndWasReached = 0;
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
MatchFinder_SetLimits(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||||
|
{
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
UInt32 value = items[i];
|
||||||
|
if (value <= subValue)
|
||||||
|
value = kEmptyHashValue;
|
||||||
|
else
|
||||||
|
value -= subValue;
|
||||||
|
items[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
UInt32 subValue = MatchFinder_GetSubValue(p);
|
||||||
|
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
|
||||||
|
MatchFinder_ReduceOffsets(p, subValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
if (p->pos == kMaxValForNormalize)
|
||||||
|
MatchFinder_Normalize(p);
|
||||||
|
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
|
||||||
|
MatchFinder_CheckAndMoveAndRead(p);
|
||||||
|
if (p->cyclicBufferPos == p->cyclicBufferSize)
|
||||||
|
p->cyclicBufferPos = 0;
|
||||||
|
MatchFinder_SetLimits(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||||
|
UInt32 *distances, UInt32 maxLen)
|
||||||
|
{
|
||||||
|
son[_cyclicBufferPos] = curMatch;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
return distances;
|
||||||
|
{
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
||||||
|
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
|
||||||
|
{
|
||||||
|
UInt32 len = 0;
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
if (maxLen < len)
|
||||||
|
{
|
||||||
|
*distances++ = maxLen = len;
|
||||||
|
*distances++ = delta - 1;
|
||||||
|
if (len == lenLimit)
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||||
|
UInt32 *distances, UInt32 maxLen)
|
||||||
|
{
|
||||||
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
|
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||||
|
UInt32 len0 = 0, len1 = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
{
|
||||||
|
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||||
|
if (pb[len] == cur[len])
|
||||||
|
{
|
||||||
|
if (++len != lenLimit && pb[len] == cur[len])
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
if (maxLen < len)
|
||||||
|
{
|
||||||
|
*distances++ = maxLen = len;
|
||||||
|
*distances++ = delta - 1;
|
||||||
|
if (len == lenLimit)
|
||||||
|
{
|
||||||
|
*ptr1 = pair[0];
|
||||||
|
*ptr0 = pair[1];
|
||||||
|
return distances;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pb[len] < cur[len])
|
||||||
|
{
|
||||||
|
*ptr1 = curMatch;
|
||||||
|
ptr1 = pair + 1;
|
||||||
|
curMatch = *ptr1;
|
||||||
|
len1 = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr0 = curMatch;
|
||||||
|
ptr0 = pair;
|
||||||
|
curMatch = *ptr0;
|
||||||
|
len0 = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||||
|
{
|
||||||
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
|
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||||
|
UInt32 len0 = 0, len1 = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 delta = pos - curMatch;
|
||||||
|
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||||
|
{
|
||||||
|
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||||
|
const Byte *pb = cur - delta;
|
||||||
|
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||||
|
if (pb[len] == cur[len])
|
||||||
|
{
|
||||||
|
while (++len != lenLimit)
|
||||||
|
if (pb[len] != cur[len])
|
||||||
|
break;
|
||||||
|
{
|
||||||
|
if (len == lenLimit)
|
||||||
|
{
|
||||||
|
*ptr1 = pair[0];
|
||||||
|
*ptr0 = pair[1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pb[len] < cur[len])
|
||||||
|
{
|
||||||
|
*ptr1 = curMatch;
|
||||||
|
ptr1 = pair + 1;
|
||||||
|
curMatch = *ptr1;
|
||||||
|
len1 = len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr0 = curMatch;
|
||||||
|
ptr0 = pair;
|
||||||
|
curMatch = *ptr0;
|
||||||
|
len0 = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MOVE_POS \
|
||||||
|
++p->cyclicBufferPos; \
|
||||||
|
p->buffer++; \
|
||||||
|
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
||||||
|
|
||||||
|
#define MOVE_POS_RET MOVE_POS return offset;
|
||||||
|
|
||||||
|
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||||
|
|
||||||
|
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
||||||
|
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
|
||||||
|
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||||
|
cur = p->buffer;
|
||||||
|
|
||||||
|
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
||||||
|
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
|
||||||
|
|
||||||
|
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
||||||
|
|
||||||
|
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
||||||
|
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
|
||||||
|
distances + offset, maxLen) - distances); MOVE_POS_RET;
|
||||||
|
|
||||||
|
#define SKIP_FOOTER \
|
||||||
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||||
|
|
||||||
|
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 offset;
|
||||||
|
GET_MATCHES_HEADER(2)
|
||||||
|
HASH2_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
offset = 0;
|
||||||
|
GET_MATCHES_FOOTER(offset, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 offset;
|
||||||
|
GET_MATCHES_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
offset = 0;
|
||||||
|
GET_MATCHES_FOOTER(offset, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, delta2, maxLen, offset;
|
||||||
|
GET_MATCHES_HEADER(3)
|
||||||
|
|
||||||
|
HASH3_CALC;
|
||||||
|
|
||||||
|
delta2 = p->pos - p->hash[hash2Value];
|
||||||
|
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||||
|
|
||||||
|
p->hash[hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
|
||||||
|
maxLen = 2;
|
||||||
|
offset = 0;
|
||||||
|
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||||
|
{
|
||||||
|
for (; maxLen != lenLimit; maxLen++)
|
||||||
|
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||||
|
break;
|
||||||
|
distances[0] = maxLen;
|
||||||
|
distances[1] = delta2 - 1;
|
||||||
|
offset = 2;
|
||||||
|
if (maxLen == lenLimit)
|
||||||
|
{
|
||||||
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
|
MOVE_POS_RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||||
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
|
HASH4_CALC;
|
||||||
|
|
||||||
|
delta2 = p->pos - p->hash[ hash2Value];
|
||||||
|
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] =
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
maxLen = 1;
|
||||||
|
offset = 0;
|
||||||
|
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||||
|
{
|
||||||
|
distances[0] = maxLen = 2;
|
||||||
|
distances[1] = delta2 - 1;
|
||||||
|
offset = 2;
|
||||||
|
}
|
||||||
|
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||||
|
{
|
||||||
|
maxLen = 3;
|
||||||
|
distances[offset + 1] = delta3 - 1;
|
||||||
|
offset += 2;
|
||||||
|
delta2 = delta3;
|
||||||
|
}
|
||||||
|
if (offset != 0)
|
||||||
|
{
|
||||||
|
for (; maxLen != lenLimit; maxLen++)
|
||||||
|
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||||
|
break;
|
||||||
|
distances[offset - 2] = maxLen;
|
||||||
|
if (maxLen == lenLimit)
|
||||||
|
{
|
||||||
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
|
MOVE_POS_RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxLen < 3)
|
||||||
|
maxLen = 3;
|
||||||
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||||
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
|
HASH4_CALC;
|
||||||
|
|
||||||
|
delta2 = p->pos - p->hash[ hash2Value];
|
||||||
|
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] =
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
maxLen = 1;
|
||||||
|
offset = 0;
|
||||||
|
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||||
|
{
|
||||||
|
distances[0] = maxLen = 2;
|
||||||
|
distances[1] = delta2 - 1;
|
||||||
|
offset = 2;
|
||||||
|
}
|
||||||
|
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||||
|
{
|
||||||
|
maxLen = 3;
|
||||||
|
distances[offset + 1] = delta3 - 1;
|
||||||
|
offset += 2;
|
||||||
|
delta2 = delta3;
|
||||||
|
}
|
||||||
|
if (offset != 0)
|
||||||
|
{
|
||||||
|
for (; maxLen != lenLimit; maxLen++)
|
||||||
|
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||||
|
break;
|
||||||
|
distances[offset - 2] = maxLen;
|
||||||
|
if (maxLen == lenLimit)
|
||||||
|
{
|
||||||
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
|
MOVE_POS_RET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxLen < 3)
|
||||||
|
maxLen = 3;
|
||||||
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
|
distances + offset, maxLen) - (distances));
|
||||||
|
MOVE_POS_RET
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
|
{
|
||||||
|
UInt32 offset;
|
||||||
|
GET_MATCHES_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
|
distances, 2) - (distances));
|
||||||
|
MOVE_POS_RET
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SKIP_HEADER(2)
|
||||||
|
HASH2_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SKIP_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 hash2Value;
|
||||||
|
SKIP_HEADER(3)
|
||||||
|
HASH3_CALC;
|
||||||
|
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||||
|
p->hash[hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value;
|
||||||
|
SKIP_HEADER(4)
|
||||||
|
HASH4_CALC;
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
SKIP_FOOTER
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
UInt32 hash2Value, hash3Value;
|
||||||
|
SKIP_HEADER(4)
|
||||||
|
HASH4_CALC;
|
||||||
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
|
p->hash[ hash2Value] =
|
||||||
|
p->hash[kFix3HashSize + hash3Value] =
|
||||||
|
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||||
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
|
MOVE_POS
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SKIP_HEADER(3)
|
||||||
|
HASH_ZIP_CALC;
|
||||||
|
curMatch = p->hash[hashValue];
|
||||||
|
p->hash[hashValue] = p->pos;
|
||||||
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
|
MOVE_POS
|
||||||
|
}
|
||||||
|
while (--num != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||||
|
{
|
||||||
|
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||||
|
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
||||||
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||||
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||||
|
if (!p->btMode)
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
else if (p->numHashBytes == 2)
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
else if (p->numHashBytes == 3)
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||||
|
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZFIND_H
|
||||||
|
#define __LZFIND_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
typedef UInt32 CLzRef;
|
||||||
|
|
||||||
|
typedef struct _CMatchFinder
|
||||||
|
{
|
||||||
|
Byte *buffer;
|
||||||
|
UInt32 pos;
|
||||||
|
UInt32 posLimit;
|
||||||
|
UInt32 streamPos;
|
||||||
|
UInt32 lenLimit;
|
||||||
|
|
||||||
|
UInt32 cyclicBufferPos;
|
||||||
|
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||||
|
|
||||||
|
UInt32 matchMaxLen;
|
||||||
|
CLzRef *hash;
|
||||||
|
CLzRef *son;
|
||||||
|
UInt32 hashMask;
|
||||||
|
UInt32 cutValue;
|
||||||
|
|
||||||
|
Byte *bufferBase;
|
||||||
|
ISeqInStream *stream;
|
||||||
|
int streamEndWasReached;
|
||||||
|
|
||||||
|
UInt32 blockSize;
|
||||||
|
UInt32 keepSizeBefore;
|
||||||
|
UInt32 keepSizeAfter;
|
||||||
|
|
||||||
|
UInt32 numHashBytes;
|
||||||
|
int directInput;
|
||||||
|
int btMode;
|
||||||
|
/* int skipModeBits; */
|
||||||
|
int bigHash;
|
||||||
|
UInt32 historySize;
|
||||||
|
UInt32 fixedHashSize;
|
||||||
|
UInt32 hashSizeSum;
|
||||||
|
UInt32 numSons;
|
||||||
|
SRes result;
|
||||||
|
UInt32 crc[256];
|
||||||
|
} CMatchFinder;
|
||||||
|
|
||||||
|
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||||
|
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
|
||||||
|
|
||||||
|
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||||
|
|
||||||
|
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||||
|
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||||
|
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||||
|
void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||||
|
|
||||||
|
void MatchFinder_Construct(CMatchFinder *p);
|
||||||
|
|
||||||
|
/* Conditions:
|
||||||
|
historySize <= 3 GB
|
||||||
|
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||||
|
*/
|
||||||
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
|
ISzAlloc *alloc);
|
||||||
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||||
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||||
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||||
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
|
UInt32 *distances, UInt32 maxLen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conditions:
|
||||||
|
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||||
|
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void (*Mf_Init_Func)(void *object);
|
||||||
|
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
||||||
|
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||||
|
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||||
|
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||||
|
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||||
|
|
||||||
|
typedef struct _IMatchFinder
|
||||||
|
{
|
||||||
|
Mf_Init_Func Init;
|
||||||
|
Mf_GetIndexByte_Func GetIndexByte;
|
||||||
|
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||||
|
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||||
|
Mf_GetMatches_Func GetMatches;
|
||||||
|
Mf_Skip_Func Skip;
|
||||||
|
} IMatchFinder;
|
||||||
|
|
||||||
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||||
|
|
||||||
|
void MatchFinder_Init(CMatchFinder *p);
|
||||||
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,54 @@
|
|||||||
|
/* LzHash.h -- HASH functions for LZ algorithms
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZHASH_H
|
||||||
|
#define __LZHASH_H
|
||||||
|
|
||||||
|
#define kHash2Size (1 << 10)
|
||||||
|
#define kHash3Size (1 << 16)
|
||||||
|
#define kHash4Size (1 << 20)
|
||||||
|
|
||||||
|
#define kFix3HashSize (kHash2Size)
|
||||||
|
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||||
|
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
||||||
|
|
||||||
|
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
|
||||||
|
|
||||||
|
#define HASH3_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||||
|
|
||||||
|
#define HASH4_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||||
|
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||||
|
|
||||||
|
#define HASH5_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||||
|
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
||||||
|
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
||||||
|
hash4Value &= (kHash4Size - 1); }
|
||||||
|
|
||||||
|
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
|
||||||
|
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
#define MT_HASH2_CALC \
|
||||||
|
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
|
||||||
|
|
||||||
|
#define MT_HASH3_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||||
|
|
||||||
|
#define MT_HASH4_CALC { \
|
||||||
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
|
hash2Value = temp & (kHash2Size - 1); \
|
||||||
|
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||||
|
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,223 @@
|
|||||||
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __LZMADEC_H
|
||||||
|
#define __LZMADEC_H
|
||||||
|
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
/* #define _LZMA_PROB32 */
|
||||||
|
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||||
|
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||||
|
|
||||||
|
#ifdef _LZMA_PROB32
|
||||||
|
#define CLzmaProb UInt32
|
||||||
|
#else
|
||||||
|
#define CLzmaProb UInt16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- LZMA Properties ---------- */
|
||||||
|
|
||||||
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
|
typedef struct _CLzmaProps
|
||||||
|
{
|
||||||
|
unsigned lc, lp, pb;
|
||||||
|
UInt32 dicSize;
|
||||||
|
} CLzmaProps;
|
||||||
|
|
||||||
|
/* LzmaProps_Decode - decodes properties
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- LZMA Decoder state ---------- */
|
||||||
|
|
||||||
|
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||||
|
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||||
|
|
||||||
|
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CLzmaProps prop;
|
||||||
|
CLzmaProb *probs;
|
||||||
|
Byte *dic;
|
||||||
|
const Byte *buf;
|
||||||
|
UInt32 range, code;
|
||||||
|
SizeT dicPos;
|
||||||
|
SizeT dicBufSize;
|
||||||
|
UInt32 processedPos;
|
||||||
|
UInt32 checkDicSize;
|
||||||
|
unsigned state;
|
||||||
|
UInt32 reps[4];
|
||||||
|
unsigned remainLen;
|
||||||
|
int needFlush;
|
||||||
|
int needInitState;
|
||||||
|
UInt32 numProbs;
|
||||||
|
unsigned tempBufSize;
|
||||||
|
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||||
|
} CLzmaDec;
|
||||||
|
|
||||||
|
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||||
|
|
||||||
|
void LzmaDec_Init(CLzmaDec *p);
|
||||||
|
|
||||||
|
/* There are two types of LZMA streams:
|
||||||
|
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||||
|
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LZMA_FINISH_ANY, /* finish at any point */
|
||||||
|
LZMA_FINISH_END /* block must be finished at the end */
|
||||||
|
} ELzmaFinishMode;
|
||||||
|
|
||||||
|
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||||
|
|
||||||
|
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||||
|
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||||
|
|
||||||
|
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||||
|
and output value of destLen will be less than output buffer size limit.
|
||||||
|
You can check status result also.
|
||||||
|
|
||||||
|
You can use multiple checks to test data integrity after full decompression:
|
||||||
|
1) Check Result and "status" variable.
|
||||||
|
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||||
|
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||||
|
You must use correct finish mode in that case. */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||||
|
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||||
|
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||||
|
} ELzmaStatus;
|
||||||
|
|
||||||
|
/* ELzmaStatus is used only as output value for function call */
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Interfaces ---------- */
|
||||||
|
|
||||||
|
/* There are 3 levels of interfaces:
|
||||||
|
1) Dictionary Interface
|
||||||
|
2) Buffer Interface
|
||||||
|
3) One Call Interface
|
||||||
|
You can select any of these interfaces, but don't mix functions from different
|
||||||
|
groups for same object. */
|
||||||
|
|
||||||
|
|
||||||
|
/* There are two variants to allocate state for Dictionary Interface:
|
||||||
|
1) LzmaDec_Allocate / LzmaDec_Free
|
||||||
|
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||||
|
You can use variant 2, if you set dictionary buffer manually.
|
||||||
|
For Buffer Interface you must always use variant 1.
|
||||||
|
|
||||||
|
LzmaDec_Allocate* can return:
|
||||||
|
SZ_OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||||
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||||
|
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
/* ---------- Dictionary Interface ---------- */
|
||||||
|
|
||||||
|
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||||
|
dictionary to some other external buffer.
|
||||||
|
You must work with CLzmaDec variables directly in this interface.
|
||||||
|
|
||||||
|
STEPS:
|
||||||
|
LzmaDec_Constr()
|
||||||
|
LzmaDec_Allocate()
|
||||||
|
for (each new stream)
|
||||||
|
{
|
||||||
|
LzmaDec_Init()
|
||||||
|
while (it needs more decompression)
|
||||||
|
{
|
||||||
|
LzmaDec_DecodeToDic()
|
||||||
|
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LzmaDec_Free()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* LzmaDec_DecodeToDic
|
||||||
|
|
||||||
|
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||||
|
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||||
|
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||||
|
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Buffer Interface ---------- */
|
||||||
|
|
||||||
|
/* It's zlib-like interface.
|
||||||
|
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||||
|
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||||
|
to work with CLzmaDec variables manually.
|
||||||
|
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
|
/* LzmaDecode
|
||||||
|
|
||||||
|
finishMode:
|
||||||
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
|
*/
|
||||||
|
|
||||||
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,231 @@
|
|||||||
|
/** @file
|
||||||
|
Types.h
|
||||||
|
|
||||||
|
Based on LZMA SDK 4.65:
|
||||||
|
Types.h -- Basic types
|
||||||
|
2008-11-23 : Igor Pavlov : Public domain
|
||||||
|
|
||||||
|
Copyright (c) 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __7Z_TYPES_H
|
||||||
|
#define __7Z_TYPES_H
|
||||||
|
|
||||||
|
#ifdef EFIAPI
|
||||||
|
|
||||||
|
#include "UefiLzma.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SZ_OK 0
|
||||||
|
|
||||||
|
#define SZ_ERROR_DATA 1
|
||||||
|
#define SZ_ERROR_MEM 2
|
||||||
|
#define SZ_ERROR_CRC 3
|
||||||
|
#define SZ_ERROR_UNSUPPORTED 4
|
||||||
|
#define SZ_ERROR_PARAM 5
|
||||||
|
#define SZ_ERROR_INPUT_EOF 6
|
||||||
|
#define SZ_ERROR_OUTPUT_EOF 7
|
||||||
|
#define SZ_ERROR_READ 8
|
||||||
|
#define SZ_ERROR_WRITE 9
|
||||||
|
#define SZ_ERROR_PROGRESS 10
|
||||||
|
#define SZ_ERROR_FAIL 11
|
||||||
|
#define SZ_ERROR_THREAD 12
|
||||||
|
|
||||||
|
#define SZ_ERROR_ARCHIVE 16
|
||||||
|
#define SZ_ERROR_NO_ARCHIVE 17
|
||||||
|
|
||||||
|
typedef int SRes;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef DWORD WRes;
|
||||||
|
#else
|
||||||
|
typedef int WRes;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RINOK
|
||||||
|
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char Byte;
|
||||||
|
typedef short Int16;
|
||||||
|
typedef unsigned short UInt16;
|
||||||
|
|
||||||
|
#ifdef _LZMA_UINT32_IS_ULONG
|
||||||
|
typedef long Int32;
|
||||||
|
typedef unsigned long UInt32;
|
||||||
|
#else
|
||||||
|
typedef int Int32;
|
||||||
|
typedef unsigned int UInt32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _SZ_NO_INT_64
|
||||||
|
|
||||||
|
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||||
|
NOTES: Some code will work incorrectly in that case! */
|
||||||
|
|
||||||
|
typedef long Int64;
|
||||||
|
typedef unsigned long UInt64;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
|
typedef __int64 Int64;
|
||||||
|
typedef unsigned __int64 UInt64;
|
||||||
|
#else
|
||||||
|
typedef long long int Int64;
|
||||||
|
typedef unsigned long long int UInt64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||||
|
typedef UInt32 SizeT;
|
||||||
|
#else
|
||||||
|
typedef size_t SizeT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int Bool;
|
||||||
|
#define True 1
|
||||||
|
#define False 0
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1300
|
||||||
|
#define MY_NO_INLINE __declspec(noinline)
|
||||||
|
#else
|
||||||
|
#define MY_NO_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MY_CDECL __cdecl
|
||||||
|
#define MY_STD_CALL __stdcall
|
||||||
|
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MY_CDECL
|
||||||
|
#define MY_STD_CALL
|
||||||
|
#define MY_FAST_CALL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The following interfaces use first parameter as pointer to structure */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||||
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
|
(output(*size) < input(*size)) is allowed */
|
||||||
|
} ISeqInStream;
|
||||||
|
|
||||||
|
/* it can return SZ_ERROR_INPUT_EOF */
|
||||||
|
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||||
|
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
|
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||||
|
/* Returns: result - the number of actually written bytes.
|
||||||
|
(result < size) means error */
|
||||||
|
} ISeqOutStream;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SZ_SEEK_SET = 0,
|
||||||
|
SZ_SEEK_CUR = 1,
|
||||||
|
SZ_SEEK_END = 2
|
||||||
|
} ESzSeek;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||||
|
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||||
|
} ISeekInStream;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Look)(void *p, void **buf, size_t *size);
|
||||||
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
|
(output(*size) > input(*size)) is not allowed
|
||||||
|
(output(*size) < input(*size)) is allowed */
|
||||||
|
SRes (*Skip)(void *p, size_t offset);
|
||||||
|
/* offset must be <= output(*size) of Look */
|
||||||
|
|
||||||
|
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||||
|
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||||
|
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||||
|
} ILookInStream;
|
||||||
|
|
||||||
|
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||||
|
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||||
|
|
||||||
|
/* reads via ILookInStream::Read */
|
||||||
|
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
|
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||||
|
|
||||||
|
#define LookToRead_BUF_SIZE (1 << 14)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ILookInStream s;
|
||||||
|
ISeekInStream *realStream;
|
||||||
|
size_t pos;
|
||||||
|
size_t size;
|
||||||
|
Byte buf[LookToRead_BUF_SIZE];
|
||||||
|
} CLookToRead;
|
||||||
|
|
||||||
|
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||||
|
void LookToRead_Init(CLookToRead *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream s;
|
||||||
|
ILookInStream *realStream;
|
||||||
|
} CSecToLook;
|
||||||
|
|
||||||
|
void SecToLook_CreateVTable(CSecToLook *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream s;
|
||||||
|
ILookInStream *realStream;
|
||||||
|
} CSecToRead;
|
||||||
|
|
||||||
|
void SecToRead_CreateVTable(CSecToRead *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||||
|
/* Returns: result. (result != SZ_OK) means break.
|
||||||
|
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||||
|
} ICompressProgress;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *(*Alloc)(void *p, size_t size);
|
||||||
|
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||||
|
} ISzAlloc;
|
||||||
|
|
||||||
|
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||||
|
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,236 @@
|
|||||||
|
HISTORY of the LZMA SDK
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
4.65 2009-02-03
|
||||||
|
-------------------------
|
||||||
|
- Some minor fixes
|
||||||
|
|
||||||
|
|
||||||
|
4.63 2008-12-31
|
||||||
|
-------------------------
|
||||||
|
- Some minor fixes
|
||||||
|
|
||||||
|
|
||||||
|
4.61 beta 2008-11-23
|
||||||
|
-------------------------
|
||||||
|
- The bug in ANSI-C LZMA Decoder was fixed:
|
||||||
|
If encoded stream was corrupted, decoder could access memory
|
||||||
|
outside of allocated range.
|
||||||
|
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||||
|
- LZMA SDK is placed in the public domain.
|
||||||
|
|
||||||
|
|
||||||
|
4.60 beta 2008-08-19
|
||||||
|
-------------------------
|
||||||
|
- Some minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
4.59 beta 2008-08-13
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed:
|
||||||
|
LZMA Encoder in fast compression mode could access memory outside of
|
||||||
|
allocated range in some rare cases.
|
||||||
|
|
||||||
|
|
||||||
|
4.58 beta 2008-05-05
|
||||||
|
-------------------------
|
||||||
|
- ANSI-C LZMA Decoder was rewritten for speed optimizations.
|
||||||
|
- ANSI-C LZMA Encoder was included to LZMA SDK.
|
||||||
|
- C++ LZMA code now is just wrapper over ANSI-C code.
|
||||||
|
|
||||||
|
|
||||||
|
4.57 2007-12-12
|
||||||
|
-------------------------
|
||||||
|
- Speed optimizations in Ñ++ LZMA Decoder.
|
||||||
|
- Small changes for more compatibility with some C/C++ compilers.
|
||||||
|
|
||||||
|
|
||||||
|
4.49 beta 2007-07-05
|
||||||
|
-------------------------
|
||||||
|
- .7z ANSI-C Decoder:
|
||||||
|
- now it supports BCJ and BCJ2 filters
|
||||||
|
- now it supports files larger than 4 GB.
|
||||||
|
- now it supports "Last Write Time" field for files.
|
||||||
|
- C++ code for .7z archives compressing/decompressing from 7-zip
|
||||||
|
was included to LZMA SDK.
|
||||||
|
|
||||||
|
|
||||||
|
4.43 2006-06-04
|
||||||
|
-------------------------
|
||||||
|
- Small changes for more compatibility with some C/C++ compilers.
|
||||||
|
|
||||||
|
|
||||||
|
4.42 2006-05-15
|
||||||
|
-------------------------
|
||||||
|
- Small changes in .h files in ANSI-C version.
|
||||||
|
|
||||||
|
|
||||||
|
4.39 beta 2006-04-14
|
||||||
|
-------------------------
|
||||||
|
- The bug in versions 4.33b:4.38b was fixed:
|
||||||
|
C++ version of LZMA encoder could not correctly compress
|
||||||
|
files larger than 2 GB with HC4 match finder (-mfhc4).
|
||||||
|
|
||||||
|
|
||||||
|
4.37 beta 2005-04-06
|
||||||
|
-------------------------
|
||||||
|
- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
|
||||||
|
|
||||||
|
|
||||||
|
4.35 beta 2005-03-02
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed in C++ version of LZMA Decoder:
|
||||||
|
If encoded stream was corrupted, decoder could access memory
|
||||||
|
outside of allocated range.
|
||||||
|
|
||||||
|
|
||||||
|
4.34 beta 2006-02-27
|
||||||
|
-------------------------
|
||||||
|
- Compressing speed and memory requirements for compressing were increased
|
||||||
|
- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
|
||||||
|
|
||||||
|
|
||||||
|
4.32 2005-12-09
|
||||||
|
-------------------------
|
||||||
|
- Java version of LZMA SDK was included
|
||||||
|
|
||||||
|
|
||||||
|
4.30 2005-11-20
|
||||||
|
-------------------------
|
||||||
|
- Compression ratio was improved in -a2 mode
|
||||||
|
- Speed optimizations for compressing in -a2 mode
|
||||||
|
- -fb switch now supports values up to 273
|
||||||
|
- The bug in 7z_C (7zIn.c) was fixed:
|
||||||
|
It used Alloc/Free functions from different memory pools.
|
||||||
|
So if program used two memory pools, it worked incorrectly.
|
||||||
|
- 7z_C: .7z format supporting was improved
|
||||||
|
- LZMA# SDK (C#.NET version) was included
|
||||||
|
|
||||||
|
|
||||||
|
4.27 (Updated) 2005-09-21
|
||||||
|
-------------------------
|
||||||
|
- Some GUIDs/interfaces in C++ were changed.
|
||||||
|
IStream.h:
|
||||||
|
ISequentialInStream::Read now works as old ReadPart
|
||||||
|
ISequentialOutStream::Write now works as old WritePart
|
||||||
|
|
||||||
|
|
||||||
|
4.27 2005-08-07
|
||||||
|
-------------------------
|
||||||
|
- The bug in LzmaDecodeSize.c was fixed:
|
||||||
|
if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
|
||||||
|
decompressing worked incorrectly.
|
||||||
|
|
||||||
|
|
||||||
|
4.26 2005-08-05
|
||||||
|
-------------------------
|
||||||
|
- Fixes in 7z_C code and LzmaTest.c:
|
||||||
|
previous versions could work incorrectly,
|
||||||
|
if malloc(0) returns 0
|
||||||
|
|
||||||
|
|
||||||
|
4.23 2005-06-29
|
||||||
|
-------------------------
|
||||||
|
- Small fixes in C++ code
|
||||||
|
|
||||||
|
|
||||||
|
4.22 2005-06-10
|
||||||
|
-------------------------
|
||||||
|
- Small fixes
|
||||||
|
|
||||||
|
|
||||||
|
4.21 2005-06-08
|
||||||
|
-------------------------
|
||||||
|
- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
|
||||||
|
- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
|
||||||
|
- LzmaStateDecode.h
|
||||||
|
- LzmaStateDecode.c
|
||||||
|
- LzmaStateTest.c
|
||||||
|
- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
|
||||||
|
|
||||||
|
|
||||||
|
4.17 2005-04-18
|
||||||
|
-------------------------
|
||||||
|
- New example for RAM->RAM compressing/decompressing:
|
||||||
|
LZMA + BCJ (filter for x86 code):
|
||||||
|
- LzmaRam.h
|
||||||
|
- LzmaRam.cpp
|
||||||
|
- LzmaRamDecode.h
|
||||||
|
- LzmaRamDecode.c
|
||||||
|
- -f86 switch for lzma.exe
|
||||||
|
|
||||||
|
|
||||||
|
4.16 2005-03-29
|
||||||
|
-------------------------
|
||||||
|
- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
|
||||||
|
If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
|
||||||
|
decoder could access memory outside of allocated range.
|
||||||
|
- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
|
||||||
|
Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
|
||||||
|
LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
|
||||||
|
- Small speed optimization in LZMA C++ code
|
||||||
|
- filter for SPARC's code was added
|
||||||
|
- Simplified version of .7z ANSI-C Decoder was included
|
||||||
|
|
||||||
|
|
||||||
|
4.06 2004-09-05
|
||||||
|
-------------------------
|
||||||
|
- The bug in v4.05 was fixed:
|
||||||
|
LZMA-Encoder didn't release output stream in some cases.
|
||||||
|
|
||||||
|
|
||||||
|
4.05 2004-08-25
|
||||||
|
-------------------------
|
||||||
|
- Source code of filters for x86, IA-64, ARM, ARM-Thumb
|
||||||
|
and PowerPC code was included to SDK
|
||||||
|
- Some internal minor changes
|
||||||
|
|
||||||
|
|
||||||
|
4.04 2004-07-28
|
||||||
|
-------------------------
|
||||||
|
- More compatibility with some C++ compilers
|
||||||
|
|
||||||
|
|
||||||
|
4.03 2004-06-18
|
||||||
|
-------------------------
|
||||||
|
- "Benchmark" command was added. It measures compressing
|
||||||
|
and decompressing speed and shows rating values.
|
||||||
|
Also it checks hardware errors.
|
||||||
|
|
||||||
|
|
||||||
|
4.02 2004-06-10
|
||||||
|
-------------------------
|
||||||
|
- C++ LZMA Encoder/Decoder code now is more portable
|
||||||
|
and it can be compiled by GCC on Linux.
|
||||||
|
|
||||||
|
|
||||||
|
4.01 2004-02-15
|
||||||
|
-------------------------
|
||||||
|
- Some detection of data corruption was enabled.
|
||||||
|
LzmaDecode.c / RangeDecoderReadByte
|
||||||
|
.....
|
||||||
|
{
|
||||||
|
rd->ExtraBytes = 1;
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4.00 2004-02-13
|
||||||
|
-------------------------
|
||||||
|
- Original version of LZMA SDK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HISTORY of the LZMA
|
||||||
|
-------------------
|
||||||
|
2001-2008: Improvements to LZMA compressing/decompressing code,
|
||||||
|
keeping compatibility with original LZMA format
|
||||||
|
1996-2001: Development of LZMA compression format
|
||||||
|
|
||||||
|
Some milestones:
|
||||||
|
|
||||||
|
2001-08-30: LZMA compression was added to 7-Zip
|
||||||
|
1999-01-02: First version of 7-Zip was released
|
||||||
|
|
||||||
|
|
||||||
|
End of document
|
@ -0,0 +1,594 @@
|
|||||||
|
LZMA SDK 4.65
|
||||||
|
-------------
|
||||||
|
|
||||||
|
LZMA SDK provides the documentation, samples, header files, libraries,
|
||||||
|
and tools you need to develop applications that use LZMA compression.
|
||||||
|
|
||||||
|
LZMA is default and general compression method of 7z format
|
||||||
|
in 7-Zip compression program (www.7-zip.org). LZMA provides high
|
||||||
|
compression ratio and very fast decompression.
|
||||||
|
|
||||||
|
LZMA is an improved version of famous LZ77 compression algorithm.
|
||||||
|
It was improved in way of maximum increasing of compression ratio,
|
||||||
|
keeping high decompression speed and low memory requirements for
|
||||||
|
decompressing.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
-------
|
||||||
|
|
||||||
|
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||||
|
|
||||||
|
|
||||||
|
LZMA SDK Contents
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
LZMA SDK includes:
|
||||||
|
|
||||||
|
- ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
|
||||||
|
- Compiled file->file LZMA compressing/decompressing program for Windows system
|
||||||
|
|
||||||
|
|
||||||
|
UNIX/Linux version
|
||||||
|
------------------
|
||||||
|
To compile C++ version of file->file LZMA encoding, go to directory
|
||||||
|
C++/7zip/Compress/LZMA_Alone
|
||||||
|
and call make to recompile it:
|
||||||
|
make -f makefile.gcc clean all
|
||||||
|
|
||||||
|
In some UNIX/Linux versions you must compile LZMA with static libraries.
|
||||||
|
To compile with static libraries, you can use
|
||||||
|
LIB = -lm -static
|
||||||
|
|
||||||
|
|
||||||
|
Files
|
||||||
|
---------------------
|
||||||
|
lzma.txt - LZMA SDK description (this file)
|
||||||
|
7zFormat.txt - 7z Format description
|
||||||
|
7zC.txt - 7z ANSI-C Decoder description
|
||||||
|
methods.txt - Compression method IDs for .7z
|
||||||
|
lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
|
||||||
|
history.txt - history of the LZMA SDK
|
||||||
|
|
||||||
|
|
||||||
|
Source code structure
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
C/ - C files
|
||||||
|
7zCrc*.* - CRC code
|
||||||
|
Alloc.* - Memory allocation functions
|
||||||
|
Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
|
||||||
|
LzFind.* - Match finder for LZ (LZMA) encoders
|
||||||
|
LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
|
||||||
|
LzHash.h - Additional file for LZ match finder
|
||||||
|
LzmaDec.* - LZMA decoding
|
||||||
|
LzmaEnc.* - LZMA encoding
|
||||||
|
LzmaLib.* - LZMA Library for DLL calling
|
||||||
|
Types.h - Basic types for another .c files
|
||||||
|
Threads.* - The code for multithreading.
|
||||||
|
|
||||||
|
LzmaLib - LZMA Library (.DLL for Windows)
|
||||||
|
|
||||||
|
LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
|
||||||
|
|
||||||
|
Archive - files related to archiving
|
||||||
|
7z - 7z ANSI-C Decoder
|
||||||
|
|
||||||
|
CPP/ -- CPP files
|
||||||
|
|
||||||
|
Common - common files for C++ projects
|
||||||
|
Windows - common files for Windows related code
|
||||||
|
|
||||||
|
7zip - files related to 7-Zip Project
|
||||||
|
|
||||||
|
Common - common files for 7-Zip
|
||||||
|
|
||||||
|
Compress - files related to compression/decompression
|
||||||
|
|
||||||
|
Copy - Copy coder
|
||||||
|
RangeCoder - Range Coder (special code of compression/decompression)
|
||||||
|
LZMA - LZMA compression/decompression on C++
|
||||||
|
LZMA_Alone - file->file LZMA compression/decompression
|
||||||
|
Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
|
||||||
|
|
||||||
|
Archive - files related to archiving
|
||||||
|
|
||||||
|
Common - common files for archive handling
|
||||||
|
7z - 7z C++ Encoder/Decoder
|
||||||
|
|
||||||
|
Bundles - Modules that are bundles of other modules
|
||||||
|
|
||||||
|
Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
|
||||||
|
Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
|
||||||
|
Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
|
||||||
|
|
||||||
|
UI - User Interface files
|
||||||
|
|
||||||
|
Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
|
||||||
|
Common - Common UI files
|
||||||
|
Console - Code for console archiver
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CS/ - C# files
|
||||||
|
7zip
|
||||||
|
Common - some common files for 7-Zip
|
||||||
|
Compress - files related to compression/decompression
|
||||||
|
LZ - files related to LZ (Lempel-Ziv) compression algorithm
|
||||||
|
LZMA - LZMA compression/decompression
|
||||||
|
LzmaAlone - file->file LZMA compression/decompression
|
||||||
|
RangeCoder - Range Coder (special code of compression/decompression)
|
||||||
|
|
||||||
|
Java/ - Java files
|
||||||
|
SevenZip
|
||||||
|
Compression - files related to compression/decompression
|
||||||
|
LZ - files related to LZ (Lempel-Ziv) compression algorithm
|
||||||
|
LZMA - LZMA compression/decompression
|
||||||
|
RangeCoder - Range Coder (special code of compression/decompression)
|
||||||
|
|
||||||
|
|
||||||
|
C/C++ source code of LZMA SDK is part of 7-Zip project.
|
||||||
|
7-Zip source code can be downloaded from 7-Zip's SourceForge page:
|
||||||
|
|
||||||
|
http://sourceforge.net/projects/sevenzip/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LZMA features
|
||||||
|
-------------
|
||||||
|
- Variable dictionary size (up to 1 GB)
|
||||||
|
- Estimated compressing speed: about 2 MB/s on 2 GHz CPU
|
||||||
|
- Estimated decompressing speed:
|
||||||
|
- 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
|
||||||
|
- 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
|
||||||
|
- Small memory requirements for decompressing (16 KB + DictionarySize)
|
||||||
|
- Small code size for decompressing: 5-8 KB
|
||||||
|
|
||||||
|
LZMA decoder uses only integer operations and can be
|
||||||
|
implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
|
||||||
|
|
||||||
|
Some critical operations that affect the speed of LZMA decompression:
|
||||||
|
1) 32*16 bit integer multiply
|
||||||
|
2) Misspredicted branches (penalty mostly depends from pipeline length)
|
||||||
|
3) 32-bit shift and arithmetic operations
|
||||||
|
|
||||||
|
The speed of LZMA decompressing mostly depends from CPU speed.
|
||||||
|
Memory speed has no big meaning. But if your CPU has small data cache,
|
||||||
|
overall weight of memory speed will slightly increase.
|
||||||
|
|
||||||
|
|
||||||
|
How To Use
|
||||||
|
----------
|
||||||
|
|
||||||
|
Using LZMA encoder/decoder executable
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Usage: LZMA <e|d> inputFile outputFile [<switches>...]
|
||||||
|
|
||||||
|
e: encode file
|
||||||
|
|
||||||
|
d: decode file
|
||||||
|
|
||||||
|
b: Benchmark. There are two tests: compressing and decompressing
|
||||||
|
with LZMA method. Benchmark shows rating in MIPS (million
|
||||||
|
instructions per second). Rating value is calculated from
|
||||||
|
measured speed and it is normalized with Intel's Core 2 results.
|
||||||
|
Also Benchmark checks possible hardware errors (RAM
|
||||||
|
errors in most cases). Benchmark uses these settings:
|
||||||
|
(-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
|
||||||
|
Also you can change the number of iterations. Example for 30 iterations:
|
||||||
|
LZMA b 30
|
||||||
|
Default number of iterations is 10.
|
||||||
|
|
||||||
|
<Switches>
|
||||||
|
|
||||||
|
|
||||||
|
-a{N}: set compression mode 0 = fast, 1 = normal
|
||||||
|
default: 1 (normal)
|
||||||
|
|
||||||
|
d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
|
||||||
|
The maximum value for dictionary size is 1 GB = 2^30 bytes.
|
||||||
|
Dictionary size is calculated as DictionarySize = 2^N bytes.
|
||||||
|
For decompressing file compressed by LZMA method with dictionary
|
||||||
|
size D = 2^N you need about D bytes of memory (RAM).
|
||||||
|
|
||||||
|
-fb{N}: set number of fast bytes - [5, 273], default: 128
|
||||||
|
Usually big number gives a little bit better compression ratio
|
||||||
|
and slower compression process.
|
||||||
|
|
||||||
|
-lc{N}: set number of literal context bits - [0, 8], default: 3
|
||||||
|
Sometimes lc=4 gives gain for big files.
|
||||||
|
|
||||||
|
-lp{N}: set number of literal pos bits - [0, 4], default: 0
|
||||||
|
lp switch is intended for periodical data when period is
|
||||||
|
equal 2^N. For example, for 32-bit (4 bytes)
|
||||||
|
periodical data you can use lp=2. Often it's better to set lc0,
|
||||||
|
if you change lp switch.
|
||||||
|
|
||||||
|
-pb{N}: set number of pos bits - [0, 4], default: 2
|
||||||
|
pb switch is intended for periodical data
|
||||||
|
when period is equal 2^N.
|
||||||
|
|
||||||
|
-mf{MF_ID}: set Match Finder. Default: bt4.
|
||||||
|
Algorithms from hc* group doesn't provide good compression
|
||||||
|
ratio, but they often works pretty fast in combination with
|
||||||
|
fast mode (-a0).
|
||||||
|
|
||||||
|
Memory requirements depend from dictionary size
|
||||||
|
(parameter "d" in table below).
|
||||||
|
|
||||||
|
MF_ID Memory Description
|
||||||
|
|
||||||
|
bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
|
||||||
|
bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
|
||||||
|
bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
|
||||||
|
hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
|
||||||
|
|
||||||
|
-eos: write End Of Stream marker. By default LZMA doesn't write
|
||||||
|
eos marker, since LZMA decoder knows uncompressed size
|
||||||
|
stored in .lzma file header.
|
||||||
|
|
||||||
|
-si: Read data from stdin (it will write End Of Stream marker).
|
||||||
|
-so: Write data to stdout
|
||||||
|
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
1) LZMA e file.bin file.lzma -d16 -lc0
|
||||||
|
|
||||||
|
compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
|
||||||
|
and 0 literal context bits. -lc0 allows to reduce memory requirements
|
||||||
|
for decompression.
|
||||||
|
|
||||||
|
|
||||||
|
2) LZMA e file.bin file.lzma -lc0 -lp2
|
||||||
|
|
||||||
|
compresses file.bin to file.lzma with settings suitable
|
||||||
|
for 32-bit periodical data (for example, ARM or MIPS code).
|
||||||
|
|
||||||
|
3) LZMA d file.lzma file.bin
|
||||||
|
|
||||||
|
decompresses file.lzma to file.bin.
|
||||||
|
|
||||||
|
|
||||||
|
Compression ratio hints
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Recommendations
|
||||||
|
---------------
|
||||||
|
|
||||||
|
To increase the compression ratio for LZMA compressing it's desirable
|
||||||
|
to have aligned data (if it's possible) and also it's desirable to locate
|
||||||
|
data in such order, where code is grouped in one place and data is
|
||||||
|
grouped in other place (it's better than such mixing: code, data, code,
|
||||||
|
data, ...).
|
||||||
|
|
||||||
|
|
||||||
|
Filters
|
||||||
|
-------
|
||||||
|
You can increase the compression ratio for some data types, using
|
||||||
|
special filters before compressing. For example, it's possible to
|
||||||
|
increase the compression ratio on 5-10% for code for those CPU ISAs:
|
||||||
|
x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
|
||||||
|
|
||||||
|
You can find C source code of such filters in C/Bra*.* files
|
||||||
|
|
||||||
|
You can check the compression ratio gain of these filters with such
|
||||||
|
7-Zip commands (example for ARM code):
|
||||||
|
No filter:
|
||||||
|
7z a a1.7z a.bin -m0=lzma
|
||||||
|
|
||||||
|
With filter for little-endian ARM code:
|
||||||
|
7z a a2.7z a.bin -m0=arm -m1=lzma
|
||||||
|
|
||||||
|
It works in such manner:
|
||||||
|
Compressing = Filter_encoding + LZMA_encoding
|
||||||
|
Decompressing = LZMA_decoding + Filter_decoding
|
||||||
|
|
||||||
|
Compressing and decompressing speed of such filters is very high,
|
||||||
|
so it will not increase decompressing time too much.
|
||||||
|
Moreover, it reduces decompression time for LZMA_decoding,
|
||||||
|
since compression ratio with filtering is higher.
|
||||||
|
|
||||||
|
These filters convert CALL (calling procedure) instructions
|
||||||
|
from relative offsets to absolute addresses, so such data becomes more
|
||||||
|
compressible.
|
||||||
|
|
||||||
|
For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
|
||||||
|
|
||||||
|
|
||||||
|
LZMA compressed file format
|
||||||
|
---------------------------
|
||||||
|
Offset Size Description
|
||||||
|
0 1 Special LZMA properties (lc,lp, pb in encoded form)
|
||||||
|
1 4 Dictionary size (little endian)
|
||||||
|
5 8 Uncompressed size (little endian). -1 means unknown size
|
||||||
|
13 Compressed data
|
||||||
|
|
||||||
|
|
||||||
|
ANSI-C LZMA Decoder
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
|
||||||
|
If you want to use old interfaces you can download previous version of LZMA SDK
|
||||||
|
from sourceforge.net site.
|
||||||
|
|
||||||
|
To use ANSI-C LZMA Decoder you need the following files:
|
||||||
|
1) LzmaDec.h + LzmaDec.c + Types.h
|
||||||
|
LzmaUtil/LzmaUtil.c is example application that uses these files.
|
||||||
|
|
||||||
|
|
||||||
|
Memory requirements for LZMA decoding
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
Stack usage of LZMA decoding function for local variables is not
|
||||||
|
larger than 200-400 bytes.
|
||||||
|
|
||||||
|
LZMA Decoder uses dictionary buffer and internal state structure.
|
||||||
|
Internal state structure consumes
|
||||||
|
state_size = (4 + (1.5 << (lc + lp))) KB
|
||||||
|
by default (lc=3, lp=0), state_size = 16 KB.
|
||||||
|
|
||||||
|
|
||||||
|
How To decompress data
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
LZMA Decoder (ANSI-C version) now supports 2 interfaces:
|
||||||
|
1) Single-call Decompressing
|
||||||
|
2) Multi-call State Decompressing (zlib-like interface)
|
||||||
|
|
||||||
|
You must use external allocator:
|
||||||
|
Example:
|
||||||
|
void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
|
||||||
|
void SzFree(void *p, void *address) { p = p; free(address); }
|
||||||
|
ISzAlloc alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
You can use p = p; operator to disable compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
|
Single-call Decompressing
|
||||||
|
-------------------------
|
||||||
|
When to use: RAM->RAM decompressing
|
||||||
|
Compile files: LzmaDec.h + LzmaDec.c + Types.h
|
||||||
|
Compile defines: no defines
|
||||||
|
Memory Requirements:
|
||||||
|
- Input buffer: compressed size
|
||||||
|
- Output buffer: uncompressed size
|
||||||
|
- LZMA Internal Structures: state_size (16 KB for default settings)
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
In:
|
||||||
|
dest - output data
|
||||||
|
destLen - output data size
|
||||||
|
src - input data
|
||||||
|
srcLen - input data size
|
||||||
|
propData - LZMA properties (5 bytes)
|
||||||
|
propSize - size of propData buffer (5 bytes)
|
||||||
|
finishMode - It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
You can use LZMA_FINISH_END, when you know that
|
||||||
|
current output buffer covers last bytes of stream.
|
||||||
|
alloc - Memory allocator.
|
||||||
|
|
||||||
|
Out:
|
||||||
|
destLen - processed output size
|
||||||
|
srcLen - processed input size
|
||||||
|
|
||||||
|
Output:
|
||||||
|
SZ_OK
|
||||||
|
status:
|
||||||
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
|
LZMA_STATUS_NOT_FINISHED
|
||||||
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|
SZ_ERROR_DATA - Data error
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
|
|
||||||
|
If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
|
||||||
|
and output value of destLen will be less than output buffer size limit.
|
||||||
|
|
||||||
|
You can use multiple checks to test data integrity after full decompression:
|
||||||
|
1) Check Result and "status" variable.
|
||||||
|
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||||
|
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||||
|
You must use correct finish mode in that case. */
|
||||||
|
|
||||||
|
|
||||||
|
Multi-call State Decompressing (zlib-like interface)
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
When to use: file->file decompressing
|
||||||
|
Compile files: LzmaDec.h + LzmaDec.c + Types.h
|
||||||
|
|
||||||
|
Memory Requirements:
|
||||||
|
- Buffer for input stream: any size (for example, 16 KB)
|
||||||
|
- Buffer for output stream: any size (for example, 16 KB)
|
||||||
|
- LZMA Internal Structures: state_size (16 KB for default settings)
|
||||||
|
- LZMA dictionary (dictionary size is encoded in LZMA properties header)
|
||||||
|
|
||||||
|
1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
|
||||||
|
unsigned char header[LZMA_PROPS_SIZE + 8];
|
||||||
|
ReadFile(inFile, header, sizeof(header)
|
||||||
|
|
||||||
|
2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
|
||||||
|
|
||||||
|
CLzmaDec state;
|
||||||
|
LzmaDec_Constr(&state);
|
||||||
|
res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
|
||||||
|
|
||||||
|
LzmaDec_Init(&state);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||||
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4) Free all allocated structures
|
||||||
|
LzmaDec_Free(&state, &g_Alloc);
|
||||||
|
|
||||||
|
For full code example, look at C/LzmaUtil/LzmaUtil.c code.
|
||||||
|
|
||||||
|
|
||||||
|
How To compress data
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
|
||||||
|
LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
|
||||||
|
|
||||||
|
Memory Requirements:
|
||||||
|
- (dictSize * 11.5 + 6 MB) + state_size
|
||||||
|
|
||||||
|
Lzma Encoder can use two memory allocators:
|
||||||
|
1) alloc - for small arrays.
|
||||||
|
2) allocBig - for big arrays.
|
||||||
|
|
||||||
|
For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
|
||||||
|
better compression speed. Note that Windows has bad implementation for
|
||||||
|
Large RAM Pages.
|
||||||
|
It's OK to use same allocator for alloc and allocBig.
|
||||||
|
|
||||||
|
|
||||||
|
Single-call Compression with callbacks
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Check C/LzmaUtil/LzmaUtil.c as example,
|
||||||
|
|
||||||
|
When to use: file->file decompressing
|
||||||
|
|
||||||
|
1) you must implement callback structures for interfaces:
|
||||||
|
ISeqInStream
|
||||||
|
ISeqOutStream
|
||||||
|
ICompressProgress
|
||||||
|
ISzAlloc
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
|
||||||
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
CFileSeqInStream inStream;
|
||||||
|
CFileSeqOutStream outStream;
|
||||||
|
|
||||||
|
inStream.funcTable.Read = MyRead;
|
||||||
|
inStream.file = inFile;
|
||||||
|
outStream.funcTable.Write = MyWrite;
|
||||||
|
outStream.file = outFile;
|
||||||
|
|
||||||
|
|
||||||
|
2) Create CLzmaEncHandle object;
|
||||||
|
|
||||||
|
CLzmaEncHandle enc;
|
||||||
|
|
||||||
|
enc = LzmaEnc_Create(&g_Alloc);
|
||||||
|
if (enc == 0)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
|
|
||||||
|
3) initialize CLzmaEncProps properties;
|
||||||
|
|
||||||
|
LzmaEncProps_Init(&props);
|
||||||
|
|
||||||
|
Then you can change some properties in that structure.
|
||||||
|
|
||||||
|
4) Send LZMA properties to LZMA Encoder
|
||||||
|
|
||||||
|
res = LzmaEnc_SetProps(enc, &props);
|
||||||
|
|
||||||
|
5) Write encoded properties to header
|
||||||
|
|
||||||
|
Byte header[LZMA_PROPS_SIZE + 8];
|
||||||
|
size_t headerSize = LZMA_PROPS_SIZE;
|
||||||
|
UInt64 fileSize;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
res = LzmaEnc_WriteProperties(enc, header, &headerSize);
|
||||||
|
fileSize = MyGetFileLength(inFile);
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
header[headerSize++] = (Byte)(fileSize >> (8 * i));
|
||||||
|
MyWriteFileAndCheck(outFile, header, headerSize)
|
||||||
|
|
||||||
|
6) Call encoding function:
|
||||||
|
res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
|
||||||
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
|
|
||||||
|
7) Destroy LZMA Encoder Object
|
||||||
|
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
|
||||||
|
|
||||||
|
|
||||||
|
If callback function return some error code, LzmaEnc_Encode also returns that code.
|
||||||
|
|
||||||
|
|
||||||
|
Single-call RAM->RAM Compression
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Single-call RAM->RAM Compression is similar to Compression with callbacks,
|
||||||
|
but you provide pointers to buffers instead of pointers to stream callbacks:
|
||||||
|
|
||||||
|
HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
|
CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
|
Return code:
|
||||||
|
SZ_OK - OK
|
||||||
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LZMA Defines
|
||||||
|
------------
|
||||||
|
|
||||||
|
_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
|
||||||
|
|
||||||
|
_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
|
||||||
|
some structures will be doubled in that case.
|
||||||
|
|
||||||
|
_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
|
||||||
|
|
||||||
|
_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
|
||||||
|
|
||||||
|
|
||||||
|
C++ LZMA Encoder/Decoder
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
C++ LZMA code use COM-like interfaces. So if you want to use it,
|
||||||
|
you can study basics of COM/OLE.
|
||||||
|
C++ LZMA code is just wrapper over ANSI-C code.
|
||||||
|
|
||||||
|
|
||||||
|
C++ Notes
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
|
||||||
|
you must check that you correctly work with "new" operator.
|
||||||
|
7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
|
||||||
|
So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
|
||||||
|
operator new(size_t size)
|
||||||
|
{
|
||||||
|
void *p = ::malloc(size);
|
||||||
|
if (p == 0)
|
||||||
|
throw CNewException();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
If you use MSCV that throws exception for "new" operator, you can compile without
|
||||||
|
"NewHandler.cpp". So standard exception will be used. Actually some code of
|
||||||
|
7-Zip catches any exception in internal code and converts it to HRESULT code.
|
||||||
|
So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
http://www.7-zip.org
|
||||||
|
http://www.7-zip.org/sdk.html
|
||||||
|
http://www.7-zip.org/support.html
|
@ -0,0 +1,41 @@
|
|||||||
|
/** @file
|
||||||
|
LZMA UEFI Library header file
|
||||||
|
|
||||||
|
Allows LZMA code to build under UEFI (edk2) build environment
|
||||||
|
|
||||||
|
Copyright (c) 2009, Intel Corporation<BR>
|
||||||
|
All rights reserved. This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef __UEFILZMA_H__
|
||||||
|
#define __UEFILZMA_H__
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#undef _WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_WIN64) || defined(__GNUC__)
|
||||||
|
typedef unsigned int size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#undef _WIN64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int ptrdiff_t;
|
||||||
|
|
||||||
|
#define memcpy CopyMem
|
||||||
|
#define memmove CopyMem
|
||||||
|
|
||||||
|
#endif // __UEFILZMA_H__
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user