xref: /AOO41X/main/filter/source/graphicfilter/itga/itga.cxx (revision 0af288bd36294aa09e93d369656aab1681e705d2)
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/bmpacc.hxx>
29 #include <svtools/fltcall.hxx>
30 
31 //============================ TGAReader ==================================
32 
33 struct TGAFileHeader
34 {
35     sal_uInt8       nImageIDLength;
36     sal_uInt8       nColorMapType;
37     sal_uInt8       nImageType;
38     sal_uInt16      nColorMapFirstEntryIndex;
39     sal_uInt16      nColorMapLength;
40     sal_uInt8       nColorMapEntrySize;
41     sal_uInt16      nColorMapXOrigin;
42     sal_uInt16      nColorMapYOrigin;
43     sal_uInt16      nImageWidth;
44     sal_uInt16      nImageHeight;
45     sal_uInt8       nPixelDepth;
46     sal_uInt8       nImageDescriptor;
47 };
48 
49 #define SizeOfTGAFileFooter 26
50 
51 struct TGAFileFooter
52 {
53     sal_uInt32      nExtensionFileOffset;
54     sal_uInt32      nDeveloperDirectoryOffset;
55     sal_uInt32      nSignature[4];
56     sal_uInt8       nPadByte;
57     sal_uInt8       nStringTerminator;
58 };
59 
60 #define SizeOfTGAExtension 495
61 
62 struct TGAExtension
63 {
64     sal_uInt16      nExtensionSize;
65     char        sAuthorName[41];
66     char        sAuthorComment[324];
67     char        sDateTimeStamp[12];
68     char        sJobNameID[41];
69     sal_uInt16      nJobTime[3];
70     char        sSoftwareID[41];
71     sal_uInt16      nSoftwareVersionNumber;
72     sal_uInt8       nSoftwareVersionLetter;
73     sal_uInt32      nKeyColor;
74     sal_uInt16      nPixelAspectRatioNumerator;
75     sal_uInt16      nPixelAspectRatioDeNumerator;
76     sal_uInt16      nGammaValueNumerator;
77     sal_uInt16      nGammaValueDeNumerator;
78     sal_uInt32      nColorCorrectionOffset;
79     sal_uInt32      nPostageStampOffset;
80     sal_uInt32      nScanLineOffset;
81     sal_uInt8       nAttributesType;
82 };
83 
84 class TGAReader {
85 
86 private:
87 
88     SvStream*           mpTGA;
89 
90     BitmapWriteAccess*  mpAcc;
91     TGAFileHeader*      mpFileHeader;
92     TGAFileFooter*      mpFileFooter;
93     TGAExtension*       mpExtension;
94     sal_uInt32*             mpColorMap;
95 
96     sal_Bool                mbStatus;
97 
98     sal_uLong               mnTGAVersion;       // Enhanced TGA is defined as Version 2.0
99     sal_uInt16              mnDestBitDepth;
100     sal_Bool                mbIndexing;         // sal_True if source contains indexing color values
101     sal_Bool                mbEncoding;         // sal_True if source is compressed
102 
103     sal_Bool                ImplReadHeader();
104     sal_Bool                ImplReadPalette();
105     sal_Bool                ImplReadBody();
106 
107 public:
108                         TGAReader();
109                         ~TGAReader();
110     sal_Bool                ReadTGA( SvStream & rTGA, Graphic & rGraphic );
111 };
112 
113 //=================== Methoden von TGAReader ==============================
114 
TGAReader()115 TGAReader::TGAReader() :
116     mpAcc           ( NULL ),
117     mpFileHeader    ( NULL ),
118     mpFileFooter    ( NULL ),
119     mpExtension     ( NULL ),
120     mpColorMap      ( NULL ),
121     mbStatus        ( sal_True ),
122     mnTGAVersion    ( 1 ),
123     mbIndexing      ( sal_False ),
124     mbEncoding      ( sal_False )
125 {
126 }
127 
~TGAReader()128 TGAReader::~TGAReader()
129 {
130     delete[] mpColorMap;
131     delete mpFileHeader;
132     delete mpExtension;
133     delete mpFileFooter;
134 }
135 
136 // -------------------------------------------------------------------------------------------
137 
ReadTGA(SvStream & rTGA,Graphic & rGraphic)138 sal_Bool TGAReader::ReadTGA( SvStream & rTGA, Graphic & rGraphic )
139 {
140     if ( rTGA.GetError() )
141         return sal_False;
142 
143     mpTGA = &rTGA;
144     mpTGA->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
145 
146     // Kopf einlesen:
147 
148     if ( !mpTGA->GetError() )
149     {
150         mbStatus = ImplReadHeader();
151         if ( mbStatus )
152         {
153             Bitmap              aBitmap;
154 
155             aBitmap = Bitmap( Size( mpFileHeader->nImageWidth, mpFileHeader->nImageHeight ), mnDestBitDepth );
156             mpAcc = aBitmap.AcquireWriteAccess();
157             if ( mpAcc )
158             {
159                 if ( mbIndexing )
160                     mbStatus = ImplReadPalette();
161                 if ( mbStatus )
162                     mbStatus = ImplReadBody();
163             }
164             else
165                 mbStatus = sal_False;
166 
167             if ( mpAcc )
168                 aBitmap.ReleaseAccess ( mpAcc), mpAcc = NULL;
169 
170             if ( mbStatus )
171                 rGraphic = aBitmap;
172         }
173     }
174     return mbStatus;
175 }
176 
177 // -------------------------------------------------------------------------------------------
178 
ImplReadHeader()179 sal_Bool TGAReader::ImplReadHeader()
180 {
181     mpFileHeader = new TGAFileHeader;
182     if ( mpFileHeader == NULL )
183         return sal_False;
184 
185     *mpTGA >> mpFileHeader->nImageIDLength >> mpFileHeader->nColorMapType >> mpFileHeader->nImageType >>
186         mpFileHeader->nColorMapFirstEntryIndex >> mpFileHeader->nColorMapLength >> mpFileHeader->nColorMapEntrySize >>
187             mpFileHeader->nColorMapXOrigin >> mpFileHeader->nColorMapYOrigin >> mpFileHeader->nImageWidth >>
188                 mpFileHeader->nImageHeight >> mpFileHeader->nPixelDepth >> mpFileHeader->nImageDescriptor;
189 
190     if ( mpFileHeader->nColorMapType > 1 )
191         return sal_False;
192     if ( mpFileHeader->nColorMapType == 1 )
193         mbIndexing = sal_True;
194 
195     // first we want to get the version
196     mpFileFooter = new TGAFileFooter;       // read the TGA-File-Footer to determine whether
197     if ( mpFileFooter )                     // we got an old TGA format or the new one
198     {
199         sal_uLong nCurStreamPos = mpTGA->Tell();
200         mpTGA->Seek( STREAM_SEEK_TO_END );
201         sal_uLong nTemp = mpTGA->Tell();
202         mpTGA->Seek( nTemp - SizeOfTGAFileFooter );
203 
204         *mpTGA >> mpFileFooter->nExtensionFileOffset >> mpFileFooter->nDeveloperDirectoryOffset >>
205             mpFileFooter->nSignature[0] >> mpFileFooter->nSignature[1] >> mpFileFooter->nSignature[2] >>
206                 mpFileFooter->nSignature[3] >> mpFileFooter->nPadByte >> mpFileFooter->nStringTerminator;
207 
208         // check for sal_True, VISI, ON-X, FILE in the signatures
209         if ( mpFileFooter->nSignature[ 0 ] == (('T'<<24)|('R'<<16)|('U'<<8)|'E') &&
210              mpFileFooter->nSignature[ 1 ] == (('V'<<24)|('I'<<16)|('S'<<8)|'I') &&
211              mpFileFooter->nSignature[ 2 ] == (('O'<<24)|('N'<<16)|('-'<<8)|'X') &&
212              mpFileFooter->nSignature[ 3 ] == (('F'<<24)|('I'<<16)|('L'<<8)|'E') )
213         {
214             mpExtension = new TGAExtension;
215             if ( mpExtension )
216             {
217                 mpTGA->Seek( mpFileFooter->nExtensionFileOffset );
218                 *mpTGA >> mpExtension->nExtensionSize;
219                 if ( mpExtension->nExtensionSize >= SizeOfTGAExtension )
220                 {
221                     mnTGAVersion = 2;
222 
223                     mpTGA->Read( mpExtension->sAuthorName, 41 );
224                     mpTGA->Read( mpExtension->sAuthorComment, 324 );
225                     mpTGA->Read( mpExtension->sDateTimeStamp, 12 );
226                     mpTGA->Read( mpExtension->sJobNameID, 12 );
227                     *mpTGA >> mpExtension->sJobNameID[ 0 ] >> mpExtension->sJobNameID[ 1 ] >> mpExtension->sJobNameID[ 2 ];
228                     mpTGA->Read( mpExtension->sSoftwareID, 41 );
229                     *mpTGA >> mpExtension->nSoftwareVersionNumber >> mpExtension->nSoftwareVersionLetter
230                         >> mpExtension->nKeyColor >> mpExtension->nPixelAspectRatioNumerator
231                             >> mpExtension->nPixelAspectRatioDeNumerator >> mpExtension->nGammaValueNumerator
232                                 >> mpExtension->nGammaValueDeNumerator >> mpExtension->nColorCorrectionOffset
233                                     >> mpExtension->nPostageStampOffset >> mpExtension->nScanLineOffset
234                                         >> mpExtension->nAttributesType;
235 
236                 }
237             }
238         }
239         mpTGA->Seek( nCurStreamPos );
240     }
241 
242     //  using the TGA file specification this was the correct form but adobe photoshop sets nImageDescriptor
243     //  equal to nPixelDepth
244     //  mnDestBitDepth = mpFileHeader->nPixelDepth - ( mpFileHeader->nImageDescriptor & 0xf );
245     mnDestBitDepth = mpFileHeader->nPixelDepth;
246 
247     if ( mnDestBitDepth == 8 )                  // this is a patch for grayscale pictures not including a palette
248         mbIndexing = sal_True;
249 
250     if ( mnDestBitDepth > 32 )                  // maybe the pixeldepth is invalid
251         return sal_False;
252     else if ( mnDestBitDepth > 8 )
253         mnDestBitDepth = 24;
254     else if ( mnDestBitDepth > 4 )
255         mnDestBitDepth = 8;
256     else if ( mnDestBitDepth > 2 )
257         mnDestBitDepth = 4;
258 
259     if ( !mbIndexing && ( mnDestBitDepth < 15 ) )
260         return sal_False;
261 
262     switch ( mpFileHeader->nImageType )
263     {
264         case 9  :                               // encoding for colortype 9, 10, 11
265         case 10 :
266         case 11 :
267             mbEncoding = sal_True;
268             break;
269     };
270 
271     if ( mpFileHeader->nImageIDLength )         // skip the Image ID
272         mpTGA->SeekRel( mpFileHeader->nImageIDLength );
273 
274     return mbStatus;
275 }
276 
277 // -------------------------------------------------------------------------------------------
278 
ImplReadBody()279 sal_Bool TGAReader::ImplReadBody()
280 {
281 
282     sal_uInt16  nXCount, nYCount, nRGB16;
283     sal_uInt8   nRed, nGreen, nBlue, nRunCount, nDummy, nDepth;
284 
285     // this four variables match the image direction
286     long    nY, nYAdd, nX, nXAdd, nXStart;
287 
288     nX = nXStart = nY = 0;
289     nXCount = nYCount = 0;
290     nYAdd = nXAdd = 1;
291 
292     if ( mpFileHeader->nImageDescriptor & 0x10 )
293     {
294         nX = nXStart = mpFileHeader->nImageWidth - 1;
295         nXAdd -= 2;
296     }
297 
298     if ( !(mpFileHeader->nImageDescriptor & 0x20 ) )
299     {
300         nY = mpFileHeader->nImageHeight - 1;
301         nYAdd -=2;
302     }
303 
304 //  nDepth = mpFileHeader->nPixelDepth - ( mpFileHeader->nImageDescriptor & 0xf );
305     nDepth = mpFileHeader->nPixelDepth;
306 
307     if ( mbEncoding )
308     {
309         if ( mbIndexing )
310         {
311             switch( nDepth )
312             {
313                 // 16 bit encoding + indexing
314                 case 16 :
315                     while ( nYCount < mpFileHeader->nImageHeight )
316                     {
317                         *mpTGA >> nRunCount;
318                         if ( nRunCount & 0x80 )     // a run length packet
319                         {
320                             *mpTGA >> nRGB16;
321                             if ( nRGB16 >= mpFileHeader->nColorMapLength )
322                                 return sal_False;
323                             nRed = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 16 );
324                             nGreen = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 8 );
325                             nBlue = (sal_uInt8)( mpColorMap[ nRGB16 ] );
326                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
327                             {
328                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
329                                 nX += nXAdd;
330                                 nXCount++;
331                                 if ( nXCount == mpFileHeader->nImageWidth )
332                                 {
333                                     nX = nXStart;
334                                     nXCount = 0;
335                                     nY += nYAdd;
336                                     nYCount++;
337 
338                                     if( nYCount >= mpFileHeader->nImageHeight )
339                                         return false; // invalid picture
340                                 }
341                             }
342                         }
343                         else                        // a raw packet
344                         {
345                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
346                             {
347                                 *mpTGA >> nRGB16;
348                                 if ( nRGB16 >= mpFileHeader->nColorMapLength )
349                                     return sal_False;
350                                 nRed = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 16 );
351                                 nGreen = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 8 );
352                                 nBlue = (sal_uInt8)( mpColorMap[ nRGB16 ] );
353                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
354                                 nX += nXAdd;
355                                 nXCount++;
356                                 if ( nXCount == mpFileHeader->nImageWidth )
357                                 {
358                                     nX = nXStart;
359                                     nXCount = 0;
360                                     nY += nYAdd;
361                                     nYCount++;
362 
363                                     if( nYCount >= mpFileHeader->nImageHeight )
364                                         return false; // invalid picture
365                                 }
366                             }
367                         }
368                     }
369                     break;
370 
371                 // 8 bit encoding + indexing
372                 case 8 :
373                     while ( nYCount < mpFileHeader->nImageHeight )
374                     {
375                         *mpTGA >> nRunCount;
376                         if ( nRunCount & 0x80 )     // a run length packet
377                         {
378                             *mpTGA >> nDummy;
379                             if ( nDummy >= mpFileHeader->nColorMapLength )
380                                 return sal_False;
381                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
382                             {
383                                 mpAcc->SetPixelIndex( nY, nX, nDummy );
384                                 nX += nXAdd;
385                                 nXCount++;
386                                 if ( nXCount == mpFileHeader->nImageWidth )
387                                 {
388                                     nX = nXStart;
389                                     nXCount = 0;
390                                     nY += nYAdd;
391                                     nYCount++;
392 
393                                     if( nYCount >= mpFileHeader->nImageHeight )
394                                         return false; // invalid picture
395                                 }
396                             }
397                         }
398                         else                        // a raw packet
399                         {
400                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
401                             {
402 
403                                 *mpTGA >> nDummy;
404                                 if ( nDummy >= mpFileHeader->nColorMapLength )
405                                     return sal_False;
406                                 mpAcc->SetPixelIndex( nY, nX, nDummy );
407                                 nX += nXAdd;
408                                 nXCount++;
409                                 if ( nXCount == mpFileHeader->nImageWidth )
410                                 {
411                                     nX = nXStart;
412                                     nXCount = 0;
413                                     nY += nYAdd;
414                                     nYCount++;
415 
416                                     if( nYCount >= mpFileHeader->nImageHeight )
417                                         return false; // invalid picture
418                                 }
419                             }
420                         }
421                     }
422                     break;
423                 default:
424                     return sal_False;
425             }
426         }
427         else
428         {
429             switch( nDepth )
430             {
431                 // 32 bit transparent true color encoding
432                 case 32 :
433                     {
434                         while ( nYCount < mpFileHeader->nImageHeight )
435                         {
436                             *mpTGA >> nRunCount;
437                             if ( nRunCount & 0x80 )     // a run length packet
438                             {
439                                 *mpTGA >> nBlue >> nGreen >> nRed >> nDummy;
440                                 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
441                                 {
442                                     mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
443                                     nX += nXAdd;
444                                     nXCount++;
445                                     if ( nXCount == mpFileHeader->nImageWidth )
446                                     {
447                                         nX = nXStart;
448                                         nXCount = 0;
449                                         nY += nYAdd;
450                                         nYCount++;
451 
452                                         if( nYCount >= mpFileHeader->nImageHeight )
453                                             return false; // invalid picture
454                                     }
455                                 }
456                             }
457                             else                        // a raw packet
458                             {
459                                 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
460                                 {
461                                     *mpTGA >> nBlue >> nGreen >> nRed >> nDummy;
462                                     mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
463                                     nX += nXAdd;
464                                     nXCount++;
465                                     if ( nXCount == mpFileHeader->nImageWidth )
466                                     {
467                                         nX = nXStart;
468                                         nXCount = 0;
469                                         nY += nYAdd;
470                                         nYCount++;
471 
472                                         if( nYCount >= mpFileHeader->nImageHeight )
473                                             return false; // invalid picture
474                                     }
475                                 }
476                             }
477                         }
478                     }
479                     break;
480 
481                 // 24 bit true color encoding
482                 case 24 :
483                     while ( nYCount < mpFileHeader->nImageHeight )
484                     {
485                         *mpTGA >> nRunCount;
486                         if ( nRunCount & 0x80 )     // a run length packet
487                         {
488                             *mpTGA >> nBlue >> nGreen >> nRed;
489                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
490                             {
491                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
492                                 nX += nXAdd;
493                                 nXCount++;
494                                 if ( nXCount == mpFileHeader->nImageWidth )
495                                 {
496                                     nX = nXStart;
497                                     nXCount = 0;
498                                     nY += nYAdd;
499                                     nYCount++;
500 
501                                     if( nYCount >= mpFileHeader->nImageHeight )
502                                         return false; // invalid picture
503                                 }
504                             }
505                         }
506                         else                        // a raw packet
507                         {
508                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
509                             {
510                                 *mpTGA >> nBlue >> nGreen >> nRed;
511                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
512                                 nX += nXAdd;
513                                 nXCount++;
514                                 if ( nXCount == mpFileHeader->nImageWidth )
515                                 {
516                                     nX = nXStart;
517                                     nXCount = 0;
518                                     nY += nYAdd;
519                                     nYCount++;
520 
521                                     if( nYCount >= mpFileHeader->nImageHeight )
522                                         return false; // invalid picture
523                                 }
524                             }
525                         }
526                     }
527                     break;
528 
529                 // 16 bit true color encoding
530                 case 16 :
531                     while ( nYCount < mpFileHeader->nImageHeight )
532                     {
533                         *mpTGA >> nRunCount;
534                         if ( nRunCount & 0x80 )     // a run length packet
535                         {
536                             *mpTGA >> nRGB16;
537                             nRed = (sal_uInt8)( nRGB16 >> 7 ) & 0xf8;
538                             nGreen = (sal_uInt8)( nRGB16 >> 2 ) & 0xf8;
539                             nBlue = (sal_uInt8)( nRGB16 << 3 ) & 0xf8;
540                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
541                             {
542                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
543                                 nX += nXAdd;
544                                 nXCount++;
545                                 if ( nXCount == mpFileHeader->nImageWidth )
546                                 {
547                                     nX = nXStart;
548                                     nXCount = 0;
549                                     nY += nYAdd;
550                                     nYCount++;
551 
552                                     if( nYCount >= mpFileHeader->nImageHeight )
553                                         return false; // invalid picture
554                                 }
555                             }
556                         }
557                         else                        // a raw packet
558                         {
559                             for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
560                             {
561                                 *mpTGA >> nRGB16;
562                                 nRed = (sal_uInt8)( nRGB16 >> 7 ) & 0xf8;
563                                 nGreen = (sal_uInt8)( nRGB16 >> 2 ) & 0xf8;
564                                 nBlue = (sal_uInt8)( nRGB16 << 3 ) & 0xf8;
565                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
566                                 nX += nXAdd;
567                                 nXCount++;
568                                 if ( nXCount == mpFileHeader->nImageWidth )
569                                 {
570                                     nX = nXStart;
571                                     nXCount = 0;
572                                     nY += nYAdd;
573                                     nYCount++;
574 
575                                     if( nYCount >= mpFileHeader->nImageHeight )
576                                         return false; // invalid picture
577                                 }
578                             }
579                         }
580                     }
581                     break;
582 
583                 default:
584                     return sal_False;
585             }
586         }
587     }
588     else
589     {
590         for ( nYCount = 0; nYCount < mpFileHeader->nImageHeight; nYCount++, nY += nYAdd )
591         {
592             nX = nXStart;
593             nXCount = 0;
594 
595             if ( mbIndexing )
596             {
597                 switch( nDepth )
598                 {
599                     // 16 bit indexing
600                     case 16 :
601                         for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
602                         {
603                             *mpTGA >> nRGB16;
604                             if ( nRGB16 >= mpFileHeader->nColorMapLength )
605                                 return sal_False;
606                             nRed = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 16 );
607                             nGreen = (sal_uInt8)( mpColorMap[ nRGB16 ] >> 8 );
608                             nBlue = (sal_uInt8)( mpColorMap[ nRGB16 ] );
609                             mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
610                         }
611                         break;
612 
613                     // 8 bit indexing
614                     case 8 :
615                         for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
616                         {
617                             *mpTGA >> nDummy;
618                             if ( nDummy >= mpFileHeader->nColorMapLength )
619                                 return sal_False;
620                             mpAcc->SetPixelIndex( nY, nX, nDummy );
621                         }
622                         break;
623                     default:
624                         return sal_False;
625                 }
626             }
627             else
628             {
629                 switch( nDepth )
630                 {
631                     // 32 bit true color
632                     case 32 :
633                         {
634                             for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
635                             {
636                                 *mpTGA >> nBlue >> nGreen >> nRed >> nDummy;
637                                 mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
638                             }
639                         }
640                         break;
641 
642                     // 24 bit true color
643                     case 24 :
644                         for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
645                         {
646                             *mpTGA >> nBlue >> nGreen >> nRed;
647                             mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
648                         }
649                         break;
650 
651                     // 16 bit true color
652                     case 16 :
653                         for (;nXCount < mpFileHeader->nImageWidth; nXCount++, nX += nXAdd )
654                         {
655                             *mpTGA >> nRGB16;
656                             nRed = (sal_uInt8)( nRGB16 >> 7 ) & 0xf8;
657                             nGreen = (sal_uInt8)( nRGB16 >> 2 ) & 0xf8;
658                             nBlue = (sal_uInt8)( nRGB16 << 3 ) & 0xf8;
659                             mpAcc->SetPixel( nY, nX, BitmapColor( nRed, nGreen, nBlue ) );
660                         }
661                         break;
662                     default:
663                         return sal_False;
664                 }
665             }
666         }
667     }
668     return mbStatus;
669 }
670 
671 // -------------------------------------------------------------------------------------------
672 
ImplReadPalette()673 sal_Bool TGAReader::ImplReadPalette()
674 {
675     if ( mbIndexing )                           // read the colormap
676     {
677         sal_uInt16 nColors = mpFileHeader->nColorMapLength;
678 
679         if ( !nColors )                             // colors == 0 ? -> we will build a grayscale palette
680         {
681             if ( mpFileHeader->nPixelDepth != 8 )
682                 return sal_False;
683             nColors = 256;
684             mpFileHeader->nColorMapLength = 256;
685             mpFileHeader->nColorMapEntrySize = 0x3f;    // patch for the following switch routine
686         }
687         mpColorMap = new sal_uInt32[ nColors ];     // we will always index dwords
688         if ( !mpColorMap ) // NOTE: check for new-result==NULL because exceptions are disabled in this module
689             return sal_False;                       // out of memory %&!$&/!"�$
690 
691         switch( mpFileHeader->nColorMapEntrySize )
692         {
693             case 0x3f :
694                 {
695                     for ( sal_uLong i = 0; i < nColors; i++ )
696                     {
697                         mpColorMap[ i ] = ( i << 16 ) + ( i << 8 ) + i;
698                     }
699                 }
700                 break;
701 
702             case 32 :
703                 mpTGA->Read( mpColorMap, 4 * nColors );
704                 break;
705 
706             case 24 :
707                 {
708                     for ( sal_uLong i = 0; i < nColors; i++ )
709                     {
710                         mpTGA->Read( &mpColorMap[ i ], 3 );
711                     }
712                 }
713                 break;
714 
715             case 15 :
716             case 16 :
717                 {
718                     for ( sal_uLong i = 0; i < nColors; i++ )
719                     {
720                         sal_uInt16 nTemp;
721                         *mpTGA >> nTemp;
722                         mpColorMap[ i ] = ( ( nTemp & 0x7c00 ) << 9 ) + ( ( nTemp & 0x01e0 ) << 6 ) +
723                             ( ( nTemp & 0x1f ) << 3 );
724                     }
725                 }
726                 break;
727 
728             default :
729                 return sal_False;
730         }
731         if ( mnDestBitDepth <= 8 )
732         {
733             sal_uInt16 nDestColors = ( 1 << mnDestBitDepth );
734             if ( nColors > nDestColors )
735                 return sal_False;
736 
737             mpAcc->SetPaletteEntryCount( nColors );
738             for ( sal_uInt16 i = 0; i < nColors; i++ )
739             {
740                 mpAcc->SetPaletteColor( i, Color( (sal_uInt8)( mpColorMap[ i ] >> 16 ),
741                     (sal_uInt8)( mpColorMap[ i ] >> 8 ), (sal_uInt8)(mpColorMap[ i ] ) ) );
742             }
743         }
744     }
745 
746     return mbStatus;
747 }
748 
749 //================== GraphicImport - die exportierte Funktion ================
750 
GraphicImport(SvStream & rStream,Graphic & rGraphic,FilterConfigItem *,sal_Bool)751 extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool )
752 {
753     TGAReader aTGAReader;
754 
755     return aTGAReader.ReadTGA( rStream, rGraphic );
756 }
757 
758