--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFFax.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,1198 @@
+// Copyright (c) 1999-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 "TIFFFax.h"
+
+const TInt KMaxHuffmanCodeLength = 13;
+LOCAL_C inline TUint32 GetMostSignificantBits(TUint32 aBits,TInt aNumBits)
+ {
+ return(aBits>>(32-aNumBits));
+ }
+
+
+// CTiffFax1dDecoder.
+CTiffFax1dDecoder::~CTiffFax1dDecoder()
+ {
+ delete []iRunData;
+ delete iImageProcessor;
+ }
+
+void CTiffFax1dDecoder::ConstructL(const TTiffImageData& aImageData)
+ {
+ iImageData = &aImageData;
+
+ if((iImageData->iBitsPerSample>1) || (iImageData->iSamplesPerPixel>1))
+ User::Leave(KErrNotSupported);
+
+ if(iImageData->iFillOrder==2)
+ iReverseBitsInByte = ETrue;
+
+ // note officially should check for iImageData->iPhotometricInterpretation==EBlackIsZero
+ // and reverse black, white interpretation, but some TIFF writers break this rule and other
+ // readers ignore it
+ iBlack = KRgbBlack;
+ iWhite = KRgbWhite;
+
+ iRowWidth = iImageData->iSizeInPixels.iWidth;
+ iRowNumber = 0;
+ iRunData = new (ELeave) TInt[iRowWidth+2];
+ }
+
+void CTiffFax1dDecoder::DoNewFrameL(CFbsBitmap& aBitmap, TBool aDisableErrorDiffusion, TInt aReductionFactor)
+ {
+ delete iImageProcessor;
+ iImageProcessor = NULL;
+
+ iImageProcessor = ImageProcessorUtility::NewImageProcessorL(aBitmap, aReductionFactor, EGray2, aDisableErrorDiffusion);
+ iImageProcessor->PrepareL(aBitmap,iImageData->iSizeInPixels);
+ }
+
+void CTiffFax1dDecoder::NewStripL(TInt aNumBytes)
+ {
+ if(!aNumBytes)
+ aNumBytes = KMaxTInt;
+
+ iRowsRemaining = iImageData->iRowsPerStrip;
+
+ TInt maxRows = iImageData->iSizeInPixels.iHeight-iRowNumber;
+ if( (iRowsRemaining>maxRows) || (iRowsRemaining<=0) )
+ iRowsRemaining = maxRows;
+
+ iPixelsStoredInRow = 0;
+
+ iBitCache = 0;
+ iBitCacheLength = 0;
+
+ iCodeType = ETiffFaxWhiteRun;
+
+ CTiffFax1dDecoder::NewRow();
+ }
+
+void CTiffFax1dDecoder::NewRow()
+ {
+ iColor = ETiffFaxWhiteRun;
+ iRunDataIndex = 0;
+ iRunData[0] = 0;
+ }
+
+TBool CTiffFax1dDecoder::ProcessStripL(TBufPtr8* aSrc)
+ {
+ const TUint8* sourceBuffer = aSrc->Ptr();
+ iSourcePtr = sourceBuffer;
+ iSourcePtrLimit = iSourcePtr+aSrc->Length();
+
+ UseBits(0);
+
+ FOREVER
+ {
+ switch(ProcessNextCode())
+ {
+ case ETiffFaxUnderflow:
+ aSrc->Shift(iSourcePtr-sourceBuffer);
+ return(EFalse);
+
+ case ETiffFaxInvalid:
+ User::Leave(KErrCorrupt);
+
+ case ETiffFaxEndOfLine:
+ if(iPixelsStoredInRow==0)
+ continue;
+
+ if(iPixelsStoredInRow!=iRowWidth)
+ User::Leave(KErrCorrupt);
+
+ NewRow();
+
+ iPixelsStoredInRow = 0;
+ iRowNumber++;
+ iRowsRemaining--;
+ continue;
+
+ case ETiffFaxPixelRun:
+ if(!iCodeCount)
+ continue;
+
+ {
+ TInt n = iPixelsStoredInRow+iCodeCount;
+
+ if(n>iRowWidth)
+ User::Leave(KErrCorrupt);
+
+ if(iCodeType==ETiffFaxBlackRun)
+ {
+ iImageProcessor->SetMonoPixelRun(0,iCodeCount);
+
+ if(!(iRunDataIndex&1))
+ iRunDataIndex++;
+ }
+ else
+ {
+ iImageProcessor->SetMonoPixelRun(255,iCodeCount);
+
+ if(iRunDataIndex&1)
+ iRunDataIndex++;
+ }
+
+ iPixelsStoredInRow = n;
+ iRunData[iRunDataIndex] = n;
+
+ if((n!=iRowWidth) || (iRowsRemaining!=1)) // Continue if not last pixel of image
+ continue;
+ }
+
+ // else drop through....
+
+ case ETiffFaxEndOfFax:
+ iImageProcessor->FlushPixels();
+ return(ETrue);
+ }
+ }
+ }
+
+LOCAL_D const TUint8 KByteFlip[256] =
+ {
+ 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
+ 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
+ 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
+ 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
+ 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
+ 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
+ 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
+ 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
+ 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
+ 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
+ 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
+ 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
+ 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
+ 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
+ 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
+ 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
+ };
+
+void CTiffFax1dDecoder::UseBits(TInt aNumBits)
+ {
+ ASSERT(aNumBits<=iBitCacheLength);
+
+ TInt validBits = iBitCacheLength-aNumBits;
+ TUint32 bits = iBitCache<<aNumBits;
+
+ if(validBits>=KMaxHuffmanCodeLength)
+ {
+ iBitCache = bits;
+ iBitCacheLength = validBits;
+ return;
+ }
+
+ TInt shift = 32-validBits;
+ const TUint8* ptr = iSourcePtr;
+
+ TInt numBytes = shift>>3;
+ TInt maxBytes = iSourcePtrLimit-ptr;
+ if(numBytes>maxBytes)
+ numBytes = maxBytes;
+
+ iBitCacheLength = validBits+numBytes*8;
+
+ const TUint8* ptrLimit = ptr+numBytes;
+
+ if(iReverseBitsInByte)
+ {
+ while(ptr<ptrLimit)
+ {
+ TInt byte = *(ptr++);
+ byte = KByteFlip[byte]; // reverse bits within byte
+ shift -= 8;
+ bits |= byte<<shift;
+ }
+ }
+ else
+ {
+ while(ptr<ptrLimit)
+ {
+ TInt byte = *(ptr++);
+ shift -= 8;
+ bits |= byte<<shift;
+ }
+ }
+
+ iBitCache = bits;
+ iSourcePtr = ptr;
+
+ return;
+ }
+
+TTiffFaxState CTiffFax1dDecoder::Decode1d()
+ {
+ if(iBitCache&0xff000000)
+ {
+ if(iColor==ETiffFaxWhiteRun)
+ return(DecodeWhite());
+ else
+ return(DecodeBlack());
+ }
+ else
+ return(DecodeEndOfLine());
+ }
+
+#define HUFFMAN_DECODE_ENTRY(aCount,aNumBits) (aCount<<4)+aNumBits
+LOCAL_D const TUint16 White0000[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(0 ,0),
+ HUFFMAN_DECODE_ENTRY(0 ,0),
+ HUFFMAN_DECODE_ENTRY(29 ,8),
+ HUFFMAN_DECODE_ENTRY(30 ,8),
+ HUFFMAN_DECODE_ENTRY(45 ,8),
+ HUFFMAN_DECODE_ENTRY(46 ,8),
+ HUFFMAN_DECODE_ENTRY(22 ,7),
+ HUFFMAN_DECODE_ENTRY(22 ,7),
+
+ HUFFMAN_DECODE_ENTRY(23 ,7),
+ HUFFMAN_DECODE_ENTRY(23 ,7),
+ HUFFMAN_DECODE_ENTRY(47 ,8),
+ HUFFMAN_DECODE_ENTRY(48 ,8),
+ HUFFMAN_DECODE_ENTRY(13 ,6),
+ HUFFMAN_DECODE_ENTRY(13 ,6),
+ HUFFMAN_DECODE_ENTRY(13 ,6),
+ HUFFMAN_DECODE_ENTRY(13 ,6)
+ };
+
+LOCAL_D const TUint16 White0001[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(20 ,7),
+ HUFFMAN_DECODE_ENTRY(20 ,7),
+ HUFFMAN_DECODE_ENTRY(33 ,8),
+ HUFFMAN_DECODE_ENTRY(34 ,8),
+ HUFFMAN_DECODE_ENTRY(35 ,8),
+ HUFFMAN_DECODE_ENTRY(36 ,8),
+ HUFFMAN_DECODE_ENTRY(37 ,8),
+ HUFFMAN_DECODE_ENTRY(38 ,8),
+
+ HUFFMAN_DECODE_ENTRY(19 ,7),
+ HUFFMAN_DECODE_ENTRY(19 ,7),
+ HUFFMAN_DECODE_ENTRY(31 ,8),
+ HUFFMAN_DECODE_ENTRY(32 ,8),
+ HUFFMAN_DECODE_ENTRY(1 ,6),
+ HUFFMAN_DECODE_ENTRY(1 ,6),
+ HUFFMAN_DECODE_ENTRY(1 ,6),
+ HUFFMAN_DECODE_ENTRY(1 ,6)
+ };
+
+LOCAL_D const TUint16 White0010[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(12 ,6),
+ HUFFMAN_DECODE_ENTRY(12 ,6),
+ HUFFMAN_DECODE_ENTRY(12 ,6),
+ HUFFMAN_DECODE_ENTRY(12 ,6),
+ HUFFMAN_DECODE_ENTRY(53 ,8),
+ HUFFMAN_DECODE_ENTRY(54 ,8),
+ HUFFMAN_DECODE_ENTRY(26 ,7),
+ HUFFMAN_DECODE_ENTRY(26 ,7),
+
+ HUFFMAN_DECODE_ENTRY(39 ,8),
+ HUFFMAN_DECODE_ENTRY(40 ,8),
+ HUFFMAN_DECODE_ENTRY(41 ,8),
+ HUFFMAN_DECODE_ENTRY(42 ,8),
+ HUFFMAN_DECODE_ENTRY(43 ,8),
+ HUFFMAN_DECODE_ENTRY(44 ,8),
+ HUFFMAN_DECODE_ENTRY(21 ,7),
+ HUFFMAN_DECODE_ENTRY(21 ,7)
+ };
+
+LOCAL_D const TUint16 White0011[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(28 ,7),
+ HUFFMAN_DECODE_ENTRY(28 ,7),
+ HUFFMAN_DECODE_ENTRY(61 ,8),
+ HUFFMAN_DECODE_ENTRY(62 ,8),
+ HUFFMAN_DECODE_ENTRY(63 ,8),
+ HUFFMAN_DECODE_ENTRY(0 ,8),
+ HUFFMAN_DECODE_ENTRY(320 ,8),
+ HUFFMAN_DECODE_ENTRY(384 ,8),
+
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5),
+ HUFFMAN_DECODE_ENTRY(10 ,5)
+ };
+
+LOCAL_D const TUint16 White0100[32] =
+ {
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+ HUFFMAN_DECODE_ENTRY(11 ,5),
+
+ HUFFMAN_DECODE_ENTRY(27 ,7),
+ HUFFMAN_DECODE_ENTRY(27 ,7),
+ HUFFMAN_DECODE_ENTRY(27 ,7),
+ HUFFMAN_DECODE_ENTRY(27 ,7),
+ HUFFMAN_DECODE_ENTRY(59 ,8),
+ HUFFMAN_DECODE_ENTRY(59 ,8),
+ HUFFMAN_DECODE_ENTRY(60 ,8),
+ HUFFMAN_DECODE_ENTRY(60 ,8),
+
+ HUFFMAN_DECODE_ENTRY(1472 ,9),
+ HUFFMAN_DECODE_ENTRY(1536 ,9),
+ HUFFMAN_DECODE_ENTRY(1600 ,9),
+ HUFFMAN_DECODE_ENTRY(1728 ,9),
+ HUFFMAN_DECODE_ENTRY(18 ,7),
+ HUFFMAN_DECODE_ENTRY(18 ,7),
+ HUFFMAN_DECODE_ENTRY(18 ,7),
+ HUFFMAN_DECODE_ENTRY(18 ,7)
+ };
+
+LOCAL_D const TUint16 White0101[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(24 ,7),
+ HUFFMAN_DECODE_ENTRY(24 ,7),
+ HUFFMAN_DECODE_ENTRY(49 ,8),
+ HUFFMAN_DECODE_ENTRY(50 ,8),
+ HUFFMAN_DECODE_ENTRY(51 ,8),
+ HUFFMAN_DECODE_ENTRY(52 ,8),
+ HUFFMAN_DECODE_ENTRY(25 ,7),
+ HUFFMAN_DECODE_ENTRY(25 ,7),
+
+ HUFFMAN_DECODE_ENTRY(55 ,8),
+ HUFFMAN_DECODE_ENTRY(56 ,8),
+ HUFFMAN_DECODE_ENTRY(57 ,8),
+ HUFFMAN_DECODE_ENTRY(58 ,8),
+ HUFFMAN_DECODE_ENTRY(192 ,6),
+ HUFFMAN_DECODE_ENTRY(192 ,6),
+ HUFFMAN_DECODE_ENTRY(192 ,6),
+ HUFFMAN_DECODE_ENTRY(192 ,6)
+ };
+
+LOCAL_D const TUint16 White0110[32] =
+ {
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+ HUFFMAN_DECODE_ENTRY(1664 ,6),
+
+ HUFFMAN_DECODE_ENTRY(448 ,8),
+ HUFFMAN_DECODE_ENTRY(448 ,8),
+ HUFFMAN_DECODE_ENTRY(512 ,8),
+ HUFFMAN_DECODE_ENTRY(512 ,8),
+ HUFFMAN_DECODE_ENTRY(704 ,9),
+ HUFFMAN_DECODE_ENTRY(768 ,9),
+ HUFFMAN_DECODE_ENTRY(640 ,8),
+ HUFFMAN_DECODE_ENTRY(640 ,8),
+
+ HUFFMAN_DECODE_ENTRY(576 ,8),
+ HUFFMAN_DECODE_ENTRY(576 ,8),
+ HUFFMAN_DECODE_ENTRY(832 ,9),
+ HUFFMAN_DECODE_ENTRY(896 ,9),
+ HUFFMAN_DECODE_ENTRY(960 ,9),
+ HUFFMAN_DECODE_ENTRY(1024 ,9),
+ HUFFMAN_DECODE_ENTRY(1088 ,9),
+ HUFFMAN_DECODE_ENTRY(1152 ,9),
+
+ HUFFMAN_DECODE_ENTRY(1216 ,9),
+ HUFFMAN_DECODE_ENTRY(1280 ,9),
+ HUFFMAN_DECODE_ENTRY(1344 ,9),
+ HUFFMAN_DECODE_ENTRY(1408 ,9),
+ HUFFMAN_DECODE_ENTRY(256 ,7),
+ HUFFMAN_DECODE_ENTRY(256 ,7),
+ HUFFMAN_DECODE_ENTRY(256 ,7),
+ HUFFMAN_DECODE_ENTRY(256 ,7)
+ };
+
+LOCAL_D const TUint16 White0111[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(2 ,4)
+ };
+
+LOCAL_D const TUint16 White1000[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(3 ,4)
+ };
+
+LOCAL_D const TUint16 White1001[2] =
+ {
+ HUFFMAN_DECODE_ENTRY(128 ,5),
+ HUFFMAN_DECODE_ENTRY(8 ,5)
+ };
+
+LOCAL_D const TUint16 White1010[4] =
+ {
+ HUFFMAN_DECODE_ENTRY(9 ,5),
+ HUFFMAN_DECODE_ENTRY(9 ,5),
+ HUFFMAN_DECODE_ENTRY(16 ,6),
+ HUFFMAN_DECODE_ENTRY(17 ,6)
+ };
+
+LOCAL_D const TUint16 White1011[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(4 ,4)
+ };
+
+LOCAL_D const TUint16 White1100[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(5 ,4)
+ };
+
+LOCAL_D const TUint16 White1101[4] =
+ {
+ HUFFMAN_DECODE_ENTRY(14 ,6),
+ HUFFMAN_DECODE_ENTRY(15 ,6),
+ HUFFMAN_DECODE_ENTRY(64 ,5),
+ HUFFMAN_DECODE_ENTRY(64 ,5)
+ };
+
+LOCAL_D const TUint16 White1110[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(6 ,4)
+ };
+
+LOCAL_D const TUint16 White1111[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(7 ,4)
+ };
+
+LOCAL_D const TUint16 Black0001[4] =
+ {
+ HUFFMAN_DECODE_ENTRY(9 ,6),
+ HUFFMAN_DECODE_ENTRY(8 ,6),
+ HUFFMAN_DECODE_ENTRY(7 ,5),
+ HUFFMAN_DECODE_ENTRY(7 ,5)
+ };
+
+LOCAL_D const TUint16 Black0010[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(6 ,4)
+ };
+
+LOCAL_D const TUint16 Black0011[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(5 ,4)
+ };
+
+LOCAL_D const TUint16 Black010x[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(1 ,3)
+ };
+
+LOCAL_D const TUint16 Black011x[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(4 ,3)
+ };
+
+LOCAL_D const TUint16 Black10xx[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(3 ,2)
+ };
+
+LOCAL_D const TUint16 Black11xx[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(2 ,2)
+ };
+
+LOCAL_D const TUint16 Black0000_0010[32] =
+ {
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+ HUFFMAN_DECODE_ENTRY(18 ,10),
+
+ HUFFMAN_DECODE_ENTRY(52 ,12),
+ HUFFMAN_DECODE_ENTRY(52 ,12),
+ HUFFMAN_DECODE_ENTRY(640 ,13),
+ HUFFMAN_DECODE_ENTRY(704 ,13),
+ HUFFMAN_DECODE_ENTRY(768 ,13),
+ HUFFMAN_DECODE_ENTRY(832 ,13),
+ HUFFMAN_DECODE_ENTRY(55 ,12),
+ HUFFMAN_DECODE_ENTRY(55 ,12),
+
+ HUFFMAN_DECODE_ENTRY(56 ,12),
+ HUFFMAN_DECODE_ENTRY(56 ,12),
+ HUFFMAN_DECODE_ENTRY(1280 ,13),
+ HUFFMAN_DECODE_ENTRY(1344 ,13),
+ HUFFMAN_DECODE_ENTRY(1408 ,13),
+ HUFFMAN_DECODE_ENTRY(1472 ,13),
+ HUFFMAN_DECODE_ENTRY(59 ,12),
+ HUFFMAN_DECODE_ENTRY(59 ,12),
+
+ HUFFMAN_DECODE_ENTRY(60 ,12),
+ HUFFMAN_DECODE_ENTRY(60 ,12),
+ HUFFMAN_DECODE_ENTRY(1536 ,13),
+ HUFFMAN_DECODE_ENTRY(1600 ,13),
+ HUFFMAN_DECODE_ENTRY(24 ,11),
+ HUFFMAN_DECODE_ENTRY(24 ,11),
+ HUFFMAN_DECODE_ENTRY(24 ,11),
+ HUFFMAN_DECODE_ENTRY(24 ,11)
+ };
+
+LOCAL_D const TUint16 Black0000_0011[32] =
+ {
+ HUFFMAN_DECODE_ENTRY(25 ,11),
+ HUFFMAN_DECODE_ENTRY(25 ,11),
+ HUFFMAN_DECODE_ENTRY(25 ,11),
+ HUFFMAN_DECODE_ENTRY(25 ,11),
+ HUFFMAN_DECODE_ENTRY(1664 ,13),
+ HUFFMAN_DECODE_ENTRY(1728 ,13),
+ HUFFMAN_DECODE_ENTRY(320 ,12),
+ HUFFMAN_DECODE_ENTRY(320 ,12),
+
+ HUFFMAN_DECODE_ENTRY(384 ,12),
+ HUFFMAN_DECODE_ENTRY(384 ,12),
+ HUFFMAN_DECODE_ENTRY(448 ,12),
+ HUFFMAN_DECODE_ENTRY(448 ,12),
+ HUFFMAN_DECODE_ENTRY(512 ,13),
+ HUFFMAN_DECODE_ENTRY(576 ,13),
+ HUFFMAN_DECODE_ENTRY(53 ,12),
+ HUFFMAN_DECODE_ENTRY(53 ,12),
+
+ HUFFMAN_DECODE_ENTRY(54 ,12),
+ HUFFMAN_DECODE_ENTRY(54 ,12),
+ HUFFMAN_DECODE_ENTRY(896 ,13),
+ HUFFMAN_DECODE_ENTRY(960 ,13),
+ HUFFMAN_DECODE_ENTRY(1024 ,13),
+ HUFFMAN_DECODE_ENTRY(1088 ,13),
+ HUFFMAN_DECODE_ENTRY(1152 ,13),
+ HUFFMAN_DECODE_ENTRY(1216 ,13),
+
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10),
+ HUFFMAN_DECODE_ENTRY(64 ,10)
+ };
+
+LOCAL_D const TUint16 Black0000_0100[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(13 ,8)
+ };
+
+LOCAL_D const TUint16 Black0000_0101[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(23 ,11),
+ HUFFMAN_DECODE_ENTRY(23 ,11),
+ HUFFMAN_DECODE_ENTRY(50 ,12),
+ HUFFMAN_DECODE_ENTRY(51 ,12),
+ HUFFMAN_DECODE_ENTRY(44 ,12),
+ HUFFMAN_DECODE_ENTRY(45 ,12),
+ HUFFMAN_DECODE_ENTRY(46 ,12),
+ HUFFMAN_DECODE_ENTRY(47 ,12),
+
+ HUFFMAN_DECODE_ENTRY(57 ,12),
+ HUFFMAN_DECODE_ENTRY(58 ,12),
+ HUFFMAN_DECODE_ENTRY(61 ,12),
+ HUFFMAN_DECODE_ENTRY(256 ,12),
+ HUFFMAN_DECODE_ENTRY(16 ,10),
+ HUFFMAN_DECODE_ENTRY(16 ,10),
+ HUFFMAN_DECODE_ENTRY(16 ,10),
+ HUFFMAN_DECODE_ENTRY(16 ,10)
+ };
+
+LOCAL_D const TUint16 Black0000_0110[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(17 ,10),
+ HUFFMAN_DECODE_ENTRY(17 ,10),
+ HUFFMAN_DECODE_ENTRY(17 ,10),
+ HUFFMAN_DECODE_ENTRY(17 ,10),
+ HUFFMAN_DECODE_ENTRY(48 ,12),
+ HUFFMAN_DECODE_ENTRY(49 ,12),
+ HUFFMAN_DECODE_ENTRY(62 ,12),
+ HUFFMAN_DECODE_ENTRY(63 ,12),
+
+ HUFFMAN_DECODE_ENTRY(30 ,12),
+ HUFFMAN_DECODE_ENTRY(31 ,12),
+ HUFFMAN_DECODE_ENTRY(32 ,12),
+ HUFFMAN_DECODE_ENTRY(33 ,12),
+ HUFFMAN_DECODE_ENTRY(40 ,12),
+ HUFFMAN_DECODE_ENTRY(41 ,12),
+ HUFFMAN_DECODE_ENTRY(22 ,11),
+ HUFFMAN_DECODE_ENTRY(22 ,11)
+ };
+
+LOCAL_D const TUint16 Black0000_0111[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(14 ,8)
+ };
+
+LOCAL_D const TUint16 Black0000_100x[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(10 ,7)
+ };
+
+LOCAL_D const TUint16 Black0000_101x[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(11 ,7)
+ };
+
+LOCAL_D const TUint16 Black0000_1100[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+ HUFFMAN_DECODE_ENTRY(15 ,9),
+
+ HUFFMAN_DECODE_ENTRY(128 ,12),
+ HUFFMAN_DECODE_ENTRY(192 ,12),
+ HUFFMAN_DECODE_ENTRY(26 ,12),
+ HUFFMAN_DECODE_ENTRY(27 ,12),
+ HUFFMAN_DECODE_ENTRY(28 ,12),
+ HUFFMAN_DECODE_ENTRY(29 ,12),
+ HUFFMAN_DECODE_ENTRY(19 ,11),
+ HUFFMAN_DECODE_ENTRY(19 ,11)
+ };
+
+LOCAL_D const TUint16 Black0000_1101[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(20 ,11),
+ HUFFMAN_DECODE_ENTRY(20 ,11),
+ HUFFMAN_DECODE_ENTRY(34 ,12),
+ HUFFMAN_DECODE_ENTRY(35 ,12),
+ HUFFMAN_DECODE_ENTRY(36 ,12),
+ HUFFMAN_DECODE_ENTRY(37 ,12),
+ HUFFMAN_DECODE_ENTRY(38 ,12),
+ HUFFMAN_DECODE_ENTRY(39 ,12),
+
+ HUFFMAN_DECODE_ENTRY(21 ,11),
+ HUFFMAN_DECODE_ENTRY(21 ,11),
+ HUFFMAN_DECODE_ENTRY(42 ,12),
+ HUFFMAN_DECODE_ENTRY(43 ,12),
+ HUFFMAN_DECODE_ENTRY(0 ,10),
+ HUFFMAN_DECODE_ENTRY(0 ,10),
+ HUFFMAN_DECODE_ENTRY(0 ,10),
+ HUFFMAN_DECODE_ENTRY(0 ,10)
+ };
+
+LOCAL_D const TUint16 Black0000_111x[1] =
+ {
+ HUFFMAN_DECODE_ENTRY(12 ,7)
+ };
+
+LOCAL_D const TUint16 Common0000_0001[16] =
+ {
+ HUFFMAN_DECODE_ENTRY(1792 ,11),
+ HUFFMAN_DECODE_ENTRY(1792 ,11),
+ HUFFMAN_DECODE_ENTRY(1984 ,12),
+ HUFFMAN_DECODE_ENTRY(2048 ,12),
+ HUFFMAN_DECODE_ENTRY(2112 ,12),
+ HUFFMAN_DECODE_ENTRY(2176 ,12),
+ HUFFMAN_DECODE_ENTRY(2240 ,12),
+ HUFFMAN_DECODE_ENTRY(2304 ,12),
+ HUFFMAN_DECODE_ENTRY(1856 ,11),
+ HUFFMAN_DECODE_ENTRY(1856 ,11),
+ HUFFMAN_DECODE_ENTRY(1920 ,11),
+ HUFFMAN_DECODE_ENTRY(1920 ,11),
+ HUFFMAN_DECODE_ENTRY(2368 ,12),
+ HUFFMAN_DECODE_ENTRY(2432 ,12),
+ HUFFMAN_DECODE_ENTRY(2496 ,12),
+ HUFFMAN_DECODE_ENTRY(2560 ,12)
+ };
+
+class THuffmanTable
+ {
+public:
+ const TUint16* iCodes;
+ TInt iIndexBits; // Number of bits to use for indexing into iCodes
+ };
+
+LOCAL_D const THuffmanTable WhiteTables[32] =
+ {
+ {White0000,4},
+ {White0001,4},
+ {White0010,4},
+ {White0011,4},
+ {White0100,5},
+ {White0101,4},
+ {White0110,5},
+ {White0111,0},
+ {White1000,0},
+ {White1001,1},
+ {White1010,2},
+ {White1011,0},
+ {White1100,0},
+ {White1101,2},
+ {White1110,0},
+ {White1111,0},
+ };
+
+LOCAL_D const THuffmanTable BlackTables[16] =
+ {
+ {NULL,0},
+ {Black0001,2},
+ {Black0010,0},
+ {Black0011,0},
+ {Black010x,0},
+ {Black010x,0},
+ {Black011x,0},
+ {Black011x,0},
+ {Black10xx,0},
+ {Black10xx,0},
+ {Black10xx,0},
+ {Black10xx,0},
+ {Black11xx,0},
+ {Black11xx,0},
+ {Black11xx,0},
+ {Black11xx,0},
+ };
+
+LOCAL_D const THuffmanTable BlackTables0000[16] =
+ {
+ {NULL,0},
+ {Common0000_0001,4},
+ {Black0000_0010,5},
+ {Black0000_0011,5},
+ {Black0000_0100,0},
+ {Black0000_0101,4},
+ {Black0000_0110,4},
+ {Black0000_0111,0},
+ {Black0000_100x,0},
+ {Black0000_100x,0},
+ {Black0000_101x,0},
+ {Black0000_101x,0},
+ {Black0000_1100,4},
+ {Black0000_1101,4},
+ {Black0000_111x,0},
+ {Black0000_111x,0},
+ };
+
+TTiffFaxState CTiffFax1dDecoder::DecodeWhite()
+ {
+ TUint32 bits = iBitCache;
+ TUint16 code;
+
+ if(bits>=0x02000000)
+ {
+ const THuffmanTable* table = &WhiteTables[GetMostSignificantBits(bits,4)];
+ bits &= ~0xf0000000; // zero the 4 most significant bits
+ code = table->iCodes[GetMostSignificantBits(bits,4+table->iIndexBits)];
+ }
+ else if(bits>=0x01000000)
+ {
+ bits &= ~0xff000000; // zero the 8 most significant bits
+ code = Common0000_0001[GetMostSignificantBits(bits,8+4)];
+ }
+ else
+ return(ETiffFaxInvalid);
+
+ TInt numBits = code&15;
+
+ if(numBits>iBitCacheLength)
+ return(ETiffFaxUnderflow);
+
+ UseBits(numBits);
+
+ iCodeType = ETiffFaxWhiteRun;
+ iCodeCount = code>>4;
+
+ if(iCodeCount<64)
+ iColor = ETiffFaxBlackRun;
+
+ return(ETiffFaxPixelRun);
+ }
+
+TTiffFaxState CTiffFax1dDecoder::DecodeBlack()
+ {
+ TUint32 bits = iBitCache;
+ TUint16 code;
+
+ if(bits&0xf0000000)
+ {
+ const THuffmanTable* table = &BlackTables[GetMostSignificantBits(bits,4)];
+ bits &= ~0xf0000000; // zero the 4 most significant bits
+ code = table->iCodes[GetMostSignificantBits(bits,4+table->iIndexBits)];
+ }
+ else if(bits&0xff000000)
+ {
+ const THuffmanTable* table = &BlackTables0000[GetMostSignificantBits(bits,8)];
+ bits &= ~0xff000000; // zero the 8 most significant bits
+ code = table->iCodes[GetMostSignificantBits(bits,8+table->iIndexBits)];
+ }
+ else
+ return(ETiffFaxInvalid);
+
+ TInt numBits = code&15;
+
+ if(numBits>iBitCacheLength)
+ return(ETiffFaxUnderflow);
+
+ UseBits(numBits);
+
+ iCodeType = ETiffFaxBlackRun;
+ iCodeCount = code>>4;
+
+ if(iCodeCount<64)
+ iColor = ETiffFaxWhiteRun;
+
+ return(ETiffFaxPixelRun);
+ }
+
+TTiffFaxState CTiffFax1dDecoder::DecodeEndOfLine()
+ {
+ if(iBitCache>=0x00200000)
+ return(ETiffFaxInvalid);
+
+ FOREVER
+ {
+ if(iBitCacheLength<12)
+ return(ETiffFaxUnderflow);
+ if(iBitCache&0x00100000)
+ break;
+ UseBits(1);
+ }
+
+ UseBits(12);
+
+ iColor = ETiffFaxWhiteRun;
+
+ iCodeCount = 1;
+
+ if(iCodeType==ETiffFaxEndOfLineCode)
+ return(ETiffFaxEndOfFax);
+
+ iCodeType = ETiffFaxEndOfLineCode;
+ return(ETiffFaxEndOfLine);
+ }
+
+
+// CTiffFax2dDecoder.
+CTiffFax2dDecoder::~CTiffFax2dDecoder()
+ {
+ delete []iReferenceRunData;
+ }
+
+void CTiffFax2dDecoder::ConstructL(const TTiffImageData& aImageData)
+ {
+ CTiffFax1dDecoder::ConstructL(aImageData);
+ iReferenceRunData = new (ELeave) TInt[iRowWidth+2];
+ }
+
+void CTiffFax2dDecoder::NewStripL(TInt aNumBytes)
+ {
+ CTiffFax1dDecoder::NewStripL(aNumBytes);
+ CTiffFax2dDecoder::NewRow();
+ }
+
+void CTiffFax2dDecoder::NewRow()
+ {
+ if(iRunDataIndex&1)
+ iRunDataIndex++;
+ iRunData[iRunDataIndex] = iRowWidth;
+ iRunData[iRunDataIndex+1] = iRowWidth;
+
+ TInt* temp = iReferenceRunData;
+ iReferenceRunData = iRunData;
+ iRunData = temp;
+
+ iReferenceRunDataIndex = 0;
+ iHorizontalCodeCount = 0;
+ iA0 = 0;
+
+ CTiffFax1dDecoder::NewRow();
+ }
+
+TTiffFaxState CTiffFax2dDecoder::Decode2d()
+ {
+ if(iHorizontalCodeCount)
+ return(DecodeHorizontal());
+
+ TUint32 bits = iBitCache;
+ TInt validBits;
+ TInt verticalOffset;
+
+ switch(GetMostSignificantBits(bits,3))
+ {
+ case 0:
+
+ switch(GetMostSignificantBits(bits,7))
+ {
+ case 0:
+ case 1:
+ return(DecodeEndOfLine());
+ case 2:
+ verticalOffset = -3;
+ validBits = 7;
+ break;
+ case 3:
+ verticalOffset = 3;
+ validBits = 7;
+ break;
+ case 4:
+ case 5:
+ verticalOffset = -2;
+ validBits = 6;
+ break;
+ case 6:
+ case 7:
+ verticalOffset = 2;
+ validBits = 6;
+ break;
+ default:
+ if(iBitCacheLength<4)
+ return(ETiffFaxUnderflow);
+ UseBits(4);
+ return(DecodePass());
+ }
+
+ break;
+
+ case 1:
+ if(iBitCacheLength<3)
+ return(ETiffFaxUnderflow);
+ UseBits(3);
+ iHorizontalCodeCount = 2;
+ return(DecodeHorizontal());
+
+ case 2:
+
+ verticalOffset = -1;
+ validBits = 3;
+ break;
+
+ case 3:
+
+ verticalOffset = 1;
+ validBits = 3;
+ break;
+
+ default:
+
+ verticalOffset = 0;
+ validBits = 1;
+ break;
+ }
+
+ if(validBits>iBitCacheLength)
+ return(ETiffFaxUnderflow);
+
+ UseBits(validBits);
+
+ return(DecodeVertical(verticalOffset));
+ }
+
+TTiffFaxState CTiffFax2dDecoder::DecodeHorizontal()
+ {
+ TTiffFaxState returnValue;
+
+ returnValue = Decode1d();
+ if(returnValue!=ETiffFaxPixelRun)
+ return(returnValue);
+
+ iA0 += iCodeCount;
+
+ if(iCodeCount<64)
+ iHorizontalCodeCount--;
+
+ if(iHorizontalCodeCount)
+ return(ETiffFaxPixelRun);
+
+ TInt n = iA0;
+ if(n>=iRowWidth)
+ n = iRowWidth-1;
+
+ TInt i = iReferenceRunDataIndex;
+
+ while(iReferenceRunData[i]<=n)
+ i++;
+
+ if(iColor==ETiffFaxBlackRun)
+ {
+ if(!(i&1))
+ i++;
+ }
+ else
+ {
+ if(i&1)
+ i++;
+ }
+
+ iReferenceRunDataIndex = i;
+
+ return(ETiffFaxPixelRun);
+ }
+
+TTiffFaxState CTiffFax2dDecoder::DecodeVertical(TInt aDifference)
+ {
+ iA0 = iReferenceRunData[iReferenceRunDataIndex]+aDifference;
+
+ iCodeCount = iA0-iPixelsStoredInRow;
+ iCodeType = iColor;
+
+ if(iColor==ETiffFaxWhiteRun)
+ iColor = ETiffFaxBlackRun;
+ else
+ iColor = ETiffFaxWhiteRun;
+
+ TInt n = iA0;
+ if(n>=iRowWidth)
+ n = iRowWidth-1;
+
+ TInt i = iReferenceRunDataIndex;
+
+ if(i)
+ i--;
+ else
+ i++;
+
+ while(iReferenceRunData[i]<=n)
+ i += 2;
+
+ iReferenceRunDataIndex = i;
+
+ return(ETiffFaxPixelRun);
+ }
+
+TTiffFaxState CTiffFax2dDecoder::DecodePass()
+ {
+ iA0 = iReferenceRunData[iReferenceRunDataIndex+1];
+ iReferenceRunDataIndex += 2;
+
+ iCodeCount = iA0-iPixelsStoredInRow;
+ iCodeType = iColor;
+
+ return(ETiffFaxPixelRun);
+ }
+
+
+// CTiffGroup3Fax1dDecoder.
+CTiffGroup3Fax1dDecoder* CTiffGroup3Fax1dDecoder::NewL(const TTiffImageData& aImageData)
+ {
+ if(aImageData.iT4Options & ~TTiffIfdEntry::ET4ContainsPaddedEols)
+ User::Leave(KErrNotSupported);
+
+ CTiffGroup3Fax1dDecoder* decoder = new (ELeave) CTiffGroup3Fax1dDecoder;
+
+ CleanupStack::PushL(decoder);
+ decoder->ConstructL(aImageData);
+ CleanupStack::Pop();
+
+ return(decoder);
+ }
+
+TTiffFaxState CTiffGroup3Fax1dDecoder::ProcessNextCode()
+ {
+ return(Decode1d());
+ }
+
+
+// CTiffGroup3Fax2dDecoder.
+CTiffGroup3Fax2dDecoder* CTiffGroup3Fax2dDecoder::NewL(const TTiffImageData& aImageData)
+ {
+ if( (aImageData.iT4Options&~TTiffIfdEntry::ET4ContainsPaddedEols) != TTiffIfdEntry::ET4TwoDimentionalCoding )
+ User::Leave(KErrNotSupported);
+
+ CTiffGroup3Fax2dDecoder* decoder = new (ELeave) CTiffGroup3Fax2dDecoder;
+
+ CleanupStack::PushL(decoder);
+ decoder->ConstructL(aImageData);
+ CleanupStack::Pop();
+
+ return(decoder);
+ }
+
+void CTiffGroup3Fax2dDecoder::NewStripL(TInt aNumBytes)
+ {
+ CTiffFax2dDecoder::NewStripL(aNumBytes);
+ iState = E1d;
+ }
+
+TTiffFaxState CTiffGroup3Fax2dDecoder::ProcessNextCode()
+ {
+ if(iState!=ESelect1d2d)
+ {
+ TTiffFaxState returnValue;
+
+ if(iState==E1d)
+ returnValue = Decode1d();
+ else
+ returnValue = Decode2d();
+
+ if(returnValue!=ETiffFaxEndOfLine)
+ return(returnValue);
+
+ iState = ESelect1d2d;
+ }
+
+ if(!iBitCacheLength)
+ return(ETiffFaxUnderflow);
+
+ if(iBitCache&(1<<31))
+ iState = E1d;
+ else
+ iState = E2d;
+
+ UseBits(1);
+
+ return(ETiffFaxEndOfLine);
+ }
+
+void CTiffGroup3Fax2dDecoder::NewRow()
+ {
+ if(iState==E1d)
+ CTiffFax1dDecoder::NewRow();
+ else
+ CTiffFax2dDecoder::NewRow();
+ }
+
+
+// CTiffGroup4FaxDecoder.
+CTiffGroup4FaxDecoder* CTiffGroup4FaxDecoder::NewL(const TTiffImageData& aImageData)
+ {
+ if(aImageData.iT6Options!=0)
+ User::Leave(KErrNotSupported);
+
+ CTiffGroup4FaxDecoder* decoder = new (ELeave) CTiffGroup4FaxDecoder;
+
+ CleanupStack::PushL(decoder);
+ decoder->ConstructL(aImageData);
+ CleanupStack::Pop();
+
+ return(decoder);
+ }
+
+TTiffFaxState CTiffGroup4FaxDecoder::ProcessNextCode()
+ {
+ if((iA0==iRowWidth) && (iHorizontalCodeCount==0))
+ return(ETiffFaxEndOfLine);
+
+ return(Decode2d());
+ }
+