bump product version to 4.1.6.2
[LibreOffice.git] / filter / source / graphicfilter / itga / itga.cxx
blob06220e31693ab2474656764fee4dbc2cdb187de2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <vcl/graph.hxx>
22 #include <vcl/bmpacc.hxx>
24 class FilterConfigItem;
26 //============================ TGAReader ==================================
28 struct TGAFileHeader
30 sal_uInt8 nImageIDLength;
31 sal_uInt8 nColorMapType;
32 sal_uInt8 nImageType;
33 sal_uInt16 nColorMapFirstEntryIndex;
34 sal_uInt16 nColorMapLength;
35 sal_uInt8 nColorMapEntrySize;
36 sal_uInt16 nColorMapXOrigin;
37 sal_uInt16 nColorMapYOrigin;
38 sal_uInt16 nImageWidth;
39 sal_uInt16 nImageHeight;
40 sal_uInt8 nPixelDepth;
41 sal_uInt8 nImageDescriptor;
44 #define SizeOfTGAFileFooter 26
46 struct TGAFileFooter
48 sal_uInt32 nExtensionFileOffset;
49 sal_uInt32 nDeveloperDirectoryOffset;
50 sal_uInt32 nSignature[4];
51 sal_uInt8 nPadByte;
52 sal_uInt8 nStringTerminator;
55 #define SizeOfTGAExtension 495
57 struct TGAExtension
59 sal_uInt16 nExtensionSize;
60 char sAuthorName[41];
61 char sAuthorComment[324];
62 char sDateTimeStamp[12];
63 char sJobNameID[41];
64 sal_uInt16 nJobTime[3];
65 char sSoftwareID[41];
66 sal_uInt16 nSoftwareVersionNumber;
67 sal_uInt8 nSoftwareVersionLetter;
68 sal_uInt32 nKeyColor;
69 sal_uInt16 nPixelAspectRatioNumerator;
70 sal_uInt16 nPixelAspectRatioDeNumerator;
71 sal_uInt16 nGammaValueNumerator;
72 sal_uInt16 nGammaValueDeNumerator;
73 sal_uInt32 nColorCorrectionOffset;
74 sal_uInt32 nPostageStampOffset;
75 sal_uInt32 nScanLineOffset;
76 sal_uInt8 nAttributesType;
79 class TGAReader {
81 private:
83 SvStream& m_rTGA;
85 BitmapWriteAccess* mpAcc;
86 TGAFileHeader* mpFileHeader;
87 TGAFileFooter* mpFileFooter;
88 TGAExtension* mpExtension;
89 sal_uInt32* mpColorMap;
91 sal_Bool mbStatus;
93 sal_uLong mnTGAVersion; // Enhanced TGA is defined as Version 2.0
94 sal_uInt16 mnDestBitDepth;
95 sal_Bool mbIndexing; // sal_True if source contains indexing color values
96 sal_Bool mbEncoding; // sal_True if source is compressed
98 sal_Bool ImplReadHeader();
99 sal_Bool ImplReadPalette();
100 sal_Bool ImplReadBody();
102 public:
103 TGAReader(SvStream &rTGA);
104 ~TGAReader();
105 sal_Bool ReadTGA(Graphic &rGraphic);
108 //=================== Methoden von TGAReader ==============================
110 TGAReader::TGAReader(SvStream &rTGA)
111 : m_rTGA(rTGA)
112 , mpAcc(NULL)
113 , mpFileHeader(NULL)
114 , mpFileFooter(NULL)
115 , mpExtension(NULL)
116 , mpColorMap(NULL)
117 , mbStatus(sal_True)
118 , mnTGAVersion(1)
119 , mbIndexing(sal_False)
120 , mbEncoding(sal_False)
124 TGAReader::~TGAReader()
126 delete[] mpColorMap;
127 delete mpFileHeader;
128 delete mpExtension;
129 delete mpFileFooter;
132 // -------------------------------------------------------------------------------------------
134 sal_Bool TGAReader::ReadTGA(Graphic & rGraphic)
136 if ( m_rTGA.GetError() )
137 return sal_False;
139 m_rTGA.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
141 // Kopf einlesen:
143 if ( !m_rTGA.GetError() )
145 mbStatus = ImplReadHeader();
146 if ( mbStatus )
148 Bitmap aBitmap;
150 aBitmap = Bitmap( Size( mpFileHeader->nImageWidth, mpFileHeader->nImageHeight ), mnDestBitDepth );
151 mpAcc = aBitmap.AcquireWriteAccess();
152 if ( mpAcc )
154 if ( mbIndexing )
155 mbStatus = ImplReadPalette();
156 if ( mbStatus )
157 mbStatus = ImplReadBody();
159 else
160 mbStatus = sal_False;
162 if ( mpAcc )
163 aBitmap.ReleaseAccess ( mpAcc), mpAcc = NULL;
165 if ( mbStatus )
166 rGraphic = aBitmap;
169 return mbStatus;
172 // -------------------------------------------------------------------------------------------
174 sal_Bool TGAReader::ImplReadHeader()
176 mpFileHeader = new TGAFileHeader;
177 if ( mpFileHeader == NULL )
178 return sal_False;
180 m_rTGA >> mpFileHeader->nImageIDLength >> mpFileHeader->nColorMapType >> mpFileHeader->nImageType >>
181 mpFileHeader->nColorMapFirstEntryIndex >> mpFileHeader->nColorMapLength >> mpFileHeader->nColorMapEntrySize >>
182 mpFileHeader->nColorMapXOrigin >> mpFileHeader->nColorMapYOrigin >> mpFileHeader->nImageWidth >>
183 mpFileHeader->nImageHeight >> mpFileHeader->nPixelDepth >> mpFileHeader->nImageDescriptor;
185 if ( !m_rTGA.good())
186 return sal_False;
188 if ( mpFileHeader->nColorMapType > 1 )
189 return sal_False;
190 if ( mpFileHeader->nColorMapType == 1 )
191 mbIndexing = sal_True;
193 // first we want to get the version
194 mpFileFooter = new TGAFileFooter; // read the TGA-File-Footer to determine whether
195 if ( mpFileFooter ) // we got an old TGA format or the new one
197 sal_uLong nCurStreamPos = m_rTGA.Tell();
198 m_rTGA.Seek( STREAM_SEEK_TO_END );
199 sal_uLong nTemp = m_rTGA.Tell();
200 m_rTGA.Seek( nTemp - SizeOfTGAFileFooter );
202 m_rTGA >> mpFileFooter->nExtensionFileOffset >> mpFileFooter->nDeveloperDirectoryOffset >>
203 mpFileFooter->nSignature[0] >> mpFileFooter->nSignature[1] >> mpFileFooter->nSignature[2] >>
204 mpFileFooter->nSignature[3] >> mpFileFooter->nPadByte >> mpFileFooter->nStringTerminator;
207 if ( !m_rTGA.good())
208 return sal_False;
210 // check for sal_True, VISI, ON-X, FILE in the signatures
211 if ( mpFileFooter->nSignature[ 0 ] == (('T'<<24)|('R'<<16)|('U'<<8)|'E') &&
212 mpFileFooter->nSignature[ 1 ] == (('V'<<24)|('I'<<16)|('S'<<8)|'I') &&
213 mpFileFooter->nSignature[ 2 ] == (('O'<<24)|('N'<<16)|('-'<<8)|'X') &&
214 mpFileFooter->nSignature[ 3 ] == (('F'<<24)|('I'<<16)|('L'<<8)|'E') )
216 mpExtension = new TGAExtension;
217 if ( mpExtension )
219 m_rTGA.Seek( mpFileFooter->nExtensionFileOffset );
220 m_rTGA >> mpExtension->nExtensionSize;
221 if ( !m_rTGA.good())
222 return sal_False;
223 if ( mpExtension->nExtensionSize >= SizeOfTGAExtension )
225 mnTGAVersion = 2;
227 m_rTGA.Read( mpExtension->sAuthorName, 41 );
228 m_rTGA.Read( mpExtension->sAuthorComment, 324 );
229 m_rTGA.Read( mpExtension->sDateTimeStamp, 12 );
230 m_rTGA.Read( mpExtension->sJobNameID, 12 );
231 m_rTGA >> mpExtension->sJobNameID[ 0 ] >> mpExtension->sJobNameID[ 1 ] >> mpExtension->sJobNameID[ 2 ];
232 m_rTGA.Read( mpExtension->sSoftwareID, 41 );
233 m_rTGA >> mpExtension->nSoftwareVersionNumber >> mpExtension->nSoftwareVersionLetter
234 >> mpExtension->nKeyColor >> mpExtension->nPixelAspectRatioNumerator
235 >> mpExtension->nPixelAspectRatioDeNumerator >> mpExtension->nGammaValueNumerator
236 >> mpExtension->nGammaValueDeNumerator >> mpExtension->nColorCorrectionOffset
237 >> mpExtension->nPostageStampOffset >> mpExtension->nScanLineOffset
238 >> mpExtension->nAttributesType;
240 if ( !m_rTGA.good())
241 return sal_False;
245 m_rTGA.Seek( nCurStreamPos );
248 // using the TGA file specification this was the correct form but adobe photoshop sets nImageDescriptor
249 // equal to nPixelDepth
250 // mnDestBitDepth = mpFileHeader->nPixelDepth - ( mpFileHeader->nImageDescriptor & 0xf );
251 mnDestBitDepth = mpFileHeader->nPixelDepth;
253 if ( mnDestBitDepth == 8 ) // this is a patch for grayscale pictures not including a palette
254 mbIndexing = sal_True;
256 if ( mnDestBitDepth > 32 ) // maybe the pixeldepth is invalid
257 return sal_False;
258 else if ( mnDestBitDepth > 8 )
259 mnDestBitDepth = 24;
260 else if ( mnDestBitDepth > 4 )
261 mnDestBitDepth = 8;
262 else if ( mnDestBitDepth > 2 )
263 mnDestBitDepth = 4;
265 if ( !mbIndexing && ( mnDestBitDepth < 15 ) )
266 return sal_False;
268 switch ( mpFileHeader->nImageType )
270 case 9 : // encoding for colortype 9, 10, 11
271 case 10 :
272 case 11 :
273 mbEncoding = sal_True;
274 break;
277 if ( mpFileHeader->nImageIDLength ) // skip the Image ID
278 m_rTGA.SeekRel( mpFileHeader->nImageIDLength );
280 return mbStatus;
283 // -------------------------------------------------------------------------------------------
285 sal_Bool TGAReader::ImplReadBody()
288 sal_uInt16 nXCount, nYCount, nRGB16;
289 sal_uInt8 nRed, nGreen, nBlue, nRunCount, nDummy, nDepth;
291 // this four variables match the image direction
292 long nY, nYAdd, nX, nXAdd, nXStart;
294 nX = nXStart = nY = 0;
295 nXCount = nYCount = 0;
296 nYAdd = nXAdd = 1;
298 if ( mpFileHeader->nImageDescriptor & 0x10 )
300 nX = nXStart = mpFileHeader->nImageWidth - 1;
301 nXAdd -= 2;
304 if ( !(mpFileHeader->nImageDescriptor & 0x20 ) )
306 nY = mpFileHeader->nImageHeight - 1;
307 nYAdd -=2;
310 nDepth = mpFileHeader->nPixelDepth;
312 if ( mbEncoding )
314 if ( mbIndexing )
316 switch( nDepth )
318 // 16 bit encoding + indexing
319 case 16 :
320 while ( nYCount < mpFileHeader->nImageHeight )
322 m_rTGA >> nRunCount;
323 if ( !m_rTGA.good())
324 return sal_False;
325 if ( nRunCount & 0x80 ) // a run length packet
327 m_rTGA >> nRGB16;
328 if ( nRGB16 >= mpFileHeader->nColorMapLength )
329 return sal_False;
330 nRed = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 16 );
331 nGreen = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 8 );
332 nBlue = (sal_uInt8)( mpColorMap[ nRGB16 ] );
333 if ( !m_rTGA.good())
334 return sal_False;
335 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
337 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
338 nX += nXAdd;
339 nXCount++;
340 if ( nXCount == mpFileHeader->nImageWidth )
342 nX = nXStart;
343 nXCount = 0;
344 nY += nYAdd;
345 nYCount++;
347 if( nYCount >= mpFileHeader->nImageHeight )
348 break;
352 else // a raw packet
354 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
356 m_rTGA >> nRGB16;
357 if ( !m_rTGA.good())
358 return sal_False;
359 if ( nRGB16 >= mpFileHeader->nColorMapLength )
360 return sal_False;
361 nRed = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 16 );
362 nGreen = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 8 );
363 nBlue = (sal_uInt8)( mpColorMap[ nRGB16 ] );
364 if ( !m_rTGA.good())
365 return sal_False;
366 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
367 nX += nXAdd;
368 nXCount++;
369 if ( nXCount == mpFileHeader->nImageWidth )
371 nX = nXStart;
372 nXCount = 0;
373 nY += nYAdd;
374 nYCount++;
376 if( nYCount >= mpFileHeader->nImageHeight )
377 break;
382 break;
384 // 8 bit encoding + indexing
385 case 8 :
386 while ( nYCount < mpFileHeader->nImageHeight )
388 m_rTGA >> nRunCount;
389 if ( !m_rTGA.good())
390 return sal_False;
391 if ( nRunCount & 0x80 ) // a run length packet
393 m_rTGA >> nDummy;
394 if ( !m_rTGA.good())
395 return sal_False;
396 if ( nDummy >= mpFileHeader->nColorMapLength )
397 return sal_False;
398 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
400 mpAcc->SetPixelIndex( nY, nX, nDummy );
401 nX += nXAdd;
402 nXCount++;
403 if ( nXCount == mpFileHeader->nImageWidth )
405 nX = nXStart;
406 nXCount = 0;
407 nY += nYAdd;
408 nYCount++;
410 if( nYCount >= mpFileHeader->nImageHeight )
411 break;
415 else // a raw packet
417 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
420 m_rTGA >> nDummy;
421 if ( !m_rTGA.good())
422 return sal_False;
423 if ( nDummy >= mpFileHeader->nColorMapLength )
424 return sal_False;
425 mpAcc->SetPixelIndex( nY, nX, nDummy );
426 nX += nXAdd;
427 nXCount++;
428 if ( nXCount == mpFileHeader->nImageWidth )
430 nX = nXStart;
431 nXCount = 0;
432 nY += nYAdd;
433 nYCount++;
435 if( nYCount >= mpFileHeader->nImageHeight )
436 break;
441 break;
442 default:
443 return sal_False;
446 else
448 switch( nDepth )
450 // 32 bit transparent true color encoding
451 case 32 :
453 while ( nYCount < mpFileHeader->nImageHeight )
455 m_rTGA >> nRunCount;
456 if ( !m_rTGA.good())
457 return sal_False;
458 if ( nRunCount & 0x80 ) // a run length packet
460 m_rTGA >> nBlue >> nGreen >> nRed >> nDummy;
461 if ( !m_rTGA.good())
462 return sal_False;
463 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
465 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
466 nX += nXAdd;
467 nXCount++;
468 if ( nXCount == mpFileHeader->nImageWidth )
470 nX = nXStart;
471 nXCount = 0;
472 nY += nYAdd;
473 nYCount++;
475 if( nYCount >= mpFileHeader->nImageHeight )
476 break;
480 else // a raw packet
482 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
484 m_rTGA >> nBlue >> nGreen >> nRed >> nDummy;
485 if ( !m_rTGA.good())
486 return sal_False;
487 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
488 nX += nXAdd;
489 nXCount++;
490 if ( nXCount == mpFileHeader->nImageWidth )
492 nX = nXStart;
493 nXCount = 0;
494 nY += nYAdd;
495 nYCount++;
497 if( nYCount >= mpFileHeader->nImageHeight )
498 break;
504 break;
506 // 24 bit true color encoding
507 case 24 :
508 while ( nYCount < mpFileHeader->nImageHeight )
510 m_rTGA >> nRunCount;
511 if ( !m_rTGA.good())
512 return sal_False;
513 if ( nRunCount & 0x80 ) // a run length packet
515 m_rTGA >> nBlue >> nGreen >> nRed;
516 if ( !m_rTGA.good())
517 return sal_False;
518 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
520 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
521 nX += nXAdd;
522 nXCount++;
523 if ( nXCount == mpFileHeader->nImageWidth )
525 nX = nXStart;
526 nXCount = 0;
527 nY += nYAdd;
528 nYCount++;
530 if( nYCount >= mpFileHeader->nImageHeight )
531 break;
535 else // a raw packet
537 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
539 m_rTGA >> nBlue >> nGreen >> nRed;
540 if ( !m_rTGA.good())
541 return sal_False;
542 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
543 nX += nXAdd;
544 nXCount++;
545 if ( nXCount == mpFileHeader->nImageWidth )
547 nX = nXStart;
548 nXCount = 0;
549 nY += nYAdd;
550 nYCount++;
552 if( nYCount >= mpFileHeader->nImageHeight )
553 break;
558 break;
560 // 16 bit true color encoding
561 case 16 :
562 while ( nYCount < mpFileHeader->nImageHeight )
564 m_rTGA >> nRunCount;
565 if ( !m_rTGA.good())
566 return sal_False;
567 if ( nRunCount & 0x80 ) // a run length packet
569 m_rTGA >> nRGB16;
570 if ( !m_rTGA.good())
571 return sal_False;
572 nRed = (sal_uInt8)( nRGB16 >> 7 ) & 0xf8;
573 nGreen = (sal_uInt8)( nRGB16 >> 2 ) & 0xf8;
574 nBlue = (sal_uInt8)( nRGB16 << 3 ) & 0xf8;
575 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
577 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
578 nX += nXAdd;
579 nXCount++;
580 if ( nXCount == mpFileHeader->nImageWidth )
582 nX = nXStart;
583 nXCount = 0;
584 nY += nYAdd;
585 nYCount++;
587 if( nYCount >= mpFileHeader->nImageHeight )
588 break;
592 else // a raw packet
594 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
596 m_rTGA >> nRGB16;
597 if ( !m_rTGA.good())
598 return sal_False;
599 nRed = (sal_uInt8)( nRGB16 >> 7 ) & 0xf8;
600 nGreen = (sal_uInt8)( nRGB16 >> 2 ) & 0xf8;
601 nBlue = (sal_uInt8)( nRGB16 << 3 ) & 0xf8;
602 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
603 nX += nXAdd;
604 nXCount++;
605 if ( nXCount == mpFileHeader->nImageWidth )
607 nX = nXStart;
608 nXCount = 0;
609 nY += nYAdd;
610 nYCount++;
612 if( nYCount >= mpFileHeader->nImageHeight )
613 break;
618 break;
620 default:
621 return sal_False;
625 else
627 for ( nYCount = 0; nYCount < mpFileHeader->nImageHeight; nYCount++, nY += nYAdd )
629 nX = nXStart;
630 nXCount = 0;
632 if ( mbIndexing )
634 switch( nDepth )
636 // 16 bit indexing
637 case 16 :
638 for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
640 m_rTGA >> nRGB16;
641 if ( !m_rTGA.good())
642 return sal_False;
643 if ( nRGB16 >= mpFileHeader->nColorMapLength )
644 return sal_False;
645 nRed = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 16 );
646 nGreen = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 8 );
647 nBlue = (sal_uInt8)( mpColorMap[ nRGB16 ] );
648 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
650 break;
652 // 8 bit indexing
653 case 8 :
654 for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
656 m_rTGA >> nDummy;
657 if ( !m_rTGA.good())
658 return sal_False;
659 if ( nDummy >= mpFileHeader->nColorMapLength )
660 return sal_False;
661 mpAcc->SetPixelIndex( nY, nX, nDummy );
663 break;
664 default:
665 return sal_False;
668 else
670 switch( nDepth )
672 // 32 bit true color
673 case 32 :
675 for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
677 m_rTGA >> nBlue >> nGreen >> nRed >> nDummy;
678 if ( !m_rTGA.good())
679 return sal_False;
680 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
683 break;
685 // 24 bit true color
686 case 24 :
687 for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
689 m_rTGA >> nBlue >> nGreen >> nRed;
690 if ( !m_rTGA.good())
691 return sal_False;
692 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
694 break;
696 // 16 bit true color
697 case 16 :
698 for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
700 m_rTGA >> nRGB16;
701 if ( !m_rTGA.good())
702 return sal_False;
703 nRed = (sal_uInt8)( nRGB16 >> 7 ) & 0xf8;
704 nGreen = (sal_uInt8)( nRGB16 >> 2 ) & 0xf8;
705 nBlue = (sal_uInt8)( nRGB16 << 3 ) & 0xf8;
706 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
708 break;
709 default:
710 return sal_False;
715 return mbStatus;
718 // -------------------------------------------------------------------------------------------
720 sal_Bool TGAReader::ImplReadPalette()
722 if ( mbIndexing ) // read the colormap
724 sal_uInt16 nColors = mpFileHeader->nColorMapLength;
726 if ( !nColors ) // colors == 0 ? -> we will build a grayscale palette
728 if ( mpFileHeader->nPixelDepth != 8 )
729 return sal_False;
730 nColors = 256;
731 mpFileHeader->nColorMapLength = 256;
732 mpFileHeader->nColorMapEntrySize = 0x3f; // patch for the following switch routine
734 mpColorMap = new sal_uInt32[ nColors ]; // we will always index dwords
735 if ( mpColorMap == sal_False )
736 return sal_False; // out of memory %&!$&/!"�$
738 switch( mpFileHeader->nColorMapEntrySize )
740 case 0x3f :
742 for ( sal_uLong i = 0; i < nColors; i++ )
744 mpColorMap[ i ] = ( i << 16 ) + ( i << 8 ) + i;
747 break;
749 case 32 :
750 m_rTGA.Read( mpColorMap, 4 * nColors );
751 break;
753 case 24 :
755 for ( sal_uLong i = 0; i < nColors; i++ )
757 m_rTGA.Read( &mpColorMap[ i ], 3 );
760 break;
762 case 15 :
763 case 16 :
765 for ( sal_uLong i = 0; i < nColors; i++ )
767 sal_uInt16 nTemp;
768 m_rTGA >> nTemp;
769 if ( !m_rTGA.good() )
770 return sal_False;
771 mpColorMap[ i ] = ( ( nTemp & 0x7c00 ) << 9 ) + ( ( nTemp & 0x01e0 ) << 6 ) +
772 ( ( nTemp & 0x1f ) << 3 );
775 break;
777 default :
778 return sal_False;
780 if ( mnDestBitDepth <= 8 )
782 sal_uInt16 nDestColors = ( 1 << mnDestBitDepth );
783 if ( nColors > nDestColors )
784 return sal_False;
786 mpAcc->SetPaletteEntryCount( nColors );
787 for ( sal_uInt16 i = 0; i < nColors; i++ )
789 mpAcc->SetPaletteColor( i, Color( (sal_uInt8)( mpColorMap[ i ] >> 16 ),
790 (sal_uInt8)( mpColorMap[ i ] >> 8 ), (sal_uInt8)(mpColorMap[ i ] ) ) );
795 return mbStatus;
798 //================== GraphicImport - die exportierte Funktion ================
800 // this needs to be kept in sync with
801 // ImpFilterLibCacheEntry::GetImportFunction() from
802 // vcl/source/filter/graphicfilter.cxx
803 #if defined(DISABLE_DYNLOADING)
804 #define GraphicImport itgGraphicImport
805 #endif
807 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
808 GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool)
810 TGAReader aTGAReader(rStream);
812 return aTGAReader.ReadTGA(rGraphic);
815 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */