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

Generated by: LCOV version 1.10