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 
27 #include <vcl/graph.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/msgbox.hxx>
30 #include <vcl/bmpacc.hxx>
31 #include <svl/solar.hrc>
32 #include <svtools/fltcall.hxx>
33 #include <svtools/FilterConfigItem.hxx>
34 
35 #define NewSubfileType				254
36 #define ImageWidth					256
37 #define ImageLength					257
38 #define BitsPerSample				258
39 #define Compression					259
40 #define PhotometricInterpretation	262
41 #define StripOffsets				273
42 #define SamplesPerPixel				277
43 #define RowsPerStrip				278
44 #define StripByteCounts				279
45 #define XResolution					282
46 #define YResolution					283
47 #define PlanarConfiguration			284
48 #define ResolutionUnit				296
49 #define ColorMap					320
50 #define ReferenceBlackWhite			532
51 
52 // -------------
53 // - TIFFWriter -
54 // -------------
55 
56 struct TIFFLZWCTreeNode
57 {
58 
59 	TIFFLZWCTreeNode*	pBrother;		// naechster Knoten, der den selben Vater hat
60 	TIFFLZWCTreeNode*	pFirstChild;	// erster Sohn
61 	sal_uInt16				nCode;			// Der Code fuer den String von Pixelwerten, der sich ergibt, wenn
62 	sal_uInt16				nValue; 		// Der Pixelwert
63 };
64 
65 class TIFFWriter
66 {
67 private:
68 
69 	SvStream*			mpOStm;
70 	sal_uInt32				mnStreamOfs;
71 
72 	sal_Bool				mbStatus;
73 	BitmapReadAccess*	mpAcc;
74 
75 	sal_uInt32				mnWidth, mnHeight, mnColors;
76 	sal_uInt32				mnCurAllPictHeight;
77 	sal_uInt32				mnSumOfAllPictHeight;
78 	sal_uInt32				mnBitsPerPixel;
79 	sal_uInt32				mnLastPercent;
80 
81 	sal_uInt32				mnLatestIfdPos;
82 	sal_uInt16				mnTagCount;					// number of tags already written
83 	sal_uInt32				mnCurrentTagCountPos;		// offset to the position where the current
84 													// tag count is to insert
85 
86 	sal_uInt32				mnXResPos;					// if != 0 this DWORDs stores the
87 	sal_uInt32				mnYResPos;					// actual streamposition of the
88 	sal_uInt32				mnPalPos;					// Tag Entry
89 	sal_uInt32				mnBitmapPos;
90 	sal_uInt32				mnStripByteCountPos;
91 
92 	TIFFLZWCTreeNode*	pTable;
93 	TIFFLZWCTreeNode*	pPrefix;
94 	sal_uInt16				nDataSize;
95 	sal_uInt16				nClearCode;
96 	sal_uInt16				nEOICode;
97 	sal_uInt16				nTableSize;
98 	sal_uInt16				nCodeSize;
99 	sal_uLong				nOffset;
100 	sal_uLong				dwShift;
101 
102 	com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
103 
104 	void				ImplCallback( sal_uInt32 nPercent );
105 	sal_Bool				ImplWriteHeader( sal_Bool bMultiPage );
106 	void				ImplWritePalette();
107 	sal_Bool				ImplWriteBody();
108 	void				ImplWriteTag( sal_uInt16 TagID, sal_uInt16 DataType, sal_uInt32 NumberOfItems, sal_uInt32 Value);
109 	void				ImplWriteResolution( sal_uLong nStreamPos, sal_uInt32 nResolutionUnit );
110 	void				StartCompression();
111 	void				Compress( sal_uInt8 nSrc );
112 	void				EndCompression();
113 	inline void			WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen );
114 
115 public:
116 
117 						TIFFWriter();
118 						~TIFFWriter();
119 
120 	sal_Bool				WriteTIFF( const Graphic& rGraphic, SvStream& rTIFF, FilterConfigItem* pFilterConfigItem );
121 };
122 
123 // ------------------------------------------------------------------------
124 
TIFFWriter()125 TIFFWriter::TIFFWriter() :
126 		mbStatus			( sal_True ),
127 		mpAcc				( NULL ),
128 		mnCurAllPictHeight	( 0 ),
129 		mnSumOfAllPictHeight( 0 ),
130 		mnLastPercent		( 0 ),
131 		mnXResPos			( 0 ),
132 		mnYResPos			( 0 ),
133 		mnBitmapPos			( 0 ),
134 		mnStripByteCountPos	( 0 )
135 {
136 }
137 
138 // ------------------------------------------------------------------------
139 
~TIFFWriter()140 TIFFWriter::~TIFFWriter()
141 {
142 }
143 
144 // ------------------------------------------------------------------------
145 
WriteTIFF(const Graphic & rGraphic,SvStream & rTIFF,FilterConfigItem * pFilterConfigItem)146 sal_Bool TIFFWriter::WriteTIFF( const Graphic& rGraphic, SvStream& rTIFF, FilterConfigItem* pFilterConfigItem)
147 {
148 	sal_uLong*	pDummy = new sal_uLong; delete pDummy; // damit unter OS/2
149 											   // das richtige (Tools-)new
150 											   // verwendet wird, da es sonst
151 											   // in dieser DLL nur Vector-news
152 											   // gibt;
153 
154 	if ( pFilterConfigItem )
155 	{
156 		xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
157 		if ( xStatusIndicator.is() )
158 		{
159 			rtl::OUString aMsg;
160 			xStatusIndicator->start( aMsg, 100 );
161 		}
162 	}
163 
164 	// #i69169# copy stream
165 	mpOStm = &rTIFF;
166 
167 	const sal_uInt16	nOldFormat = mpOStm->GetNumberFormatInt();
168 	mnStreamOfs = mpOStm->Tell();
169 
170 	// we will use the BIG Endian Mode
171 	// TIFF header
172 	mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
173 	*mpOStm << (sal_uInt32)0x4d4d002a;		// TIFF identifier
174 	mnLatestIfdPos = mpOStm->Tell();
175 	*mpOStm << (sal_uInt32)0;
176 
177 	Animation 	aAnimation;
178 	Bitmap		aBmp;
179 
180 	if( mbStatus )
181 	{
182 		if ( rGraphic.IsAnimated() )
183 			aAnimation = rGraphic.GetAnimation();
184 		else
185 		{
186 			AnimationBitmap aAnimationBitmap( rGraphic.GetBitmap(), Point(), Size() );
187 			aAnimation.Insert( aAnimationBitmap );
188 		}
189 
190 		sal_uInt16 i;
191 		for ( i = 0; i < aAnimation.Count(); i++ )
192 			mnSumOfAllPictHeight += aAnimation.Get( i ).aBmpEx.GetSizePixel().Height();
193 
194 		for ( i = 0; mbStatus && ( i < aAnimation.Count() ); i++ )
195 		{
196 			mnPalPos = 0;
197 			const AnimationBitmap& rAnimationBitmap = aAnimation.Get( i );
198 			aBmp = rAnimationBitmap.aBmpEx.GetBitmap();
199 			mpAcc = aBmp.AcquireReadAccess();
200 			if ( mpAcc )
201 			{
202 				mnBitsPerPixel = aBmp.GetBitCount();
203 
204                 // export code below only handles four discrete cases
205                 mnBitsPerPixel =
206                     mnBitsPerPixel <= 1 ? 1 : mnBitsPerPixel <= 4 ? 4 : mnBitsPerPixel <= 8 ? 8 : 24;
207 
208 				if ( ImplWriteHeader( ( aAnimation.Count() > 0 ) ) )
209 				{
210 					Size aDestMapSize( 300, 300 );
211 					const MapMode aMapMode( aBmp.GetPrefMapMode() );
212 					if ( aMapMode.GetMapUnit() != MAP_PIXEL )
213 					{
214 						const Size aPrefSize( rGraphic.GetPrefSize() );
215 						aDestMapSize = OutputDevice::LogicToLogic( aPrefSize, aMapMode, MAP_INCH );
216 					}
217 					ImplWriteResolution( mnXResPos, aDestMapSize.Width() );
218 					ImplWriteResolution( mnYResPos, aDestMapSize.Height() );
219 					if	( mnPalPos )
220 						ImplWritePalette();
221 					ImplWriteBody();
222 				}
223 				sal_uInt32 nCurPos = mpOStm->Tell();
224 				mpOStm->Seek( mnCurrentTagCountPos );
225 				*mpOStm << mnTagCount;
226 				mpOStm->Seek( nCurPos );
227 
228 				aBmp.ReleaseAccess( mpAcc );
229 			}
230 			else
231 				mbStatus = sal_False;
232 		}
233 	}
234 	mpOStm->SetNumberFormatInt( nOldFormat );
235 
236 	if ( xStatusIndicator.is() )
237 		xStatusIndicator->end();
238 
239 	return mbStatus;
240 }
241 
242 // ------------------------------------------------------------------------
243 
ImplCallback(sal_uInt32 nPercent)244 void TIFFWriter::ImplCallback( sal_uInt32 nPercent )
245 {
246 	if ( xStatusIndicator.is() )
247 	{
248 		if( nPercent >= mnLastPercent + 3 )
249 		{
250 			mnLastPercent = nPercent;
251 			if ( nPercent <= 100 )
252 				xStatusIndicator->setValue( nPercent );
253 		}
254 	}
255 }
256 
257 
258 // ------------------------------------------------------------------------
259 
ImplWriteHeader(sal_Bool bMultiPage)260 sal_Bool TIFFWriter::ImplWriteHeader( sal_Bool bMultiPage )
261 {
262 	mnTagCount = 0;
263 	mnWidth = mpAcc->Width();
264 	mnHeight = mpAcc->Height();
265 
266 	if ( mnWidth && mnHeight && mnBitsPerPixel && mbStatus )
267 	{
268 		sal_uInt32 nCurrentPos = mpOStm->Tell();
269 		mpOStm->Seek( mnLatestIfdPos );
270 		*mpOStm << (sal_uInt32)( nCurrentPos - mnStreamOfs );	// offset to the IFD
271 		mpOStm->Seek( nCurrentPos );
272 
273 		// (OFS8) TIFF image file directory (IFD)
274 		mnCurrentTagCountPos = mpOStm->Tell();
275 		*mpOStm << (sal_uInt16)0;				// the number of tagentrys is to insert later
276 
277 		sal_uInt32 nSubFileFlags = 0;
278 		if ( bMultiPage )
279 			nSubFileFlags |= 2;
280 		ImplWriteTag( NewSubfileType, 4, 1, nSubFileFlags );
281 		ImplWriteTag( ImageWidth, 4, 1, mnWidth );
282 		ImplWriteTag( ImageLength, 4, 1, mnHeight);
283 		ImplWriteTag( BitsPerSample, 3, 1, ( mnBitsPerPixel == 24 ) ? 8 : mnBitsPerPixel );
284 		ImplWriteTag( Compression, 3, 1, 5 );
285 		sal_uInt8 nTemp;
286 		switch ( mnBitsPerPixel )
287 		{
288 			case 1 :
289 				nTemp = 1;
290 				break;
291 			case 4 :
292 			case 8 :
293 				nTemp = 3;
294 				break;
295 			case 24:
296 				nTemp = 2;
297 				break;
298 			default:
299 				nTemp = 0;	// -Wall set a default...
300 				break;
301 		}
302 		ImplWriteTag( PhotometricInterpretation, 3, 1, nTemp );
303 		mnBitmapPos = mpOStm->Tell();
304 		ImplWriteTag( StripOffsets, 4, 1, 0 );
305 		ImplWriteTag( SamplesPerPixel, 3, 1, ( mnBitsPerPixel == 24 ) ? 3 : 1 );
306 		ImplWriteTag( RowsPerStrip, 4, 1, mnHeight );	//0xffffffff );
307 		mnStripByteCountPos = mpOStm->Tell();
308 		ImplWriteTag( StripByteCounts, 4, 1, ( ( mnWidth * mnBitsPerPixel * mnHeight ) + 7 ) >> 3 );
309 		mnXResPos = mpOStm->Tell();
310 		ImplWriteTag( XResolution, 5, 1, 0 );
311 		mnYResPos = mpOStm->Tell();
312 		ImplWriteTag( YResolution, 5, 1, 0 );
313 		if ( mnBitsPerPixel != 1 )
314 			ImplWriteTag( PlanarConfiguration, 3, 1, 1 );	//  ( RGB ORDER )
315 		ImplWriteTag( ResolutionUnit, 3, 1, 2);				// Resolution Unit is Inch
316 		if ( ( mnBitsPerPixel == 4 ) || ( mnBitsPerPixel == 8 ) )
317 		{
318 			mnColors = mpAcc->GetPaletteEntryCount();
319 			mnPalPos = mpOStm->Tell();
320 			ImplWriteTag( ColorMap, 3, 3 * mnColors, 0 );
321 		}
322 
323 		// and last we write zero to close the num dir entries list
324 		mnLatestIfdPos = mpOStm->Tell();
325 		*mpOStm << (sal_uInt32)0;				// there are no more IFD
326 	}
327 	else
328 		mbStatus = sal_False;
329 
330 	return mbStatus;
331 }
332 
333 // ------------------------------------------------------------------------
334 
ImplWritePalette()335 void TIFFWriter::ImplWritePalette()
336 {
337 	sal_uInt16 i;
338 	sal_uLong nCurrentPos = mpOStm->Tell();
339 	mpOStm->Seek( mnPalPos + 8 );			// the palette tag entry needs the offset
340 	*mpOStm << static_cast<sal_uInt32>(nCurrentPos - mnStreamOfs);	// to the palette colors
341 	mpOStm->Seek( nCurrentPos );
342 
343 	for ( i = 0; i < mnColors; i++ )
344 	{
345 		const BitmapColor& rColor = mpAcc->GetPaletteColor( i );
346 		*mpOStm << (sal_uInt16)( rColor.GetRed() << 8 );
347 	}
348 	for ( i = 0; i < mnColors; i++ )
349 	{
350 		const BitmapColor& rColor = mpAcc->GetPaletteColor( i );
351 		*mpOStm << (sal_uInt16)( rColor.GetGreen() << 8 );
352 	}
353 	for ( i = 0; i < mnColors; i++ )
354 	{
355 		const BitmapColor& rColor = mpAcc->GetPaletteColor( i );
356 		*mpOStm << (sal_uInt16)( rColor.GetBlue() << 8 );
357 	}
358 }
359 
360 // ------------------------------------------------------------------------
361 
ImplWriteBody()362 sal_Bool TIFFWriter::ImplWriteBody()
363 {
364 	sal_uInt8	nTemp = 0;
365 	sal_uInt8    nShift;
366 	sal_uLong	j, x, y;
367 
368 	sal_uLong nGfxBegin = mpOStm->Tell();
369 	mpOStm->Seek( mnBitmapPos + 8 );		// the strip offset tag entry needs the offset
370 	*mpOStm << static_cast<sal_uInt32>(nGfxBegin - mnStreamOfs);		// to the bitmap data
371 	mpOStm->Seek( nGfxBegin );
372 
373 	StartCompression();
374 
375 	switch( mnBitsPerPixel )
376 	{
377 		case 24 :
378 		{
379 			for ( y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
380 			{
381 				ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
382 				for ( x = 0; x < mnWidth; x++ )
383 				{
384 					const BitmapColor& rColor = mpAcc->GetPixel( y, x );
385 					Compress( rColor.GetRed() );
386 					Compress( rColor.GetGreen() );
387 					Compress( rColor.GetBlue() );
388 				}
389 			}
390 		}
391 		break;
392 
393 		case 8 :
394 		{
395 			for ( y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
396 			{
397 				ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
398 				for ( x = 0; x < mnWidth; x++ )
399 				{
400 					Compress( mpAcc->GetPixelIndex( y, x ) );
401 				}
402 			}
403 		}
404 		break;
405 
406 		case 4 :
407 		{
408 			for ( nShift = 0, y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
409 			{
410 				ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
411 				for ( x = 0; x < mnWidth; x++, nShift++ )
412 				{
413 					if (!( nShift & 1 ))
414 						nTemp = ( mpAcc->GetPixelIndex( y, x ) << 4 );
415 					else
416 						Compress( (sal_uInt8)( nTemp | ( mpAcc->GetPixelIndex( y, x ) & 0xf ) ) );
417 				}
418 				if ( nShift & 1 )
419 					Compress( nTemp );
420 			}
421 		}
422 		break;
423 
424 		case 1 :
425 		{
426 			j = 1;
427 			for ( y = 0; y < mnHeight; y++, mnCurAllPictHeight++ )
428 			{
429 				ImplCallback( 100 * mnCurAllPictHeight / mnSumOfAllPictHeight );
430 				for ( x = 0; x < mnWidth; x++)
431 				{
432 					j <<= 1;
433 					j |= ( ( ~mpAcc->GetPixelIndex( y, x ) ) & 1 );
434 					if ( j & 0x100 )
435 					{
436 						Compress( (sal_uInt8)j );
437 						j = 1;
438 					}
439 				}
440 				if ( j != 1 )
441 				{
442 					Compress( (sal_uInt8)(j << ( ( ( x & 7) ^ 7 ) + 1 ) ) );
443 					j = 1;
444 				}
445 			}
446 		}
447 		break;
448 
449 		default:
450 		{
451 			mbStatus = sal_False;
452 		}
453 		break;
454 	}
455 
456 	EndCompression();
457 
458 	if ( mnStripByteCountPos && mbStatus )
459 	{
460 		sal_uLong nGfxEnd = mpOStm->Tell();
461 		mpOStm->Seek( mnStripByteCountPos + 8 );
462 		*mpOStm << static_cast<sal_uInt32>( nGfxEnd - nGfxBegin );		// mnStripByteCountPos needs the size of the compression data
463 		mpOStm->Seek( nGfxEnd );
464 	}
465 	return mbStatus;
466 }
467 
468 // ------------------------------------------------------------------------
469 
ImplWriteResolution(sal_uLong nStreamPos,sal_uInt32 nResolutionUnit)470 void TIFFWriter::ImplWriteResolution( sal_uLong nStreamPos, sal_uInt32 nResolutionUnit )
471 {
472 	sal_uLong nCurrentPos = mpOStm->Tell();
473 	mpOStm->Seek( nStreamPos + 8 );
474 	*mpOStm << (sal_uInt32)nCurrentPos - mnStreamOfs;
475 	mpOStm->Seek( nCurrentPos );
476 	*mpOStm << (sal_uInt32)1;
477 	*mpOStm << nResolutionUnit;
478 }
479 
480 // ------------------------------------------------------------------------
481 
ImplWriteTag(sal_uInt16 nTagID,sal_uInt16 nDataType,sal_uInt32 nNumberOfItems,sal_uInt32 nValue)482 void TIFFWriter::ImplWriteTag( sal_uInt16 nTagID, sal_uInt16 nDataType, sal_uInt32 nNumberOfItems, sal_uInt32 nValue)
483 {
484 		mnTagCount++;
485 
486 		*mpOStm << nTagID;
487 		*mpOStm << nDataType;
488 		*mpOStm << nNumberOfItems;
489 		if ( nDataType == 3 )
490 			nValue <<=16;			// in Big Endian Mode WORDS needed to be shifted to a DWORD
491 		*mpOStm << nValue;
492 }
493 
494 // ------------------------------------------------------------------------
495 
WriteBits(sal_uInt16 nCode,sal_uInt16 nCodeLen)496 inline void TIFFWriter::WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen )
497 {
498 	dwShift |= ( nCode << ( nOffset - nCodeLen ) );
499 	nOffset -= nCodeLen;
500 	while ( nOffset < 24 )
501 	{
502 		*mpOStm << (sal_uInt8)( dwShift >> 24 );
503 		dwShift <<= 8;
504 		nOffset += 8;
505 	}
506 	if ( nCode == 257 && nOffset != 32 )
507 	{
508 		*mpOStm << (sal_uInt8)( dwShift >> 24 );
509 	}
510 }
511 
512 // ------------------------------------------------------------------------
513 
StartCompression()514 void TIFFWriter::StartCompression()
515 {
516 	sal_uInt16 i;
517 	nDataSize = 8;
518 
519 	nClearCode = 1 << nDataSize;
520 	nEOICode = nClearCode + 1;
521 	nTableSize = nEOICode + 1;
522 	nCodeSize = nDataSize + 1;
523 
524 	nOffset = 32;						// anzahl freier bits in dwShift
525 	dwShift = 0;
526 
527 	pTable = new TIFFLZWCTreeNode[ 4096 ];
528 
529 	for ( i = 0; i < 4096; i++)
530 	{
531 		pTable[ i ].pBrother = pTable[ i ].pFirstChild = NULL;
532 		pTable[ i ].nValue = (sal_uInt8)( pTable[ i ].nCode = i );
533 	}
534 
535 	pPrefix = NULL;
536 	WriteBits( nClearCode, nCodeSize );
537 }
538 
539 // ------------------------------------------------------------------------
540 
Compress(sal_uInt8 nCompThis)541 void TIFFWriter::Compress( sal_uInt8 nCompThis )
542 {
543 	TIFFLZWCTreeNode*	 p;
544 	sal_uInt16				i;
545 	sal_uInt8				nV;
546 
547 	if( !pPrefix )
548 	{
549 		pPrefix = pTable + nCompThis;
550 	}
551 	else
552 	{
553 		nV = nCompThis;
554 		for( p = pPrefix->pFirstChild; p != NULL; p = p->pBrother )
555 		{
556 			if ( p->nValue == nV )
557 				break;
558 		}
559 
560 		if( p )
561 			pPrefix = p;
562 		else
563 		{
564 			WriteBits( pPrefix->nCode, nCodeSize );
565 
566 			if ( nTableSize == 409 )
567 			{
568 				WriteBits( nClearCode, nCodeSize );
569 
570 				for ( i = 0; i < nClearCode; i++ )
571 					pTable[ i ].pFirstChild = NULL;
572 
573 				nCodeSize = nDataSize + 1;
574 				nTableSize = nEOICode + 1;
575 			}
576 			else
577 			{
578 				if( nTableSize == (sal_uInt16)( ( 1 << nCodeSize ) - 1 ) )
579 					nCodeSize++;
580 
581 				p = pTable + ( nTableSize++ );
582 				p->pBrother = pPrefix->pFirstChild;
583 				pPrefix->pFirstChild = p;
584 				p->nValue = nV;
585 				p->pFirstChild = NULL;
586 			}
587 
588 			pPrefix = pTable + nV;
589 		}
590 	}
591 }
592 
593 // ------------------------------------------------------------------------
594 
EndCompression()595 void TIFFWriter::EndCompression()
596 {
597 	if( pPrefix )
598 		WriteBits( pPrefix->nCode, nCodeSize );
599 
600 	WriteBits( nEOICode, nCodeSize );
601 	delete[] pTable;
602 }
603 
604 // ------------------------------------------------------------------------
605 
606 // ---------------------
607 // - exported function -
608 // ---------------------
609 
GraphicExport(SvStream & rStream,Graphic & rGraphic,FilterConfigItem * pFilterConfigItem,sal_Bool)610 extern "C" sal_Bool __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool )
611 {
612 	return TIFFWriter().WriteTIFF( rGraphic, rStream, pFilterConfigItem );
613 }
614 
615