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