LCOV - code coverage report
Current view: top level - libreoffice/filter/source/graphicfilter/itga - itga.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 117 400 29.2 %
Date: 2012-12-27 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10