summaryrefslogtreecommitdiff
path: root/filter/source/graphicfilter/itiff/itiff.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/graphicfilter/itiff/itiff.cxx')
-rw-r--r--filter/source/graphicfilter/itiff/itiff.cxx1342
1 files changed, 1342 insertions, 0 deletions
diff --git a/filter/source/graphicfilter/itiff/itiff.cxx b/filter/source/graphicfilter/itiff/itiff.cxx
new file mode 100644
index 000000000000..5ad400fc3149
--- /dev/null
+++ b/filter/source/graphicfilter/itiff/itiff.cxx
@@ -0,0 +1,1342 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+#include <vcl/graph.hxx>
+#include <vcl/bmpacc.hxx>
+#ifndef _SV_FLTCALL_HXX
+#include <svtools/fltcall.hxx>
+#endif
+#include <vcl/animate.hxx>
+#include "lzwdecom.hxx"
+#include "ccidecom.hxx"
+
+#define OOODEBUG(str,Num) //(InfoBox(NULL,String(str)+String(" ")+String(Num)).Execute();
+
+namespace {
+
+template< typename T > T BYTESWAP(T nByte) {
+ return ( nByte << 7 ) | ( ( nByte & 2 ) << 5 ) | ( ( nByte & 4 ) << 3 ) |
+ ( ( nByte & 8 ) << 1 ) | ( ( nByte & 16 ) >> 1 ) |
+ ( ( nByte & 32 ) >> 3 ) | ( ( nByte & 64 ) >> 5 ) |
+ ( ( nByte & 128 ) >> 7 );
+}
+
+}
+
+//============================ TIFFReader ==================================
+
+class TIFFReader
+{
+
+private:
+
+ BOOL bStatus; // Ob bisher kein Fehler auftrat
+ Animation aAnimation;
+ ULONG nLastPercent;
+
+ SvStream* pTIFF; // Die einzulesende TIFF-Datei
+ Bitmap aBitmap;
+ BitmapWriteAccess* pAcc;
+ USHORT nDstBitsPerPixel;
+
+ ULONG nOrigPos; // Anfaengliche Position in pTIFF
+ UINT16 nOrigNumberFormat; // Anfaengliches Nummern-Format von pTIFF
+
+
+ UINT16 nDataType;
+ // Daten, die aus dem TIFF-Tags entnommen werden:
+ BOOL bByteSwap; // TRUE wenn bits 0..7 -> 7..0 invertiert werden sollen ( FILLORDER = 2 );
+ BYTE nByte1; // 'I', wenn Format LittleEndian
+
+ ULONG nNewSubFile; //
+ ULONG nSubFile; //
+ ULONG nImageWidth; // Bildbreite in Pixel
+ ULONG nImageLength; // Bildhoehe in Pixel
+ ULONG nBitsPerSample; // Bits pro Pixel pro Ebene
+ ULONG nCompression; // Art der Kompriemierung
+ ULONG nPhotometricInterpretation; //
+ ULONG nThresholding; //
+ ULONG nCellWidth; //
+ ULONG nCellLength; //
+ ULONG nFillOrder; //
+ ULONG* pStripOffsets; // Feld von Offsets zu den Bitmap-Daten-"Strips"
+ ULONG nNumStripOffsets; // Groesse obigen Feldes
+ ULONG nOrientation; //
+ ULONG nSamplesPerPixel; // Anzahl der Ebenen
+ ULONG nRowsPerStrip; // Wenn nicht komprimiert: Zahl der Zeilen pro Strip
+ ULONG* pStripByteCounts; // Wenn komprimiert (bestimmte Art): Groesse der Strips
+ ULONG nNumStripByteCounts; // Anzahl der Eintraege in obiges Feld
+ ULONG nMinSampleValue; //
+ ULONG nMaxSampleValue; //
+ double fXResolution; // X-Aufloesung oder 0.0
+ double fYResolution; // Y-Aufloesung oder 0.0
+ ULONG nPlanarConfiguration; //
+ ULONG nGroup3Options; //
+ ULONG nGroup4Options; //
+ ULONG nResolutionUnit; // Einheit von fX/YResolution: 1=unbekannt, 2(default)=Zoll, 3=cm
+ ULONG nPredictor; //
+ ULONG* pColorMap; // Farb-Palette
+ ULONG nNumColors; // Anzahl Farben in der Farbpalette
+
+ ULONG nPlanes; // Anzahl der Ebenen in der Tiff-Datei
+ ULONG nStripsPerPlane; // Anzahl der Strips pro Ebene
+ ULONG nBytesPerRow; // Bytes pro Zeile pro Ebene in der Tiff-Datei ( unkomprimiert )
+ BYTE* pMap[ 4 ]; // Temporaere Scanline
+
+
+ void MayCallback( ULONG nPercent );
+
+ ULONG DataTypeSize();
+ ULONG ReadIntData();
+ double ReadDoubleData();
+
+ void ReadHeader();
+ void ReadTagData( USHORT nTagType, sal_uInt32 nDataLen );
+
+ BOOL ReadMap( ULONG nMinPercent, ULONG nMaxPercent );
+ // Liesst/dekomprimert die Bitmap-Daten, und fuellt pMap
+
+ ULONG GetBits( const BYTE * pSrc, ULONG nBitsPos, ULONG nBitsCount );
+ // Holt nBitsCount Bits aus pSrc[..] an der Bit-Position nBitsPos
+
+ void MakePalCol( void );
+ // Erzeugt die Bitmap aus der temporaeren Bitmap pMap
+ // und loescht dabei pMap teilweise
+ BOOL ConvertScanline( ULONG nY );
+ // Konvertiert eine Scanline in das Windows-BMP-Format
+
+public:
+
+ TIFFReader() {}
+ ~TIFFReader() {}
+
+ BOOL ReadTIFF( SvStream & rTIFF, Graphic & rGraphic );
+};
+
+//=================== Methoden von TIFFReader ==============================
+
+void TIFFReader::MayCallback( ULONG /*nPercent*/ )
+{
+/*
+ if ( nPercent >= nLastPercent + 3 )
+ {
+ nLastPercent=nPercent;
+ if ( pCallback != NULL && nPercent <= 100 && bStatus == TRUE )
+ {
+ if (((*pCallback)(pCallerData,(USHORT)nPercent)) == TRUE )
+ bStatus = FALSE;
+ }
+ }
+*/
+}
+
+// ---------------------------------------------------------------------------------
+
+ULONG TIFFReader::DataTypeSize()
+{
+ ULONG nSize;
+ switch ( nDataType )
+ {
+ case 1 : // BYTE
+ case 2 : // ACSII
+ case 6 : // SIGNED Byte
+ case 7 : // UNDEFINED
+ nSize = 1;
+ break;
+ case 3 : // UINT16
+ case 8 : // INT16
+ nSize = 2;
+ break;
+ case 4 : // UINT32
+ case 9 : // INT32
+ case 11 : // FLOAT
+ nSize = 4;
+ break;
+ case 5 : // RATIONAL
+ case 10 : // SIGNED RATINAL
+ case 12 : // DOUBLE
+ nSize = 8;
+ break;
+ default:
+ pTIFF->SetError(SVSTREAM_FILEFORMAT_ERROR);
+ nSize=1;
+ }
+ return nSize;
+}
+
+// ---------------------------------------------------------------------------------
+
+ULONG TIFFReader::ReadIntData()
+{
+ double nDOUBLE;
+ float nFLOAT;
+ UINT32 nUINT32a, nUINT32b;
+ INT32 nINT32;
+ UINT16 nUINT16;
+ INT16 nINT16;
+ BYTE nBYTE;
+ char nCHAR;
+
+ switch( nDataType )
+ {
+ case 0 : //??
+ case 1 :
+ case 2 :
+ case 7 :
+ *pTIFF >> nBYTE;
+ nUINT32a = (ULONG)nBYTE;
+ break;
+ case 3 :
+ *pTIFF >> nUINT16;
+ nUINT32a = (ULONG)nUINT16;
+ break;
+ case 9 :
+ case 4 :
+ *pTIFF >> nUINT32a;
+ break;
+ case 5 :
+ *pTIFF >> nUINT32a >> nUINT32b;
+ if ( nUINT32b != 0 )
+ nUINT32a /= nUINT32b;
+ break;
+ case 6 :
+ *pTIFF >> nCHAR;
+ nUINT32a = (INT32)nCHAR;
+ break;
+ case 8 :
+ *pTIFF >> nINT16;
+ nUINT32a = (INT32)nINT16;
+ break;
+ case 10 :
+ *pTIFF >> nUINT32a >> nINT32;
+ if ( nINT32 != 0 )
+ nUINT32a /= nINT32;
+ break;
+ case 11 :
+ *pTIFF >> nFLOAT;
+ nUINT32a = (INT32)nFLOAT;
+ break;
+ case 12 :
+ *pTIFF >> nDOUBLE;
+ nUINT32a = (INT32)nDOUBLE;
+ break;
+ default:
+ *pTIFF >> nUINT32a;
+ break;
+ }
+ return nUINT32a;
+}
+
+// ---------------------------------------------------------------------------------
+
+double TIFFReader::ReadDoubleData()
+{
+ sal_uInt32 nulong;
+ double nd;
+
+ if ( nDataType == 5 )
+ {
+ *pTIFF >> nulong;
+ nd = (double)nulong;
+ *pTIFF >> nulong;
+ if ( nulong != 0 )
+ nd /= (double)nulong;
+ }
+ else
+ nd = (double)ReadIntData();
+ return nd;
+}
+
+// ---------------------------------------------------------------------------------
+
+void TIFFReader::ReadTagData( USHORT nTagType, sal_uInt32 nDataLen)
+{
+ if ( bStatus == FALSE )
+ return;
+
+ switch ( nTagType )
+ {
+ case 0x00fe: // New Sub File
+ nNewSubFile = ReadIntData();
+ OOODEBUG("NewSubFile",nNewSubFile);
+ break;
+
+ case 0x00ff: // Sub File
+ nSubFile = ReadIntData();
+ OOODEBUG("SubFile",nSubFile);
+ break;
+
+ case 0x0100: // Image Width
+ nImageWidth = ReadIntData();
+ OOODEBUG("ImageWidth",nImageWidth);
+ break;
+
+ case 0x0101: // Image Length
+ nImageLength = ReadIntData();
+ OOODEBUG("ImageLength",nImageLength);
+ break;
+
+ case 0x0102: // Bits Per Sample
+ nBitsPerSample = ReadIntData();
+ OOODEBUG("BitsPerSample",nBitsPerSample);
+ break;
+
+ case 0x0103: // Compression
+ nCompression = ReadIntData();
+ OOODEBUG("Compression",nCompression);
+ break;
+
+ case 0x0106: // Photometric Interpreation
+ nPhotometricInterpretation = ReadIntData();
+ OOODEBUG("PhotometricInterpretation",nPhotometricInterpretation);
+ break;
+
+ case 0x0107: // Thresholding
+ nThresholding = ReadIntData();
+ OOODEBUG("Thresholding",nThresholding);
+ break;
+
+ case 0x0108: // Cell Width
+ nCellWidth = ReadIntData();
+ break;
+
+ case 0x0109: // Cell Length
+ nCellLength = ReadIntData();
+ break;
+
+ case 0x010a: // Fill Order
+ nFillOrder = ReadIntData();
+ OOODEBUG("FillOrder",nFillOrder);
+ break;
+
+ case 0x0111: { // Strip Offset(s)
+ ULONG nOldNumSO, i, * pOldSO;
+ pOldSO = pStripOffsets;
+ if ( pOldSO == NULL )
+ nNumStripOffsets = 0;
+ nOldNumSO = nNumStripOffsets;
+ nDataLen += nOldNumSO;
+ if ( ( nDataLen > nOldNumSO ) && ( nDataLen < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) )
+ {
+ nNumStripOffsets = nDataLen;
+ try
+ {
+ pStripOffsets = new ULONG[ nNumStripOffsets ];
+ }
+ catch (std::bad_alloc)
+ {
+ pStripOffsets = NULL;
+ nNumStripOffsets = 0;
+ }
+ if ( pStripOffsets )
+ {
+ for ( i = 0; i < nOldNumSO; i++ )
+ pStripOffsets[ i ] = pOldSO[ i ] + nOrigPos;
+ for ( i = nOldNumSO; i < nNumStripOffsets; i++ )
+ pStripOffsets[ i ] = ReadIntData() + nOrigPos;
+ }
+ delete[] pOldSO;
+ }
+ OOODEBUG("StripOffsets (Anzahl:)",nDataLen);
+ break;
+ }
+ case 0x0112: // Orientation
+ nOrientation = ReadIntData();
+ OOODEBUG("Orientation",nOrientation);
+ break;
+
+ case 0x0115: // Samples Per Pixel
+ nSamplesPerPixel = ReadIntData();
+ OOODEBUG("SamplesPerPixel",nSamplesPerPixel);
+ break;
+
+ case 0x0116: // Rows Per Strip
+ nRowsPerStrip = ReadIntData();
+ OOODEBUG("RowsPerStrip",nRowsPerStrip);
+ break;
+
+ case 0x0117: { // Strip Byte Counts
+ ULONG nOldNumSBC, i, * pOldSBC;
+ pOldSBC = pStripByteCounts;
+ if ( pOldSBC == NULL )
+ nNumStripByteCounts = 0; // Sicherheitshalber
+ nOldNumSBC = nNumStripByteCounts;
+ nDataLen += nOldNumSBC;
+ if ( ( nDataLen > nOldNumSBC ) && ( nDataLen < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) )
+ {
+ nNumStripByteCounts = nDataLen;
+ try
+ {
+ pStripByteCounts = new ULONG[ nNumStripByteCounts ];
+ }
+ catch (std::bad_alloc)
+ {
+ pStripByteCounts = NULL;
+ nNumStripByteCounts = 0;
+ }
+ if ( pStripByteCounts )
+ {
+ for ( i = 0; i < nOldNumSBC; i++ )
+ pStripByteCounts[ i ] = pOldSBC[ i ];
+ for ( i = nOldNumSBC; i < nNumStripByteCounts; i++)
+ pStripByteCounts[ i ] = ReadIntData();
+ }
+ delete[] pOldSBC;
+ }
+ OOODEBUG("StripByteCounts (Anzahl:)",nDataLen);
+ break;
+ }
+ case 0x0118: // Min Sample Value
+ nMinSampleValue = ReadIntData();
+ OOODEBUG("MinSampleValue",nMinSampleValue);
+ break;
+
+ case 0x0119: // Max Sample Value
+ nMaxSampleValue = ReadIntData();
+ OOODEBUG("MaxSampleValue",nMaxSampleValue);
+ break;
+
+ case 0x011a: // X Resolution
+ fXResolution = ReadDoubleData();
+ break;
+
+ case 0x011b: // Y Resolution
+ fYResolution = ReadDoubleData();
+ break;
+
+ case 0x011c: // Planar Configuration
+ nPlanarConfiguration = ReadIntData();
+ OOODEBUG("PlanarConfiguration",nPlanarConfiguration);
+ break;
+
+ case 0x0124: // Group 3 Options
+ nGroup3Options = ReadIntData();
+ OOODEBUG("Group3Options",nGroup3Options);
+ break;
+
+ case 0x0125: // Group 4 Options
+ nGroup4Options = ReadIntData();
+ OOODEBUG("Group4Options",nGroup4Options);
+ break;
+
+ case 0x0128: // Resolution Unit
+ nResolutionUnit = ReadIntData();
+ break;
+
+ case 0x013d: // Predictor
+ nPredictor = ReadIntData();
+ OOODEBUG("Predictor",nPredictor);
+ break;
+
+ case 0x0140: { // Color Map
+ USHORT nVal;
+ ULONG i;
+ nNumColors= ( 1 << nBitsPerSample );
+ if ( nDataType == 3 && nNumColors <= 256)
+ {
+ pColorMap = new ULONG[ 256 ];
+ for ( i = 0; i < nNumColors; i++ )
+ pColorMap[ i ] = 0;
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ *pTIFF >> nVal;
+ pColorMap[ i ] |= ( ( (ULONG)nVal ) << 8 ) & 0x00ff0000;
+ }
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ *pTIFF >> nVal;
+ pColorMap[ i ] |= ( (ULONG)nVal ) & 0x0000ff00;
+ }
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ *pTIFF >> nVal;
+ pColorMap[ i ] |= ( ( (ULONG)nVal ) >> 8 ) & 0x000000ff;
+ }
+ }
+ else
+ bStatus = FALSE;
+ OOODEBUG("ColorMap (Anzahl Farben:)", nNumColors);
+ break;
+ }
+ }
+
+ if ( pTIFF->GetError() )
+ bStatus = FALSE;
+}
+
+// ---------------------------------------------------------------------------------
+
+BOOL TIFFReader::ReadMap( ULONG nMinPercent, ULONG nMaxPercent )
+{
+ if ( nCompression == 1 || nCompression == 32771 )
+ {
+ ULONG ny, np, nStrip, nStripBytesPerRow;
+
+ if ( nCompression == 1 )
+ nStripBytesPerRow = nBytesPerRow;
+ else
+ nStripBytesPerRow = ( nBytesPerRow + 1 ) & 0xfffffffe;
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ nStrip = ny / nRowsPerStrip + np * nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek( pStripOffsets[ nStrip ] + ( ny % nRowsPerStrip ) * nStripBytesPerRow );
+ pTIFF->Read( pMap[ np ], nBytesPerRow );
+ if ( pTIFF->GetError() )
+ return FALSE;
+ MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * ( np * nImageLength + ny) / ( nImageLength * nPlanes ) );
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else if ( nCompression == 2 || nCompression == 3 || nCompression == 4 )
+ {
+ ULONG ny, np, nStrip, nOptions;
+ if ( nCompression == 2 )
+ {
+ nOptions = CCI_OPTION_BYTEALIGNROW;
+ }
+ else if ( nCompression == 3 )
+ {
+ nOptions = CCI_OPTION_EOL;
+ if ( nGroup3Options & 0x00000001 )
+ nOptions |= CCI_OPTION_2D;
+ if ( nGroup3Options & 0x00000004 )
+ nOptions |= CCI_OPTION_BYTEALIGNEOL;
+ if ( nGroup3Options & 0xfffffffa )
+ return FALSE;
+ }
+ else
+ { // nCompression==4
+ nOptions = CCI_OPTION_2D;
+ if ( nGroup4Options & 0xffffffff )
+ return FALSE;
+ }
+ if ( nFillOrder == 2 )
+ {
+ nOptions |= CCI_OPTION_INVERSEBITORDER;
+ bByteSwap = FALSE;
+ }
+ nStrip = 0;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+
+ CCIDecompressor aCCIDecom( nOptions, nImageWidth );
+
+ aCCIDecom.StartDecompression( *pTIFF );
+
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
+ {
+ nStrip=ny/nRowsPerStrip+np*nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek( pStripOffsets[ nStrip ] );
+ aCCIDecom.StartDecompression( *pTIFF );
+ }
+ if ( aCCIDecom.DecompressScanline( pMap[ np ], nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes ) == FALSE )
+ return FALSE;
+ if ( pTIFF->GetError() )
+ return FALSE;
+ MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else if ( nCompression == 5 )
+ {
+ LZWDecompressor aLZWDecom;
+ ULONG ny, np, nStrip;
+ nStrip=0;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ aLZWDecom.StartDecompression(*pTIFF);
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
+ {
+ nStrip = ny / nRowsPerStrip + np * nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ aLZWDecom.StartDecompression(*pTIFF);
+ }
+ if ( ( aLZWDecom.Decompress( pMap[ np ], nBytesPerRow ) != nBytesPerRow ) || pTIFF->GetError() )
+ return FALSE;
+ MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else if ( nCompression == 32773 )
+ {
+ ULONG nStrip,nRecCount,nRowBytesLeft,ny,np,i;
+ BYTE * pdst, nRecHeader, nRecData;
+ nStrip = 0;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ for ( ny = 0; ny < nImageLength; ny++ )
+ {
+ for ( np = 0; np < nPlanes; np++ )
+ {
+ if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
+ {
+ nStrip=ny/nRowsPerStrip+np*nStripsPerPlane;
+ if ( nStrip >= nNumStripOffsets )
+ return FALSE;
+ pTIFF->Seek(pStripOffsets[nStrip]);
+ }
+ nRowBytesLeft = nBytesPerRow;
+ pdst=pMap[ np ];
+ do
+ {
+ *pTIFF >> nRecHeader;
+ if ((nRecHeader&0x80)==0)
+ {
+ nRecCount=0x00000001+((ULONG)nRecHeader);
+ if ( nRecCount > nRowBytesLeft )
+ return FALSE;
+ pTIFF->Read(pdst,nRecCount);
+ pdst+=nRecCount;
+ nRowBytesLeft-=nRecCount;
+ }
+ else if ( nRecHeader != 0x80 )
+ {
+ nRecCount = 0x000000101 - ( (ULONG)nRecHeader );
+ if ( nRecCount > nRowBytesLeft )
+ {
+ nRecCount = nRowBytesLeft;
+
+// bStatus = FALSE;
+// return;
+
+ }
+ *pTIFF >> nRecData;
+ for ( i = 0; i < nRecCount; i++ )
+ *(pdst++) = nRecData;
+ nRowBytesLeft -= nRecCount;
+ }
+ } while ( nRowBytesLeft != 0 );
+ if ( pTIFF->GetError() )
+ return FALSE;
+ MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
+ }
+ if ( !ConvertScanline( ny ) )
+ return FALSE;
+ }
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+ULONG TIFFReader::GetBits( const BYTE * pSrc, ULONG nBitsPos, ULONG nBitsCount )
+{
+ ULONG nRes;
+ if ( bByteSwap )
+ {
+ pSrc += ( nBitsPos >> 3 );
+ nBitsPos &= 7;
+ BYTE nDat = *pSrc;
+ nRes = (ULONG)( BYTESWAP( nDat ) & ( 0xff >> nBitsPos ) );
+
+ if ( nBitsCount <= 8 - nBitsPos )
+ {
+ nRes >>= ( 8 - nBitsPos - nBitsCount );
+ }
+ else
+ {
+ pSrc++;
+ nBitsCount -= 8 - nBitsPos;
+ while ( nBitsCount >= 8 )
+ {
+ nDat = *(pSrc++);
+ nRes = ( nRes << 8 ) | ((ULONG)BYTESWAP( nDat ) );
+ nBitsCount -= 8;
+ }
+ if ( nBitsCount > 0 )
+ {
+ nDat = *pSrc;
+ nRes = ( nRes << nBitsCount ) | (((ULONG)BYTESWAP(nDat))>>(8-nBitsCount));
+ }
+ }
+ }
+ else
+ {
+ pSrc += ( nBitsPos >> 3 );
+ nBitsPos &= 7;
+ nRes = (ULONG)((*pSrc)&(0xff>>nBitsPos));
+ if ( nBitsCount <= 8 - nBitsPos )
+ {
+ nRes >>= ( 8 - nBitsPos - nBitsCount );
+ }
+ else
+ {
+ pSrc++;
+ nBitsCount -= 8 - nBitsPos;
+ while ( nBitsCount >= 8 )
+ {
+ nRes = ( nRes << 8 ) | ((ULONG)*(pSrc++));
+ nBitsCount -= 8;
+ }
+ if ( nBitsCount > 0 )
+ nRes = ( nRes << nBitsCount ) | (((ULONG)*pSrc)>>(8-nBitsCount));
+ }
+ }
+ return nRes;
+}
+
+// ---------------------------------------------------------------------------------
+
+BOOL TIFFReader::ConvertScanline( ULONG nY )
+{
+ UINT32 nRed, nGreen, nBlue, ns, nx, nVal, nByteCount;
+ BYTE nByteVal;
+
+ if ( nDstBitsPerPixel == 24 )
+ {
+ if ( nBitsPerSample == 8 && nSamplesPerPixel >= 3 &&
+ nPlanes == 1 && nPhotometricInterpretation == 2 )
+ {
+ BYTE* pt = pMap[ 0 ];
+
+ // sind die Werte als Differenz abgelegt?
+ if ( 2 == nPredictor )
+ {
+ BYTE nLRed = 0;
+ BYTE nLGreen = 0;
+ BYTE nLBlue = 0;
+ for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel )
+ {
+ nLRed = nLRed + pt[ 0 ];
+ nLGreen = nLGreen + pt[ 1 ];
+ nLBlue = nLBlue + pt[ 2 ];
+ pAcc->SetPixel( nY, nx, Color( nLRed, nLGreen, nLBlue ) );
+ }
+ }
+ else
+ {
+ for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel )
+ {
+ pAcc->SetPixel( nY, nx, Color( pt[0], pt[1], pt[2] ) );
+ }
+ }
+ }
+ else if ( nPhotometricInterpretation == 2 && nSamplesPerPixel >= 3 )
+ {
+ ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ if ( nPlanes < 3 )
+ {
+ nRed = GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 1 ], ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 2 ], ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
+ }
+ else
+ {
+ nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample );
+ }
+ pAcc->SetPixel( nY, nx, Color( (BYTE)( nRed - nMinMax ), (BYTE)( nGreen - nMinMax ), (BYTE)(nBlue - nMinMax) ) );
+ }
+ }
+ else if ( nPhotometricInterpretation == 5 && nSamplesPerPixel == 3 )
+ {
+ ULONG nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ if ( nPlanes < 3 )
+ {
+ nRed = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
+ }
+ else
+ {
+ nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample );
+ nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample );
+ nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample );
+ }
+ nRed = 255 - (BYTE)( nRed - nMinMax );
+ nGreen = 255 - (BYTE)( nGreen - nMinMax );
+ nBlue = 255 - (BYTE)( nBlue - nMinMax );
+ pAcc->SetPixel( nY, nx, Color( (BYTE) nRed, (BYTE) nGreen, (BYTE) nBlue ) );
+ }
+ }
+ else if( nPhotometricInterpretation == 5 && nSamplesPerPixel == 4 )
+ {
+ BYTE nSamp[ 4 ];
+ BYTE nSampLast[ 4 ] = { 0, 0, 0, 0 };
+ long nBlack;
+
+ for( nx = 0; nx < nImageWidth; nx++ )
+ {
+ // sind die Werte als Differenz abgelegt?
+ if( 2 == nPredictor )
+ {
+ for( ns = 0; ns < 4; ns++ )
+ {
+ if( nPlanes < 3 )
+ nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample );
+ else
+ nSampLast[ ns ] = nSampLast[ ns ] + (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample );
+ nSamp[ ns ] = nSampLast[ ns ];
+ }
+ }
+ else
+ {
+ for( ns = 0; ns < 4; ns++ )
+ {
+ if( nPlanes < 3 )
+ nSamp[ ns ] = (BYTE) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample );
+ else
+ nSamp[ ns ]= (BYTE) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample );
+ }
+ }
+ nBlack = nSamp[ 3 ];
+ nRed = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 0 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
+ 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
+ nGreen = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 1 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
+ 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
+ nBlue = (BYTE) Max( 0L, 255L - ( ( (long) nSamp[ 2 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
+ 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
+ pAcc->SetPixel( nY, nx, Color ( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) );
+
+ }
+ }
+ }
+ else if ( nSamplesPerPixel == 1 && ( nPhotometricInterpretation <= 1 || nPhotometricInterpretation == 3 ) )
+ {
+ ULONG nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
+ BYTE* pt = pMap[ 0 ];
+ BYTE nShift;
+
+ switch ( nDstBitsPerPixel )
+ {
+ case 8 :
+ {
+ BYTE nLast;
+ if ( bByteSwap )
+ {
+ if ( nPredictor == 2 )
+ {
+ nLast = BYTESWAP( (BYTE)*pt++ );
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ pAcc->SetPixel( nY, nx, nLast );
+ nLast = nLast + *pt++;
+ }
+ }
+ else
+ {
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ nLast = *pt++;
+ pAcc->SetPixel( nY, nx, (BYTE)( ( (BYTESWAP((ULONG)nLast ) - nMinSampleValue ) * nMinMax ) ) );
+ }
+ }
+ }
+ else
+ {
+ if ( nPredictor == 2 )
+ {
+ nLast = *pt++;
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ pAcc->SetPixel( nY, nx, nLast );
+ nLast = nLast + *pt++;
+ }
+ }
+ else
+ {
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt++ - nMinSampleValue ) * nMinMax ) );
+
+ }
+ }
+ }
+ }
+ break;
+
+ case 7 :
+ case 6 :
+ case 5 :
+ case 4 :
+ case 3 :
+ case 2 :
+ {
+ for ( nx = 0; nx < nImageWidth; nx++ )
+ {
+ nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax;
+ pAcc->SetPixel( nY, nx, (BYTE)nVal );
+ }
+ }
+ break;
+
+ case 1 :
+ {
+ if ( bByteSwap )
+ {
+ nx = 0;
+ nByteCount = ( nImageWidth >> 3 ) + 1;
+ while ( --nByteCount )
+ {
+ nByteVal = *pt++;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, nx++, nByteVal );
+ }
+ if ( nImageWidth & 7 )
+ {
+ nByteVal = *pt++;
+ while ( nx < nImageWidth )
+ {
+ pAcc->SetPixel( nY, nx++, nByteVal & 1 );
+ nByteVal >>= 1;
+ }
+ }
+ }
+ else
+ {
+ nx = 7;
+ nByteCount = ( nImageWidth >> 3 ) + 1;
+ while ( --nByteCount )
+ {
+ nByteVal = *pt++;
+ pAcc->SetPixel( nY, nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal & 1 );
+ nByteVal >>= 1;
+ pAcc->SetPixel( nY, --nx, nByteVal );
+ nx += 15;
+ }
+ if ( nImageWidth & 7 )
+ {
+ nx -= 7;
+ nByteVal = *pt++;
+ nShift = 7;
+ while ( nx < nImageWidth )
+ {
+ pAcc->SetPixel( nY, nx++, ( nByteVal >> nShift ) & 1);
+ }
+ }
+ }
+ }
+ break;
+
+ default :
+ return FALSE;
+ }
+ }
+ else if ( ( nSamplesPerPixel == 2 ) && ( nBitsPerSample == 8 ) &&
+ ( nPlanarConfiguration == 1 ) && ( pColorMap == 0 ) ) // grayscale
+ {
+ ULONG nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
+ BYTE* pt = pMap[ 0 ];
+ if ( nByte1 == 'I' )
+ pt++;
+ for ( nx = 0; nx < nImageWidth; nx++, pt += 2 )
+ {
+ pAcc->SetPixel( nY, nx, (BYTE)( ( (ULONG)*pt - nMinSampleValue ) * nMinMax ) );
+ }
+ }
+ else
+ return FALSE;
+ return TRUE;
+}
+
+// ---------------------------------------------------------------------------------
+
+void TIFFReader::MakePalCol( void )
+{
+ if ( nDstBitsPerPixel <= 8 )
+ {
+ ULONG i, nVal, n0RGB;
+ if ( pColorMap == NULL )
+ pColorMap = new ULONG[ 256 ];
+ if ( nPhotometricInterpretation <= 1 )
+ {
+ nNumColors = 1 << nBitsPerSample;
+ if ( nNumColors > 256 )
+ nNumColors = 256;
+ pAcc->SetPaletteEntryCount( (USHORT)nNumColors );
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ nVal = ( i * 255 / ( nNumColors - 1 ) ) & 0xff;
+ n0RGB = nVal | ( nVal << 8 ) | ( nVal << 16 );
+ if ( nPhotometricInterpretation == 1 )
+ pColorMap[ i ] = n0RGB;
+ else
+ pColorMap[ nNumColors - i - 1 ] = n0RGB;
+ }
+ }
+ for ( i = 0; i < nNumColors; i++ )
+ {
+ pAcc->SetPaletteColor( (USHORT)i, BitmapColor( (BYTE)( pColorMap[ i ] >> 16 ),
+ (BYTE)( pColorMap[ i ] >> 8 ), (BYTE)pColorMap[ i ] ) );
+ }
+ }
+
+ if ( fXResolution > 1.0 && fYResolution > 1.0 && ( nResolutionUnit == 2 || nResolutionUnit == 3 ) )
+ {
+ ULONG nRX,nRY;
+ if (nResolutionUnit==2)
+ {
+ nRX=(ULONG)(fXResolution+0.5);
+ nRY=(ULONG)(fYResolution+0.5);
+ }
+ else
+ {
+ nRX=(ULONG)(fXResolution*2.54+0.5);
+ nRY=(ULONG)(fYResolution*2.54+0.5);
+ }
+ MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nRX),Fraction(1,nRY));
+ aBitmap.SetPrefMapMode(aMapMode);
+ aBitmap.SetPrefSize(Size(nImageWidth,nImageLength));
+ }
+}
+
+// ---------------------------------------------------------------------------------
+
+void TIFFReader::ReadHeader()
+{
+ BYTE nbyte1, nbyte2;
+ USHORT nushort;
+
+ *pTIFF >> nbyte1;
+ if ( nbyte1 == 'I' )
+ pTIFF->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ else
+ pTIFF->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+
+ *pTIFF >> nbyte2 >> nushort;
+ if ( nbyte1 != nbyte2 || ( nbyte1 != 'I' && nbyte1 != 'M' ) || nushort != 0x002a )
+ bStatus = FALSE;
+}
+
+// ---------------------------------------------------------------------------------
+
+BOOL TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic )
+{
+ USHORT i, nNumTags, nTagType;
+ ULONG nMaxPos;
+ ULONG nPos;
+ sal_uInt32 nFirstIfd, nDataLen;
+
+ bStatus = TRUE;
+ nLastPercent = 0;
+
+ pTIFF = &rTIFF;
+ nMaxPos = nOrigPos = pTIFF->Tell();
+ nOrigNumberFormat = pTIFF->GetNumberFormatInt();
+
+ MayCallback( 0 );
+
+ // Kopf einlesen:
+ ReadHeader();
+
+ // Ersten IFD einlesen:
+ *pTIFF >> nFirstIfd;
+
+ if( !nFirstIfd || pTIFF->GetError() )
+ bStatus = FALSE;
+
+ if ( bStatus )
+ {
+ sal_uInt32 nOffset = nFirstIfd;
+
+ // calculate length of TIFF file
+ do
+ {
+ pTIFF->Seek( nOrigPos + nOffset );
+
+ if( pTIFF->GetError() )
+ {
+ pTIFF->ResetError();
+ break;
+ };
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+
+ *pTIFF >> nNumTags;
+
+ // Schleife ueber Tags:
+ for( i = 0; i < nNumTags; i++ )
+ {
+ *pTIFF >> nTagType >> nDataType >> nDataLen >> nOffset;
+
+ if( DataTypeSize() * nDataLen > 4 )
+ nMaxPos = Max( nOrigPos + nOffset + DataTypeSize() * nDataLen, nMaxPos );
+ }
+ *pTIFF >> nOffset;
+ if ( pTIFF->IsEof() )
+ nOffset = 0;
+
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ if ( !nOffset )
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ }
+ while( nOffset );
+
+ for ( UINT32 nNextIfd = nFirstIfd; nNextIfd && bStatus; )
+ {
+ pTIFF->Seek( nOrigPos + nNextIfd );
+ {
+ bByteSwap = FALSE;
+
+ nNewSubFile = 0;
+ nSubFile = 0;
+ nImageWidth = 0;
+ nImageLength = 0;
+ nBitsPerSample = 1; // Defaultwert laut Doku
+ nCompression = 1;
+ nPhotometricInterpretation = 0;
+ nThresholding = 1; // Defaultwert laut Doku
+ nCellWidth = 1;
+ nCellLength = 1;
+ nFillOrder = 1; // Defaultwert laut Doku
+ nNumStripOffsets = 0;
+ nOrientation = 1;
+ nSamplesPerPixel = 1; // Defaultwert laut Doku
+ nRowsPerStrip = 0xffffffff; // Defaultwert laut Doku
+ nNumStripByteCounts = 0;
+ nMinSampleValue = 0; // Defaultwert laut Doku
+ nMaxSampleValue = 0;
+ fXResolution = 0.0;
+ fYResolution = 0.0;
+ nPlanarConfiguration = 1;
+ nGroup3Options = 0; // Defaultwert laut Doku
+ nGroup4Options = 0; // Defaultwert laut Doku
+ nResolutionUnit = 2; // Defaultwert laut Doku
+ nPredictor = 1;
+ nNumColors = 0;
+
+ pAcc = NULL;
+ pColorMap = NULL;
+ pStripOffsets = NULL;
+ pStripByteCounts = NULL;
+ pMap[ 0 ] = pMap[ 1 ] = pMap[ 2 ] = pMap[ 3 ] = NULL;
+
+ *pTIFF >> nNumTags;
+ nPos = pTIFF->Tell();
+
+ // Schleife ueber Tags:
+ for( i = 0; i < nNumTags; i++ )
+ {
+ *pTIFF >> nTagType >> nDataType >> nDataLen;
+
+ if( DataTypeSize() * nDataLen > 4 )
+ {
+ *pTIFF >> nOffset;
+ pTIFF->Seek( nOrigPos + nOffset );
+ }
+ ReadTagData( nTagType, nDataLen );
+ nPos += 12; pTIFF->Seek( nPos );
+
+ if ( pTIFF->GetError() )
+ bStatus = FALSE;
+
+ if ( bStatus == FALSE )
+ break;
+ }
+ *pTIFF >> nNextIfd;
+ if ( pTIFF->IsEof() )
+ nNextIfd = 0;
+ }
+ if ( bStatus )
+ {
+ if ( nMaxSampleValue == 0 )
+ nMaxSampleValue = ( 1 << nBitsPerSample ) - 1;
+
+ if ( nPhotometricInterpretation == 2 || nPhotometricInterpretation == 5 || nPhotometricInterpretation == 6 )
+ nDstBitsPerPixel = 24;
+ else if ( nBitsPerSample*nSamplesPerPixel <= 1 )
+ nDstBitsPerPixel = 1;
+ else if ( nBitsPerSample*nSamplesPerPixel <= 4 )
+ nDstBitsPerPixel = 4;
+ else
+ nDstBitsPerPixel = 8;
+
+ aBitmap = Bitmap( Size( nImageWidth, nImageLength ), nDstBitsPerPixel );
+ pAcc = aBitmap.AcquireWriteAccess();
+ if ( pAcc )
+ {
+ if ( nPlanarConfiguration == 1 )
+ nPlanes = 1;
+ else
+ nPlanes = nSamplesPerPixel;
+
+ if ( ( nFillOrder == 2 ) && ( nCompression != 5 ) ) // im LZW Mode werden die bits schon invertiert
+ bByteSwap = TRUE;
+
+ nStripsPerPlane = ( nImageLength - 1 ) / nRowsPerStrip + 1;
+ nBytesPerRow = ( nImageWidth * nSamplesPerPixel / nPlanes * nBitsPerSample + 7 ) >> 3;
+
+ for ( ULONG j = 0; j < 4; j++ )
+ {
+ try
+ {
+ pMap[ j ] = new BYTE[ nBytesPerRow ];
+ }
+ catch (std::bad_alloc)
+ {
+ pMap[ j ] = NULL;
+ bStatus = FALSE;
+ break;
+ }
+ }
+
+ if ( bStatus && ReadMap( 10, 60 ) )
+ {
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ MakePalCol();
+ nMaxPos = Max( pTIFF->Tell(), nMaxPos );
+ }
+ else
+ bStatus = FALSE;
+
+ if( pAcc )
+ {
+ aBitmap.ReleaseAccess( pAcc );
+ if ( bStatus )
+ {
+ AnimationBitmap aAnimationBitmap( aBitmap, Point( 0, 0 ), aBitmap.GetSizePixel(),
+ ANIMATION_TIMEOUT_ON_CLICK, DISPOSE_BACK );
+
+ aAnimation.Insert( aAnimationBitmap );
+ }
+ }
+ // Aufraeumen:
+ for ( i = 0; i < 4; i++ )
+ delete[] pMap[ i ];
+
+ delete[] pColorMap;
+ delete[] pStripOffsets;
+ delete[] pStripByteCounts;
+ }
+ }
+ }
+ }
+
+ // seek to end of TIFF if succeeded
+ pTIFF->SetNumberFormatInt( nOrigNumberFormat );
+ pTIFF->Seek( bStatus ? nMaxPos : nOrigPos );
+
+ if ( aAnimation.Count() )
+ {
+ if ( aAnimation.Count() == 1 )
+ rGraphic = aAnimation.GetBitmapEx();
+ else
+ rGraphic = aAnimation; //aBitmap;
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+//================== GraphicImport - die exportierte Funktion ================
+
+extern "C" BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, BOOL )
+{
+ TIFFReader aTIFFReader;
+
+ if ( aTIFFReader.ReadTIFF( rStream, rGraphic ) == FALSE )
+ return FALSE;
+
+ return TRUE;
+}
+
+//============================= fuer Windows ==================================
+#ifndef GCC
+#endif
+
+#ifdef WIN
+
+static HINSTANCE hDLLInst = 0; // HANDLE der DLL
+
+extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
+{
+#ifndef WNT
+ if ( nHeap )
+ UnlockData( 0 );
+#endif
+
+ hDLLInst = hDLL;
+
+ return TRUE;
+}
+
+extern "C" int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+#endif
+
+