--- a/fax/faxclientandserver/faxio/FAXIO.CPP Thu Aug 19 11:03:36 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,763 +0,0 @@
-// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-//
-
-#include <s32mem.h>
-#include "CFAXIO.H"
-
-#include "FAXSTPAN.H"
-#include "FAXUHUFF.H"
-#include "FAXHUFF.H"
-
-// COPIED function from pdrutil
-
-GLDEF_C void Panic (TFaxStorePanic aPanic)
-// Panic the process with ETEXT as the category.
- //
-
-{
- User::Panic (_L ("FaxStore"), aPanic);
-}
-
-// END OF COPIED
-
-//#define KFaxFileName _L("c:\\temp.fax")
-
-/********************************************************************/
-
-#define RLE_MAKEUP(aTable,aRun) TUint8((aTable)+KRleMakeup+((aRun)>>6<<1))
-#define RLE_RUN(aTable,aRun) TUint8((aTable)+((aRun)<<1))
-
-#define WRITE_RLE(ptr,table,run) {if (run>63) {*ptr++=RLE_MAKEUP(table,run);run&=0x3f;} *ptr++=RLE_RUN(table,run);}
-#define READ_RLE(ptr,pos) {TInt x=*ptr++;if (x>=KRleMakeup) {pos+=(x&KRleMakeupMask)<<5;x=*ptr++;}pos+=x>>1;}
-
-LOCAL_C TUint8* RleEncoding(const TUint32 * aScan, TUint8* aRleEncoding)
-//
-// RLE encode a 1728 pixel scanline into the buffer, and return the end-of-rle data
-// The edge detection algorithm is almost optimal for ARM
-//
- {
- // the edge detection looks at multiple pixels at a time
- // tests show that for ARM, testing 8 is only 1-2% faster than testing 6
- // testing only 6 makes for a smaller lookup table
-
- // The FirstBit table is (5 - bitpos) of the least significant
- // bit that is set in the array index value
-
- const TInt KTestBitCount=6;
- const TInt KTestBitMask=(1u<<KTestBitCount)-1;
- const TInt KRunBias=KTestBitCount-2;
- static const TUint8 KFirstBit[64]=
- {
- 0,5,4,5,3,5,4,5,2,5,4,5,3,5,4,5,1,5,4,5,3,5,4,5,2,5,4,5,3,5,4,5,
- 0,5,4,5,3,5,4,5,2,5,4,5,3,5,4,5,1,5,4,5,3,5,4,5,2,5,4,5,3,5,4,5
- };
-
- const TUint32 *end = aScan + (KFaxPixelsPerScanLine >> 5);
- TUint32 color = ~0u; // white at start
- TInt table=KRleWhite;
- TInt run = KRunBias; // initialise run length
- const TUint8* lookup=KFirstBit; // force the table to be in a register
-
- nextword:
- while (aScan < end)
- {
- run += 32;
- TUint32 pixels = *aScan++ ^ color;
- if (pixels) // do no work if there is no edge
- {
- TInt bit = 31 + KTestBitCount;
- for (;;)
- {
- TUint pix;
- do
- {
- if ((bit-=KTestBitCount) < 0)
- goto nextword; // finished processing the word
- // now examine the next 6 pixels
- // break out if we have found an edge
- pix=(pixels>>(31-bit))&KTestBitMask;
- } while (pix==0);
- // there is an edge, use the table to discover which pixel
- bit+=lookup[pix];
- // store the run-length
- run-=bit;
- WRITE_RLE(aRleEncoding,table,run);
- // flip color and look for the next edge
- color = ~color;
- table=KRleWhite-table;
- pixels=~pixels;
- run = bit;
- }
- }
- }
- // store the final run
- run-=KRunBias;
- WRITE_RLE(aRleEncoding,table,run);
- return aRleEncoding;
- }
-
-LOCAL_C TUint8* RleEncoding (const TUint32 *aScanline,TInt aLength,TUint8* aRleEncoding)
-//
-// Justify the scanline into a full size buffer before encoding
-//
- {
- __ASSERT_DEBUG(aLength < (KFaxPixelsPerScanLine >> 3),User::Invariant());
-//
- TUint32 justified[KFaxPixelsPerScanLine/32];
-//
- TInt margin = ((KFaxPixelsPerScanLine >> 3) - aLength) / 2;
- Mem::Fill (justified, sizeof(justified), 0xff); // white fill
- Mem::Copy ((TUint8*)justified + margin, aScanline, aLength);
- return RleEncoding(justified,aRleEncoding);
- }
-
-LOCAL_C TUint8* RleEncoding (const TDesC8& aScanLine, TUint8* aRleEncoding)
-//
-// Build the RLE encoding for aScanline, handling wrong-sized scanlines
-//
- {
- TInt len = aScanLine.Length ();
- const TUint32 *scan = (const TUint32 *) aScanLine.Ptr ();
- __ASSERT_DEBUG ((TUint (scan) & 3) == 0, Panic (EFaxEncodeScanlineAlignment));
- if (len >= (KFaxPixelsPerScanLine >> 3))
- return RleEncoding(scan + ((len - (KFaxPixelsPerScanLine >> 3)) >> 3),aRleEncoding); // margin in words
- else
- return RleEncoding(scan,len,aRleEncoding);
- }
-
-LOCAL_C void EncodeHuffman(TDes8 & anEncodedScanLine,TInt aTagCode,const TUint8* aRleEncoding,const TUint8* aRleEnd)
-//
-// Starting with the tag code, encode all codes in the rle data using the single huffman table
-//
- {
- TUint8 *t4 = (TUint8 *) anEncodedScanLine.Ptr ();
- TUint8 *const e4 = t4;
- // start with tag code
- TCodeDef huff=KCodes[aTagCode];
- TUint code=HUFFBITS(huff);
- TInt bits=HUFFLEN(huff)-16;
- while (aRleEncoding<aRleEnd)
- {
- __ASSERT_DEBUG (bits < 0, User::Invariant ());
- TUint8 c=*aRleEncoding++;
- TCodeDef huff=KCodes[c];
- code|=HUFFBITS(huff)>>(bits+16);
- bits+=HUFFLEN(huff);
- if (bits<0)
- continue;
- *t4++=TUint8(code>>24);
- *t4++=TUint8(code>>16);
- code<<=16;
- bits-=16;
- }
- if (bits>-16)
- { // flush out the remaining bits
- *t4++=TUint8(code>>24);
- if (bits>-8)
- *t4++=TUint8(code>>16);
- }
- anEncodedScanLine.SetLength (t4 - e4);
- }
-
-/********************************************************************/
-
-inline CFaxT4::CFaxT4 ()
- {PageInitialize(EFaxNormal,EModifiedHuffman);}
-
-EXPORT_C CFaxT4 *CFaxT4::NewLC ()
-/** Constructs a CFaxT4 object, which provides utility functions to encode and
-decode fax scan lines.
-
-As is usual in Symbian OS, the only difference between this function and NewL()
-is that this variant pushes the object to the cleanup stack.
-
-The new object is constructed with the default compression and resolution:
-EModifiedHuffman and EFaxNormal respectively.
-
-@leave KErrNoMemory There is insufficient memory to perform the operation.
-@return A pointer to the newly created object.
-@capability None
-*/
- {
- CFaxT4 *self = NewL ();
- CleanupStack::PushL (self);
- return self;
- }
-
-EXPORT_C CFaxT4 *CFaxT4::NewL ()
-/** Constructs a CFaxT4 object, which provides utility functions to encode and
-decode fax scan lines.
-
-The function is exactly the same as NewLC() except that the new object is
-popped from the cleanup stack.
-
-The new object is constructed with the default compression and resolution:
-EModifiedHuffman and EFaxNormal respectively.
-
-@leave KErrNoMemory There is insufficient memory to perform the operation.
-@return A pointer to the newly created object.
-@capability None
-*/
- {
- return new (ELeave) CFaxT4;
- }
-
-EXPORT_C void CFaxT4::PageInitialize (TFaxResolution aResolution, TFaxCompression aCompression, TInt aFlag2)
-/**
-Initialize fax page, set page parameters.
-
-@param aResolution defines fax resolution
-@param aCompression defines fax compression
-@param aFlag2 reserved flag.
-@capability None
-*/
- {
- __ASSERT_ALWAYS (((aCompression == EModifiedHuffman) || (aCompression == EModifiedRead)), Panic (EFaxUnsupportedCompression));
- iCompression = aCompression;
- iResolution = aResolution;
- iReservedFlag2 = aFlag2;
- iK = iResolution == EFaxFine ? 4 : 2;
- iLineCount = 1;
- // an all-white reference line
- iRef[0]=RLE_MAKEUP(KRleWhite,KFaxBytesPerScanLine);
- iRef[1]=RLE_RUN(KRleWhite,0);
- iEndRef=iRef+2;
- }
-
-EXPORT_C void CFaxT4::EncodeScanLine (const TDesC8 & aScanLine, TDes8 & anEncodedScanLine)
-/** Encodes a scan line using either one dimensional Modified Huffman (MH) or two
-dimensional Modified Read (MR) encoding.
-
-The type of encoding used depends on the compression type specified when the
-object was initialised - using PageInitialize(). If the object was not initialised,
-then the default compression is MH.
-
-@param aScanLine The raw scan line to be encoded.
-@param anEncodedScanLine On return, contains the encoded scan line.
-@capability None
-*/
- {
- if (iCompression == EModifiedRead)
- EncodeScanLine2D (aScanLine, anEncodedScanLine);
- else
- EncodeScanLine1D(aScanLine,anEncodedScanLine);
- }
-
-EXPORT_C void CFaxT4::EncodeScanLine1D (const TDesC8 & aScanLine, TDes8 & anEncodedScanLine)
-/** Encodes a scan line using Modified Huffman compression.
-
-@param aScanLine The scan line to be encoded.
-@param anEncodedScanLine On return, contains the MH encoded scan line.
-@capability None
-*/
- {
- iEndRef=RleEncoding(aScanLine,iRef);
- EncodeHuffman(anEncodedScanLine,iCompression == EModifiedHuffman ? KRleStd1D : KRleTag1D,iRef,iEndRef);
- }
-
-EXPORT_C void CFaxT4::EncodeScanLine2D (const TDesC8 & aScanLine, TDes8 & anEncodedScanLine)
-/** Encodes a scan line using Modified Read compression.
-
-@param aScanLine The scan line to be encoded.
-@param anEncodedScanLine On return, contains the MR encoded scan line.
-@capability None
-*/
- {
- // initialize our own scan line
- TInt lc=iLineCount-1;
- if (lc==0)
- { // 1D reference line
- iLineCount=iK;
- EncodeScanLine1D(aScanLine,anEncodedScanLine);
- }
- else
- { // 2D line
- iLineCount=lc;
- DoEncodeScanLine2D(aScanLine,anEncodedScanLine);
- }
- }
-
-void CFaxT4::DoEncodeScanLine2D (const TDesC8 & aScanLine, TDes8 & aEncodedScanLine)
- {
- TUint8 rlebuf[KFaxPixelsPerScanLine*3/2 + 16]; // for output + reference line
-
- // the buffer is big enough that the 2d coding output into the buffer will not
- // catch the reference coding before it is used
-
- // copy the reference line into the end of the stack buffer
-
- TInt len=iEndRef-iRef;
- TUint8* ref=rlebuf+sizeof(rlebuf)-len;
- Mem::Copy(ref,iRef,len);
-
- // Do the standard RLE encoding of the current line
- iEndRef=RleEncoding(aScanLine,iRef);
- const TUint8* cur=iRef;
-
- TUint8* rle=rlebuf;
- TInt a0=-1; // previous edge on current line
- TInt a1=0; // current edge on current line
- TInt b0; // previous edge on reference line
- TInt b1=0; // current edge on reference line
- TInt b2=0; // look-ahead edge on reference line
- TInt color=KRleWhite; // color at a0 (initially white)
-
- // the reference color is not tracked. Instead the number of reference edges
- // traversed is monitored (modulo 2) to ensure that edge b1 is of the same
- // color to a1 at "gotB2"
-
- READ_RLE(cur,a1); // find the first edge
-
- for (;;)
- {
- do
- { // find the new current and next edges on reference line
- b0=b1;
- b1=b2;
- if (b1==KFaxPixelsPerScanLine)
- break; // end of line
- READ_RLE(ref,b2);
-refMove1: // find just the look-ahead edge on the reference line
- b0=b1;
- b1=b2;
- if (b1==KFaxPixelsPerScanLine)
- break;
- READ_RLE(ref,b2);
- } while(b1<=a0); // ensure that we have the right reference edge
-
-gotB2: if (b2 < a1)
- { // pass mode detected
- *rle++=KRlePassMode;
- a0=b2; // move along by 2 edges
- continue;
- }
-
- if (TUint(b1-a1+3)<=6u)
- { // vertical mode
- *rle++=TUint8(KRleVertMode0 + (b1 - a1));
- if (a1==KFaxPixelsPerScanLine)
- break; // complete
- if (b0>a1)
- {
- // special case of vertical mode edge "cross-over"
- // the next edge may match an earlier reference edge than this!
- // rewind the reference line by 2 edges
- // we know that [b0,b1] is small, and so only uses 1 byte in the rle
- // we check for [b1,b2] requiring a makeup byte as well
- ref-=2;
- if (b2-b1>=64)
- --ref;
- b2=b0;
- b1=0; // no longer know b0, but this cannot happen again without traversing 2 edges
- }
- a0 = a1; // traverse a single edge
- READ_RLE(cur,a1);
- color=KRleWhite-color;
- goto refMove1;
- }
-
- // we must be in horizontal mode - write out the RLE codes for remainder
- // and copy RLE codes for next edge from current coding
-
- *rle++=KRleHorzMode;
- a0=Max(0,a0); // deal with start-effects (a0==-1)
- TInt run=a1-a0;
- WRITE_RLE(rle,color,run);
- // copy the next run
- if (a1==KFaxPixelsPerScanLine)
- { // complete, need a zero-length, other-color, run to finish
- *rle++=RLE_RUN(KRleWhite-color,0);
- break;
- }
- // copy the next RLE code directly from the current line
- TInt x=*cur++;
- __ASSERT_DEBUG((x&KRleWhite)==KRleWhite-color,User::Invariant());
- if (x>=KRleMakeup)
- {
- *rle++=TUint8(x);
- a1+=(x&KRleMakeupMask)<<5;
- x=*cur++;
- }
- *rle++=TUint8(x);
- a1+=x>>1;
- if (a1==KFaxPixelsPerScanLine)
- break; // complete
- a0=a1;
- READ_RLE(cur,a1); // traverse another edge
- if (b1>a0)
- goto gotB2;
- }
- EncodeHuffman(aEncodedScanLine,KRleTag2D,rlebuf,rle);
- }
-
-EXPORT_C TInt CFaxT4::DecodeScanLine (TDes8 & aScanLine, const TDesC8 & anEncodedScanLine)
-/** Decodes a scan line.
-
-The decoding method depends on the compression type specified when the object
-was initialised - using PageInitialize(). If the object was not initialised,
-then the scan line is decoded as Modified Huffman.
-
-The fax client can determine the type of compression used in a fax from its
-header, and can hence use PageInitialize() to set the correct decoding method.
-KErrUnderflow is returned if the wrong type of compression is specified.
-
-@param aScanLine On return, contains the decoded scan line.
-@param anEncodedScanLine The encoded scan line to be decoded.
-@return KErrNone if successful, otherwise another of the system-wide error
-codes.
-@capability None
-*/
- {
- if (iCompression == EModifiedHuffman)
- return (DecodeScanLine1D (aScanLine, anEncodedScanLine));
- else
- return (DecodeScanLine2D (aScanLine, anEncodedScanLine));
- }
-
-void CFaxT4::DecodeHuffman(const TDesC8 & aEncodedScanLine)
- {
- // If all goes wrong then the reference line is unchanged and will be
- // used for the current line
-
- const TUint8* t4=aEncodedScanLine.Ptr();
- const TUint8* endt4=t4+aEncodedScanLine.Length();
- TUint bits=0;
-
- // store the basic RLE data locally, and copy to the member data if the decode
- // is successful
-
- TUint8 rlebuf[KFaxPixelsPerScanLine+4];
- TUint8* rle=rlebuf;
-
- // Keep track of where we have got to on the reference (previous) line
- const TUint8* ref=iRef;
- TInt b1=0; // pixel position on the reference line
- TInt a0=0; // previous position on the current line
- TInt a1=0; // current position on the current line
-
- // start decoding using the tag-tree, which finds the first 1-bit
- // and then determines the encoding (1D or 2D) based on the next bit
- const TNode* tree=KTagTree;
-
- // "color" stores the current line color (in bit 0), the reference line
- // color (in bit 1), and the number of white/black codes to expect (x4)
- // if color<0, then we are in 2d-tree mode
- // initially unused until the encoding type is known
-
- TInt color=0;
- TInt code;
-
- for (;;)
- {
- // the structure of the following code maxmises the speed of the
- // huffman decoder. Don't change it.
- code = 0; // start at the root of the tree
-nextBit2d:
- if (((bits <<= 1) & 0x80000000)==0)
- goto nextByte2d; // run out of bits in the current byte
-decode2d:
- code = CODE (tree, code, bits & 0x80);
- if (ISBRANCH (code))
- goto nextBit2d; // a branch code
-
- // We have the huffman code
-
- if (code<KOurEol)
- { // the code was a white/black length code
- __ASSERT_DEBUG(color>=0,User::Invariant());
- TInt v=CODEVALUE(code);
- a1+=v;
- if (a1>KFaxPixelsPerScanLine)
- return; // overflow
- if (v < 64)
- { // a run code (as opposed to make-up code). Emit the RLE
- a0=a1-a0;
- WRITE_RLE(rle,(color&1),a0);
- a0=a1;
- color^=KRleWhite; // switch color
- color-=4; // one less white/black code
- tree=color>=0 ? color&KRleWhite ? KWhiteTree : KBlackTree : KTwoTree;
- }
- continue;
- }
- if (code<KPassMode)
- {
- if (code == KHorzMode)
- { // expect two white/black codes to follow
- color+=8;
- tree = color&KRleWhite ? KWhiteTree : KBlackTree;
- continue;
- }
- if (code==KTag1D)
- { // 1d decoding: set color to maximum positive value
- // as all codes are standard white/black code.
- color=KMaxTInt; // current and reference color both 1 (white)
- tree=KWhiteTree;
- continue;
- }
- if (code==KTag2D)
- { // 2d decoding: set color negative to indicate 2d-tree
- color=-1; // current and reference color both 1 (white)
- tree=KTwoTree;
- continue;
- }
- if (code==KOurEol)
- goto eol2d;
- __ASSERT_DEBUG(code == KBadRun,User::Invariant());
- return; // bad run, give up
- }
-
- // The remaining 2D possibilities all require that we know the various 2D determinants
- // so we proceed as follows :
-
- // b0 tracks the previous "edge" in the reference line
- TInt b0=0;
- // find the next "edge" on the reference line after a1
- // if we've just started decoding (rle==rlebuf), b1 boundary at 0 is correct
- if (rle!=rlebuf)
- {
- while (b1<=a1)
- {
- color^=KRleWhite<<1;
- b0=b1;
- if (b1!=KFaxPixelsPerScanLine)
- READ_RLE(ref,b1);
- }
- }
- // the b1 "edge" must match the colors of a1, so move one more edge if
- // the a0 color (color&1) is the same as the b1 color (color&2)
- if (((color^(color>>1))&1)==0)
- {
- b0=b1;
- if (b1!=KFaxPixelsPerScanLine)
- READ_RLE(ref,b1);
- color^=KRleWhite<<1;
- }
-
- // If the code is below PASSMODE then it is one of the vertical code words
- // which are pretty easy to decipher as we have all the data. Vertical mode
- // flips the colour and then continues
-
- if (code==KPassMode)
- {
- // we need to identify the next reference "edge"
- if (b1==KFaxPixelsPerScanLine)
- return; // overflow
- READ_RLE(ref,b1);
- if (b1==KFaxPixelsPerScanLine)
- return; // overflow
- color^=KRleWhite<<1;
- a1=b1;
- continue;
- }
-
- __ASSERT_DEBUG(code>=KVtMode3n && code<=KVtMode3p,User::Invariant());
- // vertical mode
- a1=b1+(code-(KVtMode0));
- if (a1>KFaxPixelsPerScanLine)
- return; // overflow
- if (b0>a1)
- {
- // special case of vertical mode cross-over
- // rewind the reference line to the previous "edge"
- b1=b0;
- --ref;
- color^=KRleWhite<<1;
- }
- a0=a1-a0;
- WRITE_RLE(rle,(color&1),a0);
- a0=a1;
- color^=KRleWhite;
- }
-nextByte2d:
- if (t4 < endt4)
- {
- bits = 0xff000000u | *t4++;
- goto decode2d;
- }
-eol2d:
- if (a0==KFaxPixelsPerScanLine)
- iEndRef=Mem::Copy(iRef,rlebuf,rle-rlebuf);
- }
-
-EXPORT_C TInt CFaxT4::DecodeScanLine2D (TDes8 & aScanLine, const TDesC8 & aEncodedScanLine)
-/** Decodes a Modified Read encoded scan line.
-
-@param aScanLine On return, contains the decoded scan line.
-@param anEncodedScanLine The 2D encoded scan line to be decoded.
-@return KErrNone if successful, KErrUnderflow if the scan line is encoded as
-MR, otherwise another of the system-wide error codes.
-@capability None
-*/
- {
- DecodeHuffman(aEncodedScanLine);
-//
-// decode the RLE into the scanline
-//
- aScanLine.SetLength (KFaxPixelsPerScanLine / 8);
- TUint32 *scan = (TUint32 *) aScanLine.Ptr ();
- __ASSERT_DEBUG ((TUint (scan) & 3) == 0, Panic (EFaxDecodeScanlineAlignment));
-
- const TUint8* rle=iRef;
- const TUint8* const end=iEndRef;
-
- TUint color = ~0u; // start white
- TUint out = 0; // output pixels in accumulation
- TInt bits = 0; // this is the number of used bits in out
-
- while (rle<end)
- {
- TInt run=*rle++;
- __ASSERT_DEBUG(TUint((run&1))==(color&1),User::Invariant()); // rle-data correct
- if (run<KRleMakeup)
- { // run length code (x2)
- out += color << bits; // complete the current 32-bits
- bits += run >> 1; // add the run length
- if (bits < 32) // hasn't completed the word
- out -= color << bits; // remove the trailing bits
- else
- {
- *scan++ = out; // write the 32-bits
- bits -= 64;
- if (bits >= 0)
- *scan++ = color; // + another 32 bits
- else
- bits += 32; // no extra
- out = color - (color<<bits); // bits remaining
- }
- color = ~color; // swap color
- }
- else
- {
- // make-up code. (run-KRleMakeup)>>1 is the multiple of 64 bits
- out += color << bits; // complete the current 32-bits
- *scan++ = out; // output
- *scan++ = color; // +32 bits of color
- for (run -= KRleMakeup+4;run >= 0;run -= 2)
- { // extra multiples of 64 bits
- *scan++ = color;
- *scan++ = color;
- }
- out = color - (color<<bits); // remainder bits
- }
- }
- return KErrNone;
- }
-
-EXPORT_C TInt CFaxT4::DecodeScanLine1D (TDes8 & aScanLine, const TDesC8 & anEncodedScanLine)
-//
-// This could be done through DecodeScanLine2D, but this is an optimized version for 1D
-// The intermediate rle encoding is skipped
-//
-/** Decodes a Modified Huffman encoded scan line.
-
-@param aScanLine On return, contains the decoded scan line.
-@param anEncodedScanLine The MH encoded scan line to be decoded.
-@return KErrNone if successful, KErrUnderflow if the scan line is encoded as
-MR, otherwise another of the system-wide error codes.
-@capability None
-*/
- {
- const TUint8 *t4 = anEncodedScanLine.Ptr ();
- const TUint8 *const endt4 = t4 + anEncodedScanLine.Length ();
- //
- aScanLine.SetLength (KFaxPixelsPerScanLine / 8);
- TUint32 *scan = (TUint32 *) aScanLine.Ptr ();
- __ASSERT_DEBUG ((TUint (scan) & 3) == 0, Panic (EFaxDecodeScanlineAlignment));
- TUint out = 0;
- TInt bits = 0; // this is the number ofused bits
- //
- TInt dotsleft = KFaxPixelsPerScanLine;
- const TNode *tree = KSynchTree;
- TUint octet=0;
- TUint color = 0xffffffffu;
-
-nextCode1d:
- TInt code = 0;
-nextBit1d:
- if (((octet <<= 1) & 0x80000000)==0)
- goto nextByte1d;
-decode1d:
- code = CODE (tree, code, octet & 0x80);
- if (ISBRANCH (code))
- goto nextBit1d;
-
- // end of huffman code
-
- if (code<KEndCode+0x40)
- {
- code-=KEndCode;
- if ((dotsleft -= code) < 0)
- return KErrOverflow;
- out += color<<bits;
- bits+=code;
- if (bits<32)
- out -= color<<bits; // output word not full
- else
- { // out is full
- *scan++=out;
- bits-=64;
- if (bits>=0)
- *scan++=color;
- else
- bits+=32;
- out=color-(color<<bits);
- }
- color = ~color;
- if (color)
- tree=KWhiteTree;
- else
- tree=KBlackTree;
- goto nextCode1d;
- }
- else if (code<=KEndCode+KMaxRun)
- { // makeup (multiple of 64)
- code-=KEndCode+0x40;
- if ((dotsleft -= code<<6) < 0)
- return KErrOverflow;
- out += color << bits;
- *scan++=out;
- *scan++=color;
- for (code-=2;code>=0;--code)
- {
- *scan++=color;
- *scan++=color;
- }
- out = color-(color<<bits);
- goto nextCode1d;
- }
- else if (code == KOurEol)
- goto eol1d;
- else if (code == KStd1D)
- {
- tree=KWhiteTree;
- goto nextCode1d;
- }
- else
- {
- __ASSERT_DEBUG (code == KBadRun, User::Invariant ());
- return KErrCorrupt;
- }
-nextByte1d:
- if (t4 < endt4)
- {
- octet = 0xff000000u | *t4++;
- goto decode1d;
- }
-eol1d:
- __ASSERT_DEBUG (dotsleft || (TUint8 *) scan - aScanLine.Ptr () == KFaxPixelsPerScanLine / 8, User::Invariant ());
- return dotsleft ? KErrUnderflow : KErrNone;
- }
-