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

Generated by: LCOV version 1.11