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