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, np + 1 == 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