Update contrib.
1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfile\sf_inflate.h
18 #include "sf_deflate.h"
23 // The inflation algorithm, complete with huffman decoding
25 inline CInflater::CInflater(TBitInput& aInput)
26 :iBits(&aInput),iEncoding(0),iOut(0)
29 void CInflater::ConstructL()
31 iEncoding=new(ELeave) TEncoding;
34 iOut=new(ELeave) TUint8[KDeflateMaxDistance];
38 CInflater* CInflater::NewLC(TBitInput& aInput)
40 CInflater* self=new(ELeave) CInflater(aInput);
41 CleanupStack::PushL(self);
46 CInflater::~CInflater()
52 TInt CInflater::ReadL(TUint8* aBuffer,TInt aLength, TMemoryMoveFunction aMemMovefn)
57 TInt len=Min(aLength,iLimit-iAvail);
60 aMemMovefn(aBuffer,iAvail,len);
76 TInt CInflater::SkipL(TInt aLength)
78 return ReadL(0,aLength,Mem::Move);
81 void CInflater::InitL()
84 Huffman::InternalizeL(*iBits,iEncoding->iLitLen,KDeflationCodes);
85 // validate the encoding
86 if (!Huffman::IsValid(iEncoding->iLitLen,TEncoding::ELitLens) ||
87 !Huffman::IsValid(iEncoding->iDistance,TEncoding::EDistances))
88 LEAVE_FAILURE(KErrCorrupt);
89 // convert the length tables into huffman decoding trees
90 Huffman::Decoding(iEncoding->iLitLen,TEncoding::ELitLens,iEncoding->iLitLen);
91 Huffman::Decoding(iEncoding->iDistance,TEncoding::EDistances,iEncoding->iDistance,KDeflateDistCodeBase);
94 TInt CInflater::InflateL()
96 // consume all data lag in the history buffer, then decode to fill up the output buffer
97 // return the number of available bytes in the output buffer. This is only ever less than
98 // the buffer size if the end of stream marker has been read
101 // empty the history buffer into the output
103 TUint8* const end=out+KDeflateMaxDistance;
104 const TUint32* tree=iEncoding->iLitLen;
112 // get a huffman code
114 TInt val=iBits->HuffmanL(tree)-TEncoding::ELiterals;
118 continue; // another literal/length combo
120 if (val==TEncoding::EEos-TEncoding::ELiterals)
121 { // eos marker. we're done
125 // get the extra bits for the code
129 TInt xtra=(code>>2)-1;
132 code|=iBits->ReadL(xtra);
134 if (val<KDeflateDistCodeBase-TEncoding::ELiterals)
136 // length code... get the code
137 if(TUint(code)>TUint(KDeflateMaxLength-KDeflateMinLength))
139 CHECK_FAILURE(KErrCorrupt);
142 iLen=code+KDeflateMinLength;
143 tree=iEncoding->iDistance;
144 continue; // read the huffman code
147 if(TUint(code)>TUint(KDeflateMaxDistance-1))
149 CHECK_FAILURE(KErrCorrupt);
153 if (iRptr+KDeflateMaxDistance<end)
154 iRptr+=KDeflateMaxDistance;
157 CHECK_FAILURE(KErrCorrupt);
163 TInt tfr=Min(end-out,iLen);
165 const TUint8* from=iRptr;
170 from-=KDeflateMaxDistance;
173 tree=iEncoding->iLitLen;
180 LEAVE_FAILURE(KErrCorrupt);