diff options
author | root <root@lamia.panaceas.james.local> | 2015-12-19 14:18:43 +0000 |
---|---|---|
committer | root <root@lamia.panaceas.james.local> | 2015-12-19 14:18:43 +0000 |
commit | 71478fd62d8483483abb34609cdabb7f9cbadfd6 (patch) | |
tree | 37b8eaba1ffe2d5f775227911eb0ed6fdc3c9553 /hostTools/lzma/decompress/LZMADecoder.c | |
parent | 1a2238d1bddc823df06f67312d96ccf9de2893cc (diff) | |
download | bootloader-71478fd62d8483483abb34609cdabb7f9cbadfd6.tar.gz bootloader-71478fd62d8483483abb34609cdabb7f9cbadfd6.tar.bz2 bootloader-71478fd62d8483483abb34609cdabb7f9cbadfd6.zip |
Add hostTools from https://github.com/Noltari/cfe_bcm63xx
Diffstat (limited to 'hostTools/lzma/decompress/LZMADecoder.c')
-rw-r--r-- | hostTools/lzma/decompress/LZMADecoder.c | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/hostTools/lzma/decompress/LZMADecoder.c b/hostTools/lzma/decompress/LZMADecoder.c new file mode 100644 index 0000000..fe6d86d --- /dev/null +++ b/hostTools/lzma/decompress/LZMADecoder.c @@ -0,0 +1,398 @@ +#include "Portable.h" +#ifdef _HOST_TOOL +#include "stdio.h" +#endif +#include "LZMADecoder.h" + + +//#define RETURN_E_OUTOFMEMORY_IF_FALSE(x) { if (!(x)) return E_OUTOFMEMORY; } + + +static UINT32 kDistStart[kDistTableSizeMax]; +struct WindowOut out_window; + +/* + * BRCM modification: free all the allocated buffer by malloc + * + */ +static void LzmaDecoderFreeBuffer(LzmaDecoder *lzmaDecoder) +{ + int i,aPosState; + + //printf("free lzmaDecoder->m_LiteralDecoder\n"); + free((&lzmaDecoder->m_LiteralDecoder)->m_Coders); + + for (i = 0; i < kNumLenToPosStates; i++) { + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free((&lzmaDecoder->m_PosSlotDecoder[i])->m_Models); + } + // from LenDecoderInit(&lzmaDecoder->m_LenDecoder; + for (aPosState = 0; aPosState < (&lzmaDecoder->m_LenDecoder)->m_NumPosStates; aPosState++) { + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free( (&(&lzmaDecoder->m_LenDecoder)->m_LowCoder[aPosState])->m_Models ); + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free( (&(&lzmaDecoder->m_LenDecoder)->m_MidCoder[aPosState])->m_Models ); + } + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free( (&(&lzmaDecoder->m_LenDecoder)->m_HighCoder)->m_Models ); + + + // from LenDecoderInit(&lzmaDecoder->m_RepMatchLenDecoder); + for (aPosState = 0; aPosState < (&lzmaDecoder->m_RepMatchLenDecoder)->m_NumPosStates; aPosState++) { + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free( (&(&lzmaDecoder->m_RepMatchLenDecoder)->m_LowCoder[aPosState])->m_Models ); + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free( (&(&lzmaDecoder->m_RepMatchLenDecoder)->m_MidCoder[aPosState])->m_Models ); + } + //printf("free lzmaDecoder->m_PosSlotDecoder\n"); + free( (&(&lzmaDecoder->m_RepMatchLenDecoder)->m_HighCoder)->m_Models ); + + + //printf("free lzmaDecoder->m_PosAlignDecoder\n"); + free((&lzmaDecoder->m_PosAlignDecoder)->m_Models); + + for(i = 0; i < kNumPosModels; i++) { + //printf("free lzmaDecoder->m_PosDecoders\n"); + free((&lzmaDecoder->m_PosDecoders[i])->m_Models); + } + +} + +HRESULT LzmaDecoderSetDictionarySize( + LzmaDecoder *lzmaDecoder, + UINT32 aDictionarySize) +{ + if (aDictionarySize > (1 << kDicLogSizeMax)) + return E_INVALIDARG; + +// UINT32 aWindowReservSize = MyMax(aDictionarySize, UINT32(1 << 21)); + + if (lzmaDecoder->m_DictionarySize != aDictionarySize) + { + lzmaDecoder->m_DictionarySize = aDictionarySize; + } + return S_OK; +} + +HRESULT LzmaDecoderSetLiteralProperties( + LzmaDecoder *lzmaDecoder, + UINT32 aLiteralPosStateBits, + UINT32 aLiteralContextBits) +{ + if (aLiteralPosStateBits > 8) + return E_INVALIDARG; + if (aLiteralContextBits > 8) + return E_INVALIDARG; + LitDecoderCreate(&lzmaDecoder->m_LiteralDecoder, aLiteralPosStateBits, aLiteralContextBits); + return S_OK; +} + +HRESULT LzmaDecoderSetPosBitsProperties( + LzmaDecoder *lzmaDecoder, + UINT32 aNumPosStateBits) +{ + UINT32 aNumPosStates; + if (aNumPosStateBits > (UINT32) kNumPosStatesBitsMax) + return E_INVALIDARG; + aNumPosStates = 1 << aNumPosStateBits; + LenDecoderCreate(&lzmaDecoder->m_LenDecoder, aNumPosStates); + LenDecoderCreate(&lzmaDecoder->m_RepMatchLenDecoder, aNumPosStates); + lzmaDecoder->m_PosStateMask = aNumPosStates - 1; + return S_OK; +} + + +void LzmaDecoderConstructor(LzmaDecoder *lzmaDecoder) +{ + lzmaDecoder->m_DictionarySize = ((UINT32)-1); + LzmaDecoderCreate(lzmaDecoder); +} + +HRESULT LzmaDecoderCreate(LzmaDecoder *lzmaDecoder) +{ + int i; + for(i = 0; i < kNumPosModels; i++) + { + if (!(ReverseBitTreeDecoder2Create(&lzmaDecoder->m_PosDecoders[i],kDistDirectBits[kStartPosModelIndex + i]))) + return E_OUTOFMEMORY;; + } + return S_OK; +} + + +HRESULT LzmaDecoderInit(LzmaDecoder *lzmaDecoder) +{ + int i; + UINT32 j; + + RangeDecoderInit(&in_stream, &lzmaDecoder->m_RangeDecoder); + + OutWindowInit(); + + for(i = 0; i < kNumStates; i++) + { + for (j = 0; j <= lzmaDecoder->m_PosStateMask; j++) + { + BitDecoderInit(&lzmaDecoder->m_MainChoiceDecoders[i][j]); + BitDecoderInit(&lzmaDecoder->m_MatchRepShortChoiceDecoders[i][j]); + } + BitDecoderInit(&lzmaDecoder->m_MatchChoiceDecoders[i]); + BitDecoderInit(&lzmaDecoder->m_MatchRepChoiceDecoders[i]); + BitDecoderInit(&lzmaDecoder->m_MatchRep1ChoiceDecoders[i]); + BitDecoderInit(&lzmaDecoder->m_MatchRep2ChoiceDecoders[i]); + } + + LitDecoderInit(&lzmaDecoder->m_LiteralDecoder); + + for (i = 0; i < (int) kNumLenToPosStates; i++) + BitTreeDecoderInit(&lzmaDecoder->m_PosSlotDecoder[i],kNumPosSlotBits); + + for(i = 0; i < kNumPosModels; i++) + ReverseBitTreeDecoder2Init(&lzmaDecoder->m_PosDecoders[i]); + + LenDecoderInit(&lzmaDecoder->m_LenDecoder); + LenDecoderInit(&lzmaDecoder->m_RepMatchLenDecoder); + + ReverseBitTreeDecoderInit(&lzmaDecoder->m_PosAlignDecoder, kNumAlignBits); + return S_OK; + +} + +HRESULT LzmaDecoderCodeReal( + LzmaDecoder *lzmaDecoder, + UINT64 *anInSize, + UINT64 *anOutSize) +{ + BOOL aPeviousIsMatch = FALSE; + BYTE aPreviousByte = 0; + UINT32 aRepDistances[kNumRepDistances]; + int i; + UINT64 aNowPos64 = 0; + UINT64 aSize = *anOutSize; + ISequentialInStream my_in_stream; +// WindowOut out_window; + CState aState; + + CStateInit(&aState); + + if (anOutSize == NULL) + { + printf("CodeReal: invalid argument %x\n", (UINT32) anOutSize ); + return E_INVALIDARG; + } + + + LzmaDecoderInit(lzmaDecoder); + + my_in_stream.data = in_stream.data; + my_in_stream.remainingBytes = in_stream.remainingBytes; + + for(i = 0 ; i < (int) kNumRepDistances; i++) + aRepDistances[i] = 0; + + //while(aNowPos64 < aSize) + while(my_in_stream.remainingBytes > 0) + { + UINT64 aNext = MyMin(aNowPos64 + (1 << 18), aSize); + while(aNowPos64 < aNext) + { + UINT32 aPosState = (UINT32)(aNowPos64) & lzmaDecoder->m_PosStateMask; + if (BitDecode(&my_in_stream, + &lzmaDecoder->m_MainChoiceDecoders[aState][aPosState], + &lzmaDecoder->m_RangeDecoder) == (UINT32) kMainChoiceLiteralIndex) + { + CStateUpdateChar(&aState); + if(aPeviousIsMatch) + { + BYTE aMatchByte = OutWindowGetOneByte(0 - aRepDistances[0] - 1); + aPreviousByte = LitDecodeWithMatchByte(&my_in_stream, + &lzmaDecoder->m_LiteralDecoder, + &lzmaDecoder->m_RangeDecoder, + (UINT32)(aNowPos64), + aPreviousByte, + aMatchByte); + aPeviousIsMatch = FALSE; + } + else + aPreviousByte = LitDecodeNormal(&my_in_stream, + &lzmaDecoder->m_LiteralDecoder, + &lzmaDecoder->m_RangeDecoder, + (UINT32)(aNowPos64), + aPreviousByte); + OutWindowPutOneByte(aPreviousByte); + aNowPos64++; + } + else + { + UINT32 aDistance, aLen; + aPeviousIsMatch = TRUE; + if(BitDecode(&my_in_stream, + &lzmaDecoder->m_MatchChoiceDecoders[aState], + &lzmaDecoder->m_RangeDecoder) == (UINT32) kMatchChoiceRepetitionIndex) + { + if(BitDecode(&my_in_stream, + &lzmaDecoder->m_MatchRepChoiceDecoders[aState], + &lzmaDecoder->m_RangeDecoder) == 0) + { + if(BitDecode(&my_in_stream, + &lzmaDecoder->m_MatchRepShortChoiceDecoders[aState][aPosState], + &lzmaDecoder->m_RangeDecoder) == 0) + { + CStateUpdateShortRep(&aState); + aPreviousByte = OutWindowGetOneByte(0 - aRepDistances[0] - 1); + OutWindowPutOneByte(aPreviousByte); + aNowPos64++; + continue; + } + aDistance = aRepDistances[0]; + } + else + { + if(BitDecode(&my_in_stream, + &lzmaDecoder->m_MatchRep1ChoiceDecoders[aState], + &lzmaDecoder->m_RangeDecoder) == 0) + { + aDistance = aRepDistances[1]; + aRepDistances[1] = aRepDistances[0]; + } + else + { + if (BitDecode(&my_in_stream, + &lzmaDecoder->m_MatchRep2ChoiceDecoders[aState], + &lzmaDecoder->m_RangeDecoder) == 0) + { + aDistance = aRepDistances[2]; + } + else + { + aDistance = aRepDistances[3]; + aRepDistances[3] = aRepDistances[2]; + } + aRepDistances[2] = aRepDistances[1]; + aRepDistances[1] = aRepDistances[0]; + } + aRepDistances[0] = aDistance; + } + aLen = LenDecode(&my_in_stream, + &lzmaDecoder->m_RepMatchLenDecoder, + &lzmaDecoder->m_RangeDecoder, + aPosState) + kMatchMinLen; + CStateUpdateRep(&aState); + } + else + { + UINT32 aPosSlot; + aLen = kMatchMinLen + LenDecode(&my_in_stream, + &lzmaDecoder->m_LenDecoder, + &lzmaDecoder->m_RangeDecoder, + aPosState); + CStateUpdateMatch(&aState); + aPosSlot = BitTreeDecode(&my_in_stream, + &lzmaDecoder->m_PosSlotDecoder[GetLenToPosState(aLen)], + &lzmaDecoder->m_RangeDecoder); + if (aPosSlot >= (UINT32) kStartPosModelIndex) + { + aDistance = kDistStart[aPosSlot]; + if (aPosSlot < (UINT32) kEndPosModelIndex) + aDistance += ReverseBitTreeDecoder2Decode(&my_in_stream, + &lzmaDecoder->m_PosDecoders[aPosSlot - kStartPosModelIndex], + &lzmaDecoder->m_RangeDecoder); + else + { + aDistance += (RangeDecodeDirectBits(&my_in_stream, + &lzmaDecoder->m_RangeDecoder, + kDistDirectBits[aPosSlot] - kNumAlignBits) << kNumAlignBits); + aDistance += ReverseBitTreeDecoderDecode(&my_in_stream, + &lzmaDecoder->m_PosAlignDecoder, + &lzmaDecoder->m_RangeDecoder); + } + } + else + aDistance = aPosSlot; + + + aRepDistances[3] = aRepDistances[2]; + aRepDistances[2] = aRepDistances[1]; + aRepDistances[1] = aRepDistances[0]; + + aRepDistances[0] = aDistance; + } + if (aDistance >= aNowPos64) + { + printf("CodeReal: invalid data\n" ); + return E_INVALIDDATA; + } + OutWindowCopyBackBlock(aDistance, aLen); + aNowPos64 += aLen; + aPreviousByte = OutWindowGetOneByte(0 - 1); + } + } + } + + //BRCM modification + LzmaDecoderFreeBuffer(lzmaDecoder); + + OutWindowFlush(); + return S_OK; +} + +HRESULT LzmaDecoderCode( + LzmaDecoder *lzmaDecoder, + UINT64 *anInSize, + UINT64 *anOutSize) +{ + + UINT32 aStartValue = 0; + int i; + + for (i = 0; i < kDistTableSizeMax; i++) + { + kDistStart[i] = aStartValue; + aStartValue += (1 << kDistDirectBits[i]); + } + return LzmaDecoderCodeReal( + lzmaDecoder, + anInSize, + anOutSize); +} + +HRESULT LzmaDecoderReadCoderProperties(LzmaDecoder *lzmaDecoder) +{ + UINT32 aNumPosStateBits; + UINT32 aLiteralPosStateBits; + UINT32 aLiteralContextBits; + UINT32 aDictionarySize; + BYTE aRemainder; + UINT32 aProcessesedSize; + + BYTE aByte; + RETURN_IF_NOT_S_OK(InStreamRead(&aByte, + sizeof(aByte), + &aProcessesedSize)); + + if (aProcessesedSize != sizeof(aByte)) + return E_INVALIDARG; + + aLiteralContextBits = aByte % 9; + aRemainder = aByte / 9; + aLiteralPosStateBits = aRemainder % 5; + aNumPosStateBits = aRemainder / 5; + + RETURN_IF_NOT_S_OK(InStreamRead(&aDictionarySize, + sizeof(aDictionarySize), + &aProcessesedSize)); + + if (aProcessesedSize != sizeof(aDictionarySize)) + return E_INVALIDARG; + + RETURN_IF_NOT_S_OK( LzmaDecoderSetDictionarySize(lzmaDecoder, + aDictionarySize) ); + RETURN_IF_NOT_S_OK( LzmaDecoderSetLiteralProperties(lzmaDecoder, + aLiteralPosStateBits, + aLiteralContextBits) ); + RETURN_IF_NOT_S_OK( LzmaDecoderSetPosBitsProperties(lzmaDecoder, + aNumPosStateBits) ); + + return S_OK; +} + |