xref: /AOO41X/main/filter/source/graphicfilter/itiff/itiff.cxx (revision 87bc88d3ed834c36654f277ed18005c290f77bdd)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26 #include <vcl/graph.hxx>
27 #include <vcl/bmpacc.hxx>
28 #ifndef _SV_FLTCALL_HXX
29 #include <svtools/fltcall.hxx>
30 #endif
31 #include <vcl/animate.hxx>
32 #include "lzwdecom.hxx"
33 #include "ccidecom.hxx"
34 
35 #define OOODEBUG(str,Num) //(InfoBox(NULL,String(str)+String(" ")+String(Num)).Execute();
36 
37 namespace {
38 
BYTESWAP(T nByte)39 template< typename T > T BYTESWAP(T nByte) {
40     return ( nByte << 7 ) | ( ( nByte & 2 ) << 5 ) | ( ( nByte & 4 ) << 3 ) |
41         ( ( nByte & 8 ) << 1 ) | ( ( nByte & 16 ) >> 1 ) |
42         ( ( nByte & 32 ) >> 3 ) | ( ( nByte & 64 ) >> 5 ) |
43         ( ( nByte & 128 ) >> 7 );
44 }
45 
46 }
47 
48 //============================ TIFFReader ==================================
49 
50 class TIFFReader
51 {
52 
53 private:
54 
55     sal_Bool                bStatus;                    // Ob bisher kein Fehler auftrat
56     Animation           aAnimation;
57     sal_uLong               nLastPercent;
58 
59     SvStream*           pTIFF;                      // Die einzulesende TIFF-Datei
60     Bitmap              aBitmap;
61     BitmapWriteAccess*  pAcc;
62     sal_uInt16              nDstBitsPerPixel;
63 
64     sal_uLong               nOrigPos;                   // Anfaengliche Position in pTIFF
65     sal_uInt16              nOrigNumberFormat;          // Anfaengliches Nummern-Format von pTIFF
66 
67 
68     sal_uInt16              nDataType;
69     // Daten, die aus dem TIFF-Tags entnommen werden:
70     sal_Bool                bByteSwap;                  // sal_True wenn bits 0..7 -> 7..0 invertiert werden sollen ( FILLORDER = 2 );
71     sal_uInt8               nByte1;                     // 'I', wenn Format LittleEndian
72 
73     sal_uLong               nNewSubFile;                //
74     sal_uLong               nSubFile;                   //
75     sal_uLong               nImageWidth;                // Bildbreite in Pixel
76     sal_uLong               nImageLength;               // Bildhoehe in Pixel
77     sal_uLong               nBitsPerSample;             // Bits pro Pixel pro Ebene
78     sal_uLong               nCompression;               // Art der Kompriemierung
79     sal_uLong               nPhotometricInterpretation; //
80     sal_uLong               nThresholding;              //
81     sal_uLong               nCellWidth;                 //
82     sal_uLong               nCellLength;                //
83     sal_uLong               nFillOrder;                 //
84     sal_uLong*              pStripOffsets;              // Feld von Offsets zu den Bitmap-Daten-"Strips"
85     sal_uLong               nNumStripOffsets;           // Groesse obigen Feldes
86     sal_uLong               nOrientation;               //
87     sal_uLong               nSamplesPerPixel;           // Anzahl der Ebenen
88     sal_uLong               nRowsPerStrip;              // Wenn nicht komprimiert: Zahl der Zeilen pro Strip
89     sal_uLong*              pStripByteCounts;           // Wenn komprimiert (bestimmte Art): Groesse der Strips
90     sal_uLong               nNumStripByteCounts;        // Anzahl der Eintraege in obiges Feld
91     sal_uLong               nMinSampleValue;            //
92     sal_uLong               nMaxSampleValue;            //
93     double              fXResolution;               // X-Aufloesung oder 0.0
94     double              fYResolution;               // Y-Aufloesung oder 0.0
95     sal_uLong               nPlanarConfiguration;       //
96     sal_uLong               nGroup3Options;             //
97     sal_uLong               nGroup4Options;             //
98     sal_uLong               nResolutionUnit;            // Einheit von fX/YResolution: 1=unbekannt, 2(default)=Zoll, 3=cm
99     sal_uLong               nPredictor;                 //
100     sal_uLong*              pColorMap;                  // Farb-Palette
101     sal_uLong               nNumColors;                 // Anzahl Farben in der Farbpalette
102 
103     sal_uLong               nPlanes;                    // Anzahl der Ebenen in der Tiff-Datei
104     sal_uLong               nStripsPerPlane;            // Anzahl der Strips pro Ebene
105     sal_uLong               nBytesPerRow;               // Bytes pro Zeile pro Ebene in der Tiff-Datei ( unkomprimiert )
106     sal_uInt8*              pMap[ 4 ];                  // Temporaere Scanline
107 
108 
109     void    MayCallback( sal_uLong nPercent );
110 
111     sal_uLong   DataTypeSize();
112     sal_uLong   ReadIntData();
113     double  ReadDoubleData();
114 
115     void    ReadHeader();
116     void    ReadTagData( sal_uInt16 nTagType, sal_uInt32 nDataLen );
117 
118     sal_Bool    ReadMap( sal_uLong nMinPercent, sal_uLong nMaxPercent );
119         // Liesst/dekomprimert die Bitmap-Daten, und fuellt pMap
120 
121     sal_uLong   GetBits( const sal_uInt8 * pSrc, sal_uLong nBitsPos, sal_uLong nBitsCount );
122         // Holt nBitsCount Bits aus pSrc[..] an der Bit-Position nBitsPos
123 
124     void    MakePalCol( void );
125         // Erzeugt die Bitmap aus der temporaeren Bitmap pMap
126         // und loescht dabei pMap teilweise
127     sal_Bool    ConvertScanline( sal_uLong nY );
128         // Konvertiert eine Scanline in das Windows-BMP-Format
129 
130 public:
131 
TIFFReader()132     TIFFReader() {}
~TIFFReader()133     ~TIFFReader() {}
134 
135     sal_Bool ReadTIFF( SvStream & rTIFF, Graphic & rGraphic );
136 };
137 
138 //=================== Methoden von TIFFReader ==============================
139 
MayCallback(sal_uLong)140 void TIFFReader::MayCallback( sal_uLong /*nPercent*/ )
141 {
142 /*
143     if ( nPercent >= nLastPercent + 3 )
144     {
145         nLastPercent=nPercent;
146         if ( pCallback != NULL && nPercent <= 100 && bStatus == sal_True )
147         {
148             if (((*pCallback)(pCallerData,(sal_uInt16)nPercent)) == sal_True )
149                 bStatus = sal_False;
150         }
151     }
152 */
153 }
154 
155 // ---------------------------------------------------------------------------------
156 
DataTypeSize()157 sal_uLong TIFFReader::DataTypeSize()
158 {
159     sal_uLong nSize;
160     switch ( nDataType )
161     {
162         case 1 :            // BYTE
163         case 2 :            // ACSII
164         case 6 :            // SIGNED Byte
165         case 7 :            // UNDEFINED
166             nSize = 1;
167             break;
168         case 3 :            // UINT16
169         case 8 :            // INT16
170             nSize = 2;
171             break;
172         case 4 :            // UINT32
173         case 9 :            // INT32
174         case 11 :           // FLOAT
175             nSize = 4;
176             break;
177         case 5 :            // RATIONAL
178         case 10 :           // SIGNED RATINAL
179         case 12 :           // DOUBLE
180             nSize = 8;
181             break;
182         default:
183             pTIFF->SetError(SVSTREAM_FILEFORMAT_ERROR);
184             nSize=1;
185     }
186     return nSize;
187 }
188 
189 // ---------------------------------------------------------------------------------
190 
ReadIntData()191 sal_uLong TIFFReader::ReadIntData()
192 {
193     double  nDOUBLE;
194     float   nFLOAT;
195     sal_uInt32  nUINT32a, nUINT32b;
196     sal_Int32   nINT32;
197     sal_uInt16  nUINT16;
198     sal_Int16   nINT16;
199     sal_uInt8   nBYTE;
200     char    nCHAR;
201 
202     switch( nDataType )
203     {
204         case 0 :    //??
205         case 1 :
206         case 2 :
207         case 7 :
208             *pTIFF >> nBYTE;
209             nUINT32a = (sal_uLong)nBYTE;
210         break;
211         case 3 :
212              *pTIFF >> nUINT16;
213              nUINT32a = (sal_uLong)nUINT16;
214         break;
215         case 9 :
216         case 4 :
217             *pTIFF >> nUINT32a;
218         break;
219         case  5 :
220             *pTIFF >> nUINT32a >> nUINT32b;
221             if ( nUINT32b != 0 )
222                 nUINT32a /= nUINT32b;
223         break;
224         case 6 :
225             *pTIFF >> nCHAR;
226             nUINT32a = (sal_Int32)nCHAR;
227         break;
228         case 8 :
229             *pTIFF >> nINT16;
230             nUINT32a = (sal_Int32)nINT16;
231         break;
232         case 10 :
233             *pTIFF >> nUINT32a >> nINT32;
234             if ( nINT32 != 0 )
235                 nUINT32a /= nINT32;
236         break;
237         case 11 :
238             *pTIFF >> nFLOAT;
239             nUINT32a = (sal_Int32)nFLOAT;
240         break;
241         case 12 :
242             *pTIFF >> nDOUBLE;
243             nUINT32a = (sal_Int32)nDOUBLE;
244         break;
245         default:
246             *pTIFF >> nUINT32a;
247         break;
248     }
249     return nUINT32a;
250 }
251 
252 // ---------------------------------------------------------------------------------
253 
ReadDoubleData()254 double TIFFReader::ReadDoubleData()
255 {
256     sal_uInt32 nulong;
257     double  nd;
258 
259     if ( nDataType == 5 )
260     {
261         *pTIFF >> nulong;
262         nd = (double)nulong;
263         *pTIFF >> nulong;
264         if ( nulong != 0 )
265             nd /= (double)nulong;
266     }
267     else
268         nd = (double)ReadIntData();
269     return nd;
270 }
271 
272 // ---------------------------------------------------------------------------------
273 
ReadTagData(sal_uInt16 nTagType,sal_uInt32 nDataLen)274 void TIFFReader::ReadTagData( sal_uInt16 nTagType, sal_uInt32 nDataLen)
275 {
276     if ( bStatus == sal_False )
277         return;
278 
279     switch ( nTagType )
280     {
281         case 0x00fe:   // New Sub File
282             nNewSubFile = ReadIntData();
283             OOODEBUG("NewSubFile",nNewSubFile);
284             break;
285 
286         case 0x00ff:   // Sub File
287             nSubFile = ReadIntData();
288             OOODEBUG("SubFile",nSubFile);
289             break;
290 
291         case 0x0100:   // Image Width
292             nImageWidth = ReadIntData();
293             OOODEBUG("ImageWidth",nImageWidth);
294             break;
295 
296         case 0x0101:   // Image Length
297             nImageLength = ReadIntData();
298             OOODEBUG("ImageLength",nImageLength);
299             break;
300 
301         case 0x0102:   // Bits Per Sample
302             nBitsPerSample = ReadIntData();
303             OOODEBUG("BitsPerSample",nBitsPerSample);
304             break;
305 
306         case 0x0103:   // Compression
307             nCompression = ReadIntData();
308             OOODEBUG("Compression",nCompression);
309             break;
310 
311         case 0x0106:   // Photometric Interpreation
312             nPhotometricInterpretation = ReadIntData();
313             OOODEBUG("PhotometricInterpretation",nPhotometricInterpretation);
314             break;
315 
316         case 0x0107:   // Thresholding
317             nThresholding = ReadIntData();
318             OOODEBUG("Thresholding",nThresholding);
319             break;
320 
321         case 0x0108:   // Cell Width
322             nCellWidth = ReadIntData();
323             break;
324 
325         case 0x0109:   // Cell Length
326             nCellLength = ReadIntData();
327             break;
328 
329         case 0x010a:   // Fill Order
330             nFillOrder = ReadIntData();
331             OOODEBUG("FillOrder",nFillOrder);
332             break;
333 
334         case 0x0111: { // Strip Offset(s)
335             sal_uLong nOldNumSO, i, * pOldSO;
336             pOldSO = pStripOffsets;
337             if ( pOldSO == NULL )
338                 nNumStripOffsets = 0;
339             nOldNumSO = nNumStripOffsets;
340             nDataLen += nOldNumSO;
341             if ( ( nDataLen > nOldNumSO ) && ( nDataLen < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) )
342             {
343                 nNumStripOffsets = nDataLen;
344                 try
345                 {
346                     pStripOffsets = new sal_uLong[ nNumStripOffsets ];
347                 }
348                     catch (std::bad_alloc)
349                 {
350                     pStripOffsets = NULL;
351                     nNumStripOffsets = 0;
352                 }
353                 if ( pStripOffsets )
354                 {
355                     for ( i = 0; i < nOldNumSO; i++ )
356                         pStripOffsets[ i ] = pOldSO[ i ] + nOrigPos;
357                     for ( i = nOldNumSO; i < nNumStripOffsets; i++ )
358                         pStripOffsets[ i ] = ReadIntData() + nOrigPos;
359                 }
360                 delete[] pOldSO;
361             }
362             OOODEBUG("StripOffsets (Anzahl:)",nDataLen);
363             break;
364         }
365         case 0x0112:   // Orientation
366             nOrientation = ReadIntData();
367             OOODEBUG("Orientation",nOrientation);
368             break;
369 
370         case 0x0115:   // Samples Per Pixel
371             nSamplesPerPixel = ReadIntData();
372             OOODEBUG("SamplesPerPixel",nSamplesPerPixel);
373             break;
374 
375         case 0x0116:   // Rows Per Strip
376             nRowsPerStrip = ReadIntData();
377             OOODEBUG("RowsPerStrip",nRowsPerStrip);
378             break;
379 
380         case 0x0117: { // Strip Byte Counts
381             sal_uLong nOldNumSBC, i, * pOldSBC;
382             pOldSBC = pStripByteCounts;
383             if ( pOldSBC == NULL )
384                 nNumStripByteCounts = 0; // Sicherheitshalber
385             nOldNumSBC = nNumStripByteCounts;
386             nDataLen += nOldNumSBC;
387             if ( ( nDataLen > nOldNumSBC ) && ( nDataLen < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) )
388             {
389                 nNumStripByteCounts = nDataLen;
390                 try
391                 {
392                     pStripByteCounts = new sal_uLong[ nNumStripByteCounts ];
393                 }
394                     catch (std::bad_alloc)
395                 {
396                     pStripByteCounts = NULL;
397                     nNumStripByteCounts = 0;
398                 }
399                 if ( pStripByteCounts )
400                 {
401                     for ( i = 0; i < nOldNumSBC; i++ )
402                         pStripByteCounts[ i ] = pOldSBC[ i ];
403                     for ( i = nOldNumSBC; i < nNumStripByteCounts; i++)
404                         pStripByteCounts[ i ] = ReadIntData();
405                 }
406                 delete[] pOldSBC;
407             }
408             OOODEBUG("StripByteCounts (Anzahl:)",nDataLen);
409             break;
410         }
411         case 0x0118:   // Min Sample Value
412             nMinSampleValue = ReadIntData();
413             OOODEBUG("MinSampleValue",nMinSampleValue);
414             break;
415 
416         case 0x0119:   // Max Sample Value
417             nMaxSampleValue = ReadIntData();
418             OOODEBUG("MaxSampleValue",nMaxSampleValue);
419             break;
420 
421         case 0x011a:   // X Resolution
422             fXResolution = ReadDoubleData();
423             break;
424 
425         case 0x011b:   // Y Resolution
426             fYResolution = ReadDoubleData();
427             break;
428 
429         case 0x011c:   // Planar Configuration
430             nPlanarConfiguration = ReadIntData();
431             OOODEBUG("PlanarConfiguration",nPlanarConfiguration);
432             break;
433 
434         case 0x0124:   // Group 3 Options
435             nGroup3Options = ReadIntData();
436             OOODEBUG("Group3Options",nGroup3Options);
437             break;
438 
439         case 0x0125:   // Group 4 Options
440             nGroup4Options = ReadIntData();
441             OOODEBUG("Group4Options",nGroup4Options);
442             break;
443 
444         case 0x0128:   // Resolution Unit
445             nResolutionUnit = ReadIntData();
446             break;
447 
448         case 0x013d:   // Predictor
449             nPredictor = ReadIntData();
450             OOODEBUG("Predictor",nPredictor);
451             break;
452 
453         case 0x0140: { // Color Map
454             sal_uInt16 nVal;
455             sal_uLong i;
456             nNumColors= ( 1 << nBitsPerSample );
457             if ( nDataType == 3 && nNumColors <= 256)
458             {
459                 pColorMap = new sal_uLong[ 256 ];
460                 for ( i = 0; i < nNumColors; i++ )
461                     pColorMap[ i ] = 0;
462                 for ( i = 0; i < nNumColors; i++ )
463                 {
464                     *pTIFF >> nVal;
465                     pColorMap[ i ] |= ( ( (sal_uLong)nVal ) << 8 ) & 0x00ff0000;
466                 }
467                 for ( i = 0; i < nNumColors; i++ )
468                 {
469                     *pTIFF >> nVal;
470                     pColorMap[ i ] |= ( (sal_uLong)nVal ) & 0x0000ff00;
471                 }
472                 for ( i = 0; i < nNumColors; i++ )
473                 {
474                     *pTIFF >> nVal;
475                     pColorMap[ i ] |= ( ( (sal_uLong)nVal ) >> 8 ) & 0x000000ff;
476                 }
477             }
478             else
479                 bStatus = sal_False;
480             OOODEBUG("ColorMap (Anzahl Farben:)", nNumColors);
481             break;
482         }
483     }
484 
485     if ( pTIFF->GetError() )
486         bStatus = sal_False;
487 }
488 
489 // ---------------------------------------------------------------------------------
490 
ReadMap(sal_uLong nMinPercent,sal_uLong nMaxPercent)491 sal_Bool TIFFReader::ReadMap( sal_uLong nMinPercent, sal_uLong nMaxPercent )
492 {
493     if ( nCompression == 1 || nCompression == 32771 )
494     {
495         sal_uLong ny, np, nStrip, nStripBytesPerRow;
496 
497         if ( nCompression == 1 )
498             nStripBytesPerRow = nBytesPerRow;
499         else
500             nStripBytesPerRow = ( nBytesPerRow + 1 ) & 0xfffffffe;
501         for ( ny = 0; ny < nImageLength; ny++ )
502         {
503             for ( np = 0; np < nPlanes; np++ )
504             {
505                 nStrip = ny / nRowsPerStrip + np * nStripsPerPlane;
506                 if ( nStrip >= nNumStripOffsets )
507                     return sal_False;
508                 pTIFF->Seek( pStripOffsets[ nStrip ] + ( ny % nRowsPerStrip ) * nStripBytesPerRow );
509                 pTIFF->Read( pMap[ np ], nBytesPerRow );
510                 if ( pTIFF->GetError() )
511                     return sal_False;
512                 MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * ( np * nImageLength + ny) / ( nImageLength * nPlanes ) );
513             }
514             if ( !ConvertScanline( ny ) )
515                 return sal_False;
516         }
517     }
518     else if ( nCompression == 2 || nCompression == 3 || nCompression == 4 )
519     {
520         sal_uLong ny, np, nStrip, nOptions;
521         if ( nCompression == 2 )
522         {
523             nOptions = CCI_OPTION_BYTEALIGNROW;
524         }
525         else if ( nCompression == 3 )
526         {
527             nOptions = CCI_OPTION_EOL;
528             if ( nGroup3Options & 0x00000001 )
529                 nOptions |= CCI_OPTION_2D;
530             if ( nGroup3Options & 0x00000004 )
531                 nOptions |= CCI_OPTION_BYTEALIGNEOL;
532             if ( nGroup3Options & 0xfffffffa )
533                 return sal_False;
534         }
535         else
536         {   // nCompression==4
537             nOptions = CCI_OPTION_2D;
538             if ( nGroup4Options & 0xffffffff )
539                 return sal_False;
540         }
541         if ( nFillOrder == 2 )
542         {
543             nOptions |= CCI_OPTION_INVERSEBITORDER;
544             bByteSwap = sal_False;
545         }
546         nStrip = 0;
547         if ( nStrip >= nNumStripOffsets )
548             return sal_False;
549         pTIFF->Seek(pStripOffsets[nStrip]);
550 
551         CCIDecompressor aCCIDecom( nOptions, nImageWidth );
552 
553         aCCIDecom.StartDecompression( *pTIFF );
554 
555         for ( ny = 0; ny < nImageLength; ny++ )
556         {
557             for ( np = 0; np < nPlanes; np++ )
558             {
559                 if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
560                 {
561                     nStrip=ny/nRowsPerStrip+np*nStripsPerPlane;
562                     if ( nStrip >= nNumStripOffsets )
563                         return sal_False;
564                     pTIFF->Seek( pStripOffsets[ nStrip ] );
565                     aCCIDecom.StartDecompression( *pTIFF );
566                 }
567                 if ( aCCIDecom.DecompressScanline( pMap[ np ], nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes ) == sal_False )
568                     return sal_False;
569                 if ( pTIFF->GetError() )
570                     return sal_False;
571                 MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
572             }
573             if ( !ConvertScanline( ny ) )
574                 return sal_False;
575         }
576     }
577     else if ( nCompression == 5 )
578     {
579         LZWDecompressor aLZWDecom;
580         sal_uLong ny, np, nStrip;
581         nStrip=0;
582         if ( nStrip >= nNumStripOffsets )
583             return sal_False;
584         pTIFF->Seek(pStripOffsets[nStrip]);
585         aLZWDecom.StartDecompression(*pTIFF);
586         for ( ny = 0; ny < nImageLength; ny++ )
587         {
588             for ( np = 0; np < nPlanes; np++ )
589             {
590                 if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
591                 {
592                     nStrip = ny / nRowsPerStrip + np * nStripsPerPlane;
593                     if ( nStrip >= nNumStripOffsets )
594                         return sal_False;
595                     pTIFF->Seek(pStripOffsets[nStrip]);
596                     aLZWDecom.StartDecompression(*pTIFF);
597                 }
598                 if ( ( aLZWDecom.Decompress( pMap[ np ], nBytesPerRow ) != nBytesPerRow ) || pTIFF->GetError() )
599                     return sal_False;
600                 MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
601             }
602             if ( !ConvertScanline( ny ) )
603                 return sal_False;
604         }
605     }
606     else if ( nCompression == 32773 )
607     {
608         sal_uLong nStrip,nRecCount,nRowBytesLeft,ny,np,i;
609         sal_uInt8 * pdst, nRecHeader, nRecData;
610         nStrip = 0;
611         if ( nStrip >= nNumStripOffsets )
612             return sal_False;
613         pTIFF->Seek(pStripOffsets[nStrip]);
614         for ( ny = 0; ny < nImageLength; ny++ )
615         {
616             for ( np = 0; np < nPlanes; np++ )
617             {
618                 if ( ny / nRowsPerStrip + np * nStripsPerPlane > nStrip )
619                 {
620                     nStrip=ny/nRowsPerStrip+np*nStripsPerPlane;
621                     if ( nStrip >= nNumStripOffsets )
622                         return sal_False;
623                     pTIFF->Seek(pStripOffsets[nStrip]);
624                 }
625                 nRowBytesLeft = nBytesPerRow;
626                 pdst=pMap[ np ];
627                 do
628                 {
629                     *pTIFF >> nRecHeader;
630                     if ((nRecHeader&0x80)==0)
631                     {
632                         nRecCount=0x00000001+((sal_uLong)nRecHeader);
633                         if ( nRecCount > nRowBytesLeft )
634                             return sal_False;
635                         pTIFF->Read(pdst,nRecCount);
636                         pdst+=nRecCount;
637                         nRowBytesLeft-=nRecCount;
638                     }
639                     else if ( nRecHeader != 0x80 )
640                     {
641                         nRecCount = 0x000000101 - ( (sal_uLong)nRecHeader );
642                         if ( nRecCount > nRowBytesLeft )
643                         {
644                             nRecCount = nRowBytesLeft;
645 
646 //                          bStatus = sal_False;
647 //                          return;
648 
649                         }
650                         *pTIFF >> nRecData;
651                         for ( i = 0; i < nRecCount; i++ )
652                             *(pdst++) = nRecData;
653                         nRowBytesLeft -= nRecCount;
654                     }
655                 } while ( nRowBytesLeft != 0 );
656                 if ( pTIFF->GetError() )
657                     return sal_False;
658                 MayCallback(nMinPercent+(nMaxPercent-nMinPercent)*(np*nImageLength+ny)/(nImageLength*nPlanes));
659             }
660             if ( !ConvertScanline( ny ) )
661                 return sal_False;
662         }
663     }
664     else
665         return sal_False;
666     return sal_True;
667 }
668 
GetBits(const sal_uInt8 * pSrc,sal_uLong nBitsPos,sal_uLong nBitsCount)669 sal_uLong TIFFReader::GetBits( const sal_uInt8 * pSrc, sal_uLong nBitsPos, sal_uLong nBitsCount )
670 {
671     sal_uLong nRes;
672     if ( bByteSwap )
673     {
674         pSrc += ( nBitsPos >> 3 );
675         nBitsPos &= 7;
676         sal_uInt8 nDat = *pSrc;
677         nRes = (sal_uLong)( BYTESWAP( nDat ) & ( 0xff >> nBitsPos ) );
678 
679         if ( nBitsCount <= 8 - nBitsPos )
680         {
681             nRes >>= ( 8 - nBitsPos - nBitsCount );
682         }
683         else
684         {
685             pSrc++;
686             nBitsCount -= 8 - nBitsPos;
687             while ( nBitsCount >= 8 )
688             {
689                 nDat = *(pSrc++);
690                 nRes = ( nRes << 8 ) | ((sal_uLong)BYTESWAP( nDat ) );
691                 nBitsCount -= 8;
692             }
693             if ( nBitsCount > 0 )
694             {
695                 nDat = *pSrc;
696                 nRes = ( nRes << nBitsCount ) | (((sal_uLong)BYTESWAP(nDat))>>(8-nBitsCount));
697             }
698         }
699     }
700     else
701     {
702         pSrc += ( nBitsPos >> 3 );
703         nBitsPos &= 7;
704         nRes = (sal_uLong)((*pSrc)&(0xff>>nBitsPos));
705         if ( nBitsCount <= 8 - nBitsPos )
706         {
707             nRes >>= ( 8 - nBitsPos - nBitsCount );
708         }
709         else
710         {
711             pSrc++;
712             nBitsCount -= 8 - nBitsPos;
713             while ( nBitsCount >= 8 )
714             {
715                 nRes = ( nRes << 8 ) | ((sal_uLong)*(pSrc++));
716                 nBitsCount -= 8;
717             }
718             if ( nBitsCount > 0 )
719                 nRes = ( nRes << nBitsCount ) | (((sal_uLong)*pSrc)>>(8-nBitsCount));
720         }
721     }
722     return nRes;
723 }
724 
725 // ---------------------------------------------------------------------------------
726 
ConvertScanline(sal_uLong nY)727 sal_Bool TIFFReader::ConvertScanline( sal_uLong nY )
728 {
729     sal_uInt32  nRed, nGreen, nBlue, ns, nx, nVal, nByteCount;
730     sal_uInt8   nByteVal;
731 
732     if ( nDstBitsPerPixel == 24 )
733     {
734         if ( nBitsPerSample == 8 && nSamplesPerPixel >= 3 &&
735              nPlanes == 1 && nPhotometricInterpretation == 2 )
736         {
737             sal_uInt8*  pt = pMap[ 0 ];
738 
739             // sind die Werte als Differenz abgelegt?
740             if ( 2 == nPredictor )
741             {
742                 sal_uInt8  nLRed = 0;
743                 sal_uInt8  nLGreen = 0;
744                 sal_uInt8  nLBlue = 0;
745                 for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel )
746                 {
747                     nLRed = nLRed + pt[ 0 ];
748                     nLGreen = nLGreen + pt[ 1 ];
749                     nLBlue = nLBlue + pt[ 2 ];
750                     pAcc->SetPixel( nY, nx, Color( nLRed, nLGreen, nLBlue ) );
751                 }
752             }
753             else
754             {
755                 for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel )
756                 {
757                     pAcc->SetPixel( nY, nx, Color( pt[0], pt[1], pt[2] ) );
758                 }
759             }
760         }
761         else if ( nPhotometricInterpretation == 2 && nSamplesPerPixel >= 3 )
762         {
763             if ( nMaxSampleValue > nMinSampleValue )
764             {
765                 sal_uLong nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
766                 for ( nx = 0; nx < nImageWidth; nx++ )
767                 {
768                     if ( nPlanes < 3 )
769                     {
770                         nRed = GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
771                         nGreen = GetBits( pMap[ 1 ], ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
772                         nBlue = GetBits( pMap[ 2 ], ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
773                     }
774                     else
775                     {
776                         nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample );
777                         nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample );
778                         nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample );
779                     }
780                     pAcc->SetPixel( nY, nx, Color( (sal_uInt8)( nRed - nMinMax ), (sal_uInt8)( nGreen - nMinMax ), (sal_uInt8)(nBlue - nMinMax) ) );
781                 }
782             }
783         }
784         else if ( nPhotometricInterpretation == 5 && nSamplesPerPixel == 3 )
785         {
786             if ( nMaxSampleValue > nMinSampleValue )
787             {
788                 sal_uLong nMinMax =  nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
789                 for ( nx = 0; nx < nImageWidth; nx++ )
790                 {
791                     if ( nPlanes < 3 )
792                     {
793                         nRed = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
794                         nGreen = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
795                         nBlue = GetBits( pMap[ 0 ],( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
796                     }
797                     else
798                     {
799                         nRed = GetBits( pMap[ 0 ], nx * nBitsPerSample, nBitsPerSample );
800                         nGreen = GetBits( pMap[ 1 ], nx * nBitsPerSample, nBitsPerSample );
801                         nBlue = GetBits( pMap[ 2 ], nx * nBitsPerSample, nBitsPerSample );
802                     }
803                     nRed = 255 - (sal_uInt8)( nRed - nMinMax );
804                     nGreen = 255 - (sal_uInt8)( nGreen - nMinMax );
805                     nBlue = 255 - (sal_uInt8)( nBlue - nMinMax );
806                     pAcc->SetPixel( nY, nx, Color( (sal_uInt8) nRed, (sal_uInt8) nGreen, (sal_uInt8) nBlue ) );
807                 }
808             }
809         }
810         else if( nPhotometricInterpretation == 5 && nSamplesPerPixel == 4 )
811         {
812             if ( nMaxSampleValue > nMinSampleValue )
813             {
814                 sal_uInt8   nSamp[ 4 ];
815                 sal_uInt8   nSampLast[ 4 ] = { 0, 0, 0, 0 };
816                 long    nBlack;
817 
818                 for( nx = 0; nx < nImageWidth; nx++ )
819                 {
820                     // sind die Werte als Differenz abgelegt?
821                     if( 2 == nPredictor )
822                     {
823                         for( ns = 0; ns < 4; ns++ )
824                         {
825                             if( nPlanes < 3 )
826                                 nSampLast[ ns ] = nSampLast[ ns ] + (sal_uInt8) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample );
827                             else
828                                 nSampLast[ ns ] = nSampLast[ ns ] + (sal_uInt8) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample );
829                             nSamp[ ns ] = nSampLast[ ns ];
830                         }
831                     }
832                     else
833                     {
834                         for( ns = 0; ns < 4; ns++ )
835                         {
836                             if( nPlanes < 3 )
837                                 nSamp[ ns ] = (sal_uInt8) GetBits( pMap[ 0 ], ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample );
838                             else
839                                 nSamp[ ns ]= (sal_uInt8) GetBits( pMap[ ns ], nx * nBitsPerSample, nBitsPerSample );
840                         }
841                     }
842                     nBlack = nSamp[ 3 ];
843                     nRed = (sal_uInt8) Max( 0L, 255L - ( ( (long) nSamp[ 0 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
844                                 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
845                     nGreen = (sal_uInt8) Max( 0L, 255L - ( ( (long) nSamp[ 1 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
846                                 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
847                     nBlue = (sal_uInt8) Max( 0L, 255L - ( ( (long) nSamp[ 2 ] + nBlack - ( ( (long) nMinSampleValue ) << 1 ) ) *
848                                 255L/(long)(nMaxSampleValue-nMinSampleValue) ) );
849                     pAcc->SetPixel( nY, nx, Color ( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
850                 }
851             }
852         }
853     }
854     else if ( nSamplesPerPixel == 1 && ( nPhotometricInterpretation <= 1 || nPhotometricInterpretation == 3 ) )
855     {
856         if ( nMaxSampleValue > nMinSampleValue )
857         {
858             sal_uLong nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
859             sal_uInt8* pt = pMap[ 0 ];
860             sal_uInt8 nShift;
861 
862             switch ( nDstBitsPerPixel )
863             {
864                 case 8 :
865                 {
866                     sal_uInt8 nLast;
867                     if ( bByteSwap )
868                     {
869                         if ( nPredictor == 2 )
870                         {
871                             nLast = BYTESWAP( (sal_uInt8)*pt++ );
872                             for ( nx = 0; nx < nImageWidth; nx++ )
873                             {
874                                 pAcc->SetPixelIndex( nY, nx, nLast );
875                                 nLast = nLast + *pt++;
876                             }
877                         }
878                         else
879                         {
880                             for ( nx = 0; nx < nImageWidth; nx++ )
881                             {
882                                 nLast = *pt++;
883                                 pAcc->SetPixelIndex( nY, nx, static_cast<sal_uInt8>( (BYTESWAP((sal_uLong)nLast) - nMinSampleValue) * nMinMax ) );
884                             }
885                         }
886                     }
887                     else
888                     {
889                         if ( nPredictor == 2 )
890                         {
891                             nLast = *pt++;
892                             for ( nx = 0; nx < nImageWidth; nx++ )
893                             {
894                                 pAcc->SetPixelIndex( nY, nx, nLast );
895                                 nLast = nLast + *pt++;
896                             }
897                         }
898                         else
899                         {
900                             for ( nx = 0; nx < nImageWidth; nx++ )
901                             {
902                                 pAcc->SetPixelIndex( nY, nx, static_cast<sal_uInt8>( ((sal_uLong)*pt++ - nMinSampleValue) * nMinMax ) );
903 
904                             }
905                         }
906                     }
907                 }
908                 break;
909 
910                 case 7 :
911                 case 6 :
912                 case 5 :
913                 case 4 :
914                 case 3 :
915                 case 2 :
916                 {
917                     for ( nx = 0; nx < nImageWidth; nx++ )
918                     {
919                         nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax;
920                         pAcc->SetPixelIndex( nY, nx, static_cast<sal_uInt8>(nVal));
921                     }
922                 }
923                 break;
924 
925                 case 1 :
926                 {
927                     if ( bByteSwap )
928                     {
929                         nx = 0;
930                         nByteCount = ( nImageWidth >> 3 ) + 1;
931                         while ( --nByteCount )
932                         {
933                             nByteVal = *pt++;
934                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
935                             nByteVal >>= 1;
936                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
937                             nByteVal >>= 1;
938                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
939                             nByteVal >>= 1;
940                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
941                             nByteVal >>= 1;
942                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
943                             nByteVal >>= 1;
944                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
945                             nByteVal >>= 1;
946                             pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
947                             nByteVal >>= 1;
948                             pAcc->SetPixelIndex( nY, nx++, nByteVal );
949                         }
950                         if ( nImageWidth & 7 )
951                         {
952                             nByteVal = *pt++;
953                             while ( nx < nImageWidth )
954                             {
955                                 pAcc->SetPixelIndex( nY, nx++, nByteVal & 1 );
956                                 nByteVal >>= 1;
957                             }
958                         }
959                     }
960                     else
961                     {
962                         nx = 7;
963                         nByteCount = ( nImageWidth >> 3 ) + 1;
964                         while ( --nByteCount )
965                         {
966                             nByteVal = *pt++;
967                             pAcc->SetPixelIndex( nY, nx, nByteVal & 1 );
968                             nByteVal >>= 1;
969                             pAcc->SetPixelIndex( nY, --nx, nByteVal & 1 );
970                             nByteVal >>= 1;
971                             pAcc->SetPixelIndex( nY, --nx, nByteVal & 1 );
972                             nByteVal >>= 1;
973                             pAcc->SetPixelIndex( nY, --nx, nByteVal & 1 );
974                             nByteVal >>= 1;
975                             pAcc->SetPixelIndex( nY, --nx, nByteVal & 1 );
976                             nByteVal >>= 1;
977                             pAcc->SetPixelIndex( nY, --nx, nByteVal & 1 );
978                             nByteVal >>= 1;
979                             pAcc->SetPixelIndex( nY, --nx, nByteVal & 1 );
980                             nByteVal >>= 1;
981                             pAcc->SetPixelIndex( nY, --nx, nByteVal );
982                             nx += 15;
983                         }
984                         if ( nImageWidth & 7 )
985                         {
986                             nx -= 7;
987                             nByteVal = *pt++;
988                             nShift = 7;
989                             while ( nx < nImageWidth )
990                             {
991                                 pAcc->SetPixelIndex( nY, nx++, ( nByteVal >> nShift ) & 1);
992                             }
993                         }
994                     }
995                 }
996                 break;
997 
998                 default :
999                     return sal_False;
1000             }
1001         }
1002     }
1003     else if ( ( nSamplesPerPixel == 2 ) && ( nBitsPerSample == 8 ) &&
1004         ( nPlanarConfiguration == 1 ) && ( pColorMap == 0 ) )               // grayscale
1005     {
1006         if ( nMaxSampleValue > nMinSampleValue )
1007         {
1008             sal_uLong nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
1009             sal_uInt8*  pt = pMap[ 0 ];
1010             if ( nByte1 == 'I' )
1011                 pt++;
1012             for ( nx = 0; nx < nImageWidth; nx++, pt += 2 )
1013             {
1014                 pAcc->SetPixelIndex( nY, nx, static_cast<sal_uInt8>( ((sal_uLong)*pt - nMinSampleValue) * nMinMax) );
1015             }
1016         }
1017     }
1018     else
1019         return sal_False;
1020     return sal_True;
1021 }
1022 
1023 // ---------------------------------------------------------------------------------
1024 
MakePalCol(void)1025 void TIFFReader::MakePalCol( void )
1026 {
1027     if ( nDstBitsPerPixel <= 8 )
1028     {
1029         sal_uLong i, nVal, n0RGB;
1030         if  ( pColorMap == NULL )
1031             pColorMap = new sal_uLong[ 256 ];
1032         if ( nPhotometricInterpretation <= 1 )
1033         {
1034             nNumColors = 1 << nBitsPerSample;
1035             if ( nNumColors > 256 )
1036                 nNumColors = 256;
1037             pAcc->SetPaletteEntryCount( (sal_uInt16)nNumColors );
1038             for ( i = 0; i < nNumColors; i++ )
1039             {
1040                 nVal = ( i * 255 / ( nNumColors - 1 ) ) & 0xff;
1041                 n0RGB = nVal | ( nVal << 8 ) | ( nVal << 16 );
1042                 if ( nPhotometricInterpretation == 1 )
1043                     pColorMap[ i ] = n0RGB;
1044                 else
1045                     pColorMap[ nNumColors - i - 1 ] = n0RGB;
1046             }
1047         }
1048         for ( i = 0; i < nNumColors; i++ )
1049         {
1050             pAcc->SetPaletteColor( (sal_uInt16)i, BitmapColor( (sal_uInt8)( pColorMap[ i ] >> 16 ),
1051                 (sal_uInt8)( pColorMap[ i ] >> 8 ), (sal_uInt8)pColorMap[ i ] ) );
1052         }
1053     }
1054 
1055     if ( fXResolution > 1.0 && fYResolution > 1.0 && ( nResolutionUnit == 2 || nResolutionUnit == 3 ) )
1056     {
1057         sal_uLong nRX,nRY;
1058         if (nResolutionUnit==2)
1059         {
1060             nRX=(sal_uLong)(fXResolution+0.5);
1061             nRY=(sal_uLong)(fYResolution+0.5);
1062         }
1063         else
1064         {
1065             nRX=(sal_uLong)(fXResolution*2.54+0.5);
1066             nRY=(sal_uLong)(fYResolution*2.54+0.5);
1067         }
1068         MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nRX),Fraction(1,nRY));
1069         aBitmap.SetPrefMapMode(aMapMode);
1070         aBitmap.SetPrefSize(Size(nImageWidth,nImageLength));
1071     }
1072 }
1073 
1074 // ---------------------------------------------------------------------------------
1075 
ReadHeader()1076 void TIFFReader::ReadHeader()
1077 {
1078     sal_uInt8 nbyte1, nbyte2;
1079     sal_uInt16 nushort;
1080 
1081     *pTIFF >> nbyte1;
1082     if ( nbyte1 == 'I' )
1083         pTIFF->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1084     else
1085         pTIFF->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
1086 
1087     *pTIFF >> nbyte2 >> nushort;
1088     if ( nbyte1 != nbyte2 || ( nbyte1 != 'I' && nbyte1 != 'M' ) || nushort != 0x002a )
1089         bStatus = sal_False;
1090 }
1091 
1092 // ---------------------------------------------------------------------------------
1093 
ReadTIFF(SvStream & rTIFF,Graphic & rGraphic)1094 sal_Bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic )
1095 {
1096     sal_uInt16  i, nNumTags, nTagType;
1097     sal_uLong   nMaxPos;
1098     sal_uLong   nPos;
1099     sal_uInt32 nFirstIfd, nDataLen;
1100 
1101     bStatus = sal_True;
1102     nLastPercent = 0;
1103 
1104     pTIFF = &rTIFF;
1105     nMaxPos = nOrigPos = pTIFF->Tell();
1106     nOrigNumberFormat = pTIFF->GetNumberFormatInt();
1107 
1108     MayCallback( 0 );
1109 
1110     // Kopf einlesen:
1111     ReadHeader();
1112 
1113     // Ersten IFD einlesen:
1114     *pTIFF >> nFirstIfd;
1115 
1116     if( !nFirstIfd || pTIFF->GetError() )
1117         bStatus = sal_False;
1118 
1119     if ( bStatus )
1120     {
1121         sal_uInt32 nOffset = nFirstIfd;
1122 
1123         // calculate length of TIFF file
1124         do
1125         {
1126             pTIFF->Seek( nOrigPos + nOffset );
1127 
1128             if( pTIFF->GetError() )
1129             {
1130                 pTIFF->ResetError();
1131                 break;
1132             };
1133             nMaxPos = Max( pTIFF->Tell(), nMaxPos );
1134 
1135             *pTIFF >> nNumTags;
1136 
1137             // Schleife ueber Tags:
1138             for( i = 0; i < nNumTags; i++ )
1139             {
1140                 *pTIFF >> nTagType >> nDataType >> nDataLen >> nOffset;
1141 
1142                 if( DataTypeSize() * nDataLen > 4 )
1143                     nMaxPos = Max( nOrigPos + nOffset + DataTypeSize() * nDataLen, nMaxPos );
1144             }
1145             *pTIFF >> nOffset;
1146             if ( pTIFF->IsEof() )
1147                 nOffset = 0;
1148 
1149             nMaxPos = Max( pTIFF->Tell(), nMaxPos );
1150             if ( !nOffset )
1151                 nMaxPos = Max( pTIFF->Tell(), nMaxPos );
1152         }
1153         while( nOffset );
1154 
1155         for ( sal_uInt32 nNextIfd = nFirstIfd; nNextIfd && bStatus; )
1156         {
1157             pTIFF->Seek( nOrigPos + nNextIfd );
1158             {
1159                 bByteSwap = sal_False;
1160 
1161                 nNewSubFile = 0;
1162                 nSubFile = 0;
1163                 nImageWidth = 0;
1164                 nImageLength = 0;
1165                 nBitsPerSample = 1;                         // Defaultwert laut Doku
1166                 nCompression = 1;
1167                 nPhotometricInterpretation = 0;
1168                 nThresholding = 1;                          // Defaultwert laut Doku
1169                 nCellWidth = 1;
1170                 nCellLength = 1;
1171                 nFillOrder = 1;                             // Defaultwert laut Doku
1172                 nNumStripOffsets = 0;
1173                 nOrientation = 1;
1174                 nSamplesPerPixel = 1;                       // Defaultwert laut Doku
1175                 nRowsPerStrip = 0xffffffff;                 // Defaultwert laut Doku
1176                 nNumStripByteCounts = 0;
1177                 nMinSampleValue = 0;                        // Defaultwert laut Doku
1178                 nMaxSampleValue = 0;
1179                 fXResolution = 0.0;
1180                 fYResolution = 0.0;
1181                 nPlanarConfiguration = 1;
1182                 nGroup3Options = 0;                         // Defaultwert laut Doku
1183                 nGroup4Options = 0;                         // Defaultwert laut Doku
1184                 nResolutionUnit = 2;                        // Defaultwert laut Doku
1185                 nPredictor = 1;
1186                 nNumColors = 0;
1187 
1188                 pAcc = NULL;
1189                 pColorMap = NULL;
1190                 pStripOffsets = NULL;
1191                 pStripByteCounts = NULL;
1192                 pMap[ 0 ] = pMap[ 1 ] = pMap[ 2 ] = pMap[ 3 ] = NULL;
1193 
1194                 *pTIFF >> nNumTags;
1195                 nPos = pTIFF->Tell();
1196 
1197                 // Schleife ueber Tags:
1198                 for( i = 0; i < nNumTags; i++ )
1199                 {
1200                     *pTIFF >> nTagType >> nDataType >> nDataLen;
1201 
1202                     if( DataTypeSize() * nDataLen > 4 )
1203                     {
1204                         *pTIFF >> nOffset;
1205                         pTIFF->Seek( nOrigPos + nOffset );
1206                     }
1207                     ReadTagData( nTagType, nDataLen );
1208                     nPos += 12; pTIFF->Seek( nPos );
1209 
1210                     if ( pTIFF->GetError() )
1211                         bStatus = sal_False;
1212 
1213                     if ( bStatus == sal_False )
1214                         break;
1215                 }
1216                 *pTIFF >> nNextIfd;
1217                 if ( pTIFF->IsEof() )
1218                     nNextIfd = 0;
1219             }
1220             if ( !nBitsPerSample || ( nBitsPerSample > 32 ) )
1221                 bStatus = sal_False;
1222             if ( bStatus )
1223             {
1224                 if ( nMaxSampleValue == 0 )
1225                 {
1226                     if ( nBitsPerSample == 32 )         // sj: i93300, compiler bug, 1 << 32 gives 1 one 32bit windows platforms,
1227                         nMaxSampleValue = 0xffffffff;   // (up from 80286 only the lower 5 bits are used when shifting a 32bit register)
1228                     else
1229                         nMaxSampleValue = ( 1 << nBitsPerSample ) - 1;
1230                 }
1231                 if ( nPhotometricInterpretation == 2 || nPhotometricInterpretation == 5 || nPhotometricInterpretation == 6 )
1232                     nDstBitsPerPixel = 24;
1233                 else if ( nBitsPerSample*nSamplesPerPixel <= 1 )
1234                     nDstBitsPerPixel = 1;
1235                 else if ( nBitsPerSample*nSamplesPerPixel <= 4 )
1236                     nDstBitsPerPixel = 4;
1237                 else
1238                     nDstBitsPerPixel = 8;
1239 
1240                 aBitmap = Bitmap( Size( nImageWidth, nImageLength ), nDstBitsPerPixel );
1241                 pAcc = aBitmap.AcquireWriteAccess();
1242                 if ( pAcc )
1243                 {
1244                     if ( nPlanarConfiguration == 1 )
1245                         nPlanes = 1;
1246                     else
1247                         nPlanes = nSamplesPerPixel;
1248 
1249                     if ( ( nFillOrder == 2 ) && ( nCompression != 5 ) )     // im LZW Mode werden die bits schon invertiert
1250                         bByteSwap = sal_True;
1251 
1252                     nStripsPerPlane = ( nImageLength - 1 ) / nRowsPerStrip + 1;
1253                     nBytesPerRow = ( nImageWidth * nSamplesPerPixel / nPlanes * nBitsPerSample + 7 ) >> 3;
1254 
1255                     for ( sal_uLong j = 0; j < 4; j++ )
1256                     {
1257                         try
1258                         {
1259                             pMap[ j ] = new sal_uInt8[ nBytesPerRow ];
1260                         }
1261                             catch (std::bad_alloc)
1262                         {
1263                             pMap[ j ] = NULL;
1264                             bStatus = sal_False;
1265                             break;
1266                         }
1267                     }
1268 
1269                     if ( bStatus && ReadMap( 10, 60 ) )
1270                     {
1271                         nMaxPos = Max( pTIFF->Tell(), nMaxPos );
1272                         MakePalCol();
1273                         nMaxPos = Max( pTIFF->Tell(), nMaxPos );
1274                     }
1275                     else
1276                         bStatus = sal_False;
1277 
1278                     if( pAcc )
1279                     {
1280                         aBitmap.ReleaseAccess( pAcc );
1281                         if ( bStatus )
1282                         {
1283                             AnimationBitmap aAnimationBitmap( aBitmap, Point( 0, 0 ), aBitmap.GetSizePixel(),
1284                                                               ANIMATION_TIMEOUT_ON_CLICK, DISPOSE_BACK );
1285 
1286                             aAnimation.Insert( aAnimationBitmap );
1287                         }
1288                     }
1289                     // Aufraeumen:
1290                     for ( i = 0; i < 4; i++ )
1291                         delete[] pMap[ i ];
1292 
1293                     delete[] pColorMap;
1294                     delete[] pStripOffsets;
1295                     delete[] pStripByteCounts;
1296                 }
1297             }
1298         }
1299     }
1300 
1301     // seek to end of TIFF if succeeded
1302     pTIFF->SetNumberFormatInt( nOrigNumberFormat );
1303     pTIFF->Seek( bStatus ? nMaxPos : nOrigPos );
1304 
1305     if ( aAnimation.Count() )
1306     {
1307         if ( aAnimation.Count() == 1 )
1308             rGraphic = aAnimation.GetBitmapEx();
1309         else
1310             rGraphic = aAnimation;  //aBitmap;
1311 
1312         return sal_True;
1313     }
1314     else
1315         return sal_False;
1316 }
1317 
1318 
1319 //================== GraphicImport - die exportierte Funktion ================
1320 
GraphicImport(SvStream & rStream,Graphic & rGraphic,FilterConfigItem *,sal_Bool)1321 extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool )
1322 {
1323     TIFFReader aTIFFReader;
1324 
1325     if ( aTIFFReader.ReadTIFF( rStream, rGraphic ) == sal_False )
1326         return sal_False;
1327 
1328     return sal_True;
1329 }
1330 
1331